Showing preview only (8,461K chars total). Download the full file or copy to clipboard to get everything.
Repository: shorepine/amy
Branch: main
Commit: a63d600c6007
Files: 156
Total size: 8.0 MB
Directory structure:
gitextract_vrmra0ai/
├── .claude/
│ └── launch.json
├── .github/
│ └── workflows/
│ ├── arduino.yml
│ ├── c-cpp.yml
│ └── godot-addon.yml
├── .gitignore
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Makefile
├── README.md
├── amy/
│ ├── __init__.py
│ ├── constants.py
│ ├── examples.py
│ ├── fm.py
│ ├── headers.py
│ ├── juno.py
│ ├── piano.py
│ ├── piano_params.py
│ ├── sineclock.py
│ ├── test.py
│ ├── timing.py
│ ├── wave.py
│ └── xanadu.py
├── daisy/
│ ├── Makefile
│ └── amy_daisy.cpp
├── docs/
│ ├── amy.aw.js
│ ├── amy.graffle
│ ├── amy.js
│ ├── amy.wasm
│ ├── amy.ww.js
│ ├── amyrepl.css
│ ├── amyrepl.js
│ ├── api.md
│ ├── arduino.md
│ ├── billie_jean.md
│ ├── chunk.py
│ ├── enable-threads.js
│ ├── godot.md
│ ├── index.html
│ ├── juno_patches.md
│ ├── micropython.mjs
│ ├── micropython.wasm
│ ├── midi.md
│ ├── minimal.html
│ ├── piano.html
│ ├── repl.html
│ ├── server.py
│ ├── style.css
│ ├── synth.md
│ ├── tutorial.html
│ └── upgrading.md
├── examples/
│ ├── AMY_ESP32_manual_I2S/
│ │ └── AMY_ESP32_manual_I2S.ino
│ ├── AMY_MIDI_Synth/
│ │ └── AMY_MIDI_Synth.ino
│ ├── AMY_USB_Host_MIDI/
│ │ └── AMY_USB_Host_MIDI.ino
│ ├── AMY_custom_osc/
│ │ └── AMY_custom_osc.ino
│ ├── AMY_pico_PWM/
│ │ └── AMY_pico_PWM.ino
│ ├── BillieJeanDrums/
│ │ └── BillieJeanDrums.ino
│ ├── BillieJeanDrumsBass/
│ │ └── BillieJeanDrumsBass.ino
│ └── BillieJeanScheduled/
│ └── BillieJeanScheduled.ino
├── experiments/
│ ├── Piano.ff.D5.json
│ ├── compare_test_wavs.ipynb
│ ├── dx7_simulator.py
│ ├── make_piano_examples.ipynb
│ ├── piano-params.json
│ ├── piano-partials.ipynb
│ ├── piano_examples.py
│ ├── piano_heterodyne.ipynb
│ ├── piano_params.py
│ ├── track02-C4-bps.json
│ └── tulip_piano.py
├── godot/
│ ├── SConstruct
│ ├── amy.gd
│ ├── amy.gdextension
│ ├── install.gd
│ ├── src/
│ │ ├── amy_gdextension.cpp
│ │ ├── amy_gdextension.h
│ │ ├── amy_platform_stubs.c
│ │ ├── register_types.cpp
│ │ └── register_types.h
│ └── web/
│ ├── custom_shell.html
│ └── godot_amy_bridge.js
├── library.properties
├── pyproject.toml
├── requirements.txt
├── scripts/
│ ├── gen_amy_js_api.py
│ └── gen_patches_js.py
├── setup.py
├── setup_godot.sh
├── sounds/
│ └── HS-TR-808-Drums.sf2
├── src/
│ ├── AMY-Arduino.h
│ ├── algorithms.c
│ ├── amy-example.c
│ ├── amy-message.c
│ ├── amy-piano.c
│ ├── amy.c
│ ├── amy.h
│ ├── amy_connector.js
│ ├── amy_fixedpoint.h
│ ├── amy_midi.c
│ ├── amy_midi.h
│ ├── api.c
│ ├── clipping_lookup_table.h
│ ├── custom.c
│ ├── delay.c
│ ├── delay.h
│ ├── envelope.c
│ ├── examples.c
│ ├── examples.h
│ ├── filters.c
│ ├── i2s.c
│ ├── instrument.c
│ ├── interp_partials.c
│ ├── interp_partials.h
│ ├── libminiaudio-audio.c
│ ├── libminiaudio-audio.h
│ ├── log2_exp2.c
│ ├── log2_exp2_fxpt_lutable.h
│ ├── macos_midi.m
│ ├── midi_mappings.c
│ ├── miniaudio.h
│ ├── oscillators.c
│ ├── parse.c
│ ├── patches.c
│ ├── patches.h
│ ├── pcm.c
│ ├── pcm_samples_tiny.h
│ ├── pcm_tiny.h
│ ├── pico-audio/
│ │ ├── audio.cpp
│ │ ├── audio.h
│ │ ├── audio_i2s.c
│ │ ├── audio_i2s.h
│ │ ├── audio_i2s.pio
│ │ ├── audio_i2s.pio.h
│ │ ├── buffer.c
│ │ ├── buffer.h
│ │ └── sample_conversion.h
│ ├── pico_extras_import.cmake
│ ├── pico_sdk_import.cmake
│ ├── pico_support.cpp
│ ├── pyamy.c
│ ├── saw_lutset_fxpt.h
│ ├── sequencer.c
│ ├── sequencer.h
│ ├── sine_lutset_fxpt.h
│ ├── teensy_support.cpp
│ ├── teensy_support.h
│ ├── transfer.c
│ ├── transfer.h
│ ├── triangle_lutset_fxpt.h
│ ├── usb.c
│ └── usb.h
├── valgrind.suppressions
└── windows/
├── CMakeLists.txt
├── README.md
├── amy_sine.c
└── build.bat
================================================
FILE CONTENTS
================================================
================================================
FILE: .claude/launch.json
================================================
{
"version": "0.0.1",
"configurations": [
{
"name": "amy-docs",
"runtimeExecutable": "python3",
"runtimeArgs": ["-m", "http.server", "8080", "-d", "docs"],
"port": 8080
}
]
}
================================================
FILE: .github/workflows/arduino.yml
================================================
name: Arduino CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
compile:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: "ESP32-S3"
fqbn: "esp32:esp32:esp32s3"
platforms: |
- name: esp32:esp32
source-url: https://espressif.github.io/arduino-esp32/package_esp32_index.json
- name: "RP2040 (Pico)"
fqbn: "rp2040:rp2040:rpipico"
platforms: |
- name: rp2040:rp2040
source-url: https://github.com/earlephilhower/arduino-pico/releases/download/4.5.3/package_rp2040_index.json
- name: "RP2350 (Pico 2)"
fqbn: "rp2040:rp2040:rpipico2"
platforms: |
- name: rp2040:rp2040
source-url: https://github.com/earlephilhower/arduino-pico/releases/download/4.5.3/package_rp2040_index.json
- name: "Teensy 4.1"
fqbn: "teensy:avr:teensy41"
platforms: |
- name: teensy:avr
source-url: https://www.pjrc.com/teensy/package_teensy_index.json
name: ${{ matrix.name }}
steps:
- uses: actions/checkout@v4
- uses: arduino/compile-sketches@v1
with:
fqbn: ${{ matrix.fqbn }}
platforms: ${{ matrix.platforms }}
sketch-paths: |
- examples/BillieJeanDrums
enable-deltas-report: false
================================================
FILE: .github/workflows/c-cpp.yml
================================================
name: C/C++ CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.12', '3.13', '3.14']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install numpy scipy
- name: Build and test
env:
AMY_TEST_THRESHOLD_DB: "-70.0"
run: make test
================================================
FILE: .github/workflows/godot-addon.yml
================================================
name: Build Godot Addon
on:
push:
tags:
- '*'
workflow_dispatch:
permissions:
contents: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- name: macOS
runner: macos-latest
platform: macos
arch: universal
- name: Linux
runner: ubuntu-22.04
platform: linux
arch: x86_64
- name: Windows
runner: windows-latest
platform: windows
arch: x86_64
runs-on: ${{ matrix.runner }}
name: Build ${{ matrix.name }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install scons
run: pip install scons
- name: Checkout godot-cpp
uses: actions/checkout@v4
with:
repository: godotengine/godot-cpp
ref: godot-4.4-stable
path: godot-cpp
submodules: true
- name: Build debug
working-directory: godot
run: scons platform=${{ matrix.platform }} arch=${{ matrix.arch }} target=template_debug -j4
env:
GODOT_CPP_PATH: ${{ github.workspace }}/godot-cpp
AMY_SRC_PATH: ${{ github.workspace }}/src
- name: Build release
working-directory: godot
run: scons platform=${{ matrix.platform }} arch=${{ matrix.arch }} target=template_release -j4
env:
GODOT_CPP_PATH: ${{ github.workspace }}/godot-cpp
AMY_SRC_PATH: ${{ github.workspace }}/src
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: bin-${{ matrix.platform }}
path: godot/bin/
package:
needs: build
runs-on: ubuntu-latest
name: Package Addon
steps:
- uses: actions/checkout@v4
- name: Download all build artifacts
uses: actions/download-artifact@v4
with:
path: collected-bins/
- name: Assemble addon zip
run: |
mkdir -p addons/amy/bin
# Copy compiled binaries from all platforms
cp -r collected-bins/bin-macos/* addons/amy/bin/
cp -r collected-bins/bin-linux/* addons/amy/bin/
cp -r collected-bins/bin-windows/* addons/amy/bin/
# Copy GDExtension config and scripts
cp godot/amy.gdextension addons/amy/
cp godot/amy.gd addons/amy/
cp godot/install.gd addons/amy/
# Copy web export files
mkdir -p addons/amy/web
cp godot/web/godot_amy_bridge.js addons/amy/web/
cp godot/web/custom_shell.html addons/amy/web/
cp docs/amy.js addons/amy/web/
cp docs/amy.wasm addons/amy/web/
cp docs/amy.aw.js addons/amy/web/
cp docs/amy.ww.js addons/amy/web/
cp docs/enable-threads.js addons/amy/web/
cp docs/enable-threads.js addons/amy/web/enable-threads-root.js
# Create the zip
zip -r amy-godot-addon.zip addons/
- name: Upload addon zip
uses: actions/upload-artifact@v4
with:
name: amy-godot-addon
path: amy-godot-addon.zip
release:
needs: package
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
name: Create Release
steps:
- name: Download addon zip
uses: actions/download-artifact@v4
with:
name: amy-godot-addon
- name: Attach addon to release
uses: softprops/action-gh-release@v2
with:
files: amy-godot-addon.zip
================================================
FILE: .gitignore
================================================
uv.lock
amy-example
amy-message
tests/tst
amy-piano
src/build/
*.DS_Store*
loris-1.8/
__pycache__/
src/dist/
src/amy.egg-info/
.python-version
amy.egg-info/
build/
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
godot/.sconsign.dblite
godot/src/*.os
================================================
FILE: CLAUDE.md
================================================
# AMY Development Notes
## Releases
When creating a new release:
1. Update the version in `library.properties` to match the release tag
2. Create the GitHub release with a plain version tag (e.g. `1.2.3`, NOT `v1.2.3`) — Arduino requires this format
3. The Godot addon build workflow triggers automatically on tag push and attaches `amy-godot-addon.zip` to the release
## Godot GDExtension
- Local builds use `setup_godot.sh` which generates the SConstruct, C++ source, and GDScript wrapper inline
- CI builds use the `godot/` directory (SConstruct, src/, etc.) directly via `.github/workflows/godot-addon.yml`
- `amy_midi.c` is excluded from the Godot build because it conflicts with platform stubs. Any new functions added to `amy_midi.c` (or other excluded files) that are called from core AMY code need stub implementations added in both:
- `godot/src/amy_platform_stubs.c` (for CI builds)
- The `amy_platform_stubs.c` section of `setup_godot.sh` (for local builds)
- macOS builds produce a `.framework` bundle; the `gh auth` token needs `workflow` scope to push workflow file changes
## Web REPL (tutorial & docs)
The live Python REPL at `docs/tutorial.html` runs MicroPython in the browser with the `amy` Python module frozen in. Updating it requires rebuilding MicroPython from the `shorepine/tulipcc` repo:
1. In `tulipcc`, update the amy submodule to latest: `cd tulipcc && git submodule update --remote amy`
2. Rebuild MicroPython: `cd tulip/amyrepl && make clean && make`
3. Copy the output to amy's docs: `cp build-standard/tulip/obj/micropython.mjs build-standard/tulip/obj/micropython.wasm <amy-repo>/docs/`
4. If the AMY C code or JS API also changed, rebuild those too: `cd <amy-repo> && make web && make deploy-web`
The `docs/amy.js` file is a concatenation of the Emscripten build (`build/amy.js`), `src/amy_connector.js`, and `build/amy_api.generated.js`. The JS API is auto-generated from `amy/__init__.py` by `scripts/gen_amy_js_api.py`.
## GitHub Auth
- The `bwhitman` account needs `workflow` scope on its token to push changes to `.github/workflows/` files. Run `gh auth refresh -h github.com -s workflow` if pushes are rejected.
- SSH pushes to `shorepine/amy` use the `brianklay` key by default; use HTTPS with `gh auth token` for `bwhitman` access.
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at brian@variogr.am. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022 Brian Whitman and Daniel PW Ellis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Makefile
================================================
# Makefile for AMY , including an example
TARGET = amy-example amy-message amy-piano
LIBS = -lm -pthread
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
SOURCES = src/macos_midi.m
CFLAGS += -DMACOS
LIBS = -framework AudioUnit -framework CoreAudio -framework CoreFoundation -framework CoreMIDI -framework Cocoa -lstdc++
# Needed for brew's python3.12+ on MacOS
EXTRA_PIP_ENV = PIP_BREAK_SYSTEM_PACKAGES=1
CC = clang
else
CC = gcc
endif
# on Raspberry Pi, at least under 32-bit mode, libatomic and libdl are needed.
ifeq ($(shell uname -m), armv7l)
LIBS += -ldl -latomic
endif
ifeq ($(shell uname -m), armv6l)
LIBS += -ldl -latomic
endif
CFLAGS += -O3 -Wall -Wno-strict-aliasing -Wextra -Wno-unused-parameter -Wpointer-arith -Wno-float-conversion -Wno-missing-declarations -DAMY_WAVETABLE
#CFLAGS += -DAMY_DEBUG
# -Wdouble-promotion
EMSCRIPTEN_OPTIONS = -s WASM=1 --bind \
-DMA_ENABLE_AUDIO_WORKLETS -sAUDIO_WORKLET=1 -sWASM_WORKERS=1 \
-sSTACK_SIZE=128000\
-sMODULARIZE -s 'EXPORT_NAME="amyModule"' \
-s EXPORTED_RUNTIME_METHODS="['cwrap','ccall', 'HEAPU8']" \
-s EXPORTED_FUNCTIONS="['_amy_add_message', '_amy_add_event', '_amy_reset_sysclock', '_amy_sysclock', '_amy_process_single_midi_byte', \
'_amy_live_stop', '_amy_get_input_buffer', '_amy_get_output_buffer', '_amy_set_external_input_buffer', '_amy_live_start_web', '_amy_live_start_web_audioin',\
'_amy_start_web', '_amy_start_web_no_synths', '_sequencer_ticks', '_malloc', '_free', '_amy_bleep', '_yield_patch_events', '_size_of_amy_event', '_yield_synth_commands', '_amy_dump_state_to_string']" \
-s SUPPORT_LONGJMP=emscripten \
-s INITIAL_MEMORY=128mb -s TOTAL_STACK=64mb -s ALLOW_MEMORY_GROWTH=1 \
-s ASYNCIFY -s ASYNCIFY_STACK_SIZE=128000
PYTHON = python3
.PHONY: default all clean amy-module test web deploy-web
default: $(TARGET)
all: default
SOURCES += src/algorithms.c src/amy.c src/envelope.c src/examples.c src/parse.c \
src/filters.c src/oscillators.c src/pcm.c src/interp_partials.c src/custom.c \
src/delay.c src/log2_exp2.c src/patches.c src/transfer.c src/sequencer.c \
src/libminiaudio-audio.c src/instrument.c src/amy_midi.c src/api.c src/midi_mappings.c
OBJECTS = $(patsubst %.c, %.o, $(SOURCES))
HEADERS = $(wildcard src/*.h)
HEADERS_BUILD := $(filter-out src/patches.h,$(HEADERS))
PYTHONS = $(wildcard *.py)
src/patches.h: $(PYTHONS) $(HEADERS_BUILD)
cat src/amy.h | sed -e 's@^//.*@@' | egrep 'define +[^ ]+ +[.0-9-]+' | sed -e 's/\([.0-9]\)f$$/\1/' | awk '{print $$2 "=" $$3}' > amy/constants.py
${PYTHON} -m amy.headers
%.o: %.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.mm $(HEADERS)
clang $(CFLAGS) -c $< -o $@
%.o: %.m
clang -I$(INC) $(CFLAGS) -c -o $@ $<
.PRECIOUS: $(TARGET) $(OBJECTS)
amy-example: $(OBJECTS) src/amy-example.o
$(CC) $(CFLAGS) $(OBJECTS) src/amy-example.o -Wall $(LIBS) -o $@
amy-piano: $(OBJECTS) src/amy-piano.o
$(CC) $(CFLAGS) $(OBJECTS) src/amy-piano.o -Wall $(LIBS) -o $@
amy-message: $(OBJECTS) src/amy-message.o
$(CC) $(CFLAGS) $(OBJECTS) src/amy-message.o -Wall $(LIBS) -o $@
amy-module: amy-example
${EXTRA_PIP_ENV} ${PYTHON} -m pip install -r requirements.txt; touch src/amy.c; ${EXTRA_PIP_ENV} ${PYTHON} -m pip install . --force-reinstall --no-deps; cd ..
test: amy-module
${PYTHON} -m amy.test
qtest: amy-module
${PYTHON} -m amy.test quiet
# Report the median FILTER_PROCESS timing over 50 runs.
timing: amy-module
for a in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40; do ${PYTHON} -m amy.timing 2>&1 ; done > /tmp/timings.txt
cat /tmp/timings.txt | grep AMY_RENDER: | sed -e 's/us//' | sort -n | awk ' { a[i++]=$$4; } END { print a[int(i/2)]; }'
cat /tmp/timings.txt | grep FILTER_PROCESS: | sed -e 's/us//' | sort -n | awk ' { a[i++]=$$4; } END { print a[int(i/2)]; }'
cat /tmp/timings.txt | grep PARAMETRIC_EQ_PROCESS: | sed -e 's/us//' | sort -n | awk ' { a[i++]=$$4; } END { print a[int(i/2)]; }'
valgrind: amy-example
valgrind --leak-check=full --show-reachable=yes --suppressions=valgrind.suppressions ./amy-example
build/amy.js: $(TARGET)
mkdir -p build
emcc $(SOURCES) $(CFLAGS) $(EMSCRIPTEN_OPTIONS) -O3 -o $@
build/amy_api.generated.js: scripts/gen_amy_js_api.py amy/__init__.py src/patches.h
mkdir -p build
$(PYTHON) scripts/gen_amy_js_api.py
build/patches.generated.js: scripts/gen_patches_js.py src/patches.h
mkdir -p build
$(PYTHON) scripts/gen_patches_js.py
web: build/amy.js build/amy_api.generated.js build/patches.generated.js
deploy-web: web
cat build/amy.js src/amy_connector.js build/amy_api.generated.js > docs/amy.js
cp build/amy.wasm build/amy.aw.js build/amy.ww.js docs/
clean:
-rm -f src/*.o
-rm -r src/patches.h
-rm -f amy/constants.py
-rm -f $(TARGET)
================================================
FILE: README.md
================================================
# AMY - The high-performance fixed-point music synthesizer library
AMY is a fast and small music synthesizer library written in C with (so far) Python, Arduino, Javascript and GDScript bindings. It can easily be embedded into almost any program, architecture or microcontroller.
It can be used as a very good analog-type synthesizer (Juno-6 style) a FM synthesizer (DX7 style), a partial breakpoint synthesizer (Alles machine or Atari AMY), a [very good synthesized piano](https://shorepine.github.io/amy/piano.html), a sampler or wavetable synth (where you load in your own PCM data), a drum machine (808-style PCM samples are included), or as a lower level toolkit to make your own combinations of oscillators, filters, LFOs and effects. AMY supports MIDI internally and can manage synthesizer note messages for you, including voice stealing and assigning controller changes.
We've run AMY on:
* [the web](https://shorepine.github.io/amy/)
* Mac, Linux, and [Windows](windows/README.md), and small Linux devices like the Raspberry Pi
* ESP32, ESP32S3 (Xtensa)
* ESP32-P4, ESP32-C3, C6 (RISC-V)
* Pi Pico RP2040, the Pi Pico 2 RP2350
* [NRF52 series](https://github.com/jgartrel/amy_synth_nrf52_example)
* Teensy 3.6, Teensy 4.1
* Playdate and Electro-Smith Daisy (ARM Cortex M7)
* iOS devices
* [Godot game engine](docs/godot.md)
* And certainly much more
AMY is highly optimized for polyphony and poly-timbral operation on even the lowest power and constrained RAM microcontroller but can scale to as many oscillators as you want.
AMY powers the multi-speaker mesh synthesizer [Alles](https://github.com/shorepine/alles), as well as the [Tulip Creative Computer](https:/tulip.computer). Let us know if you use AMY for your own projects and we'll add it here!
AMY was built by [DAn Ellis](https://research.google/people/DanEllis/) and [Brian Whitman](https://notes.variogram.com), and would love your contributions.
[ **Chat about AMY on our Discord!**](https://discord.gg/TzBFkUb8pG)
## More information
* [**Interactive AMY tutorial**](https://shorepine.github.io/amy/tutorial.html)
* [**AMY API**](docs/api.md)
* [**AMY Synthesizer Details**](docs/synth.md)
* [**AMY's MIDI specification**](docs/midi.md)
* [**AMY in Arduino Getting Started**](docs/arduino.md)
* [**Other AMY web demos**](https://shorepine.github.io/amy/)
AMY supports
* MIDI input support and synthesizer voice management, including voice stealing, controllers and per-channel multi-timbral operation
* A strong Juno-6 style analog synthesizer
* An operator / algorithm-based frequency modulation (FM) synth, modeled after the DX-7
* PCM sampler, reading from a baked-in buffer of percussive and misc samples, or by loading samples into RAM, or playing from files on disk directly, with loop points and base midi note
* Wavetable oscillator
* karplus-strong string with adjustable feedback
* An arbitrary number of band-limited oscillators, each with adjustable frequency, pan, phase, amplitude:
* pulse (+ adjustable duty cycle), sine, saw (up and down), triangle, noise
* Stereo audio input or audio buffers in code can be used as an oscillator for real time audio effects
* Biquad low-pass, bandpass or hi-pass filters with cutoff and resonance, can be assigned to any oscillator
* Reverb, echo and chorus effects, set globally
* An additive partial synthesizer
* Each oscillator has 2 envelope generators, which can modify any combination of amplitude, frequency, PWM duty, filter cutoff, or pan over time
* Each oscillator can also act as an modulator to modify any combination of parameters of another oscillator, for example, a bass drum can be indicated via a half phase sine wave at 0.25Hz modulating the frequency of another sine wave.
* Control of overall gain and 3-band EQ
* 300+ built in preset patches for PCM, DX7, piano and Juno-6
* A front end for DX7 and Juno-6 SYSEX patches and conversion setup commands
* Built-in event clock and pattern sequencer, using hardware real time timers on microcontrollers
* Multi-core (including microcontrollers) for rendering if available
* File transfer to the host
The FM synth provides a Python library, [`fm.py`](https://github.com/shorepine/amy/blob/main/amy/fm.py) that can convert any DX7 patch into an AMY patch.
The Juno-6 emulation provides [`juno.py`](https://github.com/shorepine/amy/blob/main/amy/juno.py) and can read in Juno-6 SYSEX patches and convert them into AMY patches.
[The partials-driven piano voice and the code to generate the partials are described here](https://shorepine.github.io/amy/piano.html).
## Using AMY in Arduino
AMY will run on many modern microcontrollers under Arduino. On most platforms, we handle sending audio out to an I2S interface and handling MIDI input. Some platforms support more features than others.
**Please see our more detailed [Getting Started on Arduino](docs/arduino.md) page for more details.**
## Using AMY in Python on any platform
You can `import amy` in Python and have it render either out to your speakers or to a buffer of samples you can process on your own. To install the `amy` library, run `pip install .`. You can also run `make test` to install the library and run a series of tests.
[**Please see our interactive AMY tutorial for more tips on using AMY**](https://shorepine.github.io/amy/tutorial.html)
## Using AMY on the web
We provide an `emscripten` port of AMY that runs in Javascript. [See the AMY web demos](https://shorepine.github.io/amy/). To build for the web, use `make docs/amy.js`. It will generate `amy.js` in `docs/`.
## Using AMY in any other software
To use AMY in your own software, simply copy the .c and .h files in `src` to your program and compile them. No other libraries should be required to synthesize audio in AMY.
To run a simple C example on many platforms:
```
make
./amy-example # you should hear tones out your default speaker, use ./amy-example -h for options
```
# AMY quickstart
[**Please see our interactive AMY tutorial for more tips on using AMY**](https://shorepine.github.io/amy/tutorial.html)
## MIDI mode
AMY provides a [MIDI mode](docs/midi.md) by default that lets you control many parts of AMY over MIDI. You can even control the underlying oscillators over SYSEX. See our [MIDI documentation](docs/midi.md) for more details. The simplest way to use AMY is to start it and them play MIDI notes to it. By default, AMY boots with a Juno-6 patch 0 on MIDI channel 1.
In Python:
```python
>>> import amy; amy.live(default_synths=1)
>>> # play MIDI notes using system MIDI
```
In C:
```c
amy_config = amy_default_config()
amy_start(amy_config);
amy_live_start();
// play MIDI notes using system MIDI or UART MIDI on microcontrollers
```
In Javascript (see [minimal.html](docs/minimal.html) for the full example):
```html
<script type="text/javascript" src="amy.js"></script>
<script type="text/javascript" src="amy_connector.js"></script>
<script>
// You have to start AMY on a user click for audio to work
document.body.addEventListener('click', amy_js_start, true);
</script>
<!-- Now play MIDI notes over webMIDI -->
```
AMY supports [note commands, some MIDI controllers, and program changes to change the patch.](docs/midi.md)
## Controlling AMY in code
Presumably you'd like to explicitly tell AMY what to play. You can control AMY from almost anything. We mostly work in Python, C or Javascript, but AMY has been built to work with anything that can send a string.
AMY has two API interfaces: _wire messages_ and `amy_event`. An AMY wire message is a string that looks like `v0n50l1K130r0Z`, with each letter corresponding to a field (like `v0` means `oscillator 0`, `n50` means midi note 50, `K130` means patch number 130, etc.) Wire messages are converted into `amy_event`s within AMY once received.
So in C, or JS, you'd fill an `amy_event` struct to define a single event of the synthesizer. For example, that wire message above is:
```c
amy_event e = amy_default_event();
e.osc = 0;
e.patch_number = 130;
e.velocity = 1;
e.midi_note = 50;
e.voices[0] = 0;
amy_add_event(&e);
```
In Python, we provide the `amy` package that generates wire messages from a Pythonic `amy.send(**kwargs)`. In Python, you'd do
```python
amy.send(osc=0, patch = 130, vel = 1, note = 50, voices = [0])
```
Wire messages are used in AMY as a compact serialization of AMY events and become useful when communicating between AMY and other programs that may not be linked together. For example, [Alles](https://github.com/shorepine/alles) uses wire messages over Wi-Fi UDP to control a mesh of AMY synthesizers. [Tulip Web](https://tulip.computer/run) sends wire messages from the Micropython web process to the AudioWorklet running AMY on the web. We also store the Juno-6 and DX7 patches within AMY itself using wire messages, which helps keep the code size down.
You can also send wire messages over SYSEX to AMY, if you want to control AMY over MIDI beyond the default MIDI mode. [See our MIDI documentation for more details.](docs/midi.md)
It's good to understand what wire messages are but you don't need to construct them directly if you're linking AMY in your software. Use `amy_event` or `amy.send()` in Python to control AMY for almost all use cases.
# More information
* [**Interactive AMY tutorial**](https://shorepine.github.io/amy/tutorial.html)
* [**AMY API**](docs/api.md)
* [**AMY Synthesizer Details**](docs/synth.md)
* [**AMY's MIDI specification**](docs/midi.md)
* [**AMY in Arduino Getting Started**](docs/arduino.md)
* [**AMY in Godot**](docs/godot.md)
* [**AMY on Windows**](windows/README.md)
* [**Other AMY web demos**](https://shorepine.github.io/amy/)
[ **Chat about AMY on our Discord!**](https://discord.gg/TzBFkUb8pG)
================================================
FILE: amy/__init__.py
================================================
# AMY module
from .constants import *
from . import examples
import collections
import time
def _get_synth_commands_stub(synth):
return []
_get_synth_commands = _get_synth_commands_stub
try:
import c_amy as _amy # Import the C module
live = _amy.live
_get_synth_commands = _amy.get_synth_commands
except (ImportError, AttributeError):
# C module is not required? not available?
# I'm guessing this might mean we're on Micropython?
try:
import tulip
_get_synth_commands = tulip.amy_get_synth_commands
except (ImportError, AttributeError):
pass # Not available (e.g. web build); _get_synth_commands returns []
# If set, inserts func as time for every call to send(). Will not override an explicitly set time
insert_time = None
# If set, calls this instead of amy.send()
override_send = None
mess = []
log = False
show_warnings = True
block_cb = None
# Return a millis() epoch number for use in AMY timing
# On most computers, this uses ms since midnight using datetime
# On things like Tulip, this use ms since boot
def millis():
try:
import datetime
d = datetime.datetime.now()
return int((datetime.datetime.utcnow() - datetime.datetime(d.year, d.month, d.day)).total_seconds()*1000)
except ImportError:
import tulip
return tulip.ticks_ms()
# Removes trailing 0s and x.0000s from floating point numbers to trim wire message size
# Fun historical trivia: this function caused a bug so bad that Dan had to file a week-long PR for micropython
# https://github.com/micropython/micropython/pull/8905
def trunc(number):
if type(number) == str:
if number.strip() == '':
return ''
number = float(number)
if(type(number)==float):
return ('%.6f' % number).rstrip('0').rstrip('.')
return str(number)
def trunc3(number):
if(type(number)==float):
return ('%.3f' % number).rstrip('0').rstrip('.')
return str(number)
def trim_trailing(vals, pred):
"""Remove any contiguous suffix of values that return False under pred."""
bools = [pred(x) for x in vals[::-1]]
suffix_len = bools.index(True)
if suffix_len:
return vals[:-suffix_len]
return vals
def parse_ctrl_coefs(coefs):
"""Convert various acceptable forms of ControlCoefficient specs to the canonical string.
ControlCoefficients determine how amplitude, frequency, filter frequency, PWM duty, and pan
are calculated from underlying parameters on the fly. For each control input, they specify
nine coefficients which are multiplied by (0) a constant value of 1, (1) the log-frequency from
the note-on command, (2) the velocity from the note-on command, (3) Envelope Generator 0's value,
(4) Envelope Generator 1's value, (5) the modulating oscillator input, (6) the global pitch
bend value, (7) external input 0, and (8) external input 1. The sum of these scaled values is used as the control input. (Amplitude is a special
case where the individual values are *multiplied* rather than added, and values whose coefficients
are zero are skipped).
The wire protocol expects these coefficients to be specified as a single vector, e.g. "f220,1,0,0,0,0,1".
It also accepts some values to be left unspecified; only the specified values are changed. So "f,,,,0.01"
will add EG1 modulation to pitch but not change its base value etc. As a special case, a single value
(e.g. "f440") will change the constant offset for a parameter but leave its other modulations in place.
The Python API accepts multiple kinds of input:
* A scalar numeric value: freq=440
* A list of values in the format accepted by the wire protocol: freq=',,,,0.01'.
* A Python list of values, where None can be used to indicate "unspecified": freq=[None, None, None, None, 0.01]. Where the list is shorter than the expected 7 values, the remainder are treated as None (analogous to the wire-protocol string).
* A Python dict providing values for some subset of the coefficients. The only acceptable keys are 'const', 'note', 'vel', 'eg0', 'eg1', 'mod', 'bend', 'ext0', and 'ext1'.
"""
# Pass through ready-formed strings, and convert single values to single value strings
if isinstance(coefs, str):
return ','.join(trunc(x) for x in coefs.split(','))
if isinstance(coefs, int) or isinstance(coefs, float):
return trunc(coefs)
# Convert a dict into a list of values.
dict_fields = ['const', 'note', 'vel', 'eg0', 'eg1', 'mod', 'bend', 'ext0', 'ext1']
if isinstance(coefs, dict):
coef_list = [None] * len(dict_fields)
for key, value in coefs.items():
if key not in dict_fields:
raise ValueError('\'%s\' is not a recognized CtrlCoef field %s' % (key, str(dict_fields)))
coef_list[dict_fields.index(key)] = value
coefs = coef_list
assert isinstance(coefs, list)
coefs = trim_trailing(coefs, lambda x: x is not None)
def to_str(x):
if x is None:
return ''
return str(x)
return ','.join([to_str(x) for x in coefs])
def parse_list_or_comma_string(obj):
def str_none_is_empty(s):
if s is None:
return ""
return str(s)
if isinstance(obj, list):
return ','.join(map(str_none_is_empty, obj))
return str(obj)
def str_of_int(arg):
"""Cast arg to an int, but then convert it to a str for the wire string."""
return str(int(arg))
_KW_MAP_LIST = [ # Order matters because patch_string must come last.
('osc', 'vI'), ('wave', 'wI'), ('note', 'nF'), ('vel', 'lF'), ('amp', 'aC'), ('freq', 'fC'), ('duty', 'dC'),
('feedback', 'bF'), ('time', 'tI'), ('reset', 'SI'), ('phase', 'PF'), ('pan', 'QC'), ('client', 'gI'),
('volume', 'VF'), ('pitch_bend', 'sF'), ('filter_freq', 'FC'), ('resonance', 'RF'),
('bp0', 'AL'), ('bp1', 'BL'),
('eg0', 'AL'), ('eg1', 'BL'), # Aliases for bp0 and bp1
('eg0_type', 'TI'), ('eg1_type', 'XI'), ('debug', 'DI'), ('chained_osc', 'cI'),
('mod_source', 'LI'), ('eq', 'xL'), ('filter_type', 'GI'), ('ratio', 'IF'), ('latency_ms', 'NI'),
('algo_source', 'OL'), ('load_sample', 'zL'), ('transfer_file', 'zTL'), ('disk_sample', 'zFL'),
('algorithm', 'oI'), ('chorus', 'kL'), ('reverb', 'hL'), ('echo', 'ML'), ('patch', 'KI'), ('voices', 'rL'),
('external_channel', 'WI'), ('portamento', 'mI'), ('sequence', 'HL'), ('tempo', 'jF'),
('synth', 'iI'), ('pedal', 'ipI'), ('synth_flags', 'ifI'), ('num_voices', 'ivI'), ('oscs_per_voice', 'inI'),
('to_synth', 'itI'), ('grab_midi_notes', 'imI'), ('synth_delay', 'idI'),
('preset', 'pI'), ('num_partials', 'pI'), # note aliasing
('start_sample', 'zSL'), ('stop_sample', 'zOI'),
('midi_cc', 'icL'),
('patch_string', 'uS'), # patch_string MUST be last because we can't identify when it ends except by end-of-message.
]
_KW_PRIORITY = {k: i for i, (k, _) in enumerate(_KW_MAP_LIST)} # Maps each key to its index within _KW_MAP_LIST.
_KW_MAP = dict(_KW_MAP_LIST)
_ARG_HANDLERS = {
'I': str_of_int, 'F': trunc, 'S': str, 'L': parse_list_or_comma_string, 'C': parse_ctrl_coefs,
}
# Construct an AMY message
def message(**kwargs):
#print("message:", kwargs)
# Each keyword maps to two or three chars, first one or two are the wire protocol prefix, last is an arg type code
# I=int, F=float, S=str, L=list, C=ctrl_coefs
global show_warnings, _KW_MAP, _KW_PRIORITY, _ARG_HANDLERS
if show_warnings:
# Check for possible user confusions.
if 'voices' in kwargs and 'preset' in kwargs and 'osc' not in kwargs:
print('You specified \'voices\' and \'preset\' but not \'osc\' so your command will apply to the voice\'s osc 0.')
if 'voices' in kwargs and 'synth' in kwargs and not ('patch' in kwargs or 'patch_string' in kwargs):
print('You specified both \'synth\' and \'voices\' in a non-\'patch\'/\'patch_string\' message, but \'synth\' defines the voices.')
if 'patch_string' in kwargs and not ('patch' in kwargs or 'synth' in kwargs or 'voices' in kwargs):
print('\'patch_string\' is only valid with a \'patch\' or to define a new \'synth\' or \'voices\'.')
# And yet we plow ahead...
if 'patch_string' in kwargs:
# Try to avoid mistakenly calling 'patch_string' when you meant 'patch'.
if not isinstance(kwargs['patch_string'], str):
raise ValueError('\'patch_string\' should be a wire command string, not \'' + str(kwargs['patch_string']) + '\'.')
if 'num_partials' in kwargs:
if 'preset' in kwargs:
raise ValueError('You cannot use \'num_partials\' and \'preset\' in the same message.')
if 'wave' not in kwargs or kwargs['wave'] != BYO_PARTIALS:
raise ValueError('\'num_partials\' must be used with \'wave\'=BYO_PARTIALS.')
if(insert_time is not None and 'time' not in kwargs):
kwargs['time'] = insert_time()
# Validity check all the passed args.
prioritized_keys = []
for key, arg in kwargs.items():
if key not in _KW_MAP:
raise ValueError('Unknown keyword ' + key)
priority = _KW_PRIORITY[key]
if arg is None:
# Ignore time=None or sequence=None
if key != 'time' and key != 'sequence':
raise ValueError('No arg for key ' + key)
else:
prioritized_keys.append((priority, key))
# Sort by priority, then strip the priority value.
prioritized_keys = [e[1] for e in sorted(prioritized_keys)]
# We process the passed args by testing each entry in the known keys in order, to make sure 'patch_string' is added last.
m = ''
for key in prioritized_keys:
map_code = _KW_MAP[key]
arg = kwargs[key]
type_code = map_code[-1]
wire_code = map_code[:-1]
m += wire_code + _ARG_HANDLERS[type_code](arg)
#print("message:", m)
return m + 'Z'
def send_raw(m):
# override_send is used by e.g. Tulip, to send messages in a different way than C or UDP
global mess, log
global override_send
if(override_send is not None):
override_send(m)
else:
_amy.send_wire(m)
if(log): mess.append(m)
def log_patch():
global mess, log
# start recording a patch
log = True
mess = []
def retrieve_patch():
global mess, log
log = False
s = "".join(mess)
mess =[]
return s
# Convenience function to store an in-memory AMY patch
# Call this, then call stop_store_patch(patch_number) when you're done
saved_override = None
def amy_do_nothing(message):
return
def start_store_patch():
global saved_override, override_send
saved_override = override_send
override_send = amy_do_nothing
log_patch()
def stop_store_patch(patch):
global saved_override, override_send
override_send = saved_override
m = "u"+str(patch)+retrieve_patch()
send_raw(m)
# Send an AMY message to amy
def send(**kwargs):
m = message(**kwargs)
send_raw(m)
# Plots a time domain and spectra of audio
def show(data):
import matplotlib.pyplot as plt
import numpy as np
fftsize = len(data)
windowlength = fftsize
window = np.hanning(windowlength)
wavepart = data[:len(window)]
logspecmag = 20 * np.log10(np.maximum(1e-10,
np.abs(np.fft.fft(wavepart * window)))[:(fftsize // 2 + 1)])
freqs = AMY_SAMPLE_RATE * np.arange(len(logspecmag)) / fftsize
plt.subplot(211)
times = np.arange(len(wavepart)) / AMY_SAMPLE_RATE
plt.plot(times, wavepart, '.')
plt.subplot(212)
plt.plot(freqs, logspecmag, '.-')
plt.ylim(np.array([-100, 0]) + np.max(logspecmag))
plt.show()
# Writes a WAV file of rendered data
def write(data, filename):
import scipy.io.wavfile as wav
import numpy as np
wav.write(filename, int(AMY_SAMPLE_RATE), (32768.0 * data).astype(np.int16))
# Play a rendered sound out of default sounddevice
def play(samples):
import sounddevice as sd
sd.play(samples)
# Render AMY's internal buffer to a numpy array of floats
def render(seconds):
import numpy as np
# Output a npy array of samples
frame_count = int((seconds*AMY_SAMPLE_RATE)/AMY_BLOCK_SIZE)
frames = []
for f in range(frame_count):
frames.append( np.array(_amy.render_to_list())/32768.0 )
return np.hstack(frames).reshape((-1, AMY_NCHANS))
def restart(default_synths=0):
_amy.stop()
_amy.start(default_synths)
def inject_midi(a, b, c, d=None):
if d is None:
_amy.inject_midi(a, b, c)
else:
_amy.inject_midi(a, b, c, d)
def unload_sample(patch=0):
s= "%d,%d" % (patch, 0)
send(load_sample=s)
print("Patch %d unloaded from RAM" % (patch))
# For AMYBoard and other AMYs that can get messages over MIDI sysex
# AMYboard is the name of the default AMYboard USB over MIDI device.
# If you're using another MIDI device, set output_name to it
# Use this like amy.override_send = sysex_write
def sysex_write(message, output_name='AMYboard'):
import mido
outputs = mido.get_output_names()
target_name = None
for name in outputs:
if output_name in name:
target_name = name
break
if target_name is None:
print("Could not find %s MIDI")
if isinstance(message, str):
payload = message.encode('ascii')
elif isinstance(message, bytes):
payload = message
# AMY sysex message
data = [0x00, 0x03, 0x45] + list(payload)
with mido.open_output(target_name) as out:
m = mido.Message('sysex', data=data)
out.send(m)
# This sleep is because there's not really a buffer per-se for SYSEX over CDC
time.sleep(0.01)
try:
import base64
def b64(b):
return base64.b64encode(b)
except ImportError:
import ubinascii
def b64(b):
return ubinascii.b2a_base64(b)[:-1]
def start_sample(preset=0, bus=1, max_frames=0, midinote=60, loopstart=0, loopend=0):
s = "%d,%d,%d,%d,%d,%d" % (preset, bus, max_frames, midinote, loopstart, loopend)
send(start_sample=s)
def stop_sample():
send(stop_sample=1)
def load_sample_bytes(b, stereo=False, preset=0, midinote=60, loopstart=0, loopend=0, sr=AMY_SAMPLE_RATE):
# takes in a python bytes obj instead of filename
from math import ceil
if(stereo):
# just choose first channel
b = bytes([b[j] for i in range(0,len(b),4) for j in (i,i+1)])
n_frames = len(b)/2
s = "%d,%d,%d,%d,%d,%d" % (preset, n_frames, sr, midinote, loopstart, loopend)
send(load_sample=s)
last_f = 0
for i in range(ceil(n_frames/94)):
frames_bytes = b[last_f:last_f+188]
message = b64(frames_bytes)
send_raw(message.decode('ascii'))
last_f = last_f + 188
def disk_sample(wavfilename, preset=0, midinote=60):
try:
from tulip import board
if board() == "WEB":
# On web, we just use memorypcm as we can't directly accesss FS from amy-web
load_sample(wavfilename, preset, midinote)
return
except ImportError:
pass # It's ok, just means we are not under tulip or amyboard web
s = "%d,%s,%d" % (preset, wavfilename, midinote)
send(disk_sample=s)
def transfer_file(source_filename, dest_filename=None):
import os
from math import ceil
if(dest_filename is None):
dest_filename = source_filename
file_size = os.path.getsize(source_filename)
s = "%s,%d" % (dest_filename, file_size)
send(transfer_file=s)
# Now generate the base64 encoded segments, 188 bytes at a time
# why 188? that generates 252 bytes of base64 text. amy's max message size is currently 255.
# Use the _from_sysex variant so the chunks are routed to
# parse_transfer_message via the amy_parsing_from_sysex flag. Internal
# amy.send() calls from other contexts (e.g. a sketch's loop() on
# AMYboard hardware running during a live transfer) use the regular
# path and won't be mis-interpreted as transfer data.
w = open(source_filename, 'rb')
for i in range(ceil(file_size/188)):
file_bytes = w.read(188)
message = b64(file_bytes)
if override_send is not None:
override_send(message.decode('ascii'))
else:
_amy.send_wire_from_sysex(message.decode('ascii'))
w.close()
def load_sample(wavfilename, preset=0, midinote=0, loopstart=0, loopend=0):
from math import ceil
from . import wave
# tulip has ubinascii, normal has base64
w = wave.open(wavfilename, 'r')
if(loopstart==0):
if(hasattr(w,'_loopstart')):
loopstart = w._loopstart
if(loopend==0):
if(hasattr(w,'_loopend')):
loopend = w._loopend
if(midinote==0):
if(hasattr(w,'_midinote')):
midinote = w._midinote
else:
midinote=60
# Tell AMY we're sending over a sample
s = "%d,%d,%d,%d,%d,%d" % (preset, w.getnframes(), w.getframerate(), midinote, loopstart, loopend)
send(load_sample=s)
# Now generate the base64 encoded segments, 188 bytes / 94 frames at a time
# why 188? that generates 252 bytes of base64 text. amy's max message size is currently 255.
for i in range(ceil(w.getnframes()/94)):
frames_bytes = w.readframes(94)
if(w.getnchannels()==2):
# de-interleave and just choose the first channel
frames_bytes = bytes([frames_bytes[j] for i in range(0,len(frames_bytes),4) for j in (i,i+1)])
message = b64(frames_bytes)
send_raw(message.decode('ascii'))
print("Loaded sample over wire protocol. Preset #%d. %d bytes, %d frames, midinote %d" % (preset, w.getnframes()*2, w.getnframes(), midinote))
"""
Convenience functions
"""
def reset(osc=None, **kwargs):
if(osc is not None):
send(reset=osc, **kwargs)
else:
send(reset=RESET_ALL_OSCS, **kwargs)
"""
Chorus control
"""
def chorus(level=-1, max_delay=-1, freq=-1, amp=-1):
chorus_level = ''
chorus_delay = ''
chorus_freq = ''
chorus_depth = ''
if (level >= 0):
chorus_level = str(level)
if (max_delay >= 0):
chorus_delay = str(max_delay)
if (freq >= 0):
chorus_freq = str(freq)
if (amp >= 0):
chorus_depth = str(amp)
chorus_arg = "%s,%s,%s,%s" % (chorus_level, chorus_delay, chorus_freq, chorus_depth)
send(chorus=chorus_arg)
"""
Reverb control
"""
def reverb(level=-1, liveness=-1, damping=-1, xover_hz=-1):
reverb_level = ''
reverb_liveness = ''
reverb_damping = ''
reverb_xover = ''
if (level >= 0):
reverb_level = str(level)
if (liveness >= 0):
reverb_liveness = str(liveness)
if (damping >= 0):
reverb_damping = str(damping)
if (xover_hz >= 0):
reverb_xover = str(xover_hz)
reverb_arg = "%s,%s,%s,%s" % (reverb_level, reverb_liveness, reverb_damping, reverb_xover)
send(reverb=reverb_arg)
"""
Echo control
"""
def echo(level=None, delay_ms=None, max_delay_ms=None, feedback=None, filter_coef=None):
echo_level = ''
echo_delay_ms = ''
echo_max_delay_ms = ''
echo_feedback = ''
echo_filter_coef = ''
if level is not None:
echo_level = str(level)
if delay_ms is not None:
echo_delay_ms = str(delay_ms)
if max_delay_ms is not None:
echo_max_delay_ms = str(max_delay_ms)
if feedback is not None:
echo_feedback = str(feedback)
if filter_coef is not None:
echo_filter_coef = str(filter_coef)
echo_arg = '%s,%s,%s,%s,%s' % (echo_level, echo_delay_ms, echo_max_delay_ms, echo_feedback, echo_filter_coef)
send(echo=echo_arg)
"""
Reading back synth configuration
"""
def get_synth_commands(synth, patch_num=None, dest_synth=None, num_voices=6, include_fx=True, time=None):
if patch_num is not None and dest_synth is not None:
raise ValueError("At most one of patch_num and dest_synth can be specified")
commands = _get_synth_commands(synth, include_fx)
def len_digit_prefix(s):
len = 0
while s[len] in '0123456789':
len += 1
return len
# Scan for number of oscs
num_oscs = 0
for command in commands:
if command[0] == 'v':
osc_num = int(command[1: 1 + len_digit_prefix(command[1:])])
if num_oscs < osc_num + 1:
num_oscs = osc_num + 1
# Build total command string including prefix depending on use.
prefix = "t%d" % time if time is not None else ""
prologue = []
if patch_num:
# Start by resetting the patch.
prologue = [prefix + "S%dk%dZ" % (RESET_PATCH, patch_num)]
prefix += "K%d" % patch_num
if dest_synth:
# Prepend command to reset the synth.
prologue = [prefix + "i%div%din%dZ" % (dest_synth, num_voices, num_oscs)]
prefix += "i%d" % dest_synth
return "\n".join(prologue + [prefix + command for command in commands])
================================================
FILE: amy/constants.py
================================================
MAX_FILENAME_LEN=127
AMY_BLOCK_SIZE=128
BLOCK_SIZE_BITS=7
AMY_BLOCK_SIZE=256
BLOCK_SIZE_BITS=8
AMY_SAMPLE_RATE=48000
AMY_SAMPLE_RATE=48000
AMY_SAMPLE_RATE=44100
PCM_AMY_SAMPLE_RATE=22050
AMY_TRANSFER_TYPE_NONE=0
AMY_TRANSFER_TYPE_AUDIO=1
AMY_TRANSFER_TYPE_FILE=2
AMY_TRANSFER_TYPE_SAMPLE=3
AMY_PCM_TYPE_ROM=0
AMY_PCM_TYPE_FILE=1
AMY_PCM_TYPE_MEMORY=2
PCM_FILE_BUFFER_MULT=8
AMY_BUS_OUTPUT=1
AMY_BUS_AUDIO_IN=2
AMY_MAX_CORES=2
AMY_MAX_CHANNELS=2
AMY_NCHANS=2
AMY_CORES=2
AMY_CORES=1
AMY_MIDI_CHANNEL_DRUMS=10
MALLOC_CAP_DEFAULT=0
CHORUS_DEFAULT_LFO_FREQ=0.5
CHORUS_DEFAULT_MOD_DEPTH=0.5
CHORUS_DEFAULT_LEVEL=0
CHORUS_DEFAULT_MAX_DELAY=320
EQ_CENTER_LOW=800.0
EQ_CENTER_MED=2500.0
EQ_CENTER_HIGH=7000.0
REVERB_DEFAULT_LEVEL=0
REVERB_DEFAULT_LIVENESS=0.85
REVERB_DEFAULT_DAMPING=0.5
REVERB_DEFAULT_XOVER_HZ=3000.0
ECHO_DEFAULT_LEVEL=0
ECHO_DEFAULT_DELAY_MS=500.
ECHO_DEFAULT_MAX_DELAY_MS=743.
ECHO_DEFAULT_FEEDBACK=0
ECHO_DEFAULT_FILTER_COEF=0
AMY_SEQUENCER_PPQ=48
DELAY_LINE_LEN=512
CLIP_D=0.1
MAX_VOLUME=11.0
AMP_THRESH=0.001
AMP_THRESH_PLUS=0.0011
SAMPLE_MAX=32767
MAX_ALGO_OPS=6
DEFAULT_NUM_BREAKPOINTS=8
MAX_BREAKPOINTS=24
MAX_BREAKPOINT_SETS=2
THREAD_USLEEP=500
AMY_BYTES_PER_SAMPLE=2
MAX_VOICES_PER_INSTRUMENT=32
FILT_NUM_DELAYS=4
ZERO_HZ_LOG_VAL=-99.0
ZERO_LOGFREQ_IN_HZ=440.0
ZERO_MIDI_NOTE=69
MIN_FILTER_LOGFREQ=-2.75
NUM_COMBO_COEFS=9
MAX_MESSAGE_LEN=1024
MAX_PARAM_LEN=256
FILTER_NONE=0
FILTER_LPF=1
FILTER_BPF=2
FILTER_HPF=3
FILTER_LPF24=4
SINE=0
PULSE=1
SAW_DOWN=2
SAW_UP=3
TRIANGLE=4
NOISE=5
KS=6
PCM=7
ALGO=8
PARTIAL=9
BYO_PARTIALS=10
INTERP_PARTIALS=11
AUDIO_IN0=12
AUDIO_IN1=13
AUDIO_EXT0=14
AUDIO_EXT1=15
AMY_MIDI=16
PCM_LEFT=17
PCM_RIGHT=18
PCM_MIX=7
WAVETABLE=19
SILENT=20
CUSTOM=21
WAVE_OFF=22
SYNTH_OFF=0
SYNTH_AUDIBLE=1
SYNTH_INAUDIBLE=2
SYNTH_IS_MOD_SOURCE=3
SYNTH_IS_ALGO_SOURCE=4
EVENT_EMPTY=0
EVENT_SCHEDULED=1
EVENT_TRANSFER_DATA=2
EVENT_SEQUENCE=3
NOTE_SOURCE_MIDI=2
ENVELOPE_NORMAL=0
ENVELOPE_LINEAR=1
ENVELOPE_DX7=2
ENVELOPE_TRUE_EXPONENTIAL=3
SEQUENCE_TICK=0
SEQUENCE_PERIOD=1
SEQUENCE_TAG=2
RESET_SEQUENCER=4096
RESET_ALL_OSCS=8192
RESET_TIMEBASE=16384
RESET_AMY=32768
RESET_EVENTS=65536
RESET_ALL_NOTES=131072
RESET_SYNTHS=262144
RESET_PATCH=524288
RESET_QUEUE=1048576
true=1
false=0
AMY_OK=0
AMY_AUDIO_IS_NONE=0x00
AMY_AUDIO_IS_I2S=0x01
AMY_AUDIO_IS_USB_GADGET=0x02
AMY_AUDIO_IS_MINIAUDIO=0x04
AMY_MIDI_IS_NONE=0x0
AMY_MIDI_IS_UART=0x01
AMY_MIDI_IS_USB_GADGET=0x02
AMY_MIDI_IS_MACOS=0x04
AMY_MIDI_IS_WEBMIDI=0x08
AMYBOARD_LRC=2
AMYBOARD_BCLK=8
AMYBOARD_DOUT=6
AMYBOARD_DIN=9
AMYBOARD_MCLK=3
AMYBOARD_MIDI_OUT_TYPE_A=14
AMYBOARD_MIDI_OUT_TYPE_B=15
AMYBOARD_MIDI_IN=21
================================================
FILE: amy/examples.py
================================================
#!/usr/bin/env python3
# examples.py
# sound examples and patch examples
import amy
from time import sleep
class Patch:
"""
Provides a collection of illustrations of different voice configurations with AMY.
You use them like this:
amy.send(synth=0, num_voices=4, patch=patches.filter_bass())
"""
next_patch_number = 1024
@classmethod
def _new_patch_number(cls):
# just keep a global patch num around for these patches
new_num = cls.next_patch_number
cls.next_patch_number = cls.next_patch_number + 1
return new_num
@classmethod
def reset(cls):
cls.next_patch_number = 1024
def __init__(self, **kwargs):
self.patch_number = Patch._new_patch_number()
self.setup(**kwargs)
def __int__(self):
# When amy.message() tries to convert this into an int, just return the patch number.
return self.patch_number
def setup(self, **kwargs):
raise ValueError('Subclasses of Patch must define a setup(self, **kwargs) method.')
class simple_sine(Patch):
def setup(self, **kwargs):
amy.send(patchr=self.patch_number,
wave=amy.SINE, bp0="10,1,240,0.7,500,0",
**kwargs)
class filter_bass(Patch):
def setup(self, **kwargs):
amy.send(patch=self.patch_number,
osc=0, filter_freq="100,0,0,5", resonance=5, wave=amy.SAW_DOWN,
filter_type=amy.FILTER_LPF, bp0="0,1,1000,0,100,0",
**kwargs)
class amp_lfo(Patch):
def setup(self, **kwargs):
# Not clear what to do with kwargs. They probably don't want to apply to both oscs.
amy.send(patch=self.patch_number,
osc=1, wave=amy.SINE, amp=0.50, freq=1.5,
**kwargs)
amy.send(patch=self.patch_number,
osc=0, wave=amy.PULSE, bp0="150,1,1850,0.25,250,0", amp="0,0,1,1,0,1", mod_source=1,
**kwargs)
class pitch_lfo(Patch):
def setup(self, **kwargs):
amy.send(patch=self.patch_number,
osc=1, wave=amy.SINE, amp=0.50, freq=0.25,
**kwargs)
amy.send(patch=self.patch_number,
osc=0, wave=amy.PULSE, bp0="150,1,250,0,0,0", freq="261.63,1,0,0,0,1", mod_source=1,
**kwargs)
class bass_drum(Patch):
def setup(self, **kwargs):
# Uses a 0.25Hz sine wave at 0.5 phase (going down) to modify frequency of another sine wave
amy.send(patch=self.patch_number,
osc=1, wave=amy.SINE, amp=0.50, freq=0.25, phase=0.5,
**kwargs)
amy.send(patch=self.patch_number,
osc=0, wave=amy.SINE, bp0="0,1,500,0,0,0", freq="261.63,1,0,0,0,1", mod_source=1,
**kwargs)
class noise_snare(Patch):
def setup(self, **kwargs):
amy.send(patch=self.patch_number,
osc=0, wave=amy.NOISE, bp0="0,1,250,0,0,0",
**kwargs)
class closed_hat(Patch):
def setup(self, **kwargs):
amy.send(patch=self.patch_number,
osc=0, wave=amy.NOISE, bp0="5,1,30,0,0,0", filter_type=amy.FILTER_HPF, filter_freq=6000,
**kwargs)
"""
Various python examples of using AMY, including the port of all the C examples.c
"""
# Plays the example patches defined in this file
def play_example_patches(wait=1, **kwargs):
from . import examples
try:
patchClasses = examples.Patch.__subclasses__()
except AttributeError:
# micropython does not have __subclasses__
patchClasses = [
examples.simple_sine,
examples.filter_bass,
examples.amp_lfo,
examples.pitch_lfo,
examples.bass_drum,
examples.noise_snare,
examples.closed_hat,
]
for patchClass in patchClasses:
print("Patch", patchClass.__name__)
send(synth=0, num_voices=1, patch=patchClass())
time.sleep(wait/4.0)
send(synth=0, note=50, vel=1, **kwargs)
time.sleep(wait)
send(synth=0, vel=0)
time.sleep(wait/4.0)
# Plays the baked in Juno, DX7 and piano patches
def play_baked_patches(wait=1, patch_total = 256, **kwargs):
import random
patch_count = 0
while True:
patch = random.randint(0,256) #patch_count % patch_total
print("Sending patch %d" % patch)
send(synth=0, num_voices=1, patch=patch)
time.sleep(wait/4.0)
send(synth=0, note=50, vel=1, **kwargs)
time.sleep(wait)
send(synth=0, vel=0)
time.sleep(wait/4.0)
def example_multimbral_synth():
amy.send(patch=4, num_voices=6, synth=1) # juno-6 preset 4 on MIDI channel 1
amy.send(patch=129, num_voices=2, synth=2) # dx7 preset 1 on MIDI channel 2
amy.send(synth=3, num_voices=4, patch=filter_bass()) # filter bass user patch on MIDI channel 3
amy.send(synth=4, num_voices=4, patch=pitch_lfo()) # pitch LFO user patch on MIDI channel 4
def example_reset(start=0):
amy.send(osc=0, reset=amy.RESET_ALL_OSCS, time=start)
def example_voice_alloc():
# alloc 2 juno voices, then try to alloc a dx7 voice on voice 0
amy.send(patch=1, voices=[0, 1])
sleep(0.25)
amy.send(patch=131, voices=[0])
sleep(0.25)
# play the same note on both
amy.send(vel=1, note=60, voices=[0])
sleep(2)
amy.send(vel=1, note=60, voices=[1])
sleep(2)
# now try to alloc voice 0 with a juno, should use oscs 0-4 again
amy.send(patch=2, voices=[0])
sleep(0.25)
def example_voice_chord(patch=0):
amy.send(patch=patch, voices=[0, 1, 2])
sleep(.250)
amy.send(vel=0.5, voices=[0], note=50)
sleep(1)
amy.send(vel=0.5, voices=[1], note=54)
sleep(1)
amy.send(vel=0.5, voices=[2], note=56)
sleep(2)
amy.send(vel=0, voices=[0, 1, 2])
def example_synth_chord(patch=0):
# Like example_voice_chord, but use 'synth' to avoid having to keep track of voices
amy.send(patch=patch, num_voices=3, synth=0)
sleep(1)
amy.send(vel=0.5, synth=0, note=50)
sleep(1)
amy.send(vel=0.5, synth=0, note=54)
sleep(1)
amy.send(vel=0.5, synth=0, note=56)
sleep(1)
# Voices are referenced only by their note, so have to turn them off individually
amy.send(vel=0, synth=0, note=50)
amy.send(vel=0, synth=0, note=54)
amy.send(vel=0, synth=0, note=56)
def example_sustain_pedal(patch=0):
# Reset all oscillators first
amy.send(reset=amy.RESET_ALL_OSCS)
amy.send(synth=1, num_voices=4, patch=patch)
sleep(0.05)
amy.send(synth=1, note=76, vel=1.0)
sleep(0.05)
amy.send(synth=1, note=76, vel=0)
sleep(0.05)
amy.send(synth=1, pedal=127)
sleep(0.05)
amy.send(synth=1, note=63, vel=1.0)
sleep(0.05)
amy.send(synth=1, note=63, vel=0)
sleep(0.05)
amy.send(synth=1, note=67, vel=1.0)
sleep(0.05)
amy.send(synth=1, note=67, vel=0)
sleep(0.05)
amy.send(synth=1, note=72, vel=1.0)
sleep(0.05)
amy.send(synth=1, pedal=0)
sleep(0.05)
amy.send(synth=1, note=72, vel=0)
def example_patches():
for i in range(256):
amy.send(patch=i, voices=[0])
print(f"sending patch {i}")
sleep(0.25)
amy.send(voices=[0], osc=0, note=50, vel=0.5)
sleep(1)
amy.send(voices=[0], vel=0)
sleep(0.25)
amy.reset()
def example_reverb():
amy.reverb(2, amy.REVERB_DEFAULT_LIVENESS, amy.REVERB_DEFAULT_DAMPING, amy.REVERB_DEFAULT_XOVER_HZ)
def example_chorus():
amy.chorus(0.8, amy.CHORUS_DEFAULT_MAX_DELAY, amy.CHORUS_DEFAULT_LFO_FREQ, amy.CHORUS_DEFAULT_MOD_DEPTH)
def example_ks():
amy.send(vel=1, wave=amy.KS, feedback=0.996, preset=15, osc=0, note=60)
def example_sine():
amy.send(freq=[440], wave=amy.SINE, vel=1)
def example_multimbral_fm():
notes = [60, 70, 64, 68, 72, 82]
for i, note in enumerate(notes):
# Two amy sends, one to load the patch, one to play it
amy.send(voices=[i], patch=128+i)
amy.send(voices=[i], note=note, vel=0.5, pan=[i*2])
sleep(1)
def example_sequencer_drums():
# Reset all oscillators
amy.send(reset=amy.RESET_ALL_OSCS)
amy.send(tempo=120.0)
# Setup oscs for bd, snare, hat, cow, hicow
oscs = [0, 1, 2, 3, 4]
presets = [1, 5, 0, 10, 10]
for osc, preset in zip(oscs, presets):
amy.send(osc=osc, wave=amy.PCM, preset=preset)
# Update high cowbell
amy.send(osc=4, note=70)
# Add patterns
# Hi hat every 1/8th note
amy.send(sequence=[0, 24, 0], osc=2, vel=2.0)
# Bass drum every quarter note
amy.send(sequence=[0, 96, 1], osc=0, vel=1.0)
# Snare every quarter note, counterphase to BD
amy.send(sequence=[24, 96, 2], osc=1, vel=1.0)
# Cow once every other cycle
amy.send(sequence=[0, 192, 3], osc=3, vel=1.0)
def example_fm():
amy.reset()
# Modulating oscillator (op 2)
amy.send(osc=9, wave=amy.SINE, ratio=1.0,
amp=[1.0, None, 0, 0])
# Output oscillator (op 1)
amy.send(osc=8, wave=amy.SINE, ratio=0.2,
amp=[1.0, None, 0, 1.0],
bp0="0,1,1000,0,0,0")
# ALGO control oscillator
amy.send(osc=7, wave=amy.ALGO, algorithm=1,
algo_source=[0, 0, 0, 0, 9, 8]) # Only indices 4 and 5 matter here
# Add a note on event
sleep(.1)
amy.send(osc=7, note=60, vel=2.0)
def example_patch_from_events():
number = 1039
amy.send(patch=number, reset=amy.RESET_PATCH)
amy.send(patch=number, osc=0, wave=amy.SAW_DOWN,
chained_osc=1, bp0="0,1,1000,0.1,200,0")
amy.send(patch=number, osc=1, wave=amy.SINE,
freq=[131.0], bp0="0,1,500,0,200,0")
amy.send(synth=0, num_voices=4, patch=number)
sleep(.1)
amy.send(synth=0, note=60, vel=1.0)
sleep(.3)
amy.send(synth=0, note=64, vel=1.0)
sleep(.2)
amy.send(synth=0, note=67, vel=1.0)
sleep(.3)
amy.send(synth=0, vel=0.0)
================================================
FILE: amy/fm.py
================================================
# fm.py
# Some code to try to convert DX7 patches into AMY commands
import numpy as np
import time
import amy
from dataclasses import dataclass
from typing import List
@dataclass
class DX7Operator:
"""Per-operator parameters for DX7 patches."""
opnum: int = 0
rates: List[int] = None # 4
levels: List[int] = None # 4
breakpoint: int = 0
bp_depths: List[int] = None # 2
bp_curves: List[int] = None # 2
kbdratescaling: int = 0
ampmodsens: int = 0
keyvelsens: int = 0
ratiotuning: bool = False
freq_coarse: int = 0
freq_fine: int = 0
freq_detune: int = 0
opamp: int = 0
@dataclass
class DX7Patch:
"""Encapsulates information in a DX7 Patch."""
ops: List[DX7Operator] = None
pitch_rates: List[int] = None # 4
pitch_levels: List[int] = None # 4
algo: int = 0 # 1-32
feedback: int = 0
oscsync: int = 0
lfospeed: int = 0
lfodelay: int = 0
lfopitchmoddepth: int = 0
lfoampmoddepth: int = 0
lfosync: int = 0
lfowaveform: int = 0
pitchmodsens: int = 0
transpose: int = 0
name: str = ""
@staticmethod
def from_patch_number(patch_number):
# returns a patch (as in patches.h) from
# default-dx7-patches.bin generated by dx7db, see https://github.com/bwhitman/learnfm
f = bytes(open("amy/default-dx7-patches.bin", mode="rb").read())
patch_data = f[patch_number*156:patch_number*156+156]
return DX7Patch.from_bytestream(bytearray(patch_data))
@staticmethod
def from_bytestream(bytestream):
"""Simply reformat the bytestream into parameters."""
result = DX7Patch()
bytestream = bytes(bytestream)
byteno = 0
def nextbyte(count=1):
nonlocal byteno
if count > 1:
# Return a list.
return [nextbyte() for _ in range(count)]
b = bytestream[byteno]
byteno += 1
# Return a bare byte.
return b
ops = []
# Starts at op 6
for i in range(6, 0, -1):
op = DX7Operator(opnum=i)
op.rates = nextbyte(4)
op.levels = nextbyte(4)
op.breakpoint = nextbyte()
op.bp_depths = nextbyte(2)
op.bp_curves = nextbyte(2)
op.kbdratescaling = nextbyte()
op.ampmodsens = nextbyte()
op.keyvelsens = nextbyte()
op.opamp = nextbyte()
op.ratiotuning = False if nextbyte() == 1 else True
op.freq_coarse = nextbyte()
op.freq_fine = nextbyte()
op.freq_detune = nextbyte()
ops.append(op)
result.ops = ops
result.pitch_rates = nextbyte(4)
result.pitch_levels = nextbyte(4)
result.algo = 1 + nextbyte()
result.feedback = nextbyte()
result.oscsync = nextbyte()
result.lfospeed = nextbyte()
result.lfodelay = nextbyte()
result.lfopitchmoddepth = nextbyte()
result.lfoampmoddepth = nextbyte()
result.lfosync = nextbyte()
result.lfowaveform = nextbyte()
result.pitchmodsens = nextbyte()
result.transpose = nextbyte()
result.name = ''.join(chr(i) for i in nextbyte(10))
return result
def get_bytestream(self):
"""Convert a decoded patch dict back to a bytestream."""
bytestream = []
for op in self.ops:
# Assume ordering is right in ops list.
bytestream.extend(op.rates)
bytestream.extend(op.levels)
bytestream.append(op.breakpoint)
bytestream.extend(op.bp_depths)
bytestream.extend(op.bp_curves)
bytestream.append(op.kbdratescaling)
bytestream.append(op.ampmodsens)
bytestream.append(op.keyvelsens)
bytestream.append(op.opamp)
bytestream.append(0 if op.ratiotuning else 1)
bytestream.append(op.freq_coarse)
bytestream.append(op.freq_fine)
bytestream.append(op.freq_detune)
bytestream.extend(self.pitch_rates)
bytestream.extend(self.pitch_levels)
bytestream.append(self.algo - 1)
bytestream.append(self.feedback)
bytestream.append(self.oscsync)
bytestream.append(self.lfospeed)
bytestream.append(self.lfodelay)
bytestream.append(self.lfopitchmoddepth)
bytestream.append(self.lfoampmoddepth)
bytestream.append(self.lfosync)
bytestream.append(self.lfowaveform)
bytestream.append(self.pitchmodsens)
bytestream.append(self.transpose)
bytestream.extend(ord(c) for c in self.name)
return bytes(bytestream)
@dataclass
class AMYOscillator:
op_num: int = 0
amp_levels: List[float] = None
amp_times: List[float] = None
op_amp: float = 0
ampmodsens: float = 0
frequency: float = 0
freq_is_ratio: bool = False
@staticmethod
def from_dx7_op(op):
result = AMYOscillator()
result.op_num = op.opnum
result.amp_levels, result.amp_times = eg_to_bp(op.rates, op.levels)
result.op_amp = 2 * dx7level_to_linear(op.opamp)
if op.ratiotuning:
result.frequency = coarse_fine_ratio(op.freq_coarse, op.freq_fine, op.freq_detune)
result.freq_is_ratio = True
else:
result.frequency = coarse_fine_fixed_hz(op.freq_coarse, op.freq_fine, op.freq_detune)
result.freq_is_ratio = False
result.ampmodsens = float(op.ampmodsens) # Don't know scaling, just 0/nonzero.
return result
def fm_trunc(number):
if(type(number)==float or type(number)==np.float64):
return ('%.6f' % number).rstrip('0').rstrip('.')
return str(number)
@dataclass
class AMYPatch:
oscs: List[AMYOscillator] = None
pitch_levels: List[float] = None
pitch_times: List[float] = None
algo: int = 0
feedback: float = 0
lfo_freq: float = 0
lfo_delay: float = 0
lfo_pitchmoddepth: float = 0
lfo_ampmoddepth: float = 0
lfo_waveform: int = 0
name: str = ""
amp_lfo_amp: float = 0
pitch_lfo_amp: float = 0
@staticmethod
def from_dx7(dx7_patch):
result = AMYPatch()
result.oscs = []
for op in dx7_patch.ops:
result.oscs.append(AMYOscillator.from_dx7_op(op))
result.pitch_levels, result.pitch_times = eg_to_bp_pitch(
dx7_patch.pitch_rates, dx7_patch.pitch_levels)
result.algo = dx7_patch.algo
result.feedback = 0.00125 * (2 ** dx7_patch.feedback)
result.lfo_freq = lfo_speed_to_hz(dx7_patch.lfospeed)
result.lfo_delay = dx7_patch.lfodelay
#result.lfo_pitchmoddepth = dx7_patch.lfopitchmoddepth
result.lfo_ampmoddepth = dx7_patch.lfoampmoddepth
result.lfo_waveform = lfo_wave(dx7_patch.lfowaveform)
result.amp_lfo_amp = dx7level_to_linear(result.lfo_ampmoddepth)
# With pitchmodsens at max (7), and PMD at max (99), the pitch mod is +/- 1 octave (24 semis range)
# PMS 7 / PMD 50 is 12 semis range
# PMS 7 / PMD 25 is 6 semis
# PMS 7 / PMD 12 is 2 semis
# PMS 7 / PMD 6 is 1 semi .. really does look linear.
# PMS 6 / PMD 99 is 14 semis range
# PMS 5 / PMD 99 is ~8.5 semis
# PMS 4 / PMD 99 is ~5.5 semis range
# PMS 3 / PMD 99 is ~3.5
# PMS 2 / PMD 99 is ~2 semi
# PMS 1 / PMD 99 is ~1.5 semi
# PMS 0 is no semi
# Finally, matching K128 by ear, PMS 3/PDM 05 should give pitch_lfo_amp about 0.008.
# So total range is about 1.7 ^ (PMS - 1) * (PMD / 99) semis
# So scaling from +/-1 LFO to octaves is pow(1.7, (PMS - 1)) * (PMD / 99) / 12
# 0.6 is a fudge factor. Seems way too large for small values of PMD, so maybe PMD is exp-lin or smt
result.pitch_lfo_amp = (
0 if dx7_patch.pitchmodsens == 0
else 0.6 * (1.7 ** (dx7_patch.pitchmodsens - 1)) * dx7_patch.lfopitchmoddepth / 1188.0
)
result.name = dx7_patch.name
return result
def send_to_AMY(self, reset=True):
# Take a FM patch and output AMY commands to set up the patch.
# Send amy.send(vel=1,osc=0,note=50) after
t = fm_trunc
if(reset): amy.reset()
pitch_levels, pitch_times = self.pitch_levels, self.pitch_times
pitchbp = "%d,%s,%d,%s,%d,%s,%d,%s,%d,%s" % (
pitch_times[0], t(pitch_levels[0]), pitch_times[1], t(pitch_levels[1]),
pitch_times[2], t(pitch_levels[2]), pitch_times[3], t(pitch_levels[3]),
pitch_times[4], t(pitch_levels[4])
)
# Set up each operator.
last_release_time = 0
last_release_value = 0
# Oscs: 0 is algo, 1 is pitch LFO, 2 is amp LFO, 3-8 are ops 1-6
main_osc = 0
lfo_osc = 1
# The osc of op0 (they go up from here)
op0_osc = 2
for op_num_from_0, osc in enumerate(self.oscs):
osc_num = op0_osc + op_num_from_0
amp_levels, amp_times = osc.amp_levels, osc.amp_times
oscbp = "%d,%s,%d,%s,%d,%s,%d,%s,%d,%s" % (
amp_times[0], t(amp_levels[0]), amp_times[1], t(amp_levels[1]),
amp_times[2], t(amp_levels[2]), amp_times[3], t(amp_levels[3]),
amp_times[4], t(amp_levels[4])
)
oscbpfmt = "%d,%s/%d,%s/%d,%s/%d,%s/%d,%s" % (
amp_times[0], t(amp_levels[0]), amp_times[1], t(amp_levels[1]),
amp_times[2], t(amp_levels[2]), amp_times[3], t(amp_levels[3]),
amp_times[4], t(amp_levels[4])
)
if(amp_times[4] > last_release_time):
last_release_time = amp_times[4]
last_release_value = amp_levels[4]
#print("osc %d (op %d) freq %.6f ratio %d env %s amp %.6f amp_mod %d" % \
# (osc_num, osc.op_num_from_0, osc.frequency, osc.freq_is_ratio, oscbpfmt,
# osc.op_amp, osc.ampmodsens))
# Make them all in cosine phase, to be like DX7. Important for slow oscs
args = {"osc": osc_num,
"bp0": oscbp, "phase": 0.25}
if osc.freq_is_ratio:
args["ratio"] = t(osc.frequency)
else:
args["freq"] = t(osc.frequency)
# TODO: we xignore intensity of amp mod sens, just on/off
args.update({"mod_source": lfo_osc, "amp": "%s,0,0,1,0,%s" % (t(osc.op_amp), t(self.amp_lfo_amp * (osc.ampmodsens > 0)))})
# We are _NOT_ updating operators with pitch bp, per dan tuesday 7/5 morning (but not monday 7/4 morning)
#args.update({"bp1": pitchbp})
amy.send(**args)
# Set up the LFO x
#print("osc %d amp lfo wave %d freq %f amp %f" % (
# lfo_osc, self.lfo_waveform, self.lfo_freq, 1)
amy.send(osc=lfo_osc, wave=self.lfo_waveform, freq=t(self.lfo_freq),
amp=1, phase=0.25)
#print("not used: lfo delay %d " % self.lfo_delay)
#ampbp = "0,1,%d,%f" % (last_release_time, last_release_value)
#print("osc 0 (main) algo %d feedback %f pitchenv %s ampenv %s" % (
# self.algo, self.feedback, pitchbp, ampbp))
amy.send(osc=main_osc, wave=amy.ALGO, algorithm=self.algo, feedback=t(self.feedback),
algo_source=",".join(str(o) for o in range(op0_osc, op0_osc + 6)),
#bp0=ampbp,
#bp1=pitchbp,
#freq="0,1,0,0,1,1",
bp0=pitchbp,
# bp1 is now ununsed.
amp="1,0,1,0,0,0", # Turn off EG0 for amp
freq="0,1,0,1,0,%s" % t(self.pitch_lfo_amp), # Turn on EG0 and LFO for freq
mod_source=lfo_osc)
def dx7level_to_linear(dx7level):
"""Map the dx7 0..99 levels to linear amplitude."""
return 2 ** ((dx7level - 99) / 8)
def linear_to_dx7level(linear):
"""Map a linear amplitude to the dx7 0..99 scale."""
return np.log2(np.maximum(dx7level_to_linear(0), linear)) * 8 + 99
def pitchval_to_ratio(pitchval):
"""Map 0..99 DX7 pitch vals (e.g. from pitch_env) into f0 ratios."""
# Pitch map 0..99 actually becomes -128..127 via a symmetric map with 50->0, linear from 15 to 85, then
# quadratic in the remainder.
pitchsign = -1 + 2*(pitchval >= 50)
semipitchval = np.abs(pitchval - 50).astype(float)
# Above (50 + 36), Quadratic to reach 127 at level 99.
semipitchval += (semipitchval > 36) * (((semipitchval - 34)**2) * 93/225 - semipitchval + 34)
# DX7 manual states pitchmod range is +/- 4 octaves, so 32 steps/oct sounds right.
return 2 ** ((pitchsign * semipitchval) / 32)
def ratio_to_pitchval(ratio):
semipitchval = 32 * np.log2(ratio)
pitchsign = -1 + 2*(semipitchval >= 0)
semipitchval = np.abs(semipitchval)
# Vectorized conditional treatment of outside -36 to 36.
semipitchval += (semipitchval > 36) * (34 + np.sqrt(np.abs(semipitchval - 34) * (225/93)) - semipitchval)
return 50 + pitchsign * semipitchval
def calc_loglin_eg_breakpoints(rates, levels, dx7_attacks=True,
rate_double_interval=6, rate_scale=0.5, rate_offset=0.5):
"""Convert the DX7 rates/levels into (time, target) pairs (for amy)"""
if dx7_attacks:
level_to_lin_fn = dx7level_to_linear
else:
level_to_lin_fn = pitchval_to_ratio
# This is the part we precompute in fm.py to get breakpoints to send to amy.
current_level = levels[-1]
# EG at time 0 has final value from release.
breakpoints = [(0, level_to_lin_fn(current_level))]
MIN_LEVEL = 34
ATTACK_RANGE = 75
def level_to_attack_time(level, t_const):
"""Return the time at which a paradigmatic DX7 attack envelope will reach a level (0..99 range)"""
# Return the t0 that solves level = MIN_LEVEL + ATTACK_RANGE * (1 - exp(-t0 / t_const))
return -t_const * np.log((MIN_LEVEL + ATTACK_RANGE - np.maximum(MIN_LEVEL, level))/ATTACK_RANGE)
for segment, (rate, target_level) in enumerate(zip(rates, levels)):
release_segment = (segment == len(rates)-1)
if dx7_attacks and target_level > current_level: # Attack segment
# The attack envelopes L(t) appear to be ~ 34 + 75 * (1 - exp(t / t_const)), starting from L = 34
# i.e. they are rising exponentials (as in analog ADSR, but here in the log(amp) domain)
# with an asymptote at 109 (i.e., 10 higher than the highest possible amp).
# The time constant depends on the R (rate) parameter, and is well fit by:
t_const = 0.008 * (2 ** ((65 - rate)/6))
# Total time for this segment is t1 - t0 where t0 and t1 solve
# effective_start = 34 + 75 * (1 - np.exp(-t0 / t_const)) = 109 - 75 exp(-t0 / t_c)
# target_level = 34 + 75 * (1 - np.exp(-t1 / t_const)) = 109 - 75 exp(-t1 / t_c)
# so t1 - t0 = -t_c * [log((34 + 75 - target_level)/75) - log((34 + 75 - effective_start)/75)]
effective_start_level = np.maximum(current_level, MIN_LEVEL)
t0 = level_to_attack_time(effective_start_level, t_const)
segment_duration = level_to_attack_time(target_level, t_const) - t0
#print("eff_st=", effective_start_level, "t_c=", t_const, "t0=", t0, "dur=", segment_duration)
# Now amy's task will be to recover t0 and t_const from (time, target) pairs
else:
# Decay segment, or TRUE_EXPONENTIAL attack segment.
direction = 1 if target_level > current_level else -1
# "A falling segment takes 3.5 mins"
# so delta = 99 in 210 seconds -> level_change_per_sec = 0.5
# I think just offset everything by 0.5, avoids div0.
level_change_per_sec = direction*(rate_offset + rate_scale * (2 ** (rate / rate_double_interval)))
level_difference = target_level - current_level
# Hack to cover for sustain = 0, release = 0 release segments which look like they should be zero long
if release_segment and level_difference == 0:
level_difference = direction * 60 # e.g. from a decayed level of 80 to zero.
#print("** Goosing release amp")
segment_duration = level_difference / level_change_per_sec
#print("lcps=", level_change_per_sec, "dur=", segment_duration)
breakpoints.append((segment_duration, level_to_lin_fn(target_level)))
current_level = target_level
return breakpoints
def eg_to_bp(egrate, eglevel, calc_eg_args={}):
breakpoints = calc_loglin_eg_breakpoints(egrate, eglevel, **calc_eg_args)
rates = []
times = []
for time, level in breakpoints:
times.append(int(1000 * time))
rates.append(level)
return rates, times
def eg_to_bp_pitch(egrate, eglevel):
# Additional args to make breakpoint calculation to the right thing for pitch.
calc_pitch_eg_args = {'dx7_attacks': False, 'rate_double_interval': 20, 'rate_scale': 11, 'rate_offset': -6}
return eg_to_bp(egrate, eglevel, calc_pitch_eg_args)
def coarse_fine_fixed_hz(coarse, fine, detune=7):
coarse = coarse & 3
return 10 ** (coarse + (fine + ((detune - 7) / 8)) / 100 )
def coarse_fine_ratio(coarse, fine, detune=7):
coarse = coarse & 31
if(coarse == 0):
coarse = 0.5
return coarse * (1 + (fine + ((detune - 7) / 8)) / 100)
def lfo_speed_to_hz(byte):
# Measured values from TX802, linear fit by eye
if byte == 0:
return 0.064
if byte <= 64:
return byte / 6.0
if byte <= 85:
return byte - 64.0 * 5.0/6.0
# Byte > 85
return 31.67 + (byte - 85.0) * 1.33
def lfo_wave(byte):
if byte > 5:
return None
return [
amy.TRIANGLE, amy.SAW_DOWN, amy.SAW_UP,
amy.PULSE, amy.SINE, amy.NOISE
][byte]
# Play a numpy array on an Apple Silicon mac without having to use an external library
# (sounddevice is currently broken on AS macs)
def play_np_array(np_array, samplerate=amy.AMY_SAMPLE_RATE):
import wave, tempfile , os, struct
tf = tempfile.NamedTemporaryFile()
obj = wave.open(tf,'wb')
obj.setnchannels(1) # mono
obj.setsampwidth(2)
obj.setframerate(samplerate)
for i in range(np_array.shape[0]):
value = int(np_array[i] * 32767.0)
data = struct.pack('<h', value)
obj.writeframesraw( data )
obj.close()
os.system("afplay " + tf.name)
tf.close()
================================================
FILE: amy/headers.py
================================================
# headers.py
# Generate headers for AMY
import sys
import glob
import numpy as np
import amy
from . import constants
def _read_wavetables(wavetable_files):
tables = []
wavetable_len = None
for wavfile in wavetable_files:
with open(wavfile, 'rb') as f:
samplerate, wav_data = wav.read(f)
if getattr(wav_data, "ndim", 1) != 1:
raise ValueError(f"{wavfile} is not mono")
wav_data = wav_data.astype(np.int16)
if wavetable_len is None:
wavetable_len = len(wav_data)
elif len(wav_data) != wavetable_len:
raise ValueError(f"{wavfile} length {len(wav_data)} != {wavetable_len}")
tables.append((wavfile, wav_data))
return tables, wavetable_len
def generate_amy_pcm_header(sample_set, name, pcm_AMY_SAMPLE_RATE=22050, wavetable_files=None):
from sf2utils.sf2parse import Sf2File
import resampy
import struct
# Download the sf2 file here
# https://github.com/vigliensoni/soundfonts/blob/master/hs_tr808/HS-TR-808-Drums.sf2
fn = "sounds/HS-TR-808-Drums.sf2"
offsets = []
offset = 0
int16s = []
samples = []
sample_counter = 0
my_sample_counter = 0
orig_map = {}
try:
sf2 = Sf2File(open(fn, 'rb'))
except Exception as e:
print("For PCM presets, download the sf2 files first. See comment in amy.headers.generate_amy_pcm_header()")
return
for sample in sf2.samples[:-1]:
if(sample_counter in sample_set):
samples.append(sample)
orig_map[my_sample_counter] = sample_counter
my_sample_counter += 1
sample_counter += 1
for sample in samples:
try:
s = {}
s["name"] = sample.name
floaty =(np.frombuffer(bytes(sample.raw_sample_data),dtype='int16'))/32768.0
resampled = resampy.resample(floaty, sample.sample_rate, pcm_AMY_SAMPLE_RATE)
# Make sure the float value doesn't cause overflow in int. resampling can cause overshoot.
samples_int16 = np.int16(np.minimum(32767.0, np.maximum(-32768.0, resampled*32768.0)))
#floats.append(resampled)
int16s.append(samples_int16)
s["offset"] = offset
s["length"] = resampled.shape[0]
s["loopstart"] = int(float(sample.start_loop) / float(sample.sample_rate / pcm_AMY_SAMPLE_RATE))
s["loopend"] = int(float(sample.end_loop) / float(sample.sample_rate / pcm_AMY_SAMPLE_RATE))
s["midinote"] = sample.original_pitch
offset = offset + resampled.shape[0]
offsets.append(s)
except AttributeError:
print("skipping %s" % (sample.name))
all_samples = np.hstack(int16s)
wavetable_tables = []
wavetable_len = 0
if wavetable_files is not None and len(wavetable_files) > 0:
wavetable_tables, wavetable_len = _read_wavetables(wavetable_files)
wavetable_count = len(wavetable_tables)
base_samples = len(offsets)
base_length = all_samples.shape[0]
p = open("src/pcm_%s.h" % (name), "w")
p.write("// Automatically generated by amy.headers.generate_pcm_header()\n")
p.write("#ifndef __PCM_H\n#define __PCM_H\n")
p.write("#define PCM_AMY_SAMPLE_RATE %d\n" % (pcm_AMY_SAMPLE_RATE))
p.write("#define PCM_BASE_SAMPLES %d\n" % (base_samples))
p.write("#define PCM_BASE_LENGTH %d\n" % (base_length))
if wavetable_count > 0:
p.write("#if defined(AMY_WAVETABLE)\n")
p.write("#define PCM_WAVETABLE_BASE PCM_BASE_SAMPLES\n")
p.write("#define PCM_WAVETABLE_SAMPLES %d\n" % (wavetable_count))
p.write("#define PCM_WAVETABLE_LEN %d\n" % (wavetable_len))
p.write("#define PCM_LENGTH (PCM_BASE_LENGTH + (PCM_WAVETABLE_SAMPLES * PCM_WAVETABLE_LEN))\n")
p.write("#define PCM_MAP_ENTRIES (PCM_BASE_SAMPLES + PCM_WAVETABLE_SAMPLES)\n")
p.write("#else\n")
p.write("#define PCM_WAVETABLE_BASE PCM_BASE_SAMPLES\n")
p.write("#define PCM_WAVETABLE_SAMPLES 0\n")
p.write("#define PCM_WAVETABLE_LEN 0\n")
p.write("#define PCM_LENGTH PCM_BASE_LENGTH\n")
p.write("#define PCM_MAP_ENTRIES PCM_BASE_SAMPLES\n")
p.write("#endif\n")
else:
p.write("#define PCM_WAVETABLE_BASE PCM_BASE_SAMPLES\n")
p.write("#define PCM_WAVETABLE_SAMPLES 0\n")
p.write("#define PCM_WAVETABLE_LEN 0\n")
p.write("#define PCM_LENGTH PCM_BASE_LENGTH\n")
p.write("#define PCM_MAP_ENTRIES PCM_BASE_SAMPLES\n")
p.write("#include \"pcm_samples_%s.h\"\n" % (name))
p.write("const uint16_t pcm_samples = PCM_MAP_ENTRIES;\n")
p.write("const uint16_t pcm_wavetable_base = PCM_WAVETABLE_BASE;\n")
p.write("const uint16_t pcm_wavetable_samples = PCM_WAVETABLE_SAMPLES;\n")
p.write("const uint32_t pcm_wavetable_len = PCM_WAVETABLE_LEN;\n")
p.write("const pcm_map_t pcm_map[PCM_MAP_ENTRIES] PROGMEM = {\n")
for i,o in enumerate(offsets):
p.write(" /* [%d] %d */ {%d, %d, %d, %d, %d}, /* %s */\n" %(i, orig_map[i], o["offset"], o["length"], o["loopstart"], o["loopend"], o["midinote"], o["name"]))
if wavetable_count > 0:
p.write("#if defined(AMY_WAVETABLE)\n")
for i, (wavfile, wav_data) in enumerate(wavetable_tables):
wav_index = base_samples + i
wav_offset = base_length + i * wavetable_len
wav_name = os.path.basename(wavfile)
p.write(" /* [%d] WT */ {%d, %d, %d, %d, %d}, /* %s */\n" % (
wav_index, wav_offset, wavetable_len, 0, wavetable_len, 69, wav_name))
p.write("#endif\n")
p.write("};\n")
p.write("\n#endif // __PCM_H\n")
p.close()
p = open("src/pcm_samples_%s.h" % (name), 'w')
p.write("// Automatically generated by amy.headers.generate_pcm_header()\n")
p.write("#ifndef __PCM_SAMPLES_H\n#define __PCM_SAMPLES_H\n")
p.write("const int16_t pcm[PCM_LENGTH] PROGMEM = {\n")
column = 15
count = 0
for i in range(int(all_samples.shape[0]/column)):
p.write(" %s,\n" % (",".join([("%d" % (d)).ljust(8) for d in all_samples[i*column:(i+1)*column]])))
count = count + column
print("count %d all_samples.shape %d" % (count, all_samples.shape[0]))
if(count != all_samples.shape[0]):
p.write(" %s\n" % (",".join([("%d" % (d)).ljust(8) for d in all_samples[count:]])))
if wavetable_count > 0:
p.write("#if defined(AMY_WAVETABLE)\n")
for wavfile, wav_data in wavetable_tables:
p.write(" // %s\n" % (wavfile))
for i in range(int(len(wav_data)/column)):
p.write(" %s,\n" % (",".join([("%d" % (d)).ljust(8) for d in wav_data[i*column:(i+1)*column]])))
rem = int(len(wav_data) % column)
if rem != 0:
p.write(" %s,\n" % (",".join([("%d" % (d)).ljust(8) for d in wav_data[-rem:]])))
p.write("#endif\n")
p.write("};\n")
p.write("\n#endif // __PCM_SAMPLES_H\n")
def generate_pcm_headers():
tiny = [0, 3, 8, 11, 14, 16, 17, 18, 20, 23, 25]
wavetable_files = sorted(glob.glob('sounds/wavetables/*.WAV'))
generate_amy_pcm_header(tiny, "tiny", wavetable_files=wavetable_files)
def cos_lut(table_size, harmonics_weights, harmonics_phases=None):
if harmonics_phases is None:
harmonics_phases = np.zeros(len(harmonics_weights))
table = np.zeros(table_size)
phases = np.arange(table_size) * 2 * np.pi / table_size
for harmonic_number, harmonic_weight in enumerate(harmonics_weights):
table += harmonic_weight * np.cos(
phases * harmonic_number + harmonics_phases[harmonic_number])
return table
# A LUTset is a list of LUTentries describing downsampled versions of the same
# basic waveform, sorted with the longest (highest-bandwidth) first.
def create_lutset(LUTentry, harmonic_weights, harmonic_phases=None,
length_factor=8, bandwidth_factor=None):
if bandwidth_factor is None:
bandwidth_factor = np.sqrt(0.5)
"""Create an ordered list of LUTs with decreasing harmonic content.
These can then be used in interp_from_lutset to make an adaptive-bandwidth
interpolation.
Args:
harmonic_weights: vector of amplitudes for cosine harmonic components.
harmonic_phases: initial phases for each harmonic, in radians. Zero
(default) indicates cosine phase.
length_factor: Each table's length is at least this factor times the order
of the highest harmonic it contains. Thus, this is a lower bound on the
number of samples per cycle for the highest harmonic. Higher factors make
the interpolation easier.
bandwidth_factor: Target ratio between the highest harmonics in successive
table entries. Default is sqrt(0.5), so after two tables, bandwidth is
reduced by 1/2 (and length with follow).
Returns:
A list of LUTentry objects, sorted in decreasing order of the highest
harmonic they contain. Each LUT's length is a power of 2, and as small as
possible while respecting the length_factor for the highest contained
harmonic.
"""
if harmonic_phases is None:
harmonic_phases = np.zeros(len(harmonic_weights))
# Calculate the length of the longest LUT we need. Must be a power of 2,
# must have at least length_factor * highest_harmonic samples.
# Harmonic 0 (dc) doesn't count.
float_num_harmonics = float(len(harmonic_weights))
lutsets = []
done = False
# harmonic 0 is DC; there's no point in generating that table.
while float_num_harmonics >= 2:
num_harmonics = int(round(float_num_harmonics))
highest_harmonic = num_harmonics - 1 # because zero doesn't count.
lut_size = int(2 ** np.ceil(np.log(length_factor * highest_harmonic) / np.log(2)))
lutsets.append(LUTentry(
table=cos_lut(lut_size, harmonic_weights[:num_harmonics],
harmonic_phases[:num_harmonics]), # / lut_size,
highest_harmonic=highest_harmonic))
float_num_harmonics = bandwidth_factor * float_num_harmonics
return lutsets
def make_table(min_val, max_val, fn, table_size=257, dtype=np.int16):
# The table includes the final value, so the actual number of steps is table_size - 1.
steps = table_size - 1
stepsize = (max_val - min_val) / steps
return fn(np.arange(min_val, max_val + stepsize, stepsize)).astype(dtype)
def create_exp2_lut(npts):
exp2_int16_fn = lambda x: np.round(-32768.0 * (np.exp2(x) - 1.0))
return make_table(0, 1, exp2_int16_fn, table_size=npts, dtype=np.int16)
def create_log2_lut(npts):
log2_int16_fn = lambda x: np.round(-32768.0 * (np.log2(x + 1.0)))
return make_table(0, 1, log2_int16_fn, table_size=npts, dtype=np.int16)
def write_lutset_to_h(filename, variable_base, lutset):
"""Savi out a lutset as a C-compatible header file."""
num_luts = len(lutset)
with open(filename, "w") as f:
f.write("// Automatically-generated LUTset\n")
f.write("#ifndef LUTSET_{:s}_DEFINED\n".format(variable_base.upper()))
f.write("#define LUTSET_{:s}_DEFINED\n".format(variable_base.upper()))
f.write("\n")
# Define the structure.
f.write("#ifndef LUTENTRY_DEFINED\n")
f.write("#define LUTENTRY_DEFINED\n")
f.write("typedef struct {\n")
f.write(" const float *table;\n")
f.write(" int table_size;\n")
f.write(" int highest_harmonic;\n")
f.write("} lut_entry;\n")
f.write("#endif // LUTENTRY_DEFINED\n")
f.write("\n")
# Define the content of the individual tables.
samples_per_row = 8
for i in range(num_luts):
table_size = len(lutset[i].table)
f.write("const float {:s}_lutable_{:d}[{:d}] PROGMEM = {{\n".format(
variable_base, i, table_size))
for row_start in range(0, table_size, samples_per_row):
for sample_index in range(row_start,
min(row_start + samples_per_row, table_size)):
f.write("{:f},".format(lutset[i].table[sample_index]))
f.write("\n")
f.write("};\n")
f.write("\n")
# Define the table of LUTs.
f.write("lut_entry {:s}_lutset[{:d}] = {{\n".format(
variable_base, num_luts + 1))
for i in range(num_luts):
f.write(" {{{:s}_lutable_{:d}, {:d}, {:d}}},\n".format(
variable_base, i, len(lutset[i].table),
lutset[i].highest_harmonic))
# Final entry is null to indicate end of table.
f.write(" {NULL, 0, 0},\n")
f.write("};\n")
f.write("\n")
f.write("#endif // LUTSET_x_DEFINED\n")
print("wrote", filename)
def write_fxpt_lutable(f, lutable, name, samples_per_row=8):
"""Write a single lutable to an open file."""
table_size = len(lutable)
scale_factor = np.max(np.abs(lutable.astype(float)))
f.write("const int16_t {:s}[{:d}] PROGMEM = {{\n".format(
name, table_size))
for row_start in range(0, table_size, samples_per_row):
for sample_index in range(row_start,
min(row_start + samples_per_row, table_size)):
f.write("{:d},".format(
min(32767,
max(-32768,
int(round(32768 / scale_factor * lutable[sample_index]))))))
f.write("\n")
f.write("};\n")
f.write("\n")
return scale_factor
def write_lutset_to_h_as_fxpt(filename, variable_base, lutset):
"""Save out a lutset as a C-compatible header file using ints."""
import math
num_luts = len(lutset)
with open(filename, "w") as f:
f.write("// Automatically-generated LUTset\n")
f.write("#ifndef LUTSET_{:s}_FXPT_DEFINED\n".format(variable_base.upper()))
f.write("#define LUTSET_{:s}_FXPT_DEFINED\n".format(variable_base.upper()))
f.write("\n")
# Define the structure.
f.write("#ifndef LUTENTRY_FXPT_DEFINED\n")
f.write("#define LUTENTRY_FXPT_DEFINED\n")
f.write("typedef struct {\n")
f.write(" const int16_t *table;\n")
f.write(" int table_size;\n")
f.write(" int log_2_table_size;\n")
f.write(" int highest_harmonic;\n")
f.write(" float scale_factor;\n")
f.write("} lut_entry_fxpt;\n")
f.write("#endif // LUTENTRY_FXPT_DEFINED\n")
f.write("\n")
# Define the content of the individual tables.
scale_factors = []
for i in range(num_luts):
scale_factor = write_fxpt_lutable(
f, lutset[i].table,
'{:s}_fxpt_lutable_{:d}'.format(variable_base, i)
)
scale_factors.append(scale_factor)
# Define the table of LUTs.
f.write("lut_entry_fxpt {:s}_fxpt_lutset[{:d}] = {{\n".format(
variable_base, num_luts + 1))
for i in range(num_luts):
table_size = len(lutset[i].table)
# Provide the shift size corresponding to the lutset.
log_2_table_size = int(round(math.log(table_size) / math.log(2.0)))
f.write(" {{{:s}_fxpt_lutable_{:d}, {:d}, {:d}, {:d}, {:f}}},\n".format(
variable_base, i, table_size, log_2_table_size,
lutset[i].highest_harmonic, scale_factors[i]))
# Final entry is null to indicate end of table.
f.write(" {NULL, 0, 0, 0, 0.0},\n")
f.write("};\n")
f.write("\n")
f.write("#endif // LUTSET_x_DEFINED\n")
print("wrote", filename)
def make_log2_exp2_luts(filename):
"""Write the fixed-point exp2 and log2 lookup tables."""
variable_base = 'exp_lut'
with open(filename, "w") as f:
f.write("// Automatically-generated LUTset\n")
f.write("#ifndef LUTSET_{:s}_FXPT_DEFINED\n".format(variable_base.upper()))
f.write("#define LUTSET_{:s}_FXPT_DEFINED\n".format(variable_base.upper()))
f.write("\n")
# Define the content of the individual tables.
write_fxpt_lutable(f, create_log2_lut(257), 'log2_fxpt_lutable')
write_fxpt_lutable(f, create_exp2_lut(257), 'exp2_fxpt_lutable')
f.write("\n")
f.write("#endif // LUTSET_x_DEFINED\n")
print("wrote", filename)
def make_clipping_lut(filename):
# Soft clipping lookup table scratchpad.
SAMPLE_MAX = 32767
linear_proportion = 0.9 # I tried 0.6 and you could hear the difference but not enough to matter.
LIN_MAX = int(round(linear_proportion * 32768)) # 29491
NONLIN_RANGE = round(1.5 * (32767 - LIN_MAX)) # size of nonlinearity lookup table = 4915
clipping_lookup_table = np.arange(LIN_MAX + NONLIN_RANGE)
for x in range(NONLIN_RANGE):
x_dash = float(x) / NONLIN_RANGE
clipping_lookup_table[x + LIN_MAX] = LIN_MAX + int(np.floor(NONLIN_RANGE * (x_dash - x_dash * x_dash * x_dash / 3.0)))
with open(filename, "w") as f:
f.write("// Automatically generated.\n// Clipping lookup table\n")
f.write("#ifndef __CLIPPING_TABLE\n#define __CLIPPING_TABLE\n")
f.write("#define FIRST_NONLIN %d\n" % LIN_MAX)
f.write("#define NONLIN_RANGE %d\n" % NONLIN_RANGE)
f.write("// First sample value beyond end of table (just clip to max).\n")
f.write("#define FIRST_HARDCLIP (FIRST_NONLIN + NONLIN_RANGE)\n")
f.write("const uint16_t clipping_lookup_table[NONLIN_RANGE] PROGMEM = {\n")
samples_per_row = 8
for row_start in range(0, NONLIN_RANGE, samples_per_row):
for sample in range(row_start, min(NONLIN_RANGE, row_start + samples_per_row)):
f.write("%d," % clipping_lookup_table[LIN_MAX + sample])
f.write("\n")
f.write("};\n")
f.write("#endif\n")
print("wrote", filename)
def make_piano_patch():
import amy
# This just allocates the 20 oscs needed for a INTERP_PARTIALS patch
# dpwe wants to add a `num_suboscs` field to fix this behavior soon
amy.send(chorus=0) # Piano sounds weird with chorus on
amy.send(osc=0, wave=amy.INTERP_PARTIALS, preset=0, amp='1,0,0,0') # Parent osc amp applies, disconnect vel and eg0.
#amy.send(osc=20, wave=amy.PARTIAL) # it's not 20, but it doesn't matter, voice is reallocated by interp_partials.c
return 25 # We now use up to 24 partials per voice + 1 control osc.
def make_amyboard_patch():
import amy
# Modified for "silent control osc"
ctl_osc = 0
lfo_osc = 1
osc_a = 2
osc_b = 3
message = amy.message(osc=ctl_osc, wave=amy.SILENT, mod_source=lfo_osc, chained_osc=osc_a,
filter_type=amy.FILTER_LPF24, filter_freq={'const': 200.0, 'note': 1.0, 'eg1': 5.0},
resonance=0.7, bp0='0,1,1000,0.2,100,0', bp1='0,1,1000,0.2,1000,0')
message += amy.message(osc=osc_a, wave=amy.PULSE, amp={'vel': 0, 'eg0': 0}, mod_source=lfo_osc, chained_osc=osc_b)
message += amy.message(osc=osc_b, wave=amy.SAW_DOWN, amp={'vel': 0, 'eg0': 0}, mod_source=lfo_osc, freq={'const': constants.ZERO_LOGFREQ_IN_HZ / 2})
message += amy.message(osc=lfo_osc, wave=amy.TRIANGLE, amp={'vel': 0}, freq={'const': 4.0, 'note': 0, 'bend': 0}, bp0='0,1.0,10000,0')
message += amy.message(eq=[0, 0, 0], chorus='0,,0.5,0.5')
return 4, message # 4 oscs
def make_patches(filename):
def nothing(message):
return
from . import juno, fm
num_oscs =[]
# Don't make any noise
amy.override_send = nothing
with open(filename, "w") as f:
f.write("// Automatically generated.\n// DX7 and juno 106 and custom patch table\n")
f.write("#ifndef __PATCHESH\n#define __PATCHESH\n")
f.write("static const char * const patch_commands[258] PROGMEM = {\n")
# Do juno
for i in range(128):
amy.log_patch()
j = juno.JunoPatch()
j.set_patch(i)
f.write("\t/* %d: Juno %s */ \"%s\",\n" % (i, j.name, amy.retrieve_patch()))
num_oscs.append(6)
# Do dx7
for i in range(128):
amy.log_patch()
p = fm.AMYPatch.from_dx7(fm.DX7Patch.from_patch_number(i))
p.send_to_AMY(reset=False)
f.write("\t/* %d: DX7 %s */ \"%s\",\n" % (i+128, p.name, amy.retrieve_patch()))
num_oscs.append(8)
# do piano
amy.log_patch()
num_osc_piano = make_piano_patch()
f.write("\t/* 256: dpwe piano */ \"%s\",\n" % (amy.retrieve_patch()))
num_oscs.append(num_osc_piano)
# do amyboard patch
num_osc_amyboard, patch_string = make_amyboard_patch()
f.write("\t/* 257: amyboard default */ \"%s\",\n" % (patch_string))
num_oscs.append(num_osc_amyboard)
f.write("};\n")
f.write("const uint16_t patch_oscs[258] PROGMEM = {\n")
for i in num_oscs:
f.write("%d," % (i))
f.write("\n};\n#endif\n")
amy.override_send = None
print("wrote", filename)
def write_vector_as_c(f, data, name, dtype='uint8_t', items_per_row=20):
num_name = "NUM_%s" % name.upper()
f.write("#define %s %d\n" % (num_name, len(data)))
f.write("const %s %s[%s] PROGMEM = {\n" % (dtype, name, num_name))
for start in range(0, len(data), items_per_row):
data_row = data[start : start + items_per_row]
f.write(" " + ", ".join("%d" % d for d in data_row) + ",\n")
f.write("};\n\n")
def make_interp_partials(filename, data_dict):
"""Write the json data from experiments/piano_heterodyne.ipynb into a C header."""
import itertools
# data_dict is {instrument_tag: {'sample_times_ms': [], 'notes': [], 'velocities': [], 'num_harmonics': xx, 'harmonics_freq': [], 'harmonics_mags': []}, ...}
with open(filename, "w") as f:
f.write("// Automatically generated.\n// Piano interpolated partials data table\n")
f.write("#ifndef __INTERP_PARTIALS_H\n#define __INTERP_PARTIALS_H\n\n")
f.write("#define NUM_INTERP_PARTIALS_PRESETS %d\n\n" % len(data_dict))
map_contents = ""
for tag, data in data_dict.items():
for varname, dtype in [('sample_times_ms', 'uint16_t'),
('velocities', 'uint8_t'),
('notes', 'uint8_t'),
('num_harmonics', 'uint8_t'),
('harmonics_freq', 'uint16_t')]:
write_vector_as_c(f, data[varname], tag + "_" + varname, dtype=dtype)
harmonics_mags = list(itertools.chain(*data['harmonics_mags']))
write_vector_as_c(f, harmonics_mags, tag + "_harmonics_mags")
TAG = tag.upper()
map_contents += """ {
NUM_%s_SAMPLE_TIMES_MS,
%s_sample_times_ms,
NUM_%s_VELOCITIES,
%s_velocities,
NUM_%s_NOTES,
%s_notes,
%s_num_harmonics,
%s_harmonics_freq,
%s_harmonics_mags,
},
""" % (TAG, tag, TAG, tag, TAG, tag, tag, tag, tag)
f.write("const interp_partials_voice_t interp_partials_map[NUM_INTERP_PARTIALS_PRESETS] PROGMEM = {\n")
f.write(map_contents)
f.write("};\n\n")
f.write("#endif // ndef __INTERP_PARTIALS_H\n\n")
print("wrote", filename)
import scipy.io.wavfile as wav
import os
"""
Generate all the headers except for the partials headers
"""
def generate_all():
from . import fm
import collections
import json
# Implement the multiple lookup tables.
# A LUT is stored as an array of values (table) and the harmonic number of the
# highest harmonic they contain (i.e., the number of cycles it completes in the
# entire table, so must be <= len(table)/2.)
LUTentry = collections.namedtuple('LUTentry', ['table', 'highest_harmonic'])
# Impulses.
#impulse_lutset = create_lutset(LUTentry, np.ones(128))
##write_lutset_to_h('src/impulse_lutset.h', 'impulse', impulse_lutset)
#write_lutset_to_h_as_fxpt('src/impulse_lutset_fxpt.h', 'impulse', impulse_lutset)
# Saw_up.
saw_lutset = create_lutset(LUTentry, [0] + list(-1 / np.arange(1, 256)), -np.pi/2 * np.ones(256))
#write_lutset_to_h('src/saw_lutset.h', 'saw', saw_lutset)
write_lutset_to_h_as_fxpt('src/saw_lutset_fxpt.h', 'saw', saw_lutset)
# Triangle wave lutset
n_harms = 64
coefs = (np.arange(n_harms) % 2) * (
np.maximum(1, np.arange(n_harms, dtype=float))**(-2))
triangle_lutset = create_lutset(LUTentry, coefs, np.arange(len(coefs)) * -np.pi / 2)
#write_lutset_to_h('src/triangle_lutset.h', 'triangle', triangle_lutset)
write_lutset_to_h_as_fxpt('src/triangle_lutset_fxpt.h', 'triangle', triangle_lutset)
# Sinusoid "lutset" (only one table)
sine_lutset = create_lutset(LUTentry, np.array([0, 1]), harmonic_phases = -np.pi / 2 * np.ones(2), length_factor=256)
#write_lutset_to_h('src/sine_lutset.h', 'sine', sine_lutset)
write_lutset_to_h_as_fxpt('src/sine_lutset_fxpt.h', 'sine', sine_lutset)
# log2/exp2 LUTs
make_log2_exp2_luts('src/log2_exp2_fxpt_lutable.h')
# Clipping LUT
make_clipping_lut('src/clipping_lookup_table.h')
# PCM LUT
try:
generate_pcm_headers()
except ImportError:
print("If you want to regenerate the PCM headers (not required!) you need to `pip install resampy sf2utils`.")
# Juno & FM patches
make_patches("src/patches.h")
# interp_partials data table
make_interp_partials("src/interp_partials.h",
{'piano': json.load(open("experiments/piano-params.json", "r"))})
# Wavetable samples are appended to tiny PCM headers in generate_pcm_headers().
def main():
print("Generating all headers needed for AMY...")
generate_all()
print("Done.")
if __name__ == '__main__':
main()
================================================
FILE: amy/juno.py
================================================
# juno.py
# Convert juno-106 sysex patches to Amy
import amy
import json
import math
import time
from . import constants
try:
math.exp2(1)
def exp2(x):
return math.exp2(x)
except AttributeError:
def exp2(x):
return math.pow(2.0, x)
# Range is from 10 ms to 12 sec i.e. 1200.
# (12 sec is allegedly the max decay time of the EG, see
# page 32 of Juno-106 owner's manual,
# https://cdn.roland.com/assets/media/pdf/JUNO-106_OM.pdf .)
# Return int value in ms
#time = 0.01 * np.exp(np.log(1e3) * midi / 127.0)
# midi 30 is ~ 200 ms, 50 is ~ 1 sec, so
# D=30
#
# from demo at https://www.synthmania.com/Roland%20Juno-106/Audio/Juno-106%20Factory%20Preset%20Group%20A/14%20Flutes.mp3
# A11 Brass set A=3 D=49 S=45 R=32 ->
# A14 Flute A=23 D=81 S=0 R=18 -> A=200ms, R=200ms, D=0.22 to 0.11 in 0.830 s / 0.28 to 0.14 in 0.92 R = 0.2 to 0.1 in 0.046
# A16 Brass & Strings A=44 D=66 S=53 R=44 -> A=355ms, R=
# A15 Moving Strings A=13 D=87 R=35 -> A=100ms, R=600ms,
# A26 Celeste A=0 D=44 S=0 R=81 -> A=2ms D=0.48 to 0.24 in 0.340 s R = 0.9 to 0.5 in 0.1s; R clearly faster than D
# A27 Elect Piano A=1 D=85 S=43 R=40 -> A=14ms, R=300ms
# A28 Elect. Piano II A=0 D=68 S=0 R=22 -> D=0.30 to 0.15 in 0.590 s R same as D?
# A32 Steel Drums A=0 D=26 S=0 R=37 -> D=0.54 to 0.27 in 0.073 s
# A34 Brass III A=58 D=100 S=94 R=37 -> A=440ms, R=1000ms
# A35 Fanfare A=72 D=104 S=75 R=49 -> A=600ms, R=1200ms
# A37 Pizzicato A=0 D=11 S=0 R=12 -> A=6ms, R=86ms D=0.66 to 0.33 in 0.013 s
# A41 Bass Clarinet A=11 D=75 S=0 R=25 -> A=92ms, R=340ms, D=0.20 to 0.10 in 0.820 s / R = 0.9 to 0.45 in 0.070
# A42 English Horn A=8 D=81 S=21 R=16 -> A=68ms, R=240ms,
# A45 Koto A=0 D=56 S=0 R=39 -> D=0.20 to 0.10 in 0.160 s
# A46 Dark Pluck A=0 D=52 S=15 R=63 ->
# A48 Synth Bass I A=0 D=34 S=0 R=36 -> D=0.60 to 0.30 in 0.096 s
# A56 Funky III A=0 D=24 S=0 R=2 D 1/2 in 0.206
# A61 Piano II A=0 D=98 S=0 R=32 D 1/2 in 1.200
# A 0 1 8 11 13 23 44 58
# ms 6 14 68 92 100 200 355 440
# D 11 24 26 34 44 56 68 75 81 98
# 1/2 time ms 13 206 73 96 340 160 590 830 920 1200
# R 12 16 18 25 35 37 40
# ms 86 240 200 340 600 1000 300
# Notes from video https://www.youtube.com/watch?v=zWOs16ccB3M
# A 0 -> 1ms 1.9 -> 30ms 3.1 -> 57ms 3.7 -> 68ms 5.4 -> 244 ms 6.0 -> 323ms 6.3 -> 462ms 6.5 -> 502ms
# D 3.3 -> 750ms
# Addendum: See online emulation
# https://github.com/pendragon-andyh/junox
# based on set of isolated samples
# https://github.com/pendragon-andyh/Juno60
def to_attack_time(val):
"""Convert a midi value (0..127) to a time for ADSR."""
# From regression of sound examples
return 6 + 8 * val * 127
# from Arturia video
#return 12 * exp2(0.066 * midi) - 12
def to_decay_time(val):
"""Convert a midi value (0..127) to a time for ADSR."""
# time = 12 * np.exp(np.log(120) * midi/100)
# time is time to decay to 1/2; Amy envelope times are to decay to exp(-3) = 0.05
# return np.log(0.05) / np.log(0.5) * time
# from Arturia video
#return 80 * exp2(0.066 * val * 127) - 80
return 80 * exp2(0.085 * val * 127) - 80
def to_release_time(val):
"""Convert a midi value (0..127) to a time for ADSR."""
#time = 100 * np.exp(np.log(16) * midi/100)
#return np.log(0.05) / np.log(0.5) * time
# from Arturia video
#return 70 * exp2(0.066 * val * 127) - 70
return 70 * exp2(0.066 * val * 127) - 70
def to_level(val):
# Map midi to 0..1, linearly.
return val
def level_to_amp(level):
# level is 0.0 to 1.0; amp is 0.001 to 1.0
if level == 0.0:
return 0.0
return float("%.3f" % (0.001 * np.exp(level * np.log(1000.0))))
def to_lfo_freq(val):
# LFO frequency in Hz varies from 0.5 to 30
# from Arturia video
return float("%.3f" % (0.6 * exp2(0.04 * val * 127) - 0.1))
def to_lfo_delay(val):
"""Convert a midi value (0..127) to a time for lfo_delay."""
#time = 100 * np.exp(np.log(16) * midi/100)
#return float("%.3f" % (np.log(0.05) / np.log(0.5) * time))
# from Arturia video
return float("%.3f" % (18 * exp2(0.066 * val * 127) - 13))
def to_resonance(val):
# Q goes from 0.5 to 16 exponentially
return float("%.3f" % (0.7 * exp2(4.0 * val)))
def to_filter_freq(val):
# filter_freq goes from ? 100 to 6400 Hz with 18 steps/octave
#return float("%.3f" % (100 * np.exp2(midi / 20.0)))
# from Arturia video
#return float("%.3f" % (6.5 * exp2(0.11 * val * 127)))
#return float("%.3f" % (25 * exp2(0.055 * val * 127)))
#return float("%.3f" % (25 * exp2(0.083 * val * 127)))
return float("%.3f" % (13 * exp2(0.0938 * val * 127)))
def ffmt(val):
"""Format float values as max 3 dp, but less if possible."""
return "%.5g" % float("%.3f" % val)
_PATCHES = [["A11 Brass Set 1", [20, 49, 0, 102, 0, 35, 13, 58, 0, 86, 108, 3, 49, 45, 32, 0, 81, 17]], ["A12 Brass Swell", [6, 48, 0, 56, 0, 43, 17, 26, 0, 84, 75, 64, 118, 38, 37, 70, 82, 25]], ["A13 Trumpet", [52, 45, 8, 102, 0, 55, 34, 24, 1, 59, 127, 5, 66, 48, 16, 0, 50, 9]], ["A14 Flutes", [60, 43, 1, 0, 0, 55, 32, 10, 11, 41, 127, 23, 81, 0, 18, 0, 50, 1]], ["A15 Moving Strings", [63, 0, 0, 39, 0, 77, 20, 4, 0, 111, 34, 13, 87, 88, 35, 14, 26, 16]], ["A16 Brass & Strings", [35, 0, 0, 56, 0, 76, 17, 4, 0, 41, 78, 44, 66, 53, 44, 23, 73, 24]], ["A17 Choir", [59, 14, 13, 25, 0, 59, 94, 2, 0, 62, 127, 68, 11, 127, 48, 0, 74, 9]], ["A18 Piano I", [20, 49, 0, 80, 0, 65, 12, 10, 0, 27, 103, 0, 66, 0, 30, 86, 42, 17]], ["A21 Organ I", [54, 15, 0, 53, 0, 43, 76, 14, 1, 127, 100, 0, 10, 82, 0, 23, 41, 28]], ["A22 Organ II", [44, 15, 0, 53, 0, 53, 76, 14, 1, 85, 74, 0, 10, 82, 0, 58, 74, 28]], ["A23 Combo Organ", [75, 21, 9, 57, 0, 63, 70, 4, 0, 109, 96, 0, 48, 43, 46, 61, 44, 13]], ["A24 Calliope", [82, 40, 11, 0, 0, 87, 27, 17, 0, 56, 89, 7, 127, 127, 6, 48, 74, 11]], ["A25 Donald Pluck", [76, 21, 9, 57, 0, 73, 105, 15, 0, 78, 82, 2, 5, 43, 10, 127, 44, 7]], ["A26 Celeste* (1 oct.up)", [28, 0, 0, 0, 0, 33, 24, 54, 0, 38, 96, 0, 44, 0, 81, 15, 44, 25]], ["A27 Elect. Piano I", [59, 0, 0, 0, 0, 16, 31, 61, 6, 35, 127, 1, 85, 43, 40, 0, 41, 1]], ["A28 Elect. Piano II", [0, 0, 0, 71, 0, 50, 69, 7, 0, 80, 102, 0, 68, 0, 22, 0, 73, 17]], ["A31 Clock Chimes* (1 oct. up)", [59, 0, 0, 0, 22, 44, 127, 0, 0, 127, 104, 0, 48, 0, 51, 127, 68, 27]], ["A32 Steel Drums", [33, 53, 0, 32, 9, 71, 46, 26, 0, 127, 127, 0, 26, 0, 37, 33, 74, 27]], ["A33 Xylophone", [0, 0, 0, 0, 0, 29, 24, 54, 0, 51, 127, 0, 29, 29, 38, 15, 44, 25]], ["A34 Brass III", [52, 20, 0, 35, 0, 66, 24, 11, 0, 12, 127, 58, 100, 94, 37, 22, 82, 25]], ["A35 Fanfare", [47, 0, 0, 70, 0, 44, 0, 32, 0, 67, 33, 72, 104, 75, 49, 50, 89, 24]], ["A36 String III", [48, 27, 0, 102, 0, 71, 14, 0, 0, 84, 73, 63, 31, 127, 45, 0, 26, 16]], ["A37 Pizzicato", [60, 18, 0, 102, 0, 66, 2, 5, 0, 42, 127, 0, 11, 0, 12, 0, 90, 0]], ["A38 High Strings", [58, 14, 0, 102, 0, 84, 8, 2, 0, 71, 77, 18, 44, 127, 40, 0, 12, 8]], ["A41 Bass clarinet", [52, 45, 8, 0, 0, 48, 36, 25, 8, 58, 104, 11, 75, 0, 25, 0, 41, 17]], ["A42 English Horn", [47, 45, 9, 102, 0, 70, 48, 7, 0, 27, 127, 8, 81, 26, 16, 0, 42, 1]], ["A43 Brass Ensemble", [52, 45, 0, 102, 0, 46, 44, 29, 1, 59, 103, 16, 103, 97, 34, 31, 82, 17]], ["A44 Guitar", [86, 58, 0, 65, 0, 12, 15, 71, 0, 30, 96, 0, 52, 54, 31, 0, 57, 17]], ["A45 Koto", [90, 28, 0, 94, 0, 40, 58, 29, 0, 75, 127, 0, 56, 0, 39, 2, 74, 1]], ["A46 Dark Pluck", [31, 0, 0, 87, 0, 38, 61, 27, 0, 71, 90, 0, 52, 15, 63, 97, 10, 25]], ["A47 Funky I", [4, 0, 0, 73, 0, 31, 23, 51, 0, 41, 71, 0, 30, 36, 2, 64, 89, 29]], ["A48 Synth Bass I (unison)", [58, 16, 1, 57, 50, 32, 0, 66, 0, 35, 75, 0, 34, 0, 36, 102, 41, 25]], ["A51 Lead I", [72, 88, 18, 0, 0, 40, 97, 36, 0, 52, 99, 0, 45, 73, 0, 0, 42, 29]], ["A52 Lead II", [24, 88, 0, 53, 0, 45, 0, 43, 0, 52, 56, 1, 23, 91, 75, 79, 57, 20]], ["A53 Lead III", [86, 71, 21, 102, 0, 60, 31, 18, 1, 76, 127, 0, 66, 48, 11, 0, 50, 21]], ["A54 Funky II", [4, 0, 0, 48, 0, 5, 23, 81, 0, 41, 100, 0, 30, 39, 2, 57, 74, 21]], ["A55 Synth Bass II", [90, 21, 0, 0, 0, 43, 0, 47, 0, 0, 78, 0, 37, 9, 22, 45, 49, 28]], ["A56 Funky III", [4, 0, 0, 9, 101, 38, 54, 45, 0, 10, 79, 0, 24, 0, 2, 127, 57, 29]], ["A57 Thud Wah", [62, 0, 0, 102, 8, 78, 89, 34, 0, 0, 106, 0, 0, 102, 45, 32, 26, 26]], ["A58 Going Up", [0, 0, 0, 100, 28, 79, 127, 37, 0, 65, 75, 0, 108, 18, 127, 0, 34, 19]], ["A61 Piano II", [1, 0, 0, 72, 0, 47, 0, 39, 0, 5, 78, 0, 98, 0, 32, 115, 42, 16]], ["A62 Clav", [66, 15, 1, 102, 0, 7, 11, 86, 2, 0, 120, 0, 39, 48, 14, 0, 73, 21]], ["A63 Frontier Organ", [79, 15, 3, 85, 0, 69, 54, 0, 0, 52, 127, 0, 0, 127, 0, 29, 42, 28]], ["A64 Snare Drum (unison)", [52, 27, 0, 0, 91, 94, 11, 17, 0, 0, 101, 0, 25, 0, 30, 64, 34, 17]], ["A65 Tom Toms (unison)", [62, 16, 8, 0, 127, 53, 4, 40, 0, 21, 101, 0, 30, 15, 40, 58, 33, 24]], ["A66 Timpani (unison)", [0, 0, 0, 35, 127, 25, 0, 54, 0, 24, 127, 1, 56, 26, 71, 47, 33, 17]], ["A67 Shaker", [21, 71, 0, 58, 127, 89, 45, 1, 17, 80, 127, 10, 9, 0, 0, 0, 34, 1]], ["A68 Synth Pad", [56, 0, 5, 43, 0, 37, 0, 84, 0, 127, 51, 0, 85, 75, 62, 37, 10, 24]], ["A71 Sweep I", [78, 0, 0, 102, 28, 115, 40, 67, 0, 0, 97, 0, 63, 127, 82, 42, 12, 18]], ["A72 Pluck Sweep", [68, 48, 0, 68, 0, 60, 111, 9, 6, 98, 45, 0, 91, 0, 77, 125, 26, 8]], ["A73 Repeater", [77, 20, 9, 101, 0, 97, 30, 56, 0, 57, 87, 14, 0, 41, 0, 44, 74, 23]], ["A74 Sweep II", [88, 72, 15, 97, 0, 66, 102, 68, 0, 70, 101, 0, 89, 53, 78, 48, 74, 25]], ["A75 Pluck Bell", [51, 0, 5, 17, 0, 39, 0, 49, 0, 127, 49, 0, 85, 75, 53, 49, 12, 24]], ["A76 Dark Synth Piano", [127, 0, 0, 0, 0, 56, 86, 6, 0, 71, 79, 0, 47, 0, 50, 127, 26, 26]], ["A77 Sustainer", [71, 0, 5, 46, 0, 39, 0, 84, 0, 127, 57, 0, 85, 75, 70, 49, 42, 24]], ["A78 Wah Release", [89, 14, 1, 25, 0, 72, 88, 19, 0, 66, 104, 0, 84, 0, 29, 87, 10, 19]], ["A81 Gong (play low chords)", [127, 0, 0, 102, 56, 70, 107, 5, 0, 72, 91, 3, 48, 127, 98, 0, 73, 19]], ["A82 Resonance Funk", [59, 0, 0, 0, 0, 26, 127, 45, 0, 89, 127, 0, 19, 0, 22, 0, 33, 17]], ["A83 Drum Booms* (1 oct. down)", [0, 0, 0, 102, 127, 42, 0, 34, 0, 58, 127, 0, 36, 15, 49, 46, 33, 25]], ["A84 Dust Storm", [0, 0, 0, 0, 127, 52, 85, 0, 44, 94, 127, 88, 91, 28, 85, 0, 33, 17]], ["A85 Rocket Men", [8, 32, 0, 102, 97, 73, 114, 8, 0, 56, 127, 0, 89, 127, 104, 0, 36, 3]], ["A86 Hand Claps", [59, 0, 0, 0, 127, 17, 88, 54, 0, 55, 127, 1, 11, 0, 8, 0, 33, 5]], ["A87 FX Sweep", [127, 65, 116, 102, 127, 71, 44, 83, 0, 94, 127, 0, 94, 0, 112, 127, 41, 18]], ["A88 Caverns", [0, 0, 0, 102, 127, 68, 118, 0, 0, 69, 107, 0, 13, 38, 47, 0, 33, 8]], ["B11 Strings", [57, 45, 0, 55, 0, 85, 0, 0, 0, 108, 52, 59, 32, 86, 40, 0, 26, 24]], ["B12 Violin", [66, 45, 20, 0, 0, 77, 0, 0, 0, 120, 110, 43, 45, 57, 26, 0, 50, 24]], ["B13 Chorus Vibes", [72, 45, 0, 0, 0, 10, 0, 59, 0, 23, 88, 0, 89, 47, 74, 0, 74, 25]], ["B14 Organ 1", [45, 42, 0, 73, 0, 60, 72, 14, 0, 127, 58, 0, 0, 0, 0, 97, 10, 29]], ["B15 Harpsichord 1", [23, 0, 0, 54, 0, 127, 127, 90, 0, 86, 125, 0, 60, 0, 31, 35, 44, 0]], ["B16 Recorder", [78, 0, 0, 8, 0, 6, 0, 46, 0, 127, 127, 5, 21, 127, 30, 0, 42, 17]], ["B17 Perc. Pluck", [62, 38, 8, 0, 0, 0, 0, 90, 0, 73, 65, 0, 16, 78, 116, 0, 74, 25]], ["B18 Noise Sweep", [127, 0, 0, 0, 127, 2, 0, 77, 0, 104, 92, 14, 78, 108, 120, 0, 33, 24]], ["B21 Space Chimes", [99, 0, 0, 0, 0, 70, 127, 0, 0, 74, 85, 0, 25, 0, 60, 0, 76, 24]], ["B22 Nylon Guitar", [72, 45, 0, 29, 0, 57, 0, 26, 0, 25, 115, 0, 89, 0, 32, 0, 42, 1]], ["B23 Orchestral Pad", [22, 45, 0, 105, 0, 33, 0, 55, 0, 36, 0, 29, 88, 50, 52, 127, 26, 24]], ["B24 Bright Pluck", [0, 0, 0, 58, 0, 57, 0, 40, 0, 86, 104, 0, 25, 42, 44, 0, 42, 17]], ["B25 Organ Bell", [78, 0, 6, 68, 0, 61, 0, 0, 0, 127, 62, 0, 0, 127, 26, 85, 90, 25]], ["B26 Accordion", [0, 0, 0, 64, 0, 77, 0, 14, 0, 74, 66, 8, 11, 110, 9, 80, 90, 1]], ["B27 FX Rise 1", [116, 0, 0, 0, 0, 108, 127, 16, 127, 64, 0, 0, 0, 127, 84, 0, 68, 26]], ["B28 FX Rise 2", [108, 0, 0, 0, 0, 94, 127, 80, 23, 127, 0, 0, 127, 51, 71, 0, 2, 26]], ["B31 Brass", [51, 127, 0, 73, 0, 0, 0, 94, 0, 127, 72, 3, 44, 51, 11, 0, 82, 28]], ["B32 Helicopter", [106, 0, 0, 48, 0, 82, 5, 93, 127, 0, 72, 0, 0, 35, 76, 127, 10, 27]], ["B33 Lute", [52, 0, 2, 105, 0, 29, 0, 35, 0, 86, 127, 0, 48, 34, 87, 0, 42, 25]], ["B34 Chorus Funk", [77, 94, 0, 73, 0, 47, 34, 53, 0, 65, 42, 0, 11, 34, 0, 79, 90, 29]], ["B35 Tomita", [78, 0, 0, 105, 0, 49, 125, 15, 2, 127, 57, 0, 14, 79, 0, 0, 36, 31]], ["B36 FX Sweep 1", [127, 0, 0, 0, 0, 58, 127, 16, 76, 64, 0, 0, 0, 127, 85, 0, 68, 24]], ["B37 Sharp Reed", [21, 0, 0, 73, 0, 33, 0, 53, 0, 65, 55, 2, 18, 112, 0, 0, 60, 28]], ["B38 Bass Pluck", [0, 0, 0, 60, 0, 37, 29, 28, 0, 43, 92, 0, 42, 35, 0, 0, 57, 24]], ["B41 Resonant Rise", [52, 0, 15, 0, 0, 66, 107, 31, 0, 73, 62, 0, 52, 39, 0, 0, 17, 30]], ["B42 Harpsichord 2", [0, 0, 0, 105, 0, 127, 95, 0, 0, 127, 107, 0, 45, 0, 0, 35, 60, 17]], ["B43 Dark Ensemble", [0, 0, 0, 57, 0, 55, 0, 0, 0, 107, 67, 21, 0, 127, 35, 75, 90, 27]], ["B44 Contact Wah", [78, 0, 0, 81, 0, 61, 101, 46, 0, 127, 127, 0, 0, 0, 0, 0, 42, 23]], ["B45 Noise Sweep 2", [127, 0, 0, 0, 127, 127, 0, 83, 0, 104, 116, 127, 79, 26, 83, 0, 68, 26]], ["B46 Glassy Wah", [0, 94, 0, 28, 0, 24, 34, 61, 0, 65, 112, 6, 18, 50, 38, 0, 42, 25]], ["B47 Phase Ensemble", [11, 45, 5, 105, 0, 79, 0, 0, 0, 127, 99, 84, 45, 57, 49, 0, 10, 24]], ["B48 Chorused Bell", [0, 11, 0, 105, 0, 59, 127, 0, 0, 127, 62, 0, 62, 0, 57, 101, 76, 24]], ["B51 Clav", [50, 11, 0, 91, 0, 32, 0, 63, 0, 0, 108, 0, 43, 55, 0, 7, 41, 9]], ["B52 Organ 2", [81, 0, 0, 104, 0, 54, 106, 7, 0, 127, 79, 0, 0, 0, 0, 0, 81, 29]], ["B53 Bassoon", [84, 38, 9, 90, 0, 35, 0, 43, 9, 98, 127, 5, 127, 106, 2, 0, 41, 1]], ["B54 Auto Release Noise Sweep", [127, 0, 0, 0, 127, 127, 0, 127, 0, 104, 107, 0, 79, 57, 83, 0, 68, 26]], ["B55 Brass Ensemble", [25, 94, 0, 73, 0, 47, 34, 35, 0, 65, 39, 6, 68, 67, 38, 0, 90, 24]], ["B56 Ethereal", [69, 0, 0, 105, 0, 47, 120, 0, 0, 127, 60, 92, 50, 127, 55, 59, 26, 24]], ["B57 Chorus Bell 2", [72, 45, 0, 29, 0, 0, 102, 62, 0, 90, 30, 0, 117, 0, 120, 0, 90, 25]], ["B58 Blizzard", [1, 0, 0, 105, 127, 56, 89, 7, 38, 121, 127, 78, 98, 87, 78, 0, 36, 0]], ["B61 E. Piano with Tremolo", [44, 0, 0, 21, 0, 22, 0, 35, 7, 107, 103, 0, 65, 60, 98, 127, 44, 16]], ["B62 Clarinet", [69, 22, 9, 0, 0, 35, 0, 43, 7, 98, 104, 5, 127, 106, 7, 0, 42, 1]], ["B63 Thunder", [127, 0, 0, 0, 127, 2, 0, 77, 0, 104, 107, 0, 22, 108, 120, 0, 33, 24]], ["B64 Reedy Organ", [35, 18, 0, 73, 0, 33, 0, 53, 0, 65, 69, 3, 44, 109, 0, 0, 42, 28]], ["B65 Flute / Horn", [34, 0, 0, 59, 0, 25, 0, 42, 0, 65, 22, 21, 73, 71, 48, 0, 25, 24]], ["B66 Toy Rhodes", [30, 45, 127, 0, 0, 58, 127, 0, 0, 127, 107, 0, 89, 0, 39, 0, 36, 0]], ["B67 Surf's Up", [1, 0, 0, 105, 127, 84, 11, 0, 49, 54, 75, 33, 97, 127, 121, 0, 36, 10]], ["B68 OW Bass", [50, 0, 0, 50, 0, 63, 84, 65, 0, 127, 70, 127, 0, 107, 0, 47, 57, 31]], ["B71 Piccolo", [70, 28, 0, 14, 0, 4, 0, 63, 16, 98, 87, 16, 103, 106, 21, 0, 60, 9]], ["B72 Melodic Taps", [99, 0, 0, 0, 127, 72, 112, 0, 0, 127, 127, 0, 24, 0, 24, 0, 65, 0]], ["B73 Meow Brass", [51, 127, 0, 73, 0, 45, 100, 35, 0, 65, 84, 4, 90, 0, 27, 0, 50, 28]], ["B74 Violin (high)", [71, 45, 22, 0, 0, 89, 0, 0, 3, 120, 85, 43, 45, 57, 26, 0, 52, 24]], ["B75 High Bells", [30, 45, 127, 0, 0, 76, 127, 0, 0, 127, 111, 0, 22, 52, 59, 0, 36, 0]], ["B76 Rolling Wah", [36, 0, 0, 105, 0, 60, 9, 0, 127, 0, 77, 34, 55, 127, 105, 0, 42, 24]], ["B77 Ping Bell", [0, 11, 0, 104, 0, 76, 127, 0, 0, 127, 83, 0, 23, 23, 57, 0, 76, 24]], ["B78 Brassy Organ", [16, 0, 0, 68, 0, 8, 0, 87, 0, 52, 14, 0, 36, 109, 0, 56, 89, 24]], ["B81 Low Dark Strings", [21, 45, 5, 81, 0, 71, 0, 0, 0, 103, 40, 83, 23, 109, 42, 0, 25, 24]], ["B82 Piccolo Trumpet", [51, 127, 0, 73, 0, 0, 0, 94, 0, 127, 97, 3, 44, 51, 11, 0, 50, 28]], ["B83 Cello", [57, 45, 21, 0, 0, 75, 0, 3, 1, 45, 109, 48, 65, 90, 34, 0, 49, 24]], ["B84 High Strings", [80, 0, 10, 70, 0, 92, 0, 0, 0, 71, 48, 27, 57, 57, 41, 0, 28, 24]], ["B85 Rocket Men", [108, 0, 0, 0, 0, 110, 127, 80, 63, 127, 0, 0, 127, 51, 89, 0, 2, 26]], ["B86 Forbidden Planet", [50, 11, 0, 44, 0, 29, 4, 88, 5, 95, 79, 0, 48, 23, 42, 9, 76, 1]], ["B87 Froggy", [78, 0, 0, 0, 0, 55, 127, 43, 0, 127, 77, 0, 0, 0, 0, 127, 41, 23]], ["B88 Owgan", [50, 0, 0, 45, 0, 38, 84, 32, 0, 127, 101, 0, 49, 55, 0, 56, 57, 25]]]
def get_juno_patch(patch_number):
# json was created by:
# import javaobj, json
# pobj = javaobj.load(open('juno106_factory_patches.ser', 'rb'))
# patches = [(p.name, list(p.sysex)) for p in pobj.v.elementData if p is not None]
# with open('juno106patches.json', 'w') as f:
# f.write(json.dumps(patches))
#pobj = javaobj.load(open('juno106_factory_patches.ser', 'rb'))
#patch = pobj.v.elementData[patch_number]
global _PATCHES
name, sysex = _PATCHES[patch_number]
return name, bytes(sysex)
class JunoPatch:
"""Encapsulates information in a Juno Patch."""
name = ""
lfo_rate = 0
lfo_delay_time = 0
dco_lfo = 0
dco_pwm = 0
dco_noise = 0
vcf_freq = 0
vcf_res = 0
vcf_env = 0
vcf_lfo = 0
vcf_kbd = 0
vca_level = 0
env_a = 0
env_d = 0
env_s = 0
env_r = 0
dco_sub = 0
stop_16 = False
stop_8 = False
stop_4 = False
pulse = False
saw = False
chorus = 0
pwm_manual = False # else lfo
vca_gate = False # else env
vcf_neg = False # else pos
hpf = 0
portamento = 0
# Map of setup_fn: [params triggering setup]
post_set_fn = {'lfo': ['lfo_rate', 'lfo_delay_time'],
'dco': ['dco_lfo', 'dco_pwm', 'dco_noise', 'dco_sub',
'stop_16', 'stop_8', 'stop_4',
'pulse', 'saw', 'pwm_manual', 'portamento'],
'vcf': ['vcf_neg', 'vcf_env', 'vcf_freq', 'vcf_lfo', 'vcf_res', 'vcf_kbd', 'vca_gate'],
'env': ['env_a', 'env_d', 'env_s', 'env_r', 'vca_level', 'vca_gate'],
'cho': ['chorus', 'hpf']}
# These lists name the fields in the order they appear in the sysex.
FIELDS = ['lfo_rate', 'lfo_delay_time', 'dco_lfo', 'dco_pwm', 'dco_noise',
'vcf_freq', 'vcf_res', 'vcf_env', 'vcf_lfo', 'vcf_kbd', 'vca_level',
'env_a', 'env_d', 'env_s', 'env_r', 'dco_sub']
# After the 16 integer values, there are two bytes of bits.
BITS1 = ['stop_16', 'stop_8', 'stop_4', 'pulse', 'saw']
BITS2 = ['pwm_manual', 'vcf_neg', 'vca_gate']
# Non-sysex state: Do we use the cheaper 12 dB/oct VCF?
cheap_filter = False
# Patch number we're based on, if any.
patch_number = None
# Name, if any
name = None
# Params that have been changed since last send_to_AMY.
dirty_params = set()
# Flag to defer param updates.
defer_param_updates = False
# Amy synth
amy_synth = None
@staticmethod
def from_patch_number(patch_number):
name, sysexbytes = get_juno_patch(patch_number)
return JunoPatch.from_sysex(sysexbytes, name, patch_number)
@classmethod
def from_sysex(cls, sysexbytes, name=None, patch_number=None):
"""Decode sysex bytestream into JunoPatch fields."""
assert len(sysexbytes) == 18
result = JunoPatch()
result.name = name
result.patch_number = patch_number
result._init_from_sysex(sysexbytes)
return result
def _init_from_patch_number(self, patch_number):
self.patch_number = patch_number
self.name, sysexbytes = get_juno_patch(patch_number)
self._init_from_sysex(sysexbytes)
def _init_from_sysex(self, sysexbytes):
# The first 16 bytes are sliders.
for index, field in enumerate(self.FIELDS):
setattr(self, field, int(sysexbytes[index])/127.0)
# Then there are two bytes of switches.
for index, field in enumerate(self.BITS1):
setattr(self, field, (int(sysexbytes[16]) & (1 << index)) > 0)
# Chorus has a weird mapping. Bit 5 is ~Chorus, bit 6 is ChorusI-notII
setattr(self, 'chorus', [2, 0, 1, 0][int(sysexbytes[16]) >> 5])
for index, field in enumerate(self.BITS2):
setattr(self, field, (int(sysexbytes[17]) & (1 << index)) > 0)
# Bits 3 & 4 also have flipped endianness & sense.
setattr(self, 'hpf', [3, 2, 1, 0][int(sysexbytes[17]) >> 3])
# Nonstandard extension: Put "cheap" flag in bit 5 of byte 2.
self.cheap_filter = int(sysexbytes[17] & (1 << 5)) > 0
def to_sysex(self):
"""Return the 18 byte SYSEX corresponding to current object state."""
byte_values = []
# 16 continuous values in order specified by self.FIELDS.
for field in self.FIELDS:
byte_values.append(int(round(127.0 * getattr(self, field))))
# 2 bytes of booleans.
val = 0
for index, field in enumerate(self.BITS1):
val |= (1 << index) if getattr(self, field) else 0
# Chorus has a weird mapping. Bit 5 is ~Chorus, bit 6 is ChorusI-notII
val |= ([1, 2, 0][getattr(self, 'chorus')]) << 5
byte_values.append(val)
val = 0
for index, field in enumerate(self.BITS2):
val |= (1 << index) if getattr(self, field) else 0
# Bits 3 & 4 also have flipped endianness & sense.
val |= ([3, 2, 1, 0][getattr(self, 'hpf')]) << 3
# Nonstandard extension: Put "cheap" flag in bit 5 of byte 2.
if self.cheap_filter:
val |= (1 << 5)
byte_values.append(val)
return bytes(byte_values)
def set_synth(self, amy_synth):
self.amy_synth = amy_synth
def _breakpoint_string(self):
"""Format a breakpoint string from the ADSR parameters reaching a peak."""
return "%d,%s,%d,%s,%d,0" % (
to_attack_time(self.env_a), ffmt(1.0), to_decay_time(self.env_d),
ffmt(to_level(self.env_s)), to_release_time(self.env_r)
)
def _amp_coef_string(self, level):
return '%s,,1,1,0' % ffmt(to_level(level))
def _freq_coef_string(self, base_freq):
return '%s,1,,,,%s,1' % (
ffmt(base_freq), ffmt(0.03 * to_level(self.dco_lfo)))
def base_freq(self):
# Only one of stop_{16,8,4} should be set.
base_freq = constants.ZERO_LOGFREQ_IN_HZ # 261.63 # The mid note
if self.stop_16:
base_freq /= 2
elif self.stop_4:
base_freq *= 2
return base_freq
def _portamento_ms(self, port_val):
# Portamento maps exponentially from 1 = 10 ms to 127 = 2560 ms
if port_val == 0:
return 0
return int(round(20 * math.pow(2, port_val * 127 / 30)))
def init_AMY(self):
"""Output AMY commands to set up patches on all the allocated synth.
Send amy.send(osc=0, note=50, vel=1) afterwards."""
#amy.reset()
# base_osc is filter/VCA (AMYboard standard)
# base_osc + 1 is LFO (AMYboard standard)
# base_osc + 2 is pulse/PWM
# base_osc + 3 is SAW
# base_osc + 4 is SUBOCTAVE
# base_osc + 5 is NOISE
# env0 is VCA (on base_osc only)
# env1 is VCF (on base_osc only)
# These are the canonical oscs (to add to amy.send(synth=..)).
self.ctl_osc = 0
self.pwm_osc = 2
self.saw_osc = 3
self.sub_osc = 4
self.nse_osc = 5
self.lfo_osc = 1
# One-time setup of oscs.
self.amy_send(osc=self.lfo_osc, wave=amy.TRIANGLE, amp='1,,0,1')
filter_type = amy.FILTER_LPF if self.cheap_filter else amy.FILTER_LPF24
self.amy_send(osc=self.ctl_osc, wave=amy.SILENT, filter_type=filter_type,
mod_source=self.lfo_osc, chained_osc=self.pwm_osc)
self.amy_send(osc=self.pwm_osc, wave=amy.PULSE,
mod_source=self.lfo_osc, chained_osc=self.saw_osc)
self.amy_send(osc=self.saw_osc, wave=amy.SAW_UP,
mod_source=self.lfo_osc, chained_osc=self.sub_osc)
self.amy_send(osc=self.sub_osc, wave=amy.PULSE,
mod_source=self.lfo_osc, chained_osc=self.nse_osc)
self.amy_send(osc=self.nse_osc, wave=amy.NOISE,
mod_source=self.lfo_osc)
# Setup all the variable params.
self.update_lfo()
self.update_dco()
self.update_vcf()
self.update_env()
self.update_cho()
def update_lfo(self):
lfo_args = {'freq': to_lfo_freq(self.lfo_rate),
'bp0': '%i,1.0,10000,0' % to_lfo_delay(self.lfo_delay_time)}
self.amy_send(osc=self.lfo_osc, **lfo_args)
def update_dco(self):
base_freq = self.base_freq()
freq_str = self._freq_coef_string(base_freq)
# PWM square wave.
const_duty = 0
lfo_duty = to_level(self.dco_pwm)
port_ms = self._portamento_ms(self.portamento)
if self.pwm_manual:
# Swap duty parameters.
const_duty, lfo_duty = lfo_duty, const_duty
self.amy_send(
osc=self.pwm_osc,
amp='%s,,0,0' % ffmt(to_level(self.pulse)),
freq=freq_str,
portamento=port_ms,
duty='%s,,,,,%s' % (
ffmt(0.5 + 0.5 * const_duty), ffmt(0.5 * lfo_duty)
),
)
self.amy_send(
osc=self.saw_osc,
amp='%s,,0,0' % ffmt(to_level(self.saw)),
freq=freq_str,
portamento=port_ms,
)
self.amy_send(
osc=self.sub_osc,
amp='%s,,0,0' % ffmt(to_level(self.dco_sub)),
freq=self._freq_coef_string(base_freq / 2.0),
portamento=port_ms,
)
self.amy_send(
osc=self.nse_osc,
amp='%s,,0,0' % ffmt(to_level(self.dco_noise)),
)
def update_vcf(self):
vcf_env_polarity = -1.0 if self.vcf_neg else 1.0
vcf_kbd_level = to_level(self.vcf_kbd)
vcf_freq_hz = to_filter_freq(self.vcf_freq)
# The Juno VCF kbd value is 0 for C4 (MIDI 60), but our scale has 0 at A4 (MIDI 69)
# So when the filter freq depends on kbd contribution, it will be wrong.
# We want log2(uncooked vcf_freq_hz) + vcf_kbd_level * (midi_note - 60) / 12
# to equal log2(cooked vcf_freq_hz) + vcf_kbd_level * (midi_note - 69) / 12
# So, cooked / uncooked) = exp2(vcf_kbd_level * 9 / 12)
vcf_freq_hz *= (2.0 ** (0.75 * vcf_kbd_level))
eg0_coef = 11 * vcf_env_polarity * to_level(self.vcf_env)
eg1_coef = 0
if self.vca_gate:
eg1_coef = eg0_coef
eg0_coef = 0
self.amy_send(osc=self.ctl_osc, resonance=to_resonance(self.vcf_res),
filter_freq='%s,%s,,%s,%s,%s' % (
ffmt(vcf_freq_hz),
ffmt(vcf_kbd_level),
ffmt(eg0_coef), ffmt(eg1_coef),
ffmt(1.25 * to_level(self.vcf_lfo))))
def update_env(self):
coefs = {'osc': self.ctl_osc, 'amp': self._amp_coef_string(self.vca_level)}
bp_coefs = self._breakpoint_string()
if self.vca_gate:
coefs |= {'bp0': '0,1,0,1,0,0', 'bp1': bp_coefs}
else:
coefs |= {'bp0': bp_coefs}
self.amy_send(**coefs)
def update_cho(self):
# Chorus & HPF
eq_l = eq_m = eq_h = 0
if self.hpf == 0:
eq_l = 7
eq_m = -3
eq_h = -3
elif self.hpf == 1:
pass
elif self.hpf == 2:
eq_l = -8
elif self.hpf == 3:
eq_l = -15
eq_m = 8
eq_h = 8
cho_args = {
'eq': '%s,%s,%s' % (str(eq_l), str(eq_m), str(eq_h)),
}
if self.chorus == 0:
cho_args['chorus'] = '0'
else:
# We choose juno 60-style I+II for chorus=3. Juno 6-style would be freq=8 depth=0.25
cho_args['chorus'] = '1,,%s,%s' % (
(0, 0.5, 0.83, 1)[self.chorus], # chorus_freq
(0, 0.5, 0.5, 0.08)[self.chorus], # chorus_depth
)
# *Don't* send to oscs, these ones are global.
amy.send(**cho_args)
# Setters for each Juno UI control
def set_param(self, param, val):
setattr(self, param, val)
if self.defer_param_updates:
self.dirty_params.add(param)
else:
for group, params in self.post_set_fn.items():
if param in params:
getattr(self, 'update_' + group)()
def send_deferred_params(self):
for group, params in self.post_set_fn.items():
if self.dirty_params.intersection(params):
getattr(self, 'update_' + group)()
self.dirty_params = set()
self.defer_param_updates = False
def set_patch(self, patch):
self._init_from_patch_number(patch)
#print("New patch", patch, ":", self.name)
self.init_AMY()
def set_sysex(self, sysex):
self._init_from_sysex(sysex)
#print("New patch", patch, ":", self.name)
self.init_AMY()
def set_pitch_bend(self, value):
# Global, not osc-specific.
amy.send(pitch_bend=value)
def amy_send(self, osc, **kwargs):
if self.amy_synth:
amy.send(synth=self.amy_synth, osc=osc, **kwargs)
else:
amy.send(osc=osc, **kwargs)
================================================
FILE: amy/piano.py
================================================
# piano.py
# examples from piano.html
import amy
from . import piano_params
def piano_example(base_note=72, volume=5, send_command=amy.send, init_command=lambda: None):
amy.send(reset=amy.RESET_TIMEBASE)
amy.send(time=0, volume=volume)
init_command()
send_command(time=50, voices='0', note=base_note, vel=0.05)
send_command(time=435, voices='0', note=base_note, vel=0)
send_command(time=450, voices='0', note=base_note, vel=0.63)
send_command(time=835, voices='0', note=base_note, vel=0)
send_command(time=850, voices='0', note=base_note, vel=1.0)
send_command(time=1485, voices='0', note=base_note, vel=0)
send_command(time=1500, voices='1', note=base_note - 24, vel=0.6)
send_command(time=2100, voices='2', note=base_note + 24, vel=1.0)
send_command(time=3000, voices='1', note=base_note - 24, vel=0)
send_command(time=3000, voices='2', note=base_note + 24, vel=0)
def juno_example():
piano_example(base_note=74, volume=10,
init_command=lambda: amy.send(time=0, voices='0,1,2', patch=7))
def dx7_example():
piano_example(base_note=50, volume=25,
init_command=lambda: amy.send(time=0, voices='0,1,2', patch=137))
"""Piano notes generated on amy/tulip."""
# Uses the partials amplitude breakpoints and residual written by piano_heterodyne.ipynb.
try:
from ulab import numpy as np
except ImportError:
import numpy as np
# Read in the params file written by piano_heterodyne.ipynb
# Contents:
# sample_times_ms - single vector of fixed log-spaced envelope sample times (in int16 integer ms).
# notes - the MIDI numbers corresponding to each note described.
# velocities - The (MIDI) strike velocities available for each note, the same for all notes.
# num_harmonics - Array of (num_notes * num_velocities) counts of how many harmonics are defined for each note+vel combination.
# harmonics_freq - Vector of (total_num_harmonics) int16s giving freq for each harmonic in "MIDI cents" i.e. 6900 = 440 Hz.
# harmonics_mags - Array of (total_num_harmonics, num_sample_times) uint8s giving envelope samples for each harmonic. In dB, between 0 and 100.
from amy.piano_params import notes_params
NOTES = np.array(notes_params['notes'], dtype=np.int8)
VELOCITIES = np.array(notes_params['velocities'], dtype=np.int8)
NUM_HARMONICS = np.array(notes_params['num_harmonics'], dtype=np.int16)
assert len(NUM_HARMONICS) == len(NOTES) * len(VELOCITIES)
NUM_MAGS = len(notes_params['harmonics_mags'][0])
# Add in a derived diff-times and start-harmonic fields
# Reintroduce the initial zero-time...
SAMPLE_TIMES = np.array([0] + notes_params['sample_times_ms'])
#.. so we can neatly calculate the time-deltas needed for BP strings.
DIFF_TIMES = SAMPLE_TIMES[1:] - SAMPLE_TIMES[:-1]
# Lookup to find first harmonic for nth note.
START_HARMONIC = np.zeros(len(NUM_HARMONICS), dtype=np.int16)
for i in range(len(NUM_HARMONICS)): # No cumsum in ulab.numpy
START_HARMONIC[i] = np.sum(NUM_HARMONICS[:i])
# We build a single array for all the harmonics with the frequency as the
# first column, followed by the envelope magnitudes. Then, we can pull
# out the entire description for a given note/velocity pair simply by
# pulling out NUM_HARMONICS[harmonic_index] rows starting at
# START_HARMONIC[harmonic_index]
FREQ_MAGS = np.zeros((np.sum(NUM_HARMONICS), 1 + NUM_MAGS), dtype=np.int16)
FREQ_MAGS[:, 0] = np.array(notes_params['harmonics_freq'], dtype=np.int16)
FREQ_MAGS[:, 1:] = np.array(notes_params['harmonics_mags'], dtype=np.int16)
def harms_params_from_note_index_vel_index(note_index, vel_index):
"""Retrieve a (log-domain) harms_params list for a given note/vel index pair."""
# A harmonic is represented as a [freq_cents, mag1_db, mag2_db, .. mag20_db] row.
# A note is represented as NUM_HARMONICS (usually 20) rows.
note_vel_index = note_index * len(VELOCITIES) + vel_index
num_harmonics = NUM_HARMONICS[note_vel_index]
start_harmonic = START_HARMONIC[note_vel_index]
harms_params = FREQ_MAGS[start_harmonic : start_harmonic + num_harmonics, :]
return harms_params
def interp_harms_params(hp0, hp1, alpha):
"""Return harm_param list that is alpha of the way to hp1 from hp0."""
# hp_ is [[freq_h1, mag1, mag2, ...], [freq_h2, mag1, mag2, ..], ...]
num_harmonics = min(hp0.shape[0], hp1.shape[0])
# Assume the units are log-scale, so linear interpolation is good.
return hp0[:num_harmonics] + alpha * (hp1[:num_harmonics] - hp0[:num_harmonics])
def cents_to_hz(cents):
"""Convert 'Midi cents' frequency to Hz. 6900 cents -> 440 Hz"""
return 440 * (2 ** ((cents - 6900) / 1200.0))
def db_to_lin(d):
"""Convert the db-scale magnitudes to linear. 0 dB -> 0.00001, so 100 dB -> 1.0."""
# Clip anything below 0.001 to zero.
return np.maximum(0, 10.0 ** ((d - 100) / 20.0) - 0.001)
def harms_params_for_note_vel(note, vel):
"""Convert midi note and velocity into an interpolated harms_params list of harmonic specifications."""
note = np.clip(note, NOTES[0], NOTES[-1])
vel = np.clip(vel, VELOCITIES[0], VELOCITIES[-1])
note_index = -1 + np.sum(NOTES[:-1] <= note) # at most the last-but-one value.
strike_index = -1 + np.sum(VELOCITIES[:-1] <= vel)
lower_note = NOTES[note_index]
upper_note = NOTES[note_index + 1]
note_alpha = (note - lower_note) / (upper_note - lower_note)
lower_strike = VELOCITIES[strike_index]
upper_strike = VELOCITIES[strike_index + 1]
strike_alpha = (vel - lower_strike) / (upper_strike - lower_strike)
# We interpolate to describe a note at both strike indices,
# then interpolate those to get the strike.
harms_params = interp_harms_params(
interp_harms_params(
harms_params_from_note_index_vel_index(note_index, strike_index),
harms_params_from_note_index_vel_index(note_index + 1, strike_index),
note_alpha,
),
interp_harms_params(
harms_params_from_note_index_vel_index(note_index, strike_index + 1),
harms_params_from_note_index_vel_index(note_index + 1, strike_index + 1),
note_alpha,
),
strike_alpha,
)
return harms_params
def init_piano_voice(num_partials, base_osc=0, **kwargs):
"""One-time initialization of the unchanging parts of the partials voices."""
amy.send(osc=base_osc, wave=amy.BYO_PARTIALS, num_partials=num_partials, amp={'eg0': 0}, **kwargs)
for partial in range(1, num_partials + 1):
bp_string = '0,0,' + ','.join("%d,0" % t for t in DIFF_TIMES)
# We append a release segment to die away to silence over 200ms on note-off.
bp_string += ',200,0'
amy.send(osc=base_osc + partial, wave=amy.PARTIAL, bp0=bp_string, eg0_type=amy.ENVELOPE_TRUE_EXPONENTIAL, **kwargs)
def setup_piano_voice(harms_params, base_osc=0, **kwargs):
"""Configure a set of PARTIALs oscs to play a particular note and velocity."""
num_partials = len(harms_params)
amy.send(osc=base_osc, wave=amy.BYO_PARTIALS, num_partials=num_partials, **kwargs)
for i in range(num_partials):
f0_hz = cents_to_hz(harms_params[i, 0])
env_vals = db_to_lin(harms_params[i, 1:])
# Omit the time-deltas from the list to save space. The osc will keep the ones we set up in init_piano_voice.
bp_string = ',,' + ','.join(",%.3f" % val for val in env_vals)
# Add final release.
bp_string += ',200,0'
amy.send(osc=base_osc + 1 + i, freq=f0_hz, bp0=bp_string, **kwargs)
patch_string = 'v0w10Zv%dw%dZ' % (NUM_HARMONICS[0] + 1, amy.PARTIAL)
# The lowest note provides an upper-bound on the number of partials we need to allocate.
def init_piano_voices(num_partials=NUM_HARMONICS[0]):
amy.send(patch='1024', patch_string=patch_string)
amy.send(voices='0,1,2', patch=1024)
init_piano_voice(num_partials, voices='0,1,2')
# piano_note_on (below) overwrites these settings before each note,
# but pre-configure each note to C4.mf so we can experiment.
setup_piano_voice(harms_params_for_note_vel(note=60, vel=80), voices='0,1,2')
def play_piano_partials_1():
piano_example(base_note=62, volume=5, init_command=init_piano_voices)
def piano_note_on(note=60, vel=1, **kwargs):
if vel == 0:
# Note off.
amy.send(vel=0, **kwargs)
else:
setup_piano_voice(harms_params_for_note_vel(note, round(vel * 127)), **kwargs)
# We already configured the pitches and magnitudes in setup, so
# the note and vel of the note-on are always the same.
amy.send(note=60, vel=1, **kwargs)
def play_piano_partials_2():
piano_example(base_note=62,
init_command=init_piano_voices,
send_command=piano_note_on)
================================================
FILE: amy/piano_params.py
================================================
# Notes params generated by piano_heterodyne.ipynb
notes_params = {"sample_times_ms": [4, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096], "notes": [24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104], "velocities": [40, 80, 120], "num_harmonics": [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 17, 17, 17, 13, 13, 13, 11, 11, 11, 9, 8, 9, 7, 7, 7, 6, 5, 5, 3, 4, 4], "harmonics_freq": [2363, 3491, 4191, 4691, 5081, 5398, 5667, 5899, 6109, 6297, 6466, 6621, 6765, 6899, 7024, 7142, 7255, 7361, 7462, 7559, 2172, 3587, 4287, 4787, 5175, 5493, 5762, 5996, 6205, 6393, 6561, 6716, 6860, 6993, 7118, 7238, 7349, 7456, 7556, 7653, 2394, 3588, 4289, 4787, 5176, 5495, 5764, 5998, 6207, 6395, 6564, 6717, 6862, 6995, 7120, 7241, 7351, 7458, 7557, 7654, 2851, 3989, 4692, 5187, 5576, 5893, 6161, 6394, 6600, 6785, 6952, 7105, 7246, 7379, 7501, 7616, 7724, 7828, 7925, 8019, 3069, 3987, 4692, 5187, 5577, 5892, 6161, 6393, 6600, 6784, 6952, 7105, 7246, 7379, 7501, 7616, 7725, 7828, 7926, 8019, 3008, 3989, 4693, 5188, 5577, 5894, 6162, 6395, 6601, 6785, 6953, 7106, 7247, 7379, 7502, 7617, 7726, 7829, 7927, 8019, 3114, 4391, 5094, 5596, 5984, 6300, 6567, 6804, 7008, 7191, 7358, 7512, 7653, 7784, 7906, 8022, 8130, 8233, 8330, 8424, 3224, 4390, 5096, 5595, 5983, 6299, 6567, 6800, 7006, 7190, 7358, 7512, 7653, 7784, 7906, 8022, 8130, 8232, 8330, 8422, 3275, 4391, 5099, 5598, 5985, 6300, 6567, 6805, 7008, 7191, 7358, 7513, 7654, 7785, 7907, 8022, 8130, 8233, 8330, 8423, 3610, 4789, 5497, 5999, 6386, 6702, 6972, 7205, 7411, 7596, 7763, 7916, 8055, 8189, 8314, 8427, 8551, 8655, 8819, 8852, 3623, 4792, 5493, 5999, 6385, 6702, 6972, 7205, 7411, 7596, 7763, 7916, 8054, 8189, 8313, 8426, 8538, 8639, 8737, 8831, 3646, 4792, 5491, 6000, 6386, 6703, 6973, 7206, 7412, 7597, 7764, 7919, 8054, 8190, 8313, 8427, 8540, 8641, 8739, 8832, 4008, 5200, 5904, 6402, 6790, 7106, 7376, 7608, 7815, 7998, 8165, 8318, 8460, 8591, 8716, 8828, 8942, 9042, 9140, 9229, 4008, 5200, 5903, 6403, 6789, 7106, 7376, 7607, 7815, 7999, 8165, 8318, 8460, 8591, 8714, 8828, 8937, 9040, 9137, 9228, 4010, 5201, 5903, 6404, 6790, 7108, 7376, 7608, 7816, 7999, 8166, 8318, 8461, 8592, 8714, 8829, 8938, 9040, 9137, 9228, 4398, 5600, 6302, 6802, 7189, 7506, 7774, 8007, 8213, 8398, 8566, 8720, 8860, 8992, 9130, 9234, 9347, 9448, 9543, 9645, 4398, 5599, 6303, 6801, 7188, 7507, 7773, 8006, 8213, 8397, 8565, 8717, 8858, 8990, 9112, 9227, 9334, 9438, 9536, 9629, 4400, 5598, 6304, 6803, 7190, 7508, 7775, 8008, 8215, 8398, 8566, 8718, 8860, 8991, 9113, 9228, 9337, 9440, 9536, 9629, 4782, 6001, 6703, 7203, 7591, 7907, 8175, 8410, 8623, 8800, 8966, 9124, 9265, 9407, 9526, 9658, 9778, 9886, 9995, 10084, 4797, 6000, 6702, 7204, 7591, 7907, 8174, 8407, 8615, 8797, 8964, 9117, 9258, 9389, 9511, 9625, 9735, 9837, 9934, 10027, 4801, 6002, 6703, 7205, 7592, 7908, 8176, 8408, 8616, 8798, 8966, 9118, 9259, 9390, 9512, 9626, 9736, 9838, 9934, 10028, 5204, 6408, 7107, 7608, 7994, 8311, 8580, 8812, 9020, 9202, 9373, 9527, 9666, 9802, 9927, 10042, 10158, 10256, 10348, 10446, 5206, 6408, 7107, 7608, 7994, 8311, 8580, 8812, 9019, 9205, 9372, 9526, 9667, 9799, 9916, 10038, 10147, 10251, 10349, 10444, 5208, 6409, 7108, 7609, 7995, 8312, 8581, 8812, 9020, 9205, 9373, 9527, 9668, 9800, 9921, 10039, 10147, 10252, 10351, 10443, 5606, 6807, 7508, 8009, 8396, 8714, 8994, 9205, 9428, 9629, 9787, 9941, 10072, 10212, 10347, 10463, 10569, 10668, 10765, 10858, 5603, 6807, 7509, 8009, 8396, 8714, 8983, 9216, 9423, 9609, 9778, 9932, 10072, 10209, 10335, 10452, 10563, 10667, 10767, 10863, 5599, 6808, 7510, 8010, 8397, 8715, 8984, 9217, 9425, 9611, 9779, 9934, 10075, 10210, 10334, 10451, 10562, 10667, 10767, 10862, 6002, 7204, 7909, 8408, 8797, 9126, 9394, 9638, 9844, 10034, 10201, 10348, 10493, 10621, 10748, 10862, 10970, 11069, 11174, 11257, 6003, 7204, 7908, 8408, 8796, 9115, 9385, 9621, 9828, 10021, 10187, 10345, 10491, 10627, 10753, 10871, 10986, 11088, 11192, 11288, 6004, 7205, 7909, 8408, 8797, 9115, 9386, 9621, 9829, 10018, 10187, 10344, 10489, 10624, 10751, 10871, 10984, 11092, 11195, 11293, 6406, 7603, 8310, 8811, 9197, 9528, 9807, 10043, 10310, 10430, 10611, 10767, 10911, 11047, 11174, 11285, 11400, 11508, 11611, 11699, 6409, 7602, 8310, 8811, 9201, 9522, 9794, 10031, 10263, 10429, 10610, 10767, 10921, 11054, 11187, 11305, 11406, 11526, 11633, 11728, 6410, 7602, 8310, 8812, 9202, 9522, 9795, 10031, 10241, 10432, 10606, 10764, 10909, 11053, 11183, 11307, 11421, 11535, 11641, 11743, 6806, 8006, 8712, 9210, 9616, 9933, 10237, 10412, 10652, 10840, 11011, 11164, 11299, 11410, 11549, 11675, 11779, 11888, 11975, 12073, 6807, 8006, 8713, 9214, 9606, 9928, 10202, 10441, 10658, 10855, 11030, 11209, 11350, 11483, 11616, 11733, 11855, 11956, 12071, 12180, 6808, 8007, 8714, 9215, 9607, 9929, 10203, 10442, 10656, 10850, 11025, 11260, 11338, 11485, 11618, 11744, 11868, 11975, 12091, 12198, 7203, 8404, 9117, 9628, 10035, 10354, 10659, 10914, 11147, 11380, 11552, 11716, 11904, 12052, 12205, 12350, 12490, 12629, 12753, 12885, 7203, 8405, 9112, 9616, 10012, 10339, 10621, 10863, 11067, 11254, 11419, 11587, 11729, 11876, 12000, 12124, 12241, 12353, 12456, 12562, 7203, 8406, 9112, 9617, 10012, 10337, 10615, 10859, 11077, 11248, 11460, 11652, 11791, 11940, 12076, 12212, 12324, 12430, 12541, 12648, 7606, 8805, 9529, 10039, 10389, 10754, 11037, 11275, 11460, 11674, 11852, 12002, 12155, 12296, 12430, 12553, 12680, 12791, 12898, 13007, 7607, 8809, 9516, 10022, 10413, 10745, 11028, 11274, 11465, 11672, 11849, 12002, 12160, 12296, 12430, 12553, 12673, 12793, 12899, 13003, 7607, 8809, 9516, 10020, 10415, 10744, 11025, 11273, 11492, 11680, 11880, 12068, 12212, 12358, 12494, 12627, 12752, 12878, 12993, 13110, 8006, 9206, 9946, 10405, 10854, 11193, 11444, 11706, 11936, 12136, 12320, 12490, 12660, 12814, 12959, 13093, 13237, 8007, 9203, 9925, 10423, 10846, 11183, 11436, 11694, 11926, 12117, 12295, 12461, 12621, 12767, 12911, 13051, 13177, 8008, 9212, 9921, 10428, 10830, 11162, 11443, 11703, 11930, 12135, 12321, 12495, 12659, 12815, 12960, 13102, 13241, 8400, 9616, 10349, 10895, 11315, 11634, 11922, 12169, 12402, 12618, 12813, 13015, 13183, 8398, 9607, 10331, 10859, 11293, 11620, 11911, 12158, 12386, 12597, 12790, 12979, 13148, 8400, 9614, 10323, 10842, 11255, 11606, 11902, 12163, 12395, 12617, 12820, 13012, 13186, 8802, 10047, 10789, 11338, 11714, 12032, 12335, 12599, 12833, 13055, 13264, 8809, 10024, 10758, 11307, 11704, 12027, 12332, 12600, 12838, 13051, 13262, 8810, 10018, 10730, 11263, 11677, 12025, 12336, 12607, 12848, 13066, 13282, 9119, 10411, 11221, 11722, 12116, 12449, 12735, 13015, 13246, 9211, 10418, 11212, 11719, 12131, 12476, 12767, 13048, 9216, 10420, 11163, 11688, 12105, 12453, 12745, 13030, 13271, 9341, 10828, 11588, 12106, 12512, 12830, 13106, 9578, 10866, 11617, 12155, 12598, 12960, 13292, 9613, 10827, 11575, 12112, 12547, 12902, 13211, 9520, 11256, 12011, 12541, 12935, 13269, 9943, 11276, 12039, 12603, 13022, 9996, 11242, 12016, 12585, 13016, 8908, 11863, 12902, 10199, 11574, 12376, 12924, 10409, 11646, 12421, 12947], "harmonics_mags": [[39, 40, 41, 41, 38, 38, 39, 40, 40, 46, 43, 40, 22, 40, 32, 31, 36, 34, 44, 37], [52, 53, 55, 56, 56, 52, 45, 53, 47, 50, 50, 53, 52, 53, 52, 52, 52, 50, 47, 46], [65, 68, 70, 72, 73, 73, 72, 73, 72, 72, 72, 73, 72, 72, 71, 71, 70, 70, 68, 67], [69, 71, 72, 73, 75, 76, 77, 77, 75, 75, 76, 75, 75, 74, 73, 71, 69, 68, 64, 59], [69, 71, 72, 73, 74, 73, 74, 74, 75, 74, 74, 74, 73, 73, 71, 70, 67, 64, 59, 55], [68, 70, 72, 73, 75, 76, 77, 76, 73, 73, 73, 73, 72, 72, 71, 70, 68, 66, 63, 59], [52, 52, 52, 52, 53, 53, 50, 52, 53, 51, 52, 52, 52, 52, 52, 51, 50, 50, 48, 44], [42, 41, 42, 47, 53, 56, 56, 57, 59, 59, 56, 55, 51, 47, 44, 44, 38, 31, 19, 32], [48, 52, 54, 56, 58, 60, 61, 63, 62, 63, 63, 63, 62, 62, 60, 59, 56, 54, 49, 43], [56, 57, 57, 58, 59, 60, 61, 62, 64, 64, 64, 63, 62, 61, 59, 57, 53, 51, 46, 43], [47, 44, 50, 56, 62, 65, 67, 67, 66, 65, 64, 63, 62, 62, 60, 58, 54, 50, 42, 36], [60, 63, 64, 65, 68, 69, 71, 71, 71, 72, 71, 71, 70, 70, 69, 67, 64, 61, 51, 43], [58, 60, 61, 62, 63, 64, 64, 64, 66, 66, 66, 66, 65, 64, 63, 62, 59, 56, 50, 43], [44, 50, 54, 57, 60, 62, 63, 63, 62, 62, 62, 61, 61, 60, 60, 59, 57, 55, 49, 44], [51, 53, 54, 56, 57, 58, 58, 58, 61, 61, 61, 61, 60, 59, 57, 55, 52, 48, 36, 44], [45, 46, 47, 47, 47, 47, 47, 47, 44, 39, 50, 51, 47, 44, 45, 45, 44, 43, 40, 38], [46, 48, 49, 50, 49, 48, 45, 41, 42, 43, 43, 37, 37, 34, 34, 29, 23, 33, 35, 34], [48, 49, 51, 52, 53, 54, 54, 55, 54, 54, 54, 55, 53, 53, 51, 49, 46, 40, 28, 38], [50, 51, 52, 53, 53, 53, 53, 53, 53, 52, 52, 52, 51, 51, 50, 49, 46, 43, 32, 25], [49, 51, 52, 53, 53, 53, 51, 49, 48, 49, 49, 48, 48, 48, 47, 46, 45, 44, 43, 42], [38, 36, 36, 36, 33, 30, 34, 44, 47, 42, 41, 35, 41, 39, 42, 37, 44, 42, 40, 38], [55, 59, 62, 64, 67, 66, 59, 57, 61, 59, 59, 59, 60, 58, 58, 57, 57, 56, 56, 53], [70, 73, 76, 79, 81, 82, 79, 79, 81, 80, 80, 79, 79, 79, 78, 77, 75, 74, 71, 68], [73, 76, 77, 78, 79, 79, 79, 76, 78, 77, 77, 77, 76, 76, 75, 75, 73, 71, 67, 61], [74, 77, 79, 81, 83, 84, 84, 82, 84, 83, 83, 83, 83, 82, 81, 80, 79, 77, 73, 69], [71, 73, 75, 76, 78, 79, 78, 79, 79, 79, 78, 78, 78, 78, 77, 76, 75, 74, 72, 69], [66, 68, 69, 69, 69, 68, 65, 64, 66, 69, 69, 69, 68, 68, 67, 66, 65, 63, 61, 58], [62, 62, 62, 62, 65, 68, 70, 71, 72, 71, 69, 68, 67, 65, 63, 61, 57, 51, 44, 43], [54, 58, 61, 64, 67, 66, 65, 67, 66, 66, 67, 66, 66, 65, 64, 63, 61, 59, 55, 51], [62, 63, 65, 66, 63, 50, 63, 61, 49, 44, 52, 50, 48, 50, 49, 48, 50, 51, 51, 51], [59, 62, 65, 67, 72, 75, 77, 77, 76, 74, 72, 70, 69, 68, 65, 63, 58, 52, 40, 47], [66, 68, 69, 70, 70, 70, 70, 72, 73, 74, 73, 72, 71, 70, 68, 66, 62, 60, 56, 52], [57, 60, 64, 67, 71, 72, 69, 67, 69, 71, 73, 72, 72, 71, 70, 69, 67, 64, 59, 54], [61, 64, 67, 69, 71, 73, 75, 74, 74, 75, 74, 74, 74, 73, 72, 71, 68, 66, 66, 64], [48, 48, 46, 44, 53, 59, 62, 64, 58, 56, 57, 52, 54, 53, 52, 53, 54, 54, 53, 49], [53, 55, 56, 58, 62, 65, 68, 67, 63, 42, 57, 46, 54, 57, 57, 50, 54, 51, 50, 48], [56, 59, 61, 62, 62, 58, 43, 50, 52, 51, 49, 47, 47, 47, 45, 45, 44, 44, 33, 34], [59, 60, 60, 60, 59, 55, 44, 48, 41, 44, 45, 46, 45, 43, 42, 44, 40, 39, 39, 32], [56, 59, 61, 63, 64, 65, 65, 64, 63, 63, 63, 62, 62, 62, 63, 62, 60, 57, 57, 51], [51, 55, 59, 61, 63, 64, 64, 62, 56, 50, 52, 54, 54, 52, 54, 52, 52, 51, 49, 45], [45, 45, 44, 49, 54, 58, 57, 42, 53, 50, 57, 43, 48, 54, 29, 47, 47, 48, 42, 42], [67, 70, 74, 76, 79, 80, 76, 69, 73, 71, 68, 69, 70, 69, 69, 69, 67, 66, 65, 63], [77, 81, 84, 86, 90, 92, 92, 91, 93, 92, 92, 91, 91, 91, 90, 89, 88, 86, 83, 80], [79, 84, 86, 88, 90, 90, 90, 88, 88, 87, 88, 87, 86, 86, 85, 84, 83, 81, 77, 72], [76, 82, 86, 89, 93, 95, 96, 95, 96, 96, 96, 95, 95, 94, 93, 92, 90, 88, 84, 80], [81, 84, 86, 88, 90, 91, 90, 89, 90, 89, 89, 88, 88, 88, 87, 87, 86, 85, 83, 81], [77, 79, 81, 82, 82, 81, 78, 76, 79, 80, 81, 80, 80, 79, 79, 78, 76, 74, 71, 68], [76, 77, 78, 78, 77, 79, 83, 85, 86, 85, 83, 83, 81, 79, 77, 75, 70, 62, 56, 52], [69, 69, 70, 73, 79, 81, 78, 76, 80, 78, 79, 78, 78, 78, 76, 75, 73, 70, 65, 61], [76, 78, 78, 79, 78, 69, 77, 76, 67, 67, 68, 70, 67, 67, 62, 58, 55, 57, 60, 62], [74, 76, 78, 80, 83, 85, 89, 89, 89, 88, 85, 83, 82, 81, 79, 78, 74, 70, 61, 54], [66, 72, 76, 79, 82, 84, 86, 87, 86, 86, 85, 85, 84, 83, 81, 80, 76, 74, 68, 64], [66, 67, 71, 76, 82, 85, 85, 82, 83, 84, 84, 83, 83, 83, 82, 80, 79, 76, 72, 67], [63, 68, 73, 76, 81, 84, 87, 87, 86, 86, 86, 87, 86, 85, 84, 83, 80, 76, 75, 75], [56, 56, 56, 55, 59, 67, 73, 77, 80, 79, 78, 70, 73, 73, 71, 66, 67, 67, 65, 61], [56, 53, 53, 61, 72, 78, 82, 80, 73, 77, 72, 74, 75, 76, 74, 56, 70, 64, 63, 61], [71, 74, 76, 78, 79, 77, 57, 70, 70, 70, 64, 63, 65, 66, 61, 63, 61, 59, 50, 50], [72, 74, 75, 76, 75, 73, 67, 72, 69, 68, 69, 70, 67, 66, 64, 64, 60, 58, 56, 51], [67, 71, 75, 77, 80, 81, 82, 82, 82, 81, 81, 80, 80, 80, 79, 78, 76, 73, 71, 66], [60, 65, 71, 74, 79, 81, 82, 81, 81, 79, 79, 77, 78, 76, 74, 71, 70, 68, 64, 61], [41, 41, 40, 38, 39, 38, 32, 40, 38, 46, 42, 32, 43, 38, 23, 41, 45, 37, 35, 45], [58, 63, 66, 69, 70, 70, 73, 73, 75, 76, 76, 76, 75, 74, 69, 63, 50, 43, 29, 34], [67, 70, 72, 73, 75, 76, 77, 77, 74, 74, 76, 75, 74, 73, 72, 70, 68, 65, 59, 52], [64, 68, 71, 72, 74, 74, 73, 72, 74, 74, 74, 74, 73, 73, 72, 72, 70, 69, 66, 64], [65, 67, 69, 70, 71, 71, 71, 71, 71, 71, 72, 71, 71, 70, 69, 68, 66, 64, 59, 51], [62, 64, 66, 67, 67, 66, 63, 65, 68, 68, 69, 70, 70, 69, 68, 66, 63, 60, 55, 50], [63, 65, 66, 67, 68, 67, 68, 67, 66, 67, 67, 67, 67, 66, 65, 64, 63, 61, 57, 53], [39, 39, 42, 45, 49, 50, 45, 44, 47, 48, 47, 48, 46, 46, 44, 45, 42, 39, 37, 33], [43, 44, 45, 47, 50, 51, 50, 52, 53, 50, 50, 50, 50, 47, 46, 46, 47, 43, 41, 40], [44, 43, 39, 24, 45, 50, 54, 54, 54, 55, 55, 56, 55, 54, 54, 53, 52, 51, 48, 45], [36, 46, 51, 55, 58, 60, 61, 63, 63, 63, 64, 63, 63, 63, 62, 61, 59, 57, 53, 50], [51, 54, 56, 57, 58, 59, 60, 60, 59, 60, 60, 59, 59, 58, 58, 56, 54, 53, 49, 46], [45, 48, 50, 52, 51, 53, 58, 58, 58, 59, 59, 59, 59, 59, 59, 58, 57, 54, 48, 40], [43, 46, 49, 51, 56, 60, 62, 61, 62, 62, 61, 60, 59, 58, 56, 55, 53, 49, 21, 35], [46, 47, 48, 49, 49, 50, 51, 52, 53, 53, 53, 53, 52, 51, 49, 47, 41, 35, 42, 42], [38, 40, 40, 41, 40, 40, 41, 38, 37, 39, 37, 35, 35, 33, 29, 19, 28, 32, 31, 14], [28, 28, 26, 23, 25, 28, 32, 30, 34, 31, 31, 29, 21, 31, 27, 18, 13, 19, 14, 10], [38, 40, 41, 41, 41, 42, 43, 43, 43, 43, 43, 43, 41, 38, 31, 18, 37, 38, 24, 30], [34, 37, 39, 40, 42, 41, 39, 41, 40, 40, 39, 38, 38, 36, 29, 26, 35, 33, 25, 22], [24, 27, 29, 30, 29, 29, 31, 28, 28, 30, 30, 32, 30, 32, 26, 20, 24, 24, 25, 21], [47, 48, 46, 41, 45, 42, 48, 47, 47, 48, 46, 51, 47, 43, 48, 38, 42, 27, 42, 34], [47, 60, 67, 71, 76, 77, 79, 80, 81, 82, 82, 81, 80, 78, 76, 73, 65, 51, 42, 38], [65, 71, 75, 77, 80, 82, 83, 83, 81, 81, 82, 81, 81, 79, 78, 76, 72, 70, 65, 60], [63, 69, 73, 76, 80, 81, 81, 79, 80, 81, 80, 80, 80, 79, 79, 78, 77, 75, 73, 71], [67, 71, 73, 75, 77, 78, 78, 78, 78, 78, 79, 78, 78, 77, 77, 76, 74, 72, 66, 59], [65, 69, 72, 74, 75, 75, 73, 72, 75, 77, 78, 78, 78, 78, 77, 75, 72, 69, 63, 57], [68, 71, 73, 75, 76, 76, 76, 76, 75, 76, 76, 76, 75, 75, 74, 73, 71, 69, 65, 62], [47, 45, 35, 42, 56, 59, 57, 53, 56, 55, 54, 55, 54, 55, 53, 52, 51, 50, 47, 44], [56, 56, 57, 57, 59, 60, 60, 62, 61, 61, 59, 60, 60, 59, 57, 58, 55, 54, 51, 48], [55, 57, 58, 56, 46, 57, 63, 65, 65, 66, 67, 66, 66, 66, 65, 64, 63, 62, 58, 55], [43, 51, 57, 62, 67, 70, 71, 73, 74, 74, 75, 74, 74, 74, 73, 72, 70, 69, 65, 61], [56, 61, 64, 67, 69, 70, 72, 72, 71, 71, 71, 71, 71, 70, 70, 69, 68, 66, 63, 60], [55, 58, 61, 63, 65, 63, 70, 71, 71, 72, 72, 72, 72, 72, 72, 71, 69, 67, 61, 56], [53, 56, 58, 61, 66, 71, 76, 76, 76, 76, 75, 75, 73, 72, 70, 69, 67, 62, 37, 51], [55, 59, 61, 63, 64, 64, 66, 66, 67, 67, 67, 67, 66, 65, 62, 60, 52, 50, 55, 56], [52, 54, 56, 57, 56, 55, 56, 55, 53, 54, 52, 52, 50, 49, 43, 31, 45, 48, 44, 28], [46, 47, 48, 47, 43, 44, 48, 49, 49, 48, 49, 47, 46, 45, 39, 28, 38, 42, 34, 34], [53, 57, 59, 61, 61, 61, 62, 62, 62, 61, 61, 60, 57, 55, 45, 45, 55, 54, 46, 46], [51, 54, 57, 59, 61, 62, 61, 61, 61, 60, 59, 59, 57, 55, 45, 46, 55, 52, 47, 42], [45, 48, 51, 52, 54, 55, 57, 56, 58, 59, 59, 59, 59, 57, 51, 47, 56, 48, 51, 47], [60, 59, 58, 56, 60, 63, 63, 44, 60, 60, 54, 53, 46, 40, 43, 44, 41, 40, 44, 47], [67, 73, 79, 82, 87, 88, 89, 92, 93, 93, 92, 91, 89, 87, 86, 85, 81, 76, 60, 44], [69, 77, 82, 86, 89, 92, 94, 94, 93, 93, 94, 93, 92, 92, 90, 88, 84, 80, 73, 66], [73, 78, 82, 86, 90, 92, 92, 90, 90, 92, 91, 91, 91, 90, 90, 88, 87, 86, 83, 80], [74, 78, 81, 83, 86, 88, 89, 89, 90, 89, 90, 89, 89, 88, 88, 87, 85, 84, 79, 72], [66, 74, 79, 82, 86, 88, 87, 84, 86, 87, 87, 88, 88, 87, 86, 84, 82, 80, 74, 68], [80, 83, 85, 87, 90, 90, 91, 90, 89, 90, 90, 90, 89, 89, 88, 87, 85, 83, 79, 76], [56, 56, 63, 68, 74, 77, 74, 67, 69, 69, 68, 68, 68, 68, 67, 65, 63, 62, 59, 55], [71, 73, 74, 75, 75, 75, 73, 74, 73, 75, 72, 72, 72, 71, 67, 71, 67, 65, 63, 60], [65, 68, 70, 70, 71, 76, 77, 79, 79, 80, 80, 80, 80, 80, 79, 78, 76, 75, 72, 68], [65, 70, 73, 76, 81, 83, 86, 87, 88, 89, 89, 88, 87, 87, 86, 85, 84, 83, 79, 76], [67, 73, 77, 80, 83, 83, 85, 86, 85, 84, 84, 84, 84, 83, 82, 81, 79, 78, 74, 72], [66, 70, 73, 77, 81, 80, 83, 86, 86, 84, 86, 85, 85, 84, 84, 83, 82, 80, 74, 68], [64, 69, 72, 76, 83, 88, 93, 93, 93, 93, 92, 92, 90, 88, 86, 85, 84, 80, 54, 66], [71, 76, 79, 81, 83, 83, 85, 85, 87, 87, 86, 85, 84, 82, 78, 74, 62, 70, 73, 71], [69, 72, 74, 75, 76, 76, 75, 73, 72, 69, 67, 64, 64, 61, 47, 51, 62, 64, 58, 50], [65, 67, 67, 66, 63, 64, 68, 69, 70, 71, 70, 69, 68, 67, 61, 44, 61, 64, 55, 55], [70, 74, 77, 79, 81, 81, 81, 80, 81, 81, 81, 81, 79, 77, 69, 61, 75, 75, 65, 67], [70, 73, 75, 77, 79, 80, 80, 79, 80, 78, 78, 76, 74, 72, 60, 64, 71, 69, 63, 58], [64, 68, 72, 74, 76, 77, 77, 74, 75, 75, 75, 75, 75, 75, 71, 67, 69, 66, 65, 59], [54, 54, 53, 50, 43, 45, 53, 42, 41, 37, 38, 44, 34, 43, 47, 41, 46, 45, 44, 45], [68, 72, 74, 75, 77, 77, 76, 75, 74, 75, 73, 72, 72, 71, 70, 68, 64, 61, 62, 63], [65, 67, 68, 67, 63, 60, 62, 61, 60, 56, 58, 56, 59, 58, 57, 56, 54, 55, 52, 50], [68, 70, 71, 72, 71, 70, 70, 70, 69, 68, 68, 68, 67, 66, 63, 60, 53, 52, 52, 47], [70, 72, 73, 73, 74, 75, 76, 76, 77, 77, 77, 77, 75, 74, 71, 68, 59, 55, 63, 63], [65, 66, 67, 67, 67, 67, 67, 69, 70, 70, 70, 70, 69, 68, 67, 66, 62, 54, 52, 57], [54, 56, 58, 59, 60, 61, 60, 58, 53, 53, 55, 55, 53, 53, 50, 48, 42, 32, 38, 41], [46, 48, 50, 49, 45, 44, 44, 36, 37, 38, 40, 39, 38, 37, 38, 32, 35, 32, 19, 24], [54, 54, 54, 55, 56, 57, 54, 50, 47, 48, 48, 48, 48, 45, 45, 42, 39, 34, 34, 40], [62, 64, 65, 65, 66, 67, 66, 67, 67, 67, 67, 66, 66, 65, 63, 62, 58, 55, 46, 38], [62, 63, 64, 64, 63, 62, 60, 60, 60, 60, 60, 59, 57, 55, 49, 31, 50, 52, 46, 43], [60, 61, 62, 63, 63, 63, 61, 61, 62, 61, 61, 60, 58, 56, 51, 44, 42, 47, 44, 36], [55, 56, 57, 58, 58, 58, 56, 56, 55, 55, 54, 52, 52, 50, 46, 42, 34, 38, 42, 40], [51, 52, 52, 52, 52, 51, 51, 51, 52, 53, 52, 52, 52, 52, 50, 49, 46, 46, 42, 10], [47, 49, 50, 51, 51, 50, 51, 51, 51, 50, 49, 48, 47, 45, 41, 38, 31, 36, 37, 34], [36, 37, 38, 38, 37, 37, 37, 36, 38, 37, 38, 38, 36, 33, 31, 30, 25, 22, 24, 23], [25, 26, 27, 27, 29, 28, 26, 29, 28, 26, 21, 23, 23, 20, 16, 16, 15, 21, 17, 18], [34, 35, 36, 37, 37, 36, 34, 35, 36, 36, 36, 35, 34, 34, 31, 28, 23, 20, 19, 20], [34, 35, 36, 36, 36, 37, 36, 35, 36, 34, 33, 32, 30, 24, 24, 27, 28, 27, 19, 18], [29, 31, 32, 32, 31, 31, 29, 33, 33, 30, 29, 31, 30, 30, 26, 27, 26, 16, 15, 19], [53, 60, 62, 64, 63, 58, 59, 56, 47, 56, 50, 56, 50, 53, 50, 48, 50, 41, 48, 44], [62, 69, 74, 78, 83, 85, 86, 84, 82, 83, 81, 81, 80, 79, 78, 76, 71, 68, 71, 70], [57, 62, 70, 74, 76, 72, 70, 69, 68, 64, 63, 64, 65, 65, 64, 63, 63, 62, 61, 59], [68, 74, 77, 79, 81, 81, 78, 78, 78, 76, 76, 75, 74, 73, 71, 68, 61, 58, 61, 58], [71, 76, 80, 82, 83, 84, 86, 86, 88, 87, 87, 86, 85, 84, 82, 79, 68, 66, 74, 74], [64, 70, 74, 77, 78, 78, 78, 79, 81, 81, 80, 80, 80, 79, 78, 76, 72, 66, 60, 67], [66, 68, 69, 70, 71, 72, 73, 72, 68, 65, 66, 66, 65, 65, 64, 62, 59, 54, 41, 50], [57, 59, 61, 61, 61, 57, 57, 53, 51, 53, 51, 53, 54, 50, 50, 49, 45, 40, 31, 29], [64, 67, 68, 68, 69, 70, 70, 67, 60, 61, 62, 62, 62, 59, 58, 57, 53, 50, 47, 52], [68, 73, 76, 78, 80, 81, 82, 82, 83, 83, 82, 82, 81, 80, 79, 77, 74, 70, 63, 57], [70, 75, 77, 78, 79, 79, 75, 75, 76, 75, 75, 74, 73, 71, 64, 53, 65, 66, 58, 57], [71, 75, 77, 78, 79, 80, 79, 78, 79, 79, 78, 78, 76, 74, 70, 64, 56, 63, 61, 55], [66, 71, 73, 75, 76, 77, 76, 72, 75, 73, 73, 73, 72, 71, 69, 65, 59, 42, 56, 56], [64, 68, 71, 72, 73, 73, 71, 71, 70, 71, 72, 72, 72, 72, 71, 70, 68, 67, 62, 49], [61, 65, 68, 70, 73, 73, 73, 74, 73, 73, 73, 72, 71, 69, 67, 63, 52, 51, 57, 54], [59, 61, 61, 61, 61, 62, 63, 63, 63, 63, 62, 62, 60, 59, 56, 53, 48, 29, 52, 49], [54, 56, 56, 56, 55, 53, 51, 54, 52, 52, 52, 51, 50, 49, 48, 45, 40, 38, 42, 39], [58, 61, 63, 63, 62, 61, 61, 62, 62, 62, 62, 61, 60, 58, 55, 52, 43, 44, 46, 45], [60, 64, 67, 68, 69, 69, 68, 67, 67, 66, 65, 64, 62, 60, 54, 48, 53, 55, 53, 43], [48, 55, 60, 62, 63, 63, 64, 64, 63, 62, 62, 62, 61, 60, 56, 56, 56, 46, 44, 35], [59, 67, 71, 73, 73, 68, 66, 67, 48, 65, 55, 66, 55, 63, 58, 53, 59, 47, 49, 54], [74, 80, 85, 88, 93, 95, 95, 93, 91, 92, 91, 91, 89, 89, 87, 85, 79, 77, 79, 77], [70, 73, 79, 84, 86, 83, 77, 80, 73, 65, 65, 65, 59, 64, 65, 68, 71, 72, 71, 69], [72, 80, 84, 87, 90, 91, 89, 90, 89, 87, 86, 85, 84, 82, 79, 74, 66, 63, 66, 64], [81, 86, 89, 91, 92, 93, 95, 96, 96, 96, 95, 94, 93, 92, 90, 87, 75, 75, 83, 83], [71, 78, 83, 86, 88, 88, 88, 88, 90, 90, 90, 89, 89, 88, 87, 86, 82, 77, 67, 75], [75, 78, 79, 81, 83, 84, 84, 83, 79, 79, 77, 78, 76, 74, 72, 69, 66, 61, 59, 62], [68, 70, 71, 70, 70, 69, 65, 67, 62, 65, 65, 66, 65, 64, 62, 60, 57, 53, 31, 47], [73, 77, 79, 80, 80, 81, 82, 78, 73, 75, 75, 74, 73, 72, 71, 68, 64, 60, 58, 61], [78, 83, 87, 89, 91, 92, 93, 93, 94, 94, 93, 93, 92, 91, 89, 87, 84, 80, 74, 69], [80, 85, 88, 89, 90, 90, 87, 87, 87, 87, 87, 85, 84, 82, 75, 67, 75, 77, 67, 66], [82, 86, 88, 89, 91, 91, 90, 89, 91, 91, 90, 89, 87, 86, 81, 74, 67, 74, 71, 65], [78, 82, 85, 87, 89, 90, 91, 86, 87, 83, 85, 84, 84, 82, 80, 76, 69, 55, 66, 67], [75, 81, 84, 85, 85, 85, 83, 82, 82, 84, 84, 85, 85, 85, 85, 84, 81, 79, 72, 59], [74, 79, 82, 85, 87, 87, 87, 87, 87, 86, 84, 84, 82, 81, 78, 75, 64, 60, 67, 64], [73, 75, 76, 76, 76, 78, 78, 77, 77, 76, 76, 75, 73, 71, 67, 65, 61, 53, 63, 61], [68, 70, 70, 70, 68, 66, 67, 69, 69, 68, 67, 68, 66, 65, 64, 60, 53, 53, 56, 51], [72, 76, 78, 78, 78, 77, 78, 79, 79, 79, 79, 77, 75, 74, 70, 67, 56, 58, 61, 62], [75, 79, 82, 83, 84, 84, 83, 83, 83, 83, 82, 81, 79, 77, 71, 55, 67, 69, 67, 55], [63, 71, 76, 79, 80, 80, 81, 81, 81, 81, 81, 81, 79, 78, 74, 73, 73, 65, 61, 52], [59, 63, 66, 67, 65, 61, 57, 44, 54, 53, 52, 53, 53, 51, 51, 48, 47, 50, 43, 39], [60, 62, 68, 70, 72, 74, 70, 70, 71, 69, 68, 68, 67, 65, 62, 58, 58, 50, 44, 42], [69, 73, 75, 76, 78, 79, 79, 78, 75, 73, 68, 67, 63, 58, 48, 43, 21, 36, 40, 43], [65, 69, 71, 71, 71, 72, 73, 73, 74, 74, 74, 73, 71, 69, 67, 65, 65, 62, 58, 56], [57, 59, 62, 64, 65, 64, 68, 71, 70, 71, 72, 71, 70, 68, 65, 62, 51, 53, 57, 55], [60, 62, 61, 57, 55, 60, 64, 65, 61, 62, 62, 61, 60, 59, 57, 55, 49, 45, 51, 52], [58, 61, 63, 66, 68, 69, 71, 71, 71, 71, 70, 69, 67, 64, 51, 60, 68, 66, 58, 59], [48, 52, 56, 60, 64, 63, 61, 60, 59, 59, 57, 55, 53, 53, 48, 41, 38, 27, 35, 37], [54, 56, 58, 57, 54, 53, 56, 54, 52, 48, 51, 51, 50, 47, 41, 41, 47, 48, 40, 42], [52, 53, 50, 42, 48, 52, 51, 51, 52, 54, 54, 53, 52, 51, 48, 46, 45, 45, 33, 34], [51, 53, 53, 55, 56, 57, 56, 55, 50, 46, 47, 49, 47, 47, 45, 44, 41, 38, 31, 21], [53, 56, 57, 57, 56, 52, 46, 33, 43, 41, 44, 47, 46, 45, 43, 41, 29, 20, 26, 26], [51, 52, 54, 56, 59, 59, 60, 60, 60, 61, 58, 60, 59, 58, 54, 51, 34, 32, 36, 41], [50, 54, 56, 57, 58, 58, 58, 58, 58, 59, 58, 57, 54, 50, 47, 49, 50, 48, 42, 39], [37, 42, 45, 46, 46, 45, 44, 44, 46, 46, 45, 44, 45, 44, 39, 36, 38, 28, 37, 36], [39, 42, 43, 44, 44, 43, 44, 45, 45, 45, 44, 44, 41, 37, 36, 39, 35, 39, 34, 29], [32, 33, 33, 30, 11, 20, 22, 21, 20, 25, 23, 20, 23, 10, 20, 11, 13, 18, 12, 9], [24, 23, 22, 22, 26, 28, 26, 25, 20, 23, 24, 22, 19, 17, 10, 18, 13, 20, 17, 7], [26, 30, 32, 34, 31, 27, 29, 32, 28, 27, 27, 13, 31, 30, 28, 21, 19, 26, 8, 12], [31, 33, 30, 19, 30, 13, 30, 29, 31, 26, 24, 25, 26, 23, 24, 23, 11, 22, 13, 0], [55, 63, 71, 75, 77, 73, 73, 45, 68, 65, 60, 60, 63, 64, 62, 62, 61, 58, 54, 54], [69, 71, 70, 77, 84, 85, 84, 82, 84, 82, 81, 80, 80, 78, 76, 73, 67, 59, 44, 50], [74, 81, 85, 87, 89, 90, 90, 90, 88, 84, 80, 77, 72, 66, 62, 54, 46, 33, 54, 59], [72, 79, 82, 84, 83, 83, 85, 86, 86, 86, 86, 86, 85, 84, 82, 80, 78, 74, 69, 63], [70, 71, 73, 76, 80, 79, 82, 84, 85, 85, 86, 86, 85, 84, 82, 79, 69, 64, 72, 68], [69, 75, 78, 77, 71, 73, 80, 81, 78, 78, 78, 77, 76, 76, 74, 73, 68, 63, 66, 67], [68, 74, 77, 79, 84, 86, 87, 87, 87, 86, 85, 85, 83, 80, 68, 72, 82, 80, 70, 71], [63, 67, 70, 73, 79, 81, 78, 78, 76, 76, 74, 70, 71, 70, 66, 59, 43, 49, 53, 54], [67, 72, 76, 77, 76, 75, 76, 75, 71, 69, 70, 69, 67, 64, 56, 56, 62, 64, 57, 61], [68, 73, 75, 73, 48, 70, 72, 72, 72, 73, 74, 74, 73, 72, 69, 66, 64, 65, 57, 52], [67, 72, 74, 74, 75, 77, 77, 75, 71, 66, 65, 68, 65, 67, 64, 62, 59, 57, 49, 40], [67, 73, 76, 77, 76, 73, 68, 62, 65, 59, 51, 62, 55, 52, 55, 50, 44, 43, 50, 53], [68, 72, 73, 75, 81, 83, 82, 82, 84, 85, 79, 85, 84, 82, 78, 77, 68, 60, 63, 58], [69, 74, 78, 81, 83, 83, 83, 83, 82, 83, 82, 80, 76, 67, 71, 69, 76, 70, 65, 62], [60, 62, 68, 72, 73, 73, 72, 71, 71, 70, 69, 68, 67, 64, 57, 59, 62, 61, 58, 60], [63, 68, 70, 71, 73, 73, 73, 73, 73, 73, 72, 70, 66, 57, 67, 69, 63, 66, 60, 52], [64, 67, 68, 68, 63, 56, 56, 57, 56, 58, 56, 54, 49, 40, 53, 52, 50, 42, 36, 40], [46, 50, 51, 43, 54, 56, 55, 55, 53, 51, 35, 38, 46, 50, 51, 37, 56, 49, 45, 44], [41, 52, 58, 58, 54, 55, 56, 58, 52, 51, 57, 59, 58, 54, 50, 50, 54, 50, 19, 44], [65, 70, 72, 73, 74, 74, 73, 72, 71, 70, 61, 66, 70, 63, 70, 68, 61, 66, 62, 55], [69, 73, 78, 82, 86, 84, 79, 61, 73, 61, 64, 53, 67, 67, 66, 67, 65, 64, 61, 57], [78, 82, 82, 84, 90, 92, 89, 86, 89, 88, 86, 86, 85, 84, 81, 79, 73, 66, 35, 56], [79, 85, 89, 91, 94, 95, 95, 93, 92, 87, 83, 81, 76, 70, 67, 61, 52, 29, 58, 63], [75, 82, 86, 87, 88, 89, 90, 91, 91, 91, 92, 92, 91, 90, 89, 88, 84, 81, 73, 67], [76, 78, 77, 77, 83, 85, 87, 89, 89, 89, 91, 90, 89, 88, 86, 83, 74, 71, 76, 73], [75, 80, 83, 84, 76, 78, 84, 86, 82, 80, 80, 80, 80, 79, 78, 76, 73, 68, 70, 72], [72, 78, 82, 84, 89, 92, 93, 93, 93, 92, 91, 91, 89, 86, 74, 78, 87, 86, 76, 76], [66, 70, 74, 78, 85, 87, 85, 85, 83, 84, 82, 80, 80, 76, 71, 66, 55, 53, 60, 62], [71, 78, 81, 83, 83, 82, 82, 81, 77, 78, 76, 76, 74, 70, 62, 63, 69, 70, 63, 66], [74, 79, 82, 81, 71, 75, 79, 78, 80, 81, 83, 83, 82, 81, 79, 75, 71, 70, 61, 58], [73, 78, 80, 81, 82, 84, 84, 83, 80, 78, 77, 80, 77, 78, 75, 75, 69, 67, 57, 53], [71, 78, 82, 83, 81, 79, 72, 58, 59, 66, 66, 68, 58, 61, 57, 47, 50, 51, 58, 59], [73, 77, 77, 78, 87, 90, 85, 86, 91, 92, 84, 90, 89, 87, 82, 82, 74, 63, 67, 65], [73, 79, 84, 87, 90, 90, 90, 89, 90, 89, 88, 87, 82, 72, 77, 75, 83, 77, 69, 66], [65, 68, 74, 78, 81, 81, 80, 80, 80, 79, 80, 79, 77, 74, 68, 69, 70, 70, 66, 68], [71, 76, 79, 80, 81, 81, 81, 82, 82, 82, 81, 80, 75, 65, 75, 77, 70, 75, 69, 63], [73, 76, 77, 77, 71, 65, 65, 64, 65, 65, 63, 61, 54, 51, 58, 56, 57, 51, 41, 46], [60, 60, 58, 52, 53, 61, 58, 61, 57, 48, 56, 56, 61, 59, 58, 37, 64, 53, 51, 51], [60, 57, 62, 64, 64, 67, 67, 68, 63, 68, 69, 68, 71, 67, 42, 53, 64, 62, 46, 56], [73, 78, 80, 81, 81, 82, 80, 80, 78, 77, 68, 72, 76, 71, 77, 74, 68, 72, 68, 61], [62, 67, 71, 73, 73, 73, 76, 76, 77, 78, 78, 77, 72, 62, 56, 48, 40, 43, 46, 45], [69, 70, 71, 71, 71, 70, 71, 68, 69, 70, 69, 67, 64, 60, 48, 50, 57, 56, 42, 37], [66, 70, 72, 73, 73, 72, 74, 74, 73, 72, 70, 69, 67, 66, 61, 56, 58, 61, 60, 50], [66, 70, 71, 71, 67, 56, 63, 67, 58, 54, 61, 58, 58, 58, 58, 57, 53, 50, 50, 46], [68, 71, 71, 68, 68, 66, 66, 65, 68, 68, 68, 67, 66, 65, 62, 59, 55, 48, 46, 48], [56, 53, 55, 65, 71, 73, 73, 70, 71, 69, 68, 66, 63, 60, 48, 52, 59, 59, 50, 43], [53, 56, 59, 62, 63, 64, 64, 64, 63, 63, 62, 62, 61, 60, 58, 56, 51, 43, 36, 33], [38, 37, 38, 41, 45, 42, 42, 43, 44, 44, 43, 38, 27, 26, 38, 39, 35, 30, 26, 23], [50, 53, 53, 53, 53, 52, 53, 51, 49, 49, 48, 45, 41, 34, 23, 36, 40, 38, 31, 25], [55, 56, 57, 57, 56, 55, 54, 54, 53, 52, 51, 51, 49, 47, 42, 33, 34, 29, 34, 33], [48, 50, 53, 55, 56, 52, 54, 53, 51, 50, 47, 41, 40, 47, 49, 45, 42, 45, 37, 37], [44, 46, 44, 39, 34, 42, 33, 40, 34, 31, 20, 25, 30, 33, 35, 33, 30, 30, 17, 18], [36, 38, 37, 36, 34, 32, 31, 33, 29, 27, 26, 31, 38, 41, 40, 37, 35, 31, 13, 31], [33, 37, 38, 39, 41, 40, 40, 40, 40, 38, 35, 30, 20, 33, 33, 21, 28, 15, 3, 21], [26, 30, 32, 33, 32, 33, 30, 31, 30, 31, 29, 24, 22, 25, 24, 19, 12, 21, 19, 17], [21, 24, 23, 16, 26, 32, 29, 26, 27, 25, 22, 19, 20, 16, 23, 25, 8, 24, 9, 9], [18, 14, 20, 21, 20, 21, 20, 18, 18, 21, 19, 21, 17, 10, 19, 17, 17, 19, 16, 0], [26, 27, 26, 28, 27, 28, 15, 26, 21, 19, 18, 14, 22, 23, 22, 22, 0, 13, 17, 12], [27, 24, 24, 24, 27, 18, 18, 21, 18, 26, 27, 29, 23, 16, 18, 15, 24, 19, 17, 5], [33, 32, 33, 34, 31, 26, 30, 28, 26, 23, 25, 26, 27, 28, 25, 22, 17, 17, 9, 11], [66, 72, 76, 79, 84, 84, 85, 86, 88, 89, 88, 87, 81, 76, 69, 59, 48, 45, 43, 46], [69, 78, 81, 83, 83, 82, 84, 83, 83, 85, 83, 82, 80, 77, 66, 65, 74, 73, 54, 55], [73, 76, 80, 83, 85, 85, 85, 86, 84, 83, 81, 79, 78, 77, 73, 67, 66, 71, 72, 66], [65, 75, 80, 82, 82, 77, 71, 78, 74, 73, 77, 76, 74, 73, 71, 68, 63, 60, 60, 59], [70, 78, 83, 84, 81, 80, 77, 78, 80, 81, 81, 80, 79, 77, 75, 72, 68, 64, 59, 58], [68, 73, 72, 60, 83, 87, 88, 86, 86, 84, 82, 81, 79, 76, 68, 55, 71, 73, 66, 60], [61, 69, 73, 76, 81, 82, 82, 82, 82, 80, 80, 80, 79, 77, 75, 74, 69, 63, 49, 53], [61, 62, 59, 59, 63, 64, 63, 66, 63, 62, 59, 57, 52, 42, 56, 57, 52, 47, 43, 45], [62, 71, 75, 77, 76, 76, 75, 73, 70, 71, 70, 68, 65, 60, 41, 51, 58, 58, 49, 45], [69, 77, 80, 81, 82, 80, 79, 79, 77, 76, 75, 74, 71, 69, 64, 61, 54, 44, 48, 50], [68, 73, 75, 78, 82, 81, 80, 79, 78, 78, 77, 73, 64, 61, 70, 68, 53, 67, 55, 52], [66, 72, 73, 71, 65, 66, 68, 70, 66, 61, 58, 50, 38, 53, 56, 54, 44, 48, 28, 33], [61, 68, 74, 77, 78, 77, 77, 78, 76, 76, 74, 72, 65, 58, 50, 66, 69, 65, 62, 45], [60, 68, 74, 76, 78, 79, 80, 79, 79, 79, 77, 76, 72, 69, 68, 67, 62, 64, 59, 48], [52, 49, 62, 67, 69, 70, 69, 70, 71, 70, 69, 68, 64, 60, 53, 47, 59, 60, 52, 44], [55, 60, 63, 65, 65, 64, 63, 64, 64, 63, 61, 58, 38, 53, 56, 58, 46, 54, 47, 36], [42, 44, 48, 52, 54, 57, 59, 58, 57, 56, 54, 52, 43, 39, 45, 49, 47, 38, 37, 26], [47, 49, 49, 48, 48, 46, 22, 48, 41, 49, 48, 49, 43, 36, 43, 48, 29, 27, 27, 0], [53, 55, 53, 49, 47, 52, 50, 52, 54, 53, 52, 53, 47, 30, 39, 36, 36, 38, 34, 24], [48, 56, 59, 61, 60, 58, 57, 57, 56, 54, 49, 43, 47, 53, 49, 49, 46, 37, 33, 30], [68, 74, 80, 85, 90, 91, 92, 94, 96, 95, 95, 94, 87, 82, 76, 68, 57, 40, 48, 41], [80, 87, 89, 90, 90, 91, 94, 92, 92, 93, 91, 90, 88, 85, 74, 71, 82, 81, 62, 63], [82, 85, 88, 91, 93, 93, 93, 94, 92, 90, 88, 87, 86, 85, 80, 73, 75, 80, 79, 70], [75, 84, 89, 91, 89, 85, 80, 85, 77, 78, 79, 76, 75, 75, 74, 72, 70, 68, 67, 66], [78, 86, 90, 92, 88, 87, 84, 85, 89, 88, 88, 88, 86, 85, 82, 79, 73, 69, 66, 66], [77, 81, 80, 65, 91, 96, 97, 95, 95, 94, 92, 90, 88, 85, 75, 68, 81, 81, 71, 67], [70, 78, 82, 85, 90, 91, 91, 90, 89, 89, 88, 88, 86, 84, 82, 81, 77, 69, 59, 56], [70, 72, 69, 70, 72, 75, 75, 78, 75, 75, 72, 69, 61, 49, 67, 68, 62, 57, 47, 51], [75, 83, 87, 87, 87, 87, 86, 85, 83, 82, 80, 78, 74, 69, 46, 62, 68, 67, 57, 51], [80, 88, 92, 93, 94, 92, 91, 91, 90, 89, 88, 87, 84, 81, 77, 73, 57, 64, 64, 63], [79, 84, 87, 91, 95, 93, 92, 90, 90, 90, 89, 86, 77, 70, 81, 80, 71, 79, 68, 66], [77, 82, 83, 81, 77, 77, 78, 78, 76, 74, 72, 69, 58, 58, 65, 68, 60, 61, 53, 36], [74, 79, 85, 88, 89, 88, 88, 89, 89, 89, 86, 85, 79, 72, 64, 79, 81, 72, 73, 64], [74, 82, 87, 90, 92, 93, 93, 92, 92, 92, 90, 89, 85, 82, 81, 80, 77, 77, 70, 61], [71, 70, 77, 81, 82, 83, 83, 84, 84, 82, 81, 79, 76, 73, 67, 67, 74, 73, 52, 63], [72, 77, 80, 81, 81, 80, 78, 80, 79, 78, 76, 74, 57, 67, 71, 71, 47, 67, 61, 53], [58, 60, 64, 65, 65, 70, 72, 72, 71, 70, 67, 66, 58, 54, 60, 63, 57, 47, 45, 42], [66, 66, 64, 60, 59, 63, 56, 63, 57, 66, 66, 69, 65, 53, 64, 68, 50, 50, 48, 33], [69, 73, 72, 70, 72, 73, 70, 73, 74, 74, 76, 75, 69, 60, 61, 58, 60, 61, 50, 48], [71, 75, 76, 77, 75, 72, 70, 70, 70, 70, 66, 62, 62, 67, 61, 61, 55, 53, 50, 43], [63, 70, 73, 74, 78, 80, 78, 76, 75, 78, 75, 73, 73, 73, 71, 70, 67, 65, 63, 57], [72, 74, 71, 60, 45, 51, 66, 64, 69, 66, 65, 65, 66, 65, 64, 62, 56, 52, 50, 47], [66, 68, 66, 61, 59, 64, 70, 66, 71, 70, 70, 70, 69, 68, 65, 63, 60, 53, 42, 53], [62, 66, 67, 66, 68, 68, 68, 69, 69, 69, 69, 68, 67, 66, 63, 59, 38, 55, 56, 51], [51, 51, 53, 60, 65, 66, 64, 64, 64, 63, 63, 62, 60, 59, 53, 44, 45, 47, 42, 50], [51, 49, 44, 39, 51, 56, 56, 53, 49, 46, 45, 47, 40, 30, 33, 37, 42, 39, 44, 43], [50, 50, 53, 56, 59, 57, 60, 58, 56, 56, 56, 54, 50, 44, 36, 46, 46, 38, 50, 43], [49, 51, 48, 45, 48, 45, 46, 48, 47, 46, 46, 44, 41, 39, 32, 33, 28, 30, 32, 33], [40, 42, 42, 44, 45, 46, 45, 45, 43, 42, 42, 39, 36, 31, 30, 34, 26, 31, 34, 28], [31, 37, 41, 43, 46, 46, 47, 46, 44, 43, 40, 33, 27, 36, 40, 38, 18, 38, 32, 19], [31, 31, 32, 32, 33, 33, 28, 30, 30, 30, 31, 27, 27, 31, 33, 21, 23, 24, 9, 18], [30, 24, 18, 15, 10, 25, 28, 30, 26, 20, 26, 26, 17, 13, 16, 13, 16, 21, 21, 8], [32, 35, 35, 35, 35, 34, 34, 32, 33, 29, 27, 18, 19, 12, 7, 27, 23, 23, 23, 20], [25, 21, 20, 22, 21, 17, 24, 24, 23, 23, 23, 14, 22, 24, 15, 14, 15, 19, 0, 5], [25, 21, 14, 5, 19, 20, 15, 22, 14, 20, 12, 23, 25, 24, 22, 9, 17, 12, 14, 14], [10, 15, 15, 20, 21, 19, 20, 13, 19, 19, 10, 21, 16, 3, 17, 13, 10, 0, 16, 17], [20, 17, 16, 10, 12, 24, 16, 15, 9, 9, 8, 10, 3, 13, 3, 4, 5, 5, 12, 7], [21, 16, 12, 21, 19, 17, 20, 16, 18, 20, 14, 9, 13, 4, 13, 0, 16, 0, 9, 9], [16, 22, 26, 26, 21, 23, 25, 24, 24, 25, 22, 23, 15, 14, 15, 14, 18, 13, 8, 7], [8, 14, 13, 13, 10, 16, 15, 13, 16, 13, 8, 6, 11, 16, 7, 5, 9, 7, 6, 8], [55, 68, 77, 82, 84, 89, 88, 87, 84, 87, 84, 84, 83, 82, 81, 79, 76, 74, 69, 63], [68, 79, 85, 85, 72, 65, 75, 79, 79, 78, 76, 77, 77, 76, 75, 72, 67, 62, 59, 59], [64, 75, 80, 80, 66, 71, 81, 76, 82, 80, 80, 80, 79, 78, 76, 74, 71, 66, 54, 64], [64, 72, 77, 78, 79, 79, 81, 81, 81, 81, 81, 80, 79, 77, 75, 71, 50, 65, 67, 60], [54, 61, 63, 65, 75, 78, 77, 77, 77, 77, 77, 76, 75, 74, 70, 64, 50, 61, 55, 62], [61, 66, 66, 64, 60, 69, 72, 68, 67, 69, 70, 68, 65, 62, 53, 33, 53, 52, 55, 56], [58, 67, 68, 70, 77, 78, 79, 79, 76, 76, 76, 75, 73, 69, 58, 61, 64, 58, 65, 59], [63, 68, 70, 70, 66, 69, 66, 68, 68, 67, 66, 64, 61, 58, 50, 49, 42, 46, 50, 52], [48, 60, 65, 67, 69, 68, 69, 69, 67, 65, 65, 64, 61, 57, 49, 55, 52, 52, 57, 49], [51, 44, 60, 66, 71, 74, 74, 76, 74, 73, 70, 67, 60, 52, 61, 63, 55, 60, 58, 46], [44, 51, 58, 61, 62, 64, 62, 62, 61, 62, 63, 62, 56, 47, 59, 56, 56, 50, 41, 37], [51, 52, 41, 52, 57, 57, 59, 60, 55, 56, 53, 53, 48, 43, 38, 31, 39, 45, 41, 24], [54, 62, 64, 65, 64, 64, 64, 64, 64, 62, 60, 57, 48, 39, 49, 47, 52, 47, 42, 40], [54, 59, 62, 62, 63, 61, 60, 57, 55, 53, 50, 48, 40, 45, 48, 40, 52, 41, 42, 20], [50, 56, 63, 64, 64, 63, 59, 60, 63, 63, 58, 56, 48, 47, 51, 49, 49, 41, 39, 34], [53, 58, 62, 62, 61, 60, 60, 61, 59, 59, 58, 55, 46, 36, 42, 50, 51, 37, 39, 26], [40, 50, 55, 55, 49, 58, 60, 54, 50, 43, 38, 45, 34, 37, 38, 36, 37, 20, 26, 9], [42, 47, 38, 47, 49, 46, 51, 49, 48, 42, 41, 42, 39, 33, 42, 35, 39, 30, 25, 23], [41, 49, 51, 51, 53, 53, 51, 52, 50, 47, 44, 45, 49, 50, 41, 37, 45, 39, 37, 27], [41, 47, 46, 42, 44, 41, 36, 32, 26, 27, 29, 30, 26, 29, 16, 36, 25, 17, 23, 19], [69, 87, 93, 96, 97, 102, 101, 99, 97, 97, 96, 96, 95, 94, 92, 90, 86, 83, 78, 70], [83, 93, 98, 96, 84, 81, 83, 88, 85, 86, 82, 83, 84, 83, 82, 80, 75, 67, 69, 69], [78, 89, 92, 91, 68, 85, 91, 84, 93, 94, 94, 94, 92, 91, 88, 86, 82, 76, 66, 75], [78, 86, 91, 92, 92, 92, 94, 95, 94, 94, 94, 94, 92, 91, 88, 84, 63, 77, 75, 72], [73, 78, 76, 76, 87, 89, 87, 86, 85, 84, 83, 83, 82, 80, 76, 70, 61, 68, 53, 70], [74, 79, 78, 74, 74, 81, 85, 82, 67, 71, 78, 75, 72, 68, 59, 53, 64, 60, 65, 65], [66, 75, 77, 83, 91, 92, 94, 93, 90, 88, 86, 84, 82, 78, 69, 71, 74, 68, 77, 66], [77, 82, 85, 86, 78, 83, 83, 83, 82, 83, 82, 81, 78, 74, 65, 63, 60, 63, 68, 65], [70, 73, 82, 85, 84, 83, 85, 86, 81, 80, 81, 79, 74, 71, 62, 65, 57, 67, 68, 58], [76, 73, 77, 82, 86, 89, 88, 90, 89, 88, 86, 84, 77, 63, 76, 78, 63, 78, 71, 54], [67, 71, 76, 77, 79, 81, 74, 73, 75, 75, 75, 73, 71, 71, 76, 76, 63, 55, 59, 54], [72, 74, 69, 57, 68, 70, 78, 79, 75, 77, 74, 72, 67, 65, 58, 53, 59, 70, 54, 52], [75, 80, 81, 80, 79, 79, 80, 81, 80, 79, 77, 76, 69, 60, 64, 63, 65, 64, 57, 57], [70, 75, 78, 80, 80, 77, 79, 81, 79, 81, 78, 76, 68, 61, 62, 64, 57, 68, 41, 53], [68, 78, 84, 86, 86, 85, 83, 81, 84, 81, 78, 77, 71, 47, 71, 70, 75, 67, 61, 52], [78, 82, 85, 85, 84, 83, 83, 85, 82, 81, 79, 75, 64, 54, 64, 68, 72, 64, 60, 49], [63, 75, 81, 80, 76, 83, 85, 78, 72, 76, 56, 66, 61, 43, 58, 55, 59, 50, 50, 44], [73, 76, 69, 76, 73, 73, 77, 74, 75, 71, 68, 66, 68, 68, 69, 64, 61, 48, 42, 45], [71, 77, 78, 77, 80, 81, 76, 81, 80, 79, 75, 69, 65, 73, 56, 68, 68, 58, 43, 52], [69, 73, 73, 72, 72, 66, 68, 71, 71, 69, 62, 57, 56, 54, 56, 62, 47, 52, 34, 20], [67, 71, 75, 76, 75, 73, 69, 67, 71, 67, 67, 66, 66, 64, 60, 58, 47, 28, 35, 25], [73, 75, 76, 78, 79, 79, 80, 81, 81, 81, 80, 80, 78, 77, 75, 72, 68, 61, 54, 59], [71, 74, 74, 74, 70, 68, 71, 69, 70, 70, 69, 68, 67, 65, 60, 55, 29, 46, 52, 50], [66, 66, 65, 68, 72, 72, 70, 68, 65, 64, 63, 61, 59, 56, 53, 52, 40, 47, 49, 24], [50, 52, 49, 47, 49, 44, 47, 36, 32, 49, 50, 49, 47, 46, 43, 35, 38, 41, 31, 35], [55, 56, 55, 54, 55, 56, 56, 53, 53, 50, 49, 48, 45, 43, 37, 28, 37, 38, 18, 32], [56, 58, 59, 59, 59, 59, 59, 59, 58, 58, 57, 56, 54, 52, 45, 34, 41, 36, 38, 34], [37, 38, 38, 40, 40, 42, 39, 40, 39, 41, 40, 38, 34, 34, 29, 26, 21, 25, 22, 21], [20, 29, 33, 34, 35, 31, 28, 19, 16, 27, 16, 8, 22, 21, 23, 20, 23, 25, 14, 20], [32, 36, 37, 34, 29, 33, 30, 29, 31, 33, 30, 27, 21, 16, 12, 27, 25, 18, 16, 7], [33, 37, 39, 38, 37, 38, 38, 38, 36, 35, 34, 31, 26, 12, 27, 31, 22, 16, 13, 0], [33, 38, 39, 38, 38, 36, 36, 36, 35, 35, 35, 33, 27, 10, 20, 17, 24, 15, 17, 18], [26, 28, 27, 25, 28, 27, 26, 27, 23, 27, 19, 23, 23, 11, 19, 20, 19, 17, 6, 13], [25, 21, 25, 18, 19, 22, 18, 21, 16, 18, 19, 20, 2, 14, 12, 11, 7, 15, 2, 0], [31, 30, 24, 26, 24, 26, 21, 25, 21, 20, 17, 18, 12, 12, 14, 10, 7, 11, 4, 17], [15, 11, 19, 13, 0, 0, 13, 11, 10, 12, 11, 4, 11, 12, 13, 11, 0, 10, 14, 11], [12, 11, 5, 10, 1, 9, 0, 18, 5, 14, 16, 13, 12, 0, 10, 11, 4, 7, 0, 12], [16, 13, 4, 0, 15, 7, 15, 0, 13, 18, 9, 9, 11, 9, 0, 0, 9, 13, 4, 10], [11, 13, 15, 12, 9, 8, 6, 16, 16, 7, 8, 8, 6, 1, 0, 7, 14, 15, 11, 1], [13, 19, 11, 10, 2, 3, 0, 11, 9, 0, 14, 1, 6, 7, 14, 1, 10, 0, 11, 16], [62, 78, 82, 86, 88, 85, 82, 82, 83, 80, 80, 78, 77, 76, 73, 70, 65, 60, 48, 43], [72, 83, 89, 89, 92, 92, 93, 93, 95, 94, 93, 93, 92, 91, 89, 86, 80, 72, 68, 73], [53, 81, 88, 89, 88, 84, 86, 85, 85, 86, 86, 84, 82, 80, 76, 70, 57, 63, 65, 63], [69, 80, 83, 82, 87, 88, 86, 86, 82, 81, 79, 77, 74, 72, 66, 65, 61, 53, 63, 53], [52, 66, 69, 67, 62, 62, 57, 56, 60, 67, 67, 67, 65, 64, 59, 53, 49, 55, 50, 41], [66, 74, 75, 76, 73, 75, 76, 73, 73, 69, 68, 67, 65, 63, 57, 41, 56, 57, 46, 52], [66, 78, 82, 83, 84, 83, 84, 84, 83, 83, 82, 81, 79, 76, 67, 62, 68, 64, 61, 58], [57, 61, 69, 65, 65, 66, 67, 68, 69, 69, 68, 68, 66, 62, 51, 52, 53, 34, 49, 43], [58, 60, 63, 67, 61, 64, 57, 53, 53, 54, 54, 52, 51, 47, 37, 42, 49, 43, 41, 32], [59, 68, 74, 76, 75, 74, 75, 74, 73, 72, 72, 70, 67, 63, 60, 63, 62, 53, 50, 41], [55, 65, 68, 70, 70, 70, 71, 70, 69, 68, 66, 64, 58, 45, 61, 63, 56, 45, 42, 42], [53, 61, 67, 68, 69, 68, 66, 67, 67, 67, 66, 66, 63, 59, 56, 54, 51, 45, 44, 29], [42, 59, 62, 60, 60, 59, 61, 64, 63, 60, 57, 57, 53, 40, 42, 41, 48, 42, 20, 25], [54, 68, 72, 72, 72, 71, 71, 71, 71, 71, 69, 67, 62, 52, 41, 54, 54, 46, 45, 38], [57, 68, 69, 63, 65, 64, 66, 67, 67, 63, 60, 56, 49, 47, 52, 54, 47, 41, 37, 29], [52, 52, 54, 56, 45, 49, 47, 49, 46, 33, 29, 33, 40, 44, 42, 40, 33, 29, 24, 19], [42, 47, 45, 46, 43, 43, 49, 46, 48, 47, 47, 45, 38, 40, 37, 35, 36, 28, 19, 9], [40, 48, 49, 49, 48, 48, 47, 44, 41, 42, 41, 35, 35, 36, 36, 33, 30, 24, 19, 11], [43, 49, 52, 51, 52, 54, 51, 52, 48, 50, 46, 40, 41, 47, 50, 47, 37, 35, 19, 20], [35, 30, 32, 35, 43, 45, 46, 47, 47, 46, 45, 43, 37, 34, 36, 35, 33, 18, 13, 13], [72, 86, 89, 94, 96, 93, 94, 89, 89, 89, 87, 87, 86, 85, 83, 80, 74, 68, 64, 55], [81, 91, 97, 97, 100, 101, 102, 102, 103, 103, 102, 102, 101, 99, 97, 95, 89, 80, 76, 80], [65, 91, 97, 98, 97, 94, 95, 94, 93, 93, 92, 91, 89, 87, 81, 75, 60, 69, 71, 72], [78, 89, 92, 91, 96, 97, 95, 95, 92, 93, 92, 91, 88, 86, 81, 77, 74, 68, 73, 62], [54, 75, 78, 78, 75, 73, 62, 68, 62, 72, 75, 72, 70, 68, 63, 55, 56, 61, 58, 50], [77, 82, 82, 83, 81, 83, 84, 80, 82, 80, 79, 79, 77, 75, 70, 62, 66, 68, 52, 60], [76, 88, 93, 94, 95, 94, 94, 94, 94, 94, 93, 92, 90, 87, 77, 73, 77, 73, 71, 68], [67, 74, 80, 74, 75, 79, 80, 80, 80, 79, 79, 79, 76, 72, 61, 63, 64, 45, 59, 51], [73, 76, 74, 80, 73, 78, 75, 72, 69, 66, 59, 49, 55, 51, 42, 60, 65, 61, 54, 39], [72, 81, 87, 89, 88, 87, 88, 87, 87, 87, 86, 85, 81, 76, 71, 76, 75, 66, 57, 59], [67, 78, 80, 82, 81, 81, 81, 81, 80, 79, 77, 76, 70, 63, 71, 73, 65, 55, 48, 48], [67, 76, 82, 84, 86, 85, 84, 84, 83, 82, 81, 80, 77, 71, 69, 68, 67, 62, 57, 34], [53, 72, 75, 76, 75, 75, 71, 74, 80, 74, 74, 74, 66, 58, 57, 60, 64, 56, 45, 37], [72, 83, 87, 87, 87, 86, 87, 87, 86, 85, 83, 81, 75, 62, 65, 70, 67, 61, 57, 51], [76, 86, 86, 79, 82, 80, 85, 84, 84, 80, 76, 70, 62, 66, 72, 70, 69, 53, 53, 36], [72, 70, 72, 75, 67, 68, 67, 65, 68, 63, 58, 29, 58, 62, 62, 58, 51, 50, 42, 36], [65, 71, 69, 69, 69, 68, 71, 71, 72, 72, 71, 68, 58, 59, 61, 55, 56, 50, 41, 25], [59, 69, 71, 73, 73, 73, 71, 70, 68, 68, 65, 61, 58, 59, 56, 54, 57, 45, 43, 34], [61, 68, 70, 69, 70, 74, 69, 70, 65, 68, 64, 60, 56, 64, 66, 62, 52, 52, 36, 30], [52, 45, 59, 63, 65, 67, 66, 68, 66, 64, 63, 61, 49, 56, 61, 58, 47, 40, 25, 35], [69, 79, 79, 76, 82, 80, 80, 78, 76, 79, 77, 77, 75, 74, 70, 65, 55, 49, 50, 51], [65, 74, 79, 79, 81, 83, 82, 83, 84, 84, 81, 79, 75, 70, 57, 58, 60, 55, 47, 34], [56, 53, 59, 67, 73, 75, 77, 76, 76, 75, 73, 73, 71, 69, 66, 62, 57, 61, 59, 56], [58, 66, 69, 67, 64, 61, 65, 64, 63, 65, 65, 64, 62, 60, 54, 43, 53, 42, 46, 34], [59, 57, 61, 64, 65, 65, 66, 67, 68, 68, 68, 67, 66, 63, 55, 51, 51, 52, 42, 40], [56, 64, 66, 67, 66, 66, 66, 67, 65, 65, 65, 64, 62, 60, 51, 50, 37, 52, 36, 40], [49, 51, 52, 52, 54, 55, 56, 56, 56, 56, 56, 56, 55, 53, 50, 50, 45, 37, 38, 32], [43, 40, 45, 45, 44, 44, 42, 43, 45, 44, 41, 39, 38, 29, 33, 34, 29, 21, 18, 16], [37, 40, 40, 43, 44, 44, 44, 45, 45, 44, 45, 42, 38, 30, 36, 32, 30, 24, 15, 17], [25, 29, 25, 12, 23, 23, 26, 23, 25, 21, 28, 28, 31, 30, 8, 23, 22, 20, 20, 0], [18, 31, 34, 35, 35, 37, 38, 39, 39, 40, 41, 41, 38, 30, 28, 17, 23, 15, 14, 7], [27, 33, 33, 31, 33, 33, 33, 33, 34, 34, 34, 34, 31, 21, 20, 21, 21, 18, 19, 9], [22, 25, 25, 28, 26, 23, 24, 24, 25, 25, 21, 24, 18, 18, 26, 12, 20, 7, 2, 8], [17, 6, 25, 28, 22, 27, 28, 27, 30, 31, 32, 32, 27, 14, 11, 14, 18, 5, 11, 2], [9, 19, 23, 21, 25, 25, 25, 22, 17, 19, 25, 9, 10, 19, 11, 5, 0, 0, 8, 5], [9, 1, 13, 10, 12, 8, 14, 9, 8, 11, 5, 15, 17, 6, 15, 3, 10, 8, 8, 15], [7, 7, 9, 1, 9, 20, 12, 14, 14, 8, 11, 11, 9, 14, 15, 1, 8, 7, 0, 7], [16, 20, 19, 23, 23, 21, 20, 23, 22, 21, 15, 12, 7, 0, 15, 14, 11, 8, 12, 6], [25, 22, 19, 22, 19, 15, 22, 14, 19, 12, 16, 10, 13, 14, 18, 18, 16, 18, 18, 17], [10, 3, 1, 14, 18, 15, 19, 4, 13, 9, 13, 13, 8, 8, 6, 8, 8, 11, 0, 15], [70, 84, 89, 87, 90, 90, 91, 88, 85, 89, 87, 87, 85, 83, 79, 75, 62, 60, 63, 54], [74, 81, 90, 91, 92, 94, 94, 94, 95, 95, 92, 90, 86, 81, 72, 71, 70, 66, 56, 52], [64, 74, 67, 79, 85, 88, 89, 88, 88, 87, 85, 84, 81, 77, 68, 64, 67, 68, 66, 65], [64, 78, 84, 85, 80, 79, 81, 81, 80, 81, 79, 77, 74, 70, 56, 61, 67, 51, 54, 55], [73, 73, 76, 79, 80, 80, 80, 82, 82, 82, 81, 80, 77, 72, 60, 69, 53, 68, 58, 60], [67, 79, 83, 84, 84, 84, 84, 85, 83, 83, 82, 80, 76, 69, 66, 68, 62, 65, 53, 45], [64, 73, 75, 74, 76, 76, 78, 79, 78, 77, 76, 76, 72, 69, 67, 58, 70, 58, 61, 54], [69, 67, 69, 74, 71, 73, 71, 71, 71, 70, 67, 61, 55, 57, 58, 44, 51, 42, 40, 41], [62, 72, 74, 75, 77, 76, 76, 77, 77, 76, 74, 71, 61, 63, 63, 60, 54, 53, 52, 43], [56, 58, 52, 59, 63, 65, 66, 65, 66, 66, 65, 63, 55, 53, 56, 50, 55, 53, 46, 34], [52, 64, 68, 69, 70, 70, 70, 70, 71, 70, 69, 67, 57, 52, 46, 59, 50, 42, 39, 33], [55, 65, 67, 66, 66, 66, 65, 66, 66, 66, 64, 61, 48, 55, 50, 49, 43, 33, 27, 29], [50, 60, 62, 63, 63, 65, 65, 63, 65, 65, 60, 52, 52, 56, 53, 44, 40, 38, 35, 20], [54, 48, 63, 64, 63, 64, 66, 66, 66, 67, 66, 63, 48, 51, 40, 43, 45, 43, 22, 27], [53, 53, 54, 59, 57, 61, 48, 55, 42, 52, 54, 49, 41, 49, 44, 41, 42, 29, 19, 19], [46, 43, 48, 46, 43, 44, 42, 40, 40, 40, 30, 21, 25, 25, 23, 12, 8, 12, 10, 11], [39, 37, 40, 39, 38, 36, 41, 41, 39, 41, 39, 31, 33, 35, 17, 29, 26, 14, 15, 8], [35, 45, 46, 46, 48, 48, 50, 50, 51, 51, 50, 45, 31, 40, 33, 37, 29, 25, 19, 7], [40, 46, 40, 38, 41, 34, 30, 29, 38, 40, 41, 41, 32, 24, 33, 26, 24, 11, 13, 14], [29, 32, 30, 27, 30, 34, 31, 32, 30, 23, 28, 30, 34, 33, 19, 24, 21, 18, 0, 14], [79, 89, 95, 94, 96, 99, 98, 98, 93, 95, 94, 94, 92, 91, 88, 84, 71, 67, 71, 62], [80, 88, 97, 98, 100, 102, 102, 103, 104, 103, 100, 98, 94, 89, 80, 80, 78, 73, 61, 56], [68, 82, 75, 86, 92, 95, 95, 95, 94, 93, 92, 90, 86, 80, 71, 74, 74, 74, 74, 71], [72, 86, 91, 92, 88, 88, 88, 87, 85, 87, 85, 83, 80, 75, 53, 70, 72, 48, 61, 57], [80, 82, 84, 87, 90, 89, 88, 90, 89, 89, 89, 88, 84, 78, 73, 78, 65, 77, 64, 68], [75, 87, 90, 91, 91, 91, 90, 90, 88, 88, 86, 84, 78, 67, 74, 71, 73, 70, 61, 55], [74, 82, 85, 83, 85, 86, 88, 88, 88, 88, 87, 86, 82, 79, 78, 62, 79, 71, 72, 63], [80, 77, 80, 85, 83, 84, 82, 82, 82, 81, 76, 65, 66, 63, 57, 56, 41, 55, 44, 32], [72, 84, 86, 87, 89, 88, 88, 88, 87, 86, 84, 80, 73, 77, 70, 75, 70, 62, 60, 55], [69, 72, 54, 71, 74, 78, 79, 79, 80, 80, 78, 73, 47, 69, 69, 62, 65, 66, 53, 51], [64, 77, 80, 81, 82, 82, 82, 83, 82, 81, 79, 75, 62, 69, 60, 72, 63, 57, 50, 44], [69, 79, 82, 80, 81, 81, 80, 80, 80, 80, 77, 72, 64, 71, 51, 65, 60, 56, 48, 41], [65, 73, 76, 76, 75, 76, 79, 75, 78, 76, 74, 66, 68, 66, 67, 54, 50, 38, 47, 26], [70, 68, 78, 79, 77, 77, 79, 78, 79, 79, 77, 73, 63, 67, 64, 62, 57, 36, 35, 31], [71, 69, 75, 79, 76, 82, 75, 79, 72, 67, 71, 63, 68, 69, 61, 57, 60, 49, 40, 22], [65, 65, 69, 68, 64, 66, 63, 64, 62, 57, 32, 51, 46, 53, 47, 42, 28, 36, 17, 12], [61, 62, 55, 57, 60, 47, 61, 61, 61, 61, 58, 50, 56, 48, 41, 47, 42, 31, 17, 11], [57, 64, 67, 69, 69, 69, 68, 68, 67, 65, 60, 55, 59, 50, 46, 51, 48, 17, 25, 22], [58, 63, 55, 50, 58, 57, 56, 61, 60, 58, 54, 55, 51, 38, 48, 50, 35, 36, 24, 22], [44, 54, 52, 53, 55, 56, 54, 54, 52, 52, 52, 54, 51, 50, 45, 47, 38, 30, 16, 1], [74, 74, 58, 70, 67, 62, 62, 67, 64, 64, 64, 65, 65, 64, 64, 63, 59, 56, 54, 55], [63, 71, 74, 72, 74, 75, 77, 77, 76, 75, 73, 71, 67, 63, 58, 56, 54, 57, 55, 51], [48, 53, 59, 63, 64, 63, 61, 62, 63, 61, 58, 54, 40, 51, 56, 55, 49, 48, 44, 47], [50, 53, 52, 51, 51, 51, 53, 54, 56, 56, 56, 56, 56, 52, 46, 48, 47, 32, 41, 41], [30, 40, 44, 47, 49, 50, 50, 49, 45, 40, 36, 44, 50, 52, 50, 45, 45, 46, 38, 36], [45, 48, 48, 50, 51, 50, 49, 49, 49, 48, 46, 45, 44, 43, 42, 41, 33, 39, 29, 28], [33, 26, 23, 30, 27, 29, 23, 31, 30, 27, 16, 14, 19, 22, 25, 23, 17, 17, 16, 8], [15, 2, 25, 19, 26, 26, 24, 22, 18, 20, 17, 23, 20, 21, 15, 15, 4, 19, 12, 21], [14, 10, 17, 9, 16, 15, 19, 13, 18, 19, 16, 18, 0, 9, 14, 18, 0, 5, 16, 0], [21, 19, 19, 24, 23, 22, 19, 17, 19, 14, 16, 16, 16, 17, 9, 8, 10, 9, 16, 8], [19, 22, 22, 25, 24, 24, 23, 21, 22, 22, 18, 16, 17, 13, 0, 0, 15, 5, 12, 8], [21, 21, 23, 17, 18, 20, 9, 9, 15, 20, 19, 17, 0, 14, 0, 9, 2, 8, 4, 3], [11, 20, 20, 21, 14, 17, 20, 20, 18, 14, 8, 0, 4, 9, 3, 16, 8, 15, 11, 7], [15, 20, 12, 8, 11, 14, 14, 15, 18, 15, 18, 8, 16, 5, 15, 8, 2, 8, 12, 7], [10, 17, 20, 21, 22, 15, 21, 18, 23, 21, 7, 18, 18, 16, 16, 18, 20, 11, 12, 0], [7, 12, 10, 16, 16, 10, 0, 13, 16, 1, 11, 4, 8, 9, 14, 0, 12, 3, 8, 7], [14, 13, 5, 7, 15, 15, 7, 2, 0, 16, 13, 18, 0, 9, 0, 7, 10, 11, 11, 4], [12, 11, 2, 12, 8, 9, 13, 15, 12, 15, 12, 17, 17, 4, 8, 6, 13, 13, 5, 2], [5, 14, 15, 17, 17, 13, 16, 14, 9, 0, 3, 12, 0, 4, 15, 7, 4, 3, 13, 13], [19, 19, 16, 11, 13, 16, 18, 7, 11, 15, 14, 13, 10, 8, 15, 2, 13, 9, 13, 0], [80, 87, 79, 80, 76, 66, 71, 80, 73, 70, 73, 73, 73, 73, 72, 71, 69, 65, 65, 67], [71, 84, 90, 90, 88, 92, 93, 93, 93, 92, 90, 89, 85, 80, 68, 54, 56, 67, 66, 59], [70, 59, 77, 81, 83, 83, 81, 82, 83, 82, 79, 77, 71, 62, 63, 65, 57, 66, 49, 52], [74, 80, 80, 80, 79, 77, 79, 80, 80, 77, 78, 78, 77, 74, 71, 71, 65, 60, 60, 59], [67, 68, 70, 68, 74, 78, 78, 78, 77, 76, 75, 75, 74, 73, 68, 68, 68, 62, 56, 42], [68, 71, 72, 73, 75, 75, 73, 75, 74, 73, 71, 67, 60, 52, 57, 48, 58, 57, 51, 47], [60, 52, 67, 63, 55, 58, 61, 61, 58, 56, 58, 60, 62, 60, 54, 53, 57, 50, 44, 42], [55, 53, 58, 60, 60, 60, 58, 57, 57, 57, 54, 54, 51, 50, 46, 26, 32, 31, 30, 16], [53, 56, 63, 65, 65, 63, 62, 61, 61, 60, 59, 57, 48, 53, 55, 45, 49, 32, 34, 30], [50, 52, 55, 57, 52, 51, 50, 51, 43, 38, 41, 40, 23, 35, 34, 41, 33, 32, 22, 19], [54, 59, 61, 60, 59, 60, 60, 60, 59, 58, 55, 45, 53, 55, 41, 49, 45, 38, 28, 24], [48, 52, 51, 51, 51, 51, 48, 49, 46, 46, 37, 25, 46, 50, 42, 41, 36, 29, 18, 16], [45, 51, 51, 49, 49, 34, 48, 33, 43, 46, 46, 46, 42, 36, 41, 20, 34, 24, 22, 12], [30, 27, 36, 39, 47, 49, 48, 50, 48, 42, 33, 27, 38, 41, 31, 37, 31, 26, 16, 13], [42, 39, 37, 35, 37, 45, 44, 45, 47, 46, 44, 36, 42, 35, 36, 25, 26, 20, 23, 17], [26, 31, 34, 32, 32, 31, 28, 27, 31, 30, 31, 32, 30, 26, 21, 17, 3, 1, 14, 10], [31, 36, 34, 30, 25, 29, 27, 21, 19, 24, 30, 31, 31, 21, 21, 18, 0, 11, 15, 11], [27, 40, 40, 38, 37, 38, 36, 35, 32, 33, 33, 32, 16, 26, 14, 19, 13, 16, 7, 5], [30, 33, 31, 30, 28, 28, 31, 29, 25, 22, 31, 32, 31, 24, 24, 17, 14, 13, 8, 6], [27, 26, 17, 25, 30, 30, 30, 28, 28, 30, 27, 23, 9, 22, 19, 5, 6, 6, 9, 10], [86, 96, 89, 93, 86, 80, 86, 82, 80, 78, 80, 81, 83, 82, 81, 81, 78, 75, 73, 75], [77, 93, 99, 99, 97, 101, 102, 101, 102, 101, 100, 99, 94, 89, 76, 69, 61, 75, 72, 70], [80, 67, 85, 90, 93, 93, 91, 91, 92, 89, 87, 84, 76, 64, 74, 72, 68, 73, 53, 55], [85, 89, 89, 91, 91, 90, 91, 92, 91, 89, 88, 87, 84, 82, 78, 80, 73, 71, 68, 66], [77, 81, 83, 80, 87, 90, 90, 90, 90, 88, 87, 84, 82, 81, 74, 76, 77, 69, 65, 53], [79, 83, 84, 84, 85, 86, 84, 84, 82, 81, 77, 72, 58, 62, 69, 61, 64, 62, 54, 50], [74, 64, 78, 73, 73, 72, 69, 74, 70, 63, 70, 72, 69, 65, 58, 63, 63, 50, 44, 43], [71, 64, 78, 78, 74, 76, 73, 72, 72, 70, 69, 66, 56, 55, 50, 51, 36, 40, 37, 28], [70, 75, 81, 84, 84, 81, 79, 77, 75, 69, 62, 59, 65, 70, 69, 49, 60, 42, 42, 39], [67, 71, 74, 75, 74, 72, 72, 72, 66, 70, 65, 58, 43, 51, 58, 55, 53, 47, 39, 33], [74, 79, 81, 79, 79, 79, 79, 79, 77, 74, 71, 66, 69, 70, 63, 58, 57, 50, 44, 28], [68, 70, 67, 68, 69, 68, 65, 66, 68, 67, 64, 58, 61, 63, 53, 55, 47, 39, 32, 19], [65, 73, 74, 72, 76, 70, 73, 61, 66, 70, 66, 61, 58, 59, 59, 49, 52, 45, 34, 26], [66, 70, 65, 67, 70, 70, 70, 72, 70, 67, 65, 55, 61, 63, 39, 57, 51, 45, 34, 22], [71, 68, 67, 67, 66, 74, 73, 73, 75, 74, 64, 59, 66, 56, 66, 47, 43, 36, 26, 21], [56, 62, 65, 66, 65, 64, 63, 62, 58, 55, 57, 58, 57, 55, 52, 44, 24, 20, 0, 4], [56, 63, 64, 57, 61, 59, 58, 56, 54, 52, 50, 55, 55, 34, 47, 37, 33, 28, 19, 3], [55, 61, 60, 61, 62, 61, 60, 59, 56, 47, 53, 53, 43, 48, 43, 32, 31, 24, 14, 15], [54, 57, 56, 59, 60, 58, 53, 52, 54, 51, 50, 51, 52, 41, 43, 31, 31, 22, 10, 7], [52, 58, 57, 56, 61, 62, 62, 62, 62, 60, 54, 55, 56, 49, 47, 36, 30, 27, 15, 13], [77, 82, 86, 87, 86, 86, 86, 87, 86, 85, 82, 80, 76, 73, 66, 59, 46, 52, 56, 52], [52, 57, 51, 62, 64, 65, 68, 68, 69, 69, 68, 66, 64, 65, 67, 66, 58, 56, 53, 36], [49, 37, 39, 42, 48, 51, 54, 54, 53, 52, 50, 48, 42, 40, 36, 37, 31, 32, 38, 34], [46, 49, 50, 53, 55, 55, 55, 55, 55, 54, 53, 50, 45, 46, 47, 40, 24, 40, 38, 27], [42, 47, 49, 50, 50, 51, 51, 50, 50, 48, 46, 44, 42, 42, 39, 39, 32, 31, 28, 25], [16, 21, 25, 29, 18, 28, 28, 25, 26, 29, 33, 31, 16, 27, 22, 18, 27, 20, 21, 13], [5, 24, 21, 27, 26, 22, 26, 29, 28, 29, 27, 27, 26, 22, 17, 16, 14, 8, 14, 10], [14, 21, 18, 17, 17, 8, 10, 19, 13, 7, 17, 17, 20, 16, 12, 8, 15, 12, 12, 18], [20, 23, 27, 28, 24, 26, 22, 20, 13, 21, 20, 21, 20, 17, 8, 16, 10, 13, 8, 12], [20, 18, 26, 23, 16, 23, 12, 10, 8, 5, 14, 13, 14, 10, 13, 15, 17, 14, 15, 18], [20, 22, 27, 12, 21, 12, 16, 21, 15, 14, 17, 12, 17, 15, 6, 17, 16, 14, 3, 5], [19, 22, 20, 22, 19, 23, 19, 22, 11, 22, 9, 23, 13, 14, 6, 14, 17, 18, 7, 17], [25, 14, 25, 24, 15, 22, 11, 22, 17, 9, 17, 14, 13, 10, 12, 14, 10, 14, 0, 4], [12, 7, 19, 22, 16, 8, 10, 0, 19, 6, 13, 5, 15, 17, 10, 13, 12, 7, 9, 6], [11, 10, 13, 24, 13, 20, 12, 12, 12, 5, 9, 10, 12, 12, 18, 17, 11, 8, 14, 11], [11, 14, 10, 18, 11, 13, 4, 3, 6, 14, 16, 14, 15, 11, 12, 12, 8, 0, 0, 12], [6, 15, 9, 13, 0, 12, 9, 2, 5, 12, 10, 5, 0, 11, 1, 16, 9, 18, 13, 7], [6, 16, 8, 17, 13, 14, 4, 4, 11, 11, 0, 9, 18, 6, 0, 6, 9, 18, 16, 10], [17, 9, 15, 21, 10, 10, 5, 14, 8, 11, 14, 8, 0, 9, 1, 6, 10, 6, 12, 2], [16, 19, 16, 10, 15, 14, 20, 8, 12, 9, 15, 15, 11, 17, 7, 16, 8, 5, 13, 15], [86, 91, 96, 99, 97, 97, 97, 97, 97, 96, 93, 91, 88, 84, 77, 69, 62, 58, 64, 62], [70, 72, 74, 80, 85, 85, 89, 89, 89, 89, 88, 86, 81, 77, 75, 75, 73, 73, 65, 56], [71, 66, 64, 67, 70, 75, 77, 78, 76, 76, 74, 72, 68, 66, 63, 58, 58, 45, 50, 43], [69, 70, 72, 76, 78, 78, 77, 77, 77, 76, 74, 72, 68, 68, 68, 62, 51, 57, 59, 47], [72, 77, 79, 80, 81, 82, 81, 81, 80, 79, 78, 76, 71, 63, 51, 52, 58, 52, 49, 44], [57, 59, 61, 66, 63, 66, 67, 67, 67, 67, 65, 63, 58, 51, 46, 41, 46, 48, 36, 30], [51, 62, 62, 62, 65, 66, 66, 67, 67, 67, 66, 65, 60, 52, 51, 44, 51, 35, 38, 31], [46, 47, 50, 45, 47, 47, 50, 50, 50, 49, 50, 49, 45, 40, 37, 33, 27, 26, 17, 17], [45, 53, 51, 50, 50, 48, 47, 45, 39, 45, 40, 40, 38, 25, 39, 32, 25, 17, 11, 8], [28, 38, 38, 36, 35, 36, 35, 29, 25, 25, 33, 32, 27, 20, 23, 22, 11, 9, 9, 17], [40, 38, 40, 44, 41, 41, 39, 37, 36, 35, 38, 43, 42, 34, 17, 29, 21, 23, 13, 11], [23, 32, 37, 41, 41, 42, 40, 40, 38, 32, 32, 37, 31, 32, 20, 25, 21, 23, 13, 21], [33, 29, 23, 32, 32, 37, 36, 35, 32, 29, 22, 21, 25, 26, 17, 23, 6, 12, 15, 9], [35, 38, 35, 16, 32, 27, 34, 28, 32, 25, 24, 20, 21, 18, 13, 18, 11, 13, 13, 11], [24, 31, 33, 34, 33, 33, 34, 33, 33, 29, 18, 16, 24, 8, 13, 9, 8, 3, 9, 3], [1
gitextract_vrmra0ai/
├── .claude/
│ └── launch.json
├── .github/
│ └── workflows/
│ ├── arduino.yml
│ ├── c-cpp.yml
│ └── godot-addon.yml
├── .gitignore
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Makefile
├── README.md
├── amy/
│ ├── __init__.py
│ ├── constants.py
│ ├── examples.py
│ ├── fm.py
│ ├── headers.py
│ ├── juno.py
│ ├── piano.py
│ ├── piano_params.py
│ ├── sineclock.py
│ ├── test.py
│ ├── timing.py
│ ├── wave.py
│ └── xanadu.py
├── daisy/
│ ├── Makefile
│ └── amy_daisy.cpp
├── docs/
│ ├── amy.aw.js
│ ├── amy.graffle
│ ├── amy.js
│ ├── amy.wasm
│ ├── amy.ww.js
│ ├── amyrepl.css
│ ├── amyrepl.js
│ ├── api.md
│ ├── arduino.md
│ ├── billie_jean.md
│ ├── chunk.py
│ ├── enable-threads.js
│ ├── godot.md
│ ├── index.html
│ ├── juno_patches.md
│ ├── micropython.mjs
│ ├── micropython.wasm
│ ├── midi.md
│ ├── minimal.html
│ ├── piano.html
│ ├── repl.html
│ ├── server.py
│ ├── style.css
│ ├── synth.md
│ ├── tutorial.html
│ └── upgrading.md
├── examples/
│ ├── AMY_ESP32_manual_I2S/
│ │ └── AMY_ESP32_manual_I2S.ino
│ ├── AMY_MIDI_Synth/
│ │ └── AMY_MIDI_Synth.ino
│ ├── AMY_USB_Host_MIDI/
│ │ └── AMY_USB_Host_MIDI.ino
│ ├── AMY_custom_osc/
│ │ └── AMY_custom_osc.ino
│ ├── AMY_pico_PWM/
│ │ └── AMY_pico_PWM.ino
│ ├── BillieJeanDrums/
│ │ └── BillieJeanDrums.ino
│ ├── BillieJeanDrumsBass/
│ │ └── BillieJeanDrumsBass.ino
│ └── BillieJeanScheduled/
│ └── BillieJeanScheduled.ino
├── experiments/
│ ├── Piano.ff.D5.json
│ ├── compare_test_wavs.ipynb
│ ├── dx7_simulator.py
│ ├── make_piano_examples.ipynb
│ ├── piano-params.json
│ ├── piano-partials.ipynb
│ ├── piano_examples.py
│ ├── piano_heterodyne.ipynb
│ ├── piano_params.py
│ ├── track02-C4-bps.json
│ └── tulip_piano.py
├── godot/
│ ├── SConstruct
│ ├── amy.gd
│ ├── amy.gdextension
│ ├── install.gd
│ ├── src/
│ │ ├── amy_gdextension.cpp
│ │ ├── amy_gdextension.h
│ │ ├── amy_platform_stubs.c
│ │ ├── register_types.cpp
│ │ └── register_types.h
│ └── web/
│ ├── custom_shell.html
│ └── godot_amy_bridge.js
├── library.properties
├── pyproject.toml
├── requirements.txt
├── scripts/
│ ├── gen_amy_js_api.py
│ └── gen_patches_js.py
├── setup.py
├── setup_godot.sh
├── sounds/
│ └── HS-TR-808-Drums.sf2
├── src/
│ ├── AMY-Arduino.h
│ ├── algorithms.c
│ ├── amy-example.c
│ ├── amy-message.c
│ ├── amy-piano.c
│ ├── amy.c
│ ├── amy.h
│ ├── amy_connector.js
│ ├── amy_fixedpoint.h
│ ├── amy_midi.c
│ ├── amy_midi.h
│ ├── api.c
│ ├── clipping_lookup_table.h
│ ├── custom.c
│ ├── delay.c
│ ├── delay.h
│ ├── envelope.c
│ ├── examples.c
│ ├── examples.h
│ ├── filters.c
│ ├── i2s.c
│ ├── instrument.c
│ ├── interp_partials.c
│ ├── interp_partials.h
│ ├── libminiaudio-audio.c
│ ├── libminiaudio-audio.h
│ ├── log2_exp2.c
│ ├── log2_exp2_fxpt_lutable.h
│ ├── macos_midi.m
│ ├── midi_mappings.c
│ ├── miniaudio.h
│ ├── oscillators.c
│ ├── parse.c
│ ├── patches.c
│ ├── patches.h
│ ├── pcm.c
│ ├── pcm_samples_tiny.h
│ ├── pcm_tiny.h
│ ├── pico-audio/
│ │ ├── audio.cpp
│ │ ├── audio.h
│ │ ├── audio_i2s.c
│ │ ├── audio_i2s.h
│ │ ├── audio_i2s.pio
│ │ ├── audio_i2s.pio.h
│ │ ├── buffer.c
│ │ ├── buffer.h
│ │ └── sample_conversion.h
│ ├── pico_extras_import.cmake
│ ├── pico_sdk_import.cmake
│ ├── pico_support.cpp
│ ├── pyamy.c
│ ├── saw_lutset_fxpt.h
│ ├── sequencer.c
│ ├── sequencer.h
│ ├── sine_lutset_fxpt.h
│ ├── teensy_support.cpp
│ ├── teensy_support.h
│ ├── transfer.c
│ ├── transfer.h
│ ├── triangle_lutset_fxpt.h
│ ├── usb.c
│ └── usb.h
├── valgrind.suppressions
└── windows/
├── CMakeLists.txt
├── README.md
├── amy_sine.c
└── build.bat
Showing preview only (494K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5164 symbols across 76 files)
FILE: amy/__init__.py
function _get_synth_commands_stub (line 6) | def _get_synth_commands_stub(synth):
function millis (line 40) | def millis():
function trunc (line 53) | def trunc(number):
function trunc3 (line 62) | def trunc3(number):
function trim_trailing (line 67) | def trim_trailing(vals, pred):
function parse_ctrl_coefs (line 75) | def parse_ctrl_coefs(coefs):
function parse_list_or_comma_string (line 122) | def parse_list_or_comma_string(obj):
function str_of_int (line 133) | def str_of_int(arg):
function message (line 164) | def message(**kwargs):
function send_raw (line 217) | def send_raw(m):
function log_patch (line 227) | def log_patch():
function retrieve_patch (line 233) | def retrieve_patch():
function amy_do_nothing (line 245) | def amy_do_nothing(message):
function start_store_patch (line 248) | def start_store_patch():
function stop_store_patch (line 254) | def stop_store_patch(patch):
function send (line 262) | def send(**kwargs):
function show (line 269) | def show(data):
function write (line 288) | def write(data, filename):
function play (line 294) | def play(samples):
function render (line 299) | def render(seconds):
function restart (line 308) | def restart(default_synths=0):
function inject_midi (line 312) | def inject_midi(a, b, c, d=None):
function unload_sample (line 318) | def unload_sample(patch=0):
function sysex_write (line 327) | def sysex_write(message, output_name='AMYboard'):
function b64 (line 352) | def b64(b):
function b64 (line 356) | def b64(b):
function start_sample (line 359) | def start_sample(preset=0, bus=1, max_frames=0, midinote=60, loopstart=...
function stop_sample (line 363) | def stop_sample():
function load_sample_bytes (line 366) | def load_sample_bytes(b, stereo=False, preset=0, midinote=60, loopstart=...
function disk_sample (line 382) | def disk_sample(wavfilename, preset=0, midinote=60):
function transfer_file (line 394) | def transfer_file(source_filename, dest_filename=None):
function load_sample (line 420) | def load_sample(wavfilename, preset=0, midinote=0, loopstart=0, loopend=0):
function reset (line 457) | def reset(osc=None, **kwargs):
function chorus (line 470) | def chorus(level=-1, max_delay=-1, freq=-1, amp=-1):
function reverb (line 489) | def reverb(level=-1, liveness=-1, damping=-1, xover_hz=-1):
function echo (line 508) | def echo(level=None, delay_ms=None, max_delay_ms=None, feedback=None, fi...
function get_synth_commands (line 530) | def get_synth_commands(synth, patch_num=None, dest_synth=None, num_voice...
FILE: amy/examples.py
class Patch (line 9) | class Patch:
method _new_patch_number (line 20) | def _new_patch_number(cls):
method reset (line 27) | def reset(cls):
method __init__ (line 30) | def __init__(self, **kwargs):
method __int__ (line 34) | def __int__(self):
method setup (line 38) | def setup(self, **kwargs):
class simple_sine (line 42) | class simple_sine(Patch):
method setup (line 43) | def setup(self, **kwargs):
class filter_bass (line 48) | class filter_bass(Patch):
method setup (line 49) | def setup(self, **kwargs):
class amp_lfo (line 55) | class amp_lfo(Patch):
method setup (line 56) | def setup(self, **kwargs):
class pitch_lfo (line 65) | class pitch_lfo(Patch):
method setup (line 66) | def setup(self, **kwargs):
class bass_drum (line 74) | class bass_drum(Patch):
method setup (line 75) | def setup(self, **kwargs):
class noise_snare (line 84) | class noise_snare(Patch):
method setup (line 85) | def setup(self, **kwargs):
class closed_hat (line 90) | class closed_hat(Patch):
method setup (line 91) | def setup(self, **kwargs):
function play_example_patches (line 105) | def play_example_patches(wait=1, **kwargs):
function play_baked_patches (line 130) | def play_baked_patches(wait=1, patch_total = 256, **kwargs):
function example_multimbral_synth (line 143) | def example_multimbral_synth():
function example_reset (line 149) | def example_reset(start=0):
function example_voice_alloc (line 152) | def example_voice_alloc():
function example_voice_chord (line 171) | def example_voice_chord(patch=0):
function example_synth_chord (line 186) | def example_synth_chord(patch=0):
function example_sustain_pedal (line 205) | def example_sustain_pedal(patch=0):
function example_patches (line 241) | def example_patches():
function example_reverb (line 255) | def example_reverb():
function example_chorus (line 258) | def example_chorus():
function example_ks (line 261) | def example_ks():
function example_sine (line 264) | def example_sine():
function example_multimbral_fm (line 267) | def example_multimbral_fm():
function example_sequencer_drums (line 276) | def example_sequencer_drums():
function example_fm (line 305) | def example_fm():
function example_patch_from_events (line 324) | def example_patch_from_events():
FILE: amy/fm.py
class DX7Operator (line 11) | class DX7Operator:
class DX7Patch (line 29) | class DX7Patch:
method from_patch_number (line 48) | def from_patch_number(patch_number):
method from_bytestream (line 56) | def from_bytestream(bytestream):
method get_bytestream (line 108) | def get_bytestream(self):
class AMYOscillator (line 143) | class AMYOscillator:
method from_dx7_op (line 153) | def from_dx7_op(op):
function fm_trunc (line 167) | def fm_trunc(number):
class AMYPatch (line 173) | class AMYPatch:
method from_dx7 (line 189) | def from_dx7(dx7_patch):
method send_to_AMY (line 227) | def send_to_AMY(self, reset=True):
function dx7level_to_linear (line 303) | def dx7level_to_linear(dx7level):
function linear_to_dx7level (line 307) | def linear_to_dx7level(linear):
function pitchval_to_ratio (line 311) | def pitchval_to_ratio(pitchval):
function ratio_to_pitchval (line 322) | def ratio_to_pitchval(ratio):
function calc_loglin_eg_breakpoints (line 330) | def calc_loglin_eg_breakpoints(rates, levels, dx7_attacks=True,
function eg_to_bp (line 385) | def eg_to_bp(egrate, eglevel, calc_eg_args={}):
function eg_to_bp_pitch (line 394) | def eg_to_bp_pitch(egrate, eglevel):
function coarse_fine_fixed_hz (line 399) | def coarse_fine_fixed_hz(coarse, fine, detune=7):
function coarse_fine_ratio (line 403) | def coarse_fine_ratio(coarse, fine, detune=7):
function lfo_speed_to_hz (line 409) | def lfo_speed_to_hz(byte):
function lfo_wave (line 420) | def lfo_wave(byte):
function play_np_array (line 431) | def play_np_array(np_array, samplerate=amy.AMY_SAMPLE_RATE):
FILE: amy/headers.py
function _read_wavetables (line 10) | def _read_wavetables(wavetable_files):
function generate_amy_pcm_header (line 27) | def generate_amy_pcm_header(sample_set, name, pcm_AMY_SAMPLE_RATE=22050,...
function generate_pcm_headers (line 156) | def generate_pcm_headers():
function cos_lut (line 161) | def cos_lut(table_size, harmonics_weights, harmonics_phases=None):
function create_lutset (line 174) | def create_lutset(LUTentry, harmonic_weights, harmonic_phases=None,
function make_table (line 222) | def make_table(min_val, max_val, fn, table_size=257, dtype=np.int16):
function create_exp2_lut (line 229) | def create_exp2_lut(npts):
function create_log2_lut (line 234) | def create_log2_lut(npts):
function write_lutset_to_h (line 239) | def write_lutset_to_h(filename, variable_base, lutset):
function write_fxpt_lutable (line 285) | def write_fxpt_lutable(f, lutable, name, samples_per_row=8):
function write_lutset_to_h_as_fxpt (line 304) | def write_lutset_to_h_as_fxpt(filename, variable_base, lutset):
function make_log2_exp2_luts (line 351) | def make_log2_exp2_luts(filename):
function make_clipping_lut (line 367) | def make_clipping_lut(filename):
function make_piano_patch (line 398) | def make_piano_patch():
function make_amyboard_patch (line 407) | def make_amyboard_patch():
function make_patches (line 423) | def make_patches(filename):
function write_vector_as_c (line 470) | def write_vector_as_c(f, data, name, dtype='uint8_t', items_per_row=20):
function make_interp_partials (line 480) | def make_interp_partials(filename, data_dict):
function generate_all (line 526) | def generate_all():
function main (line 581) | def main():
FILE: amy/juno.py
function exp2 (line 14) | def exp2(x):
function exp2 (line 17) | def exp2(x):
function to_attack_time (line 65) | def to_attack_time(val):
function to_decay_time (line 73) | def to_decay_time(val):
function to_release_time (line 83) | def to_release_time(val):
function to_level (line 92) | def to_level(val):
function level_to_amp (line 97) | def level_to_amp(level):
function to_lfo_freq (line 104) | def to_lfo_freq(val):
function to_lfo_delay (line 110) | def to_lfo_delay(val):
function to_resonance (line 118) | def to_resonance(val):
function to_filter_freq (line 123) | def to_filter_freq(val):
function ffmt (line 133) | def ffmt(val):
function get_juno_patch (line 139) | def get_juno_patch(patch_number):
class JunoPatch (line 153) | class JunoPatch:
method from_patch_number (line 214) | def from_patch_number(patch_number):
method from_sysex (line 219) | def from_sysex(cls, sysexbytes, name=None, patch_number=None):
method _init_from_patch_number (line 228) | def _init_from_patch_number(self, patch_number):
method _init_from_sysex (line 233) | def _init_from_sysex(self, sysexbytes):
method to_sysex (line 249) | def to_sysex(self):
method set_synth (line 273) | def set_synth(self, amy_synth):
method _breakpoint_string (line 276) | def _breakpoint_string(self):
method _amp_coef_string (line 283) | def _amp_coef_string(self, level):
method _freq_coef_string (line 286) | def _freq_coef_string(self, base_freq):
method base_freq (line 290) | def base_freq(self):
method _portamento_ms (line 299) | def _portamento_ms(self, port_val):
method init_AMY (line 305) | def init_AMY(self):
method update_lfo (line 344) | def update_lfo(self):
method update_dco (line 349) | def update_dco(self):
method update_vcf (line 385) | def update_vcf(self):
method update_env (line 407) | def update_env(self):
method update_cho (line 416) | def update_cho(self):
method set_param (line 446) | def set_param(self, param, val):
method send_deferred_params (line 455) | def send_deferred_params(self):
method set_patch (line 462) | def set_patch(self, patch):
method set_sysex (line 467) | def set_sysex(self, sysex):
method set_pitch_bend (line 472) | def set_pitch_bend(self, value):
method amy_send (line 476) | def amy_send(self, osc, **kwargs):
FILE: amy/piano.py
function piano_example (line 7) | def piano_example(base_note=72, volume=5, send_command=amy.send, init_co...
function juno_example (line 23) | def juno_example():
function dx7_example (line 27) | def dx7_example():
function harms_params_from_note_index_vel_index (line 73) | def harms_params_from_note_index_vel_index(note_index, vel_index):
function interp_harms_params (line 83) | def interp_harms_params(hp0, hp1, alpha):
function cents_to_hz (line 90) | def cents_to_hz(cents):
function db_to_lin (line 94) | def db_to_lin(d):
function harms_params_for_note_vel (line 99) | def harms_params_for_note_vel(note, vel):
function init_piano_voice (line 129) | def init_piano_voice(num_partials, base_osc=0, **kwargs):
function setup_piano_voice (line 138) | def setup_piano_voice(harms_params, base_osc=0, **kwargs):
function init_piano_voices (line 154) | def init_piano_voices(num_partials=NUM_HARMONICS[0]):
function play_piano_partials_1 (line 162) | def play_piano_partials_1():
function piano_note_on (line 166) | def piano_note_on(note=60, vel=1, **kwargs):
function play_piano_partials_2 (line 176) | def play_piano_partials_2():
FILE: amy/sineclock.py
function setup_triple (line 12) | def setup_triple(
function start_sine_clock (line 29) | def start_sine_clock(hour, minute, second, vel=0.1):
FILE: amy/test.py
function wavread (line 16) | def wavread(filename):
function rms (line 26) | def rms(samples):
function dB (line 30) | def dB(level):
class AmyTest (line 35) | class AmyTest:
method __init__ (line 40) | def __init__(self):
method test (line 43) | def test(self):
class TestSineOsc (line 71) | class TestSineOsc(AmyTest):
method run (line 73) | def run(self):
class TestPulseOsc (line 79) | class TestPulseOsc(AmyTest):
method run (line 81) | def run(self):
class TestSawDownOsc (line 87) | class TestSawDownOsc(AmyTest):
method run (line 89) | def run(self):
class TestSawUpOsc (line 95) | class TestSawUpOsc(AmyTest):
method run (line 97) | def run(self):
class TestTriangleOsc (line 103) | class TestTriangleOsc(AmyTest):
method run (line 105) | def run(self):
class TestNoiseOsc (line 111) | class TestNoiseOsc(AmyTest):
method run (line 113) | def run(self):
class TestPcm (line 120) | class TestPcm(AmyTest):
method run (line 122) | def run(self):
class TestPcmShift (line 127) | class TestPcmShift(AmyTest):
method run (line 129) | def run(self):
class TestPcmPatchChange (line 137) | class TestPcmPatchChange(AmyTest):
method run (line 140) | def run(self):
class TestPcmLoop (line 147) | class TestPcmLoop(AmyTest):
method run (line 149) | def run(self):
class TestPcmLoopEnvFilt (line 155) | class TestPcmLoopEnvFilt(AmyTest):
method run (line 158) | def run(self):
class TestBuildYourOwnPartials (line 168) | class TestBuildYourOwnPartials(AmyTest):
method run (line 170) | def run(self):
class TestBYOPVoices (line 186) | class TestBYOPVoices(AmyTest):
method run (line 188) | def run(self):
class TestBYOPNoteOff (line 204) | class TestBYOPNoteOff(AmyTest):
method run (line 206) | def run(self):
class TestInterpPartials (line 220) | class TestInterpPartials(AmyTest):
method run (line 222) | def run(self):
class TestInterpPartialsRetrigger (line 235) | class TestInterpPartialsRetrigger(AmyTest):
method run (line 237) | def run(self):
class TestSineEnv (line 253) | class TestSineEnv(AmyTest):
method run (line 255) | def run(self):
class TestSineEnv2 (line 262) | class TestSineEnv2(AmyTest):
method run (line 264) | def run(self):
class TestSineAM (line 275) | class TestSineAM(AmyTest):
method run (line 278) | def run(self):
class TestAlgo (line 287) | class TestAlgo(AmyTest):
method run (line 289) | def run(self):
class TestAlgo2 (line 295) | class TestAlgo2(AmyTest):
method run (line 297) | def run(self):
class TestWoodPiano (line 304) | class TestWoodPiano(AmyTest):
method run (line 307) | def run(self):
class TestFMRepeat (line 327) | class TestFMRepeat(AmyTest):
method run (line 330) | def run(self):
class TestXanaduFM (line 338) | class TestXanaduFM(AmyTest):
method run (line 341) | def run(self):
class TestFilter (line 353) | class TestFilter(AmyTest):
method run (line 355) | def run(self):
class TestFilter24 (line 361) | class TestFilter24(AmyTest):
method run (line 363) | def run(self):
class TestFilterLFO (line 369) | class TestFilterLFO(AmyTest):
method run (line 371) | def run(self):
class TestLFO (line 378) | class TestLFO(AmyTest):
method run (line 380) | def run(self):
class TestDuty (line 390) | class TestDuty(AmyTest):
method run (line 392) | def run(self):
class TestPWM (line 401) | class TestPWM(AmyTest):
method run (line 403) | def run(self):
class TestGlobalEQ (line 410) | class TestGlobalEQ(AmyTest):
method run (line 412) | def run(self):
class TestChorus (line 419) | class TestChorus(AmyTest):
method run (line 421) | def run(self):
class TestBrass (line 430) | class TestBrass(AmyTest):
method run (line 433) | def run(self):
class TestBrassAlt (line 456) | class TestBrassAlt(AmyTest):
method run (line 459) | def run(self):
class TestBrass2 (line 478) | class TestBrass2(AmyTest):
method run (line 481) | def run(self):
class TestGuitar (line 490) | class TestGuitar(AmyTest):
method run (line 493) | def run(self):
class TestBleep (line 505) | class TestBleep(AmyTest):
method run (line 508) | def run(self):
class TestOverload (line 515) | class TestOverload(AmyTest):
method run (line 518) | def run(self):
class TestJunoPatch (line 526) | class TestJunoPatch(AmyTest):
method run (line 529) | def run(self):
class TestJunoClip (line 542) | class TestJunoClip(AmyTest):
method run (line 545) | def run(self):
class TestLowVcf (line 557) | class TestLowVcf(AmyTest):
method run (line 560) | def run(self):
class TestLowerVcf (line 571) | class TestLowerVcf(AmyTest):
method run (line 574) | def run(self):
class TestFlutesEq (line 585) | class TestFlutesEq(AmyTest):
method run (line 588) | def run(self):
class TestOscBD (line 603) | class TestOscBD(AmyTest):
method run (line 606) | def run(self):
class TestChainedOsc (line 616) | class TestChainedOsc(AmyTest):
method run (line 619) | def run(self):
class TestJunoTrumpetPatch (line 635) | class TestJunoTrumpetPatch(AmyTest):
method run (line 638) | def run(self):
class TestJunoCheapTrumpetPatch (line 646) | class TestJunoCheapTrumpetPatch(AmyTest):
method run (line 649) | def run(self):
class TestFilterReleaseGlitch (line 658) | class TestFilterReleaseGlitch(AmyTest):
method run (line 661) | def run(self):
class TestPortamento (line 667) | class TestPortamento(AmyTest):
method run (line 669) | def run(self):
class TestEcho (line 688) | class TestEcho(AmyTest):
method run (line 690) | def run(self):
class TestEchoLPF (line 697) | class TestEchoLPF(AmyTest):
method run (line 699) | def run(self):
class TestEchoHPF (line 706) | class TestEchoHPF(AmyTest):
method run (line 708) | def run(self):
class TestVoiceManagement (line 715) | class TestVoiceManagement(AmyTest):
method run (line 718) | def run(self):
class TestVoiceStealing (line 737) | class TestVoiceStealing(AmyTest):
method __init__ (line 740) | def __init__(self):
method run (line 744) | def run(self):
class TestVoiceStealDecay (line 769) | class TestVoiceStealDecay(AmyTest):
method run (line 772) | def run(self):
class TestVoiceStealClick (line 790) | class TestVoiceStealClick(AmyTest):
method run (line 793) | def run(self):
class TestOwBassClick (line 805) | class TestOwBassClick(AmyTest):
method run (line 808) | def run(self):
class TestMidiDrums (line 826) | class TestMidiDrums(AmyTest):
method __init__ (line 829) | def __init__(self):
method run (line 833) | def run(self):
class TestDrumsVoiceStealing (line 842) | class TestDrumsVoiceStealing(AmyTest):
method __init__ (line 845) | def __init__(self):
method run (line 849) | def run(self):
class TestDefaultChan1Synth (line 858) | class TestDefaultChan1Synth(AmyTest):
method __init__ (line 861) | def __init__(self):
method run (line 865) | def run(self):
class TestSynthProgChange (line 876) | class TestSynthProgChange(AmyTest):
method __init__ (line 879) | def __init__(self):
method run (line 883) | def run(self):
class TestSynthDrums (line 896) | class TestSynthDrums(AmyTest):
method __init__ (line 899) | def __init__(self):
method run (line 903) | def run(self):
class TestSynthFlags (line 911) | class TestSynthFlags(AmyTest):
method run (line 914) | def run(self):
class TestDoubleNoteOff (line 925) | class TestDoubleNoteOff(AmyTest):
method run (line 928) | def run(self):
class TestSustainPedal (line 935) | class TestSustainPedal(AmyTest):
method run (line 938) | def run(self):
class TestPatchFromEvents (line 953) | class TestPatchFromEvents(AmyTest):
method __init__ (line 956) | def __init__(self):
method run (line 960) | def run(self):
class TestInvalidPatchNumber (line 972) | class TestInvalidPatchNumber(AmyTest):
method run (line 975) | def run(self):
class TestBreakpointsRealloc (line 988) | class TestBreakpointsRealloc(AmyTest):
method run (line 991) | def run(self):
class TestFileTransfer (line 997) | class TestFileTransfer(AmyTest):
method test (line 999) | def test(self):
class TestDiskSample (line 1021) | class TestDiskSample(AmyTest):
method run (line 1023) | def run(self):
class TestDiskSampleWithSilentGap (line 1028) | class TestDiskSampleWithSilentGap(AmyTest):
method run (line 1030) | def run(self):
class TestRestartFileSample (line 1035) | class TestRestartFileSample(AmyTest):
method run (line 1037) | def run(self):
class TestDiskSampleStereo (line 1043) | class TestDiskSampleStereo(AmyTest):
method run (line 1045) | def run(self):
class TestLoadSample (line 1052) | class TestLoadSample(AmyTest):
method run (line 1059) | def run(self):
class TestSample (line 1064) | class TestSample(AmyTest):
method run (line 1066) | def run(self):
class TestParamsInPatchCmd (line 1082) | class TestParamsInPatchCmd(AmyTest):
method run (line 1084) | def run(self):
class TestHPFHighBaseFreq (line 1096) | class TestHPFHighBaseFreq(AmyTest):
method run (line 1098) | def run(self):
class TestWavetable (line 1110) | class TestWavetable(AmyTest):
method run (line 1113) | def run(self):
class TestCopyingSynthConfig (line 1119) | class TestCopyingSynthConfig(AmyTest):
method __init__ (line 1122) | def __init__(self):
method run (line 1126) | def run(self):
class TestGetSynthCommandsGetsMidiCcs (line 1141) | class TestGetSynthCommandsGetsMidiCcs(AmyTest):
method test (line 1143) | def test(self):
class TestClearMidiCCs (line 1167) | class TestClearMidiCCs(AmyTest):
method test (line 1170) | def test(self):
class TestClearOneMidiCC (line 1193) | class TestClearOneMidiCC(AmyTest):
method test (line 1196) | def test(self):
class TestResetOscs (line 1220) | class TestResetOscs(AmyTest):
method run (line 1223) | def run(self):
class TestPreset257 (line 1230) | class TestPreset257(AmyTest):
method run (line 1233) | def run(self):
class TestChangeSustain (line 1239) | class TestChangeSustain(AmyTest):
method run (line 1242) | def run(self):
function float_or_val (line 1249) | def float_or_val(str, error_val=None):
class TestResetPreset (line 1257) | class TestResetPreset(AmyTest):
method run (line 1260) | def run(self):
function main (line 1269) | def main(argv):
FILE: amy/timing.py
function wavread (line 10) | def wavread(filename):
function rms (line 20) | def rms(samples):
function dB (line 24) | def dB(level):
class AmyTest (line 29) | class AmyTest:
method __init__ (line 34) | def __init__(self):
method test (line 38) | def test(self):
class TestSineOsc (line 61) | class TestSineOsc(AmyTest):
method run (line 63) | def run(self):
class TestPulseOsc (line 69) | class TestPulseOsc(AmyTest):
method run (line 71) | def run(self):
class TestSawDownOsc (line 77) | class TestSawDownOsc(AmyTest):
method run (line 79) | def run(self):
class TestSawUpOsc (line 85) | class TestSawUpOsc(AmyTest):
method run (line 87) | def run(self):
class TestTriangleOsc (line 93) | class TestTriangleOsc(AmyTest):
method run (line 95) | def run(self):
class TestNoiseOsc (line 101) | class TestNoiseOsc(AmyTest):
method run (line 103) | def run(self):
class TestPcm (line 110) | class TestPcm(AmyTest):
method run (line 112) | def run(self):
class TestPcmShift (line 117) | class TestPcmShift(AmyTest):
method run (line 119) | def run(self):
class TestSineEnv (line 128) | class TestSineEnv(AmyTest):
method run (line 130) | def run(self):
class TestFilter (line 138) | class TestFilter(AmyTest):
method run (line 140) | def run(self):
class TestFilterLFO (line 146) | class TestFilterLFO(AmyTest):
method run (line 148) | def run(self):
class TestLFO (line 155) | class TestLFO(AmyTest):
method run (line 157) | def run(self):
class TestDuty (line 167) | class TestDuty(AmyTest):
method run (line 169) | def run(self):
class TestPWM (line 178) | class TestPWM(AmyTest):
method run (line 180) | def run(self):
class TestGlobalEQ (line 187) | class TestGlobalEQ(AmyTest):
method run (line 189) | def run(self):
class TestChorus (line 196) | class TestChorus(AmyTest):
method run (line 198) | def run(self):
class TestBrass (line 207) | class TestBrass(AmyTest):
method run (line 210) | def run(self):
class TestBrass2 (line 232) | class TestBrass2(AmyTest):
method run (line 235) | def run(self):
class TestGuitar (line 242) | class TestGuitar(AmyTest):
method run (line 245) | def run(self):
class TestBleep (line 255) | class TestBleep(AmyTest):
method run (line 258) | def run(self):
class TestTiming (line 264) | class TestTiming(AmyTest):
method run (line 267) | def run(self):
class TestJunoPatch (line 286) | class TestJunoPatch(AmyTest):
method run (line 289) | def run(self):
class TestJunoPatch3 (line 300) | class TestJunoPatch3(AmyTest):
method run (line 303) | def run(self):
function main (line 309) | def main(argv):
FILE: amy/wave.py
class Error (line 78) | class Error(Exception):
class Chunk (line 93) | class Chunk:
method __init__ (line 94) | def __init__(self, file, align=True, bigendian=True, inclheader=False):
method getname (line 116) | def getname(self):
method getsize (line 119) | def getsize(self):
method close (line 122) | def close(self):
method isatty (line 129) | def isatty(self):
method seek (line 134) | def seek(self, pos, whence=0):
method tell (line 148) | def tell(self):
method read (line 153) | def read(self, size=-1):
method skip (line 170) | def skip(self):
class Wave_read (line 192) | class Wave_read:
method initfp (line 223) | def initfp(self, file):
method __init__ (line 256) | def __init__(self, f):
method __del__ (line 269) | def __del__(self):
method __enter__ (line 272) | def __enter__(self):
method __exit__ (line 275) | def __exit__(self, *args):
method getfp (line 281) | def getfp(self):
method rewind (line 284) | def rewind(self):
method close (line 288) | def close(self):
method tell (line 294) | def tell(self):
method getnchannels (line 297) | def getnchannels(self):
method getnframes (line 300) | def getnframes(self):
method getsampwidth (line 303) | def getsampwidth(self):
method getframerate (line 306) | def getframerate(self):
method getcomptype (line 309) | def getcomptype(self):
method getcompname (line 312) | def getcompname(self):
method getparams (line 315) | def getparams(self):
method getmarkers (line 320) | def getmarkers(self):
method getmark (line 323) | def getmark(self, id):
method setpos (line 326) | def setpos(self, pos):
method readframes (line 332) | def readframes(self, nframes):
method _read_smpl_chunk (line 352) | def _read_smpl_chunk(self, chunk):
method _read_fmt_chunk (line 357) | def _read_fmt_chunk(self, chunk):
class Wave_write (line 368) | class Wave_write:
method __init__ (line 394) | def __init__(self, f):
method initfp (line 406) | def initfp(self, file):
method __del__ (line 418) | def __del__(self):
method __enter__ (line 421) | def __enter__(self):
method __exit__ (line 424) | def __exit__(self, *args):
method setnchannels (line 430) | def setnchannels(self, nchannels):
method getnchannels (line 437) | def getnchannels(self):
method setsampwidth (line 442) | def setsampwidth(self, sampwidth):
method getsampwidth (line 449) | def getsampwidth(self):
method setframerate (line 454) | def setframerate(self, framerate):
method getframerate (line 461) | def getframerate(self):
method setnframes (line 466) | def setnframes(self, nframes):
method getnframes (line 471) | def getnframes(self):
method setcomptype (line 474) | def setcomptype(self, comptype, compname):
method getcomptype (line 482) | def getcomptype(self):
method getcompname (line 485) | def getcompname(self):
method setparams (line 488) | def setparams(self, params):
method getparams (line 498) | def getparams(self):
method setmark (line 504) | def setmark(self, id, pos, name):
method getmark (line 507) | def getmark(self, id):
method getmarkers (line 510) | def getmarkers(self):
method tell (line 513) | def tell(self):
method writeframesraw (line 516) | def writeframesraw(self, data):
method writeframes (line 529) | def writeframes(self, data):
method close (line 534) | def close(self):
method _ensure_header_written (line 551) | def _ensure_header_written(self, datasize):
method _write_header (line 561) | def _write_header(self, initlength):
method _patchheader (line 582) | def _patchheader(self):
function open (line 594) | def open(f, mode=None):
FILE: amy/xanadu.py
function pitch2freq (line 24) | def pitch2freq(pitch):
function pitch2note (line 32) | def pitch2note(pitch):
function shift_pitch (line 37) | def shift_pitch(pitch, shift):
function amy_message_of_send_args (line 49) | def amy_message_of_send_args(list_of_arg_dicts):
function note1_patch (line 57) | def note1_patch(pan=0.5):
function note2_patch (line 72) | def note2_patch(pitch_dev=0.1, pan=0.5):
function fm_note_patch (line 86) | def fm_note_patch(duration=7.5):
function synth_note_on (line 96) | def synth_note_on(synth=0, note=60, vel=1, timestamp=0):
function Note (line 99) | def Note(pitch, vel=1.0, time=0, pitch_shift=0, second_delay=200, use_th...
function NoteFM (line 109) | def NoteFM(pitch, vel=1.0, time=0, duration=8000):
function broken_chord (line 117) | def broken_chord(base_pitch, intervals, start_time, **kwargs):
function xanadu_init (line 124) | def xanadu_init():
function loop (line 164) | def loop():
FILE: daisy/amy_daisy.cpp
function AudioCallback (line 19) | void AudioCallback(AudioHandle::InterleavingInputBuffer in,
function test_audio_in (line 38) | void test_audio_in() {
function midi_polyphony (line 54) | void midi_polyphony(uint32_t start, uint16_t patch) {
function event_polyphony (line 68) | void event_polyphony(uint32_t start, uint16_t patch) {
function HandleMidiMessage (line 91) | void HandleMidiMessage(MidiEvent m) {
function sequencer_timer_callback (line 125) | void sequencer_timer_callback(void* arg) {
function init_sequencer (line 129) | void init_sequencer() {
function main (line 151) | int main(void)
FILE: docs/amy.aw.js
function createWasmAudioWorkletProcessor (line 15) | function createWasmAudioWorkletProcessor(audioParams) {
class BootstrapMessages (line 140) | class BootstrapMessages extends AudioWorkletProcessor {
method constructor (line 141) | constructor(arg) {
method process (line 198) | process() {
FILE: docs/amy.js
function locateFile (line 1) | function locateFile(path){if(Module["locateFile"]){return Module["locate...
function growMemViews (line 1) | function growMemViews(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemory...
function startWasmWorker (line 1) | function startWasmWorker(props){wwParams=props;wasmMemory=props.wasmMemo...
function wrapMsgHandler (line 1) | function wrapMsgHandler(h){var f=wrappedHandlers.get(h);if(!f){f=msg=>h(...
function createWasmAudioWorkletProcessor (line 1) | function createWasmAudioWorkletProcessor(audioParams){class WasmAudioWor...
class BootstrapMessages (line 1) | class BootstrapMessages extends AudioWorkletProcessor{constructor(arg){s...
method constructor (line 1) | constructor(arg){super();startWasmWorker(arg.processorOptions);if(!(po...
method process (line 1) | process(){}
function updateMemoryViews (line 1) | function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array...
function initMemory (line 1) | function initMemory(){if(ENVIRONMENT_IS_WASM_WORKER){return}if(Module["w...
function preRun (line 1) | function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="func...
function initRuntime (line 1) | function initRuntime(){runtimeInitialized=true;if(ENVIRONMENT_IS_WASM_WO...
function postRun (line 1) | function postRun(){if(ENVIRONMENT_IS_WASM_WORKER){return}if(Module["post...
function abort (line 1) | function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";...
function findWasmBinary (line 1) | function findWasmBinary(){return locateFile("amy.wasm")}
function getBinarySync (line 1) | function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return...
function getWasmBinary (line 1) | async function getWasmBinary(binaryFile){if(!wasmBinary){try{var respons...
function instantiateArrayBuffer (line 1) | async function instantiateArrayBuffer(binaryFile,imports){try{var binary...
function instantiateAsync (line 1) | async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!...
function getWasmImports (line 1) | function getWasmImports(){assignWasmImports();var imports={a:wasmImports...
function createWasm (line 1) | async function createWasm(){function receiveInstance(instance,module){wa...
class ExitStatus (line 1) | class ExitStatus{name="ExitStatus";constructor(status){this.message=`Pro...
method constructor (line 1) | constructor(status){this.message=`Program terminated with exit(${statu...
method constructor (line 1) | constructor(message){super(message);this.name="BindingError"}
function sharedRegisterType (line 1) | function sharedRegisterType(rawType,registeredInstance,options={}){var n...
function registerType (line 1) | function registerType(rawType,registeredInstance,options={}){return shar...
function readPointer (line 1) | function readPointer(pointer){return this.fromWireType((growMemViews(),H...
function decodeMemoryView (line 1) | function decodeMemoryView(handle){var size=(growMemViews(),HEAPU32)[hand...
method fromWireType (line 1) | fromWireType(value){var length=(growMemViews(),HEAPU32)[value>>2];var pa...
method toWireType (line 1) | toWireType(destructors,value){if(value instanceof ArrayBuffer){value=new...
method destructorFunction (line 1) | destructorFunction(ptr){_free(ptr)}
method destructorFunction (line 1) | destructorFunction(ptr){_free(ptr)}
function checkIsRunning (line 1) | function checkIsRunning(){if(thisMainLoopId<MainLoop.currentlyRunningMai...
method pause (line 1) | pause(){MainLoop.scheduler=null;MainLoop.currentlyRunningMainloop++}
method resume (line 1) | resume(){MainLoop.currentlyRunningMainloop++;var timingMode=MainLoop.tim...
method updateStatus (line 1) | updateStatus(){if(Module["setStatus"]){var message=Module["statusMessage...
method init (line 1) | init(){Module["preMainLoop"]&&MainLoop.preMainLoop.push(Module["preMainL...
method runIter (line 1) | runIter(func){if(ABORT)return;for(var pre of MainLoop.preMainLoop){if(pr...
method fakeRequestAnimationFrame (line 1) | fakeRequestAnimationFrame(func){var now=Date.now();if(MainLoop.nextRAF==...
method requestAnimationFrame (line 1) | requestAnimationFrame(func){if(globalThis.requestAnimationFrame){request...
function readRenderSizeHint (line 1) | function readRenderSizeHint(val){return val<0?"hardware":val||"default"}
function readChannelCountArray (line 1) | function readChannelCountArray(heapIndex,numOutputs){if(!heapIndex)retur...
function _fd_seek (line 1) | function _fd_seek(fd,offset,whence,newOffset){offset=bigintToI53Checked(...
method instrumentWasmImports (line 1) | instrumentWasmImports(imports){var importPattern=/^(invoke_.*|__asyncjs_...
method instrumentFunction (line 1) | instrumentFunction(original){var wrapper=(...args)=>{Asyncify.exportCall...
method instrumentWasmExports (line 1) | instrumentWasmExports(exports){var ret={};for(let[x,original]of Object.e...
method getCallStackId (line 1) | getCallStackId(func){if(!Asyncify.callstackFuncToId.has(func)){var id=As...
method maybeStopUnwind (line 1) | maybeStopUnwind(){if(Asyncify.currData&&Asyncify.state===Asyncify.State....
method whenDone (line 1) | whenDone(){return new Promise((resolve,reject)=>{Asyncify.asyncPromiseHa...
method allocateData (line 1) | allocateData(){var ptr=_malloc(12+Asyncify.StackSize);Asyncify.setDataHe...
method setDataHeader (line 1) | setDataHeader(ptr,stack,stackSize){(growMemViews(),HEAPU32)[ptr>>2]=stac...
method setDataRewindFunc (line 1) | setDataRewindFunc(ptr){var bottomOfCallStack=Asyncify.exportCallStack[0]...
method getDataRewindFunc (line 1) | getDataRewindFunc(ptr){var id=(growMemViews(),HEAP32)[ptr+8>>2];var func...
method doRewind (line 1) | doRewind(ptr){var original=Asyncify.getDataRewindFunc(ptr);var func=Asyn...
method handleSleep (line 1) | handleSleep(startAsync){if(ABORT)return;if(Asyncify.state===Asyncify.Sta...
function convertReturnValue (line 1) | function convertReturnValue(ret){if(returnType==="string"){return UTF8To...
function onDone (line 1) | function onDone(ret){runtimeKeepalivePop();if(stack!==0)stackRestore(sta...
function assignWasmExports (line 1) | function assignWasmExports(wasmExports){_free=Module["_free"]=wasmExport...
function assignWasmImports (line 1) | function assignWasmImports(){wasmImports={b:___assert_fail,A:__abort_js,...
function run (line 1) | function run(){if(ENVIRONMENT_IS_WASM_WORKER){readyPromiseResolve?.(Modu...
function amy_js_start (line 65) | async function amy_js_start() {
function setup_midi_devices (line 82) | async function setup_midi_devices() {
function start_midi (line 100) | async function start_midi() {
function sleep_ms (line 136) | async function sleep_ms(ms) {
function toggle_audioin (line 141) | async function toggle_audioin() {
function _str_of_int (line 281) | function _str_of_int(arg) {
function _trunc (line 285) | function _trunc(number) {
function _parse_list (line 299) | function _parse_list(obj) {
function _trim_trailing (line 306) | function _trim_trailing(arr) {
function _parse_ctrl_coefs (line 312) | function _parse_ctrl_coefs(coefs) {
function amy_message (line 355) | function amy_message(params) {
function amy_send (line 391) | function amy_send(params, log) {
FILE: docs/amy.ww.js
function wrapMsgHandler (line 21) | function wrapMsgHandler(h) {
FILE: docs/amyrepl.js
function start_python_and_amy (line 9) | async function start_python_and_amy() {
function run_async (line 14) | async function run_async(code) {
function start_python (line 19) | async function start_python() {
function resetAMY (line 45) | async function resetAMY() {
function print_error (line 51) | async function print_error(text) {
function runCodeBlock (line 57) | async function runCodeBlock(index) {
function create_editor (line 70) | function create_editor(element, index) {
function amy_sequencer_js_hook (line 111) | function amy_sequencer_js_hook(tick) {
FILE: docs/chunk.py
class Chunk (line 51) | class Chunk:
method __init__ (line 52) | def __init__(self, file, align=True, bigendian=True, inclheader=False):
method getname (line 79) | def getname(self):
method getsize (line 83) | def getsize(self):
method close (line 87) | def close(self):
method isatty (line 92) | def isatty(self):
method seek (line 97) | def seek(self, pos, whence=0):
method tell (line 116) | def tell(self):
method read (line 121) | def read(self, size=-1):
method skip (line 144) | def skip(self):
FILE: docs/enable-threads.js
function handleFetch (line 10) | async function handleFetch(request) {
FILE: docs/micropython.mjs
function _createMicroPythonModule (line 6) | async function _createMicroPythonModule(moduleArg = {}) {
function loadMicroPython (line 5707) | async function loadMicroPython(options) {
function runCLI (line 5865) | async function runCLI() {
class PyProxy (line 5995) | class PyProxy {
method constructor (line 5996) | constructor(ref) {
method toJs (line 6001) | static toJs(js_obj) {
method isExtensible (line 6096) | isExtensible() {
method ownKeys (line 6099) | ownKeys(target) {
method getOwnPropertyDescriptor (line 6110) | getOwnPropertyDescriptor(target, prop) {
method has (line 6118) | has(target, prop) {
method get (line 6126) | get(target, prop) {
method set (line 6169) | set(target, prop, value) {
method deleteProperty (line 6181) | deleteProperty(target, prop) {
class PyProxyThenable (line 6192) | class PyProxyThenable {
method constructor (line 6193) | constructor(ref) {
method then (line 6197) | then(resolve, reject) {
constant PROXY_JS_REF_NUM_STATIC (line 6237) | const PROXY_JS_REF_NUM_STATIC = 2;
constant PROXY_KIND_MP_EXCEPTION (line 6241) | const PROXY_KIND_MP_EXCEPTION = -1;
constant PROXY_KIND_MP_NULL (line 6242) | const PROXY_KIND_MP_NULL = 0;
constant PROXY_KIND_MP_NONE (line 6243) | const PROXY_KIND_MP_NONE = 1;
constant PROXY_KIND_MP_BOOL (line 6244) | const PROXY_KIND_MP_BOOL = 2;
constant PROXY_KIND_MP_INT (line 6245) | const PROXY_KIND_MP_INT = 3;
constant PROXY_KIND_MP_FLOAT (line 6246) | const PROXY_KIND_MP_FLOAT = 4;
constant PROXY_KIND_MP_STR (line 6247) | const PROXY_KIND_MP_STR = 5;
constant PROXY_KIND_MP_CALLABLE (line 6248) | const PROXY_KIND_MP_CALLABLE = 6;
constant PROXY_KIND_MP_GENERATOR (line 6249) | const PROXY_KIND_MP_GENERATOR = 7;
constant PROXY_KIND_MP_OBJECT (line 6250) | const PROXY_KIND_MP_OBJECT = 8;
constant PROXY_KIND_MP_JSPROXY (line 6251) | const PROXY_KIND_MP_JSPROXY = 9;
constant PROXY_KIND_MP_EXISTING (line 6252) | const PROXY_KIND_MP_EXISTING = 10;
constant PROXY_KIND_JS_UNDEFINED (line 6254) | const PROXY_KIND_JS_UNDEFINED = 0;
constant PROXY_KIND_JS_NULL (line 6255) | const PROXY_KIND_JS_NULL = 1;
constant PROXY_KIND_JS_BOOLEAN (line 6256) | const PROXY_KIND_JS_BOOLEAN = 2;
constant PROXY_KIND_JS_INTEGER (line 6257) | const PROXY_KIND_JS_INTEGER = 3;
constant PROXY_KIND_JS_DOUBLE (line 6258) | const PROXY_KIND_JS_DOUBLE = 4;
constant PROXY_KIND_JS_STRING (line 6259) | const PROXY_KIND_JS_STRING = 5;
constant PROXY_KIND_JS_OBJECT (line 6260) | const PROXY_KIND_JS_OBJECT = 6;
constant PROXY_KIND_JS_PYPROXY (line 6261) | const PROXY_KIND_JS_PYPROXY = 7;
class PythonError (line 6263) | class PythonError extends Error {
method constructor (line 6264) | constructor(exc_type, exc_details) {
function proxy_js_init (line 6271) | function proxy_js_init() {
function proxy_js_check_existing (line 6287) | function proxy_js_check_existing(c_ref) {
function proxy_js_add_obj (line 6308) | function proxy_js_add_obj(js_obj) {
function proxy_call_python (line 6328) | function proxy_call_python(target, argumentsList) {
function proxy_convert_js_to_mp_obj_jsside (line 6377) | function proxy_convert_js_to_mp_obj_jsside(js_obj, out) {
function proxy_convert_js_to_mp_obj_jsside_force_double_proxy (line 6422) | function proxy_convert_js_to_mp_obj_jsside_force_double_proxy(js_obj, ou...
function proxy_convert_mp_to_js_obj_jsside (line 6437) | function proxy_convert_mp_to_js_obj_jsside(value) {
function proxy_convert_mp_to_js_obj_jsside_with_free (line 6505) | function proxy_convert_mp_to_js_obj_jsside_with_free(value) {
function python_index_semantics (line 6511) | function python_index_semantics(target, index_in) {
FILE: docs/server.py
function test (line 9) | def test (*args):
class CORSRequestHandler (line 15) | class CORSRequestHandler (SimpleHTTPRequestHandler):
method end_headers (line 16) | def end_headers (self):
FILE: experiments/dx7_simulator.py
function final_hpf (line 10) | def final_hpf(x):
function final_hpf (line 13) | def final_hpf(x):
function calc_loglin_eg_env (line 35) | def calc_loglin_eg_env(breakpoints, keyup_time=0.5, frame_rate=1000, do_...
function fm_waveform (line 123) | def fm_waveform(freq, amp=1.0, freq_mod=None, duration=1.0, sr=44100, fe...
function dx7_op_waveform (line 148) | def dx7_op_waveform(op, f0=440, mod=None, sr=44100, duration=1.0, keyup_...
function dx7_f0_contour (line 225) | def dx7_f0_contour(patch, f0=440, sr=44100, duration=1.0, keyup_time=0.5):
function dx7_lfo (line 239) | def dx7_lfo(patch, sr=44100, duration=1.0):
function ampmoddepth_to_linear (line 254) | def ampmoddepth_to_linear(ampmoddepth):
function synth_dx7_patch (line 271) | def synth_dx7_patch(patch, f0=440, sr=44100, duration=1.0, keyup_time=0.5):
FILE: experiments/piano_examples.py
function wavwrite (line 14) | def wavwrite(filename, data, samplerate=44100, force_mono=True):
function piano_example (line 21) | def piano_example(base_note=72, filename='piano_examples.wav', volume=5,
function init_piano_voices (line 47) | def init_piano_voices():
function main (line 56) | def main(argv):
FILE: experiments/tulip_piano.py
function harms_params_from_note_index_vel_index (line 56) | def harms_params_from_note_index_vel_index(note_index, vel_index):
function interp_harms_params (line 66) | def interp_harms_params(hp0, hp1, alpha):
function cents_to_hz (line 73) | def cents_to_hz(cents):
function db_to_lin (line 77) | def db_to_lin(d):
function harms_params_for_note_vel (line 82) | def harms_params_for_note_vel(note, vel):
function init_piano_voice (line 111) | def init_piano_voice(num_partials, base_osc=0, **kwargs):
function setup_piano_voice (line 120) | def setup_piano_voice(harms_params, base_osc=0, voices=None, time=None, ...
function piano_note_on (line 149) | def piano_note_on(note=60, vel=1, **kwargs):
function amy_send (line 161) | def amy_send(**kwargs):
class PianoVoiceObject (line 180) | class PianoVoiceObject:
method __init__ (line 182) | def __init__(self, amy_voice):
method note_on (line 185) | def note_on(self, note, vel, time=None, sequence=None):
method note_off (line 189) | def note_off(self, time=None, sequence=None):
FILE: godot/src/amy_gdextension.cpp
function PackedVector2Array (line 127) | PackedVector2Array AmySynth::fill_buffer() {
FILE: godot/src/amy_gdextension.h
function namespace (line 9) | namespace godot {
FILE: godot/src/amy_platform_stubs.c
function amy_platform_init (line 11) | void amy_platform_init(void) {}
function amy_platform_deinit (line 12) | void amy_platform_deinit(void) {}
function amy_update_tasks (line 13) | void amy_update_tasks(void) {}
function amy_i2s_write (line 15) | size_t amy_i2s_write(const uint8_t *buffer, size_t nbytes) {
function stop_midi (line 20) | void stop_midi(void) {}
function run_midi (line 21) | void run_midi(void) {}
function amy_send_midi_note_on (line 22) | void amy_send_midi_note_on(uint8_t channel, uint8_t note, uint8_t veloci...
function amy_send_midi_note_off (line 25) | void amy_send_midi_note_off(uint8_t channel, uint8_t note, uint8_t veloc...
function midi_out (line 29) | void midi_out(uint8_t *bytes, uint16_t len) { (void)bytes; (void)len; }
function delay_ms (line 32) | void delay_ms(uint32_t ms) { (void)ms; }
FILE: godot/src/register_types.cpp
function initialize_amy_module (line 11) | void initialize_amy_module(ModuleInitializationLevel p_level) {
function uninitialize_amy_module (line 18) | void uninitialize_amy_module(ModuleInitializationLevel p_level) {
function GDExtensionBool (line 26) | GDExtensionBool GDE_EXPORT amy_library_init(
FILE: godot/web/godot_amy_bridge.js
function _try_start_audio (line 14) | async function _try_start_audio() {
function _try_configure (line 45) | function _try_configure() {
FILE: scripts/gen_amy_js_api.py
function extract_kw_map_list (line 19) | def extract_kw_map_list(source: str):
function extract_coef_fields (line 34) | def extract_coef_fields(source: str):
function extract_constants (line 42) | def extract_constants(source: str):
function generate_js (line 70) | def generate_js(kw_map_list, coef_fields, constants=None):
function main (line 253) | def main():
FILE: scripts/gen_patches_js.py
function parse_patches (line 21) | def parse_patches(source: str):
function generate_js (line 29) | def generate_js(patches):
function main (line 102) | def main():
FILE: src/algorithms.c
type FmOperatorFlags (line 5) | enum FmOperatorFlags {
type FmAlgorithm (line 36) | struct FmAlgorithm { uint8_t ops[MAX_ALGO_OPS]; }
type FmAlgorithm (line 37) | struct FmAlgorithm
function zero (line 76) | static inline void zero(SAMPLE* a) {
function copy (line 82) | static inline void copy(SAMPLE* a, SAMPLE* b) {
function SAMPLE (line 86) | SAMPLE render_mod(SAMPLE *in, SAMPLE* out, uint16_t osc, SAMPLE feedback...
function note_on_mod (line 99) | void note_on_mod(uint16_t osc, uint16_t algo_osc) {
function algo_note_off (line 108) | void algo_note_off(uint16_t osc) {
function algo_note_on (line 122) | void algo_note_on(uint16_t osc, float freq) {
function algo_deinit (line 133) | void algo_deinit() {
function algo_init (line 141) | void algo_init() {
function SAMPLE (line 152) | SAMPLE render_algo(SAMPLE* buf, uint16_t osc, uint8_t core) {
FILE: src/amy-example.c
function delay_ms (line 11) | void delay_ms(uint32_t ms) {
function render (line 17) | uint8_t render(uint16_t osc, SAMPLE * buf, uint16_t len) {
function print_events_for_patch_number (line 22) | void print_events_for_patch_number(int patch_number) {
function print_events_for_synth (line 35) | void print_events_for_synth(int synth, bool wirecode) {
function print_events_for_synth_2 (line 47) | void print_events_for_synth_2(int synth, bool wirecode) {
function test_patch_set (line 57) | void test_patch_set() {
function test_loop_env_filt (line 71) | void test_loop_env_filt() {
function test_algo (line 89) | void test_algo() {
function test_stored_patch (line 98) | void test_stored_patch() {
function main (line 177) | int main(int argc, char ** argv) {
FILE: src/amy-message.c
function delay_ms (line 8) | void delay_ms(uint32_t ms) {
function main (line 12) | int main(int argc, char ** argv) {
FILE: src/amy-piano.c
function delay_ms (line 9) | void delay_ms(uint32_t ms) {
function main (line 14) | int main(int argc, char ** argv) {
FILE: src/amy.c
type itags (line 8) | enum itags
type profile (line 43) | struct profile
function amy_get_us (line 48) | int64_t amy_get_us() { return esp_timer_get_time(); }
function amy_get_us (line 50) | int64_t amy_get_us() { return to_us_since_boot(get_absolute_time()); }
function amy_get_us (line 56) | int64_t amy_get_us() {
function amy_get_us (line 64) | int64_t amy_get_us() { struct timeval tv; gettimeofday(&tv,NULL); return...
function amy_profiles_init (line 67) | void amy_profiles_init() {
function amy_profiles_print (line 70) | void amy_profiles_print() { for(uint8_t i=0;i<NO_TAG;i++) { AMY_PROFILE_...
function amy_profiles_init (line 72) | void amy_profiles_init() {}
function amy_profiles_print (line 73) | void amy_profiles_print() {}
function amy_grab_lock (line 94) | void amy_grab_lock() {
function amy_release_lock (line 97) | void amy_release_lock() {
function amy_init_lock (line 100) | void amy_init_lock() {
function amy_grab_lock (line 105) | void amy_grab_lock() {
function amy_release_lock (line 108) | void amy_release_lock() {
function amy_init_lock (line 111) | void amy_init_lock() {
function amy_grab_lock (line 116) | void amy_grab_lock() {
function amy_release_lock (line 119) | void amy_release_lock() {
function amy_init_lock (line 122) | void amy_init_lock() {
function amy_grab_lock (line 132) | void amy_grab_lock() {
function amy_release_lock (line 135) | void amy_release_lock() {
function amy_init_lock (line 138) | void amy_init_lock() {
function amy_grab_lock (line 143) | void amy_grab_lock() {
function amy_release_lock (line 145) | void amy_release_lock() {
function amy_init_lock (line 147) | void amy_init_lock() {
type state (line 155) | struct state
type delta (line 157) | struct delta
type synthinfo (line 159) | struct synthinfo
type mod_synthinfo (line 161) | struct mod_synthinfo
function dealloc_echo_delay_lines (line 200) | void dealloc_echo_delay_lines(void) {
function alloc_echo_delay_lines (line 207) | bool alloc_echo_delay_lines(uint32_t max_delay_samples) {
function enclosing_power_of_2 (line 226) | uint32_t enclosing_power_of_2(uint32_t n) {
function config_echo (line 232) | void config_echo(float level, float delay_ms, float max_delay_ms, float ...
function dealloc_chorus_delay_lines (line 267) | void dealloc_chorus_delay_lines(void) {
function alloc_chorus_delay_lines (line 276) | void alloc_chorus_delay_lines(void) {
function config_chorus (line 294) | void config_chorus(float level, uint16_t max_delay, float lfo_freq, floa...
function config_reverb (line 333) | void config_reverb(float level, float liveness, float damping, float xov...
function check_init (line 353) | int8_t check_init(amy_err_t (*fn)(), const char *name) {
function peek_stack (line 374) | int peek_stack(const char *tag) {
function peek_stack (line 385) | int peek_stack(const char *tag) { return 0; }
function global_init (line 389) | int8_t global_init(amy_config_t c) {
function logfreq_of_freq (line 438) | float logfreq_of_freq(float freq) {
function freq_of_logfreq (line 446) | float freq_of_logfreq(float logfreq) {
function freq_for_midi_note (line 451) | float freq_for_midi_note(float midi_note) {
function logfreq_for_midi_note (line 455) | float logfreq_for_midi_note(float midi_note) {
function midi_note_for_logfreq (line 460) | float midi_note_for_logfreq(float logfreq) {
function add_delta_to_queue (line 466) | void add_delta_to_queue(struct delta *d, struct delta **queue) {
function map_60dB_to_01f (line 488) | float map_60dB_to_01f(float lin) {
function map_01_to_60dBf (line 495) | float map_01_to_60dBf(float log) {
function amy_event_to_deltas_queue (line 525) | void amy_event_to_deltas_queue(amy_event *e, uint16_t base_osc, struct d...
function reset_modosc (line 685) | void reset_modosc(struct mod_synthinfo *pmsynth) {
function reset_osc_params (line 700) | void reset_osc_params(struct synthinfo *psynth) {
function reset_osc_state (line 748) | void reset_osc_state(struct synthinfo *psynth) {
function reset_osc_by_pointer (line 767) | void reset_osc_by_pointer(struct synthinfo *psynth, struct mod_synthinfo...
function reset_osc (line 775) | void reset_osc(uint16_t i ) {
function amy_reset_oscs (line 782) | void amy_reset_oscs() {
function amy_deltas_reset (line 813) | void amy_deltas_reset() {
function alloc_osc (line 819) | void alloc_osc(int osc, uint8_t *max_num_breakpoints) {
function free_osc (line 845) | void free_osc(int osc) {
function ensure_osc_allocd (line 854) | void ensure_osc_allocd(int osc, uint8_t *max_num_breakpoints) {
function oscs_init (line 920) | int8_t oscs_init() {
function print_osc_debug (line 971) | void print_osc_debug(int i /* osc */, bool show_eg) {
function show_debug (line 998) | void show_debug(uint8_t type) {
function oscs_deinit (line 1048) | void oscs_deinit() {
function osc_note_on (line 1078) | void osc_note_on(uint16_t osc, float initial_freq) {
function chained_osc_would_cause_loop (line 1113) | int chained_osc_would_cause_loop(uint16_t osc, uint16_t chained_osc) {
function portamento_ms_to_alpha (line 1128) | float portamento_ms_to_alpha(uint16_t portamento_ms) {
function alpha_to_portamento_ms (line 1132) | uint16_t alpha_to_portamento_ms(float alpha) {
function play_delta (line 1143) | void play_delta(struct delta *d) {
function combine_controls (line 1414) | float combine_controls(float *controls, float *coefs) {
function amp_combine_controls (line 1421) | float amp_combine_controls(float *controls, float *coefs) {
function hold_and_modify (line 1450) | void hold_and_modify(uint16_t osc) {
function lgain_of_pan (line 1534) | static inline float lgain_of_pan(float pan) {
function rgain_of_pan (line 1540) | static inline float rgain_of_pan(float pan) {
function mix_with_pan (line 1547) | void mix_with_pan(SAMPLE *stereo_dest, SAMPLE *mono_src, float pan_start...
function SAMPLE (line 1570) | SAMPLE render_osc_wave(uint16_t osc, uint8_t core, SAMPLE* buf) {
function amy_render (line 1708) | void amy_render(uint16_t start, uint16_t end, uint8_t core) {
function amy_execute_delta (line 1769) | void amy_execute_delta() {
function amy_execute_deltas (line 1791) | void amy_execute_deltas() {
function amy_block_processed (line 1815) | void amy_block_processed(void) {
function amy_process_event (line 1830) | void amy_process_event(amy_event *e) {
function amy_reset_sysclock (line 2000) | void amy_reset_sysclock() {
type delta (line 2010) | struct delta
type delta (line 2013) | struct delta
type delta (line 2018) | struct delta
type delta (line 2018) | struct delta
type delta (line 2019) | struct delta
type delta (line 2019) | struct delta
type delta (line 2019) | struct delta
type delta (line 2021) | struct delta
function deltas_add_pool_block (line 2035) | void deltas_add_pool_block(void) {
function deltas_pool_init (line 2044) | void deltas_pool_init() {
function deltas_pool_free (line 2049) | void deltas_pool_free() {
type delta (line 2057) | struct delta
type delta (line 2057) | struct delta
type delta (line 2059) | struct delta
type delta (line 2076) | struct delta
type delta (line 2076) | struct delta
type delta (line 2078) | struct delta
function delta_release_list (line 2090) | void delta_release_list(struct delta *d) {
function delta_list_len (line 2095) | int32_t delta_list_len(struct delta *d) {
function delta_num_free (line 2104) | int32_t delta_num_free() {
FILE: src/amy.h
function __builtin_clz (line 18) | static inline int __builtin_clz(unsigned int x) {
type pcm_map_t (line 39) | typedef struct {
type output_sample_type (line 202) | typedef int16_t output_sample_type;
type coefs (line 213) | enum coefs{
type amy_err_t (line 303) | typedef int amy_err_t;
type params (line 323) | enum params{
type itags (line 367) | enum itags{
type profile (line 374) | struct profile {
type profile (line 404) | struct profile
function isnan_c11 (line 420) | static inline int isnan_c11(float test)
type delta (line 459) | struct delta {
type amy_event (line 472) | typedef struct amy_event {
type synthinfo (line 541) | struct synthinfo {
type mod_synthinfo (line 591) | struct mod_synthinfo {
type sequence_entry_ll_t (line 607) | typedef struct sequence_entry_ll_t {
type delay_line_t (line 616) | typedef struct delay_line {
type amy_config_t (line 654) | typedef struct {
type reverb_state_t (line 726) | typedef struct reverb_state {
type chorus_config_t (line 733) | typedef struct chorus_config {
type echo_config_t (line 740) | typedef struct echo_config {
type state (line 750) | struct state {
type custom_oscillator (line 789) | struct custom_oscillator {
type synthinfo (line 802) | struct synthinfo
type mod_synthinfo (line 803) | struct mod_synthinfo
type state (line 804) | struct state
type delta (line 812) | struct delta
type delta (line 812) | struct delta
type delta (line 814) | struct delta
type custom_oscillator (line 896) | struct custom_oscillator
type synthinfo (line 901) | struct synthinfo
type mod_synthinfo (line 901) | struct mod_synthinfo
type delta (line 950) | struct delta
type amy_event (line 954) | struct amy_event
type amy_event (line 955) | struct amy_event
type delta (line 959) | struct delta
type delta (line 1073) | struct delta
type delta (line 1073) | struct delta
type delta (line 1074) | struct delta
type delta (line 1074) | struct delta
type delta (line 1075) | struct delta
type delta (line 1076) | struct delta
FILE: src/amy_connector.js
function amy_js_start (line 63) | async function amy_js_start() {
function setup_midi_devices (line 80) | async function setup_midi_devices() {
function start_midi (line 98) | async function start_midi() {
function sleep_ms (line 134) | async function sleep_ms(ms) {
function toggle_audioin (line 139) | async function toggle_audioin() {
FILE: src/amy_fixedpoint.h
type s_15 (line 120) | typedef int16_t s_15;
type s_31 (line 121) | typedef int32_t s_31;
type s8_23 (line 122) | typedef int32_t s8_23;
type s16_15 (line 123) | typedef int32_t s16_15;
function SAMPLE (line 170) | static inline SAMPLE SMULR6(SAMPLE a, SAMPLE b) {
function SAMPLE (line 176) | static inline SAMPLE SMULR7(SAMPLE a, SAMPLE b) {
type lut_entry_fxpt (line 218) | typedef struct {
FILE: src/amy_midi.c
function amy_external_midi_sync (line 37) | void amy_external_midi_sync(uint8_t enabled) {
function debug_print_midi_hex (line 42) | static void debug_print_midi_hex(const uint8_t *data, uint32_t len, uint...
function amy_send_midi_note_on (line 52) | void amy_send_midi_note_on(uint16_t osc) {
function amy_send_midi_note_off (line 64) | void amy_send_midi_note_off(uint16_t osc) {
function amy_received_note_on (line 76) | void amy_received_note_on(uint8_t channel, uint8_t note, uint8_t vel, ui...
function amy_received_note_off (line 88) | void amy_received_note_off(uint8_t channel, uint8_t note, uint8_t vel, u...
function amy_received_control_change (line 99) | void amy_received_control_change(uint8_t channel, uint8_t control, uint8...
function amy_received_program_change (line 113) | void amy_received_program_change(uint8_t channel, uint8_t program, uint3...
function amy_received_pedal (line 131) | void amy_received_pedal(uint8_t channel, uint8_t value, uint32_t time) {
function amy_received_all_notes_off (line 140) | void amy_received_all_notes_off(uint8_t channel, uint32_t time) {
function amy_received_pitch_bend (line 151) | void amy_received_pitch_bend(uint8_t channel, uint8_t low_byte, uint8_t ...
function amy_event_midi_message_received (line 164) | void amy_event_midi_message_received(uint8_t * data, uint32_t len, uint8...
function midi_clock_received (line 196) | void midi_clock_received() {
function parse_sysex (line 242) | void parse_sysex() {
function convert_midi_bytes_to_messages (line 310) | void convert_midi_bytes_to_messages(uint8_t * data, size_t len, uint8_t ...
function amy_process_single_midi_byte (line 375) | void amy_process_single_midi_byte(uint8_t byte, uint8_t from_web_or_usb) {
function amy_external_midi_output (line 382) | void amy_external_midi_output(uint8_t * data, uint32_t len) {
function run_midi (line 392) | void run_midi() {
function stop_midi (line 396) | void stop_midi() {
function midi_out (line 399) | void midi_out(uint8_t * bytes, uint16_t len) {
function esp_get_uart (line 416) | int8_t esp_get_uart(int8_t index) {
function check_tusb_midi (line 431) | void check_tusb_midi() {
function esp_init_midi (line 440) | void esp_init_midi(void) {
function esp_deinit_midi (line 474) | void esp_deinit_midi(void) {
function esp_poll_midi (line 488) | void esp_poll_midi(void) {
function run_midi_task (line 497) | void run_midi_task() {
function run_midi (line 507) | void run_midi() {
function stop_midi (line 528) | void stop_midi() {
function uart_inst_t (line 550) | uart_inst_t * rp_get_uart(int8_t index) {
function on_pico_uart_rx (line 557) | void on_pico_uart_rx() {
function run_midi (line 573) | void run_midi() {
function stop_midi (line 592) | void stop_midi() {
function run_midi (line 614) | void run_midi() {
function stop_midi (line 618) | void stop_midi() {
function stop_midi (line 624) | void stop_midi() {
function run_midi (line 627) | void run_midi() {
function run_midi (line 634) | void run_midi() {
function stop_midi (line 640) | void stop_midi() {
function run_midi (line 643) | void run_midi() {
function midi_out (line 647) | void midi_out(uint8_t * bytes, uint16_t len) {
FILE: src/api.c
function amy_config_t (line 6) | amy_config_t amy_default_config() {
function amy_event (line 103) | amy_event amy_default_event() {
function amy_clear_event (line 109) | void amy_clear_event(amy_event *e) {
function amy_get_output_buffer (line 187) | int amy_get_output_buffer(output_sample_type * samples) {
function amy_get_input_buffer (line 194) | int amy_get_input_buffer(output_sample_type * samples) {
function amy_set_external_input_buffer (line 200) | void amy_set_external_input_buffer(output_sample_type * samples) {
function output_sample_type (line 204) | output_sample_type * amy_simple_fill_buffer() {
function amy_sysclock (line 212) | uint32_t amy_sysclock() {
function amy_add_message (line 227) | void amy_add_message(char *message) {
function amy_add_message_from_sysex (line 244) | void amy_add_message_from_sysex(char *message) {
function amy_add_event (line 251) | void amy_add_event(amy_event *e) {
function amy_start_web (line 265) | void amy_start_web() {
function amy_start_web_no_synths (line 275) | void amy_start_web_no_synths() {
function amy_default_synths (line 286) | void amy_default_synths() {
function amy_bleep (line 328) | void amy_bleep(uint32_t start) {
function amy_bleep_synth (line 348) | void amy_bleep_synth(uint32_t start) {
function amy_start (line 372) | void amy_start(amy_config_t c) {
function amy_stop (line 395) | void amy_stop() {
FILE: src/custom.c
type custom_oscillator (line 6) | struct custom_oscillator
function amy_set_custom (line 8) | void amy_set_custom(struct custom_oscillator* custom) {
function custom_init (line 13) | void custom_init() {
function custom_deinit (line 19) | void custom_deinit() {
function custom_note_on (line 25) | void custom_note_on(uint16_t osc, float freq) {
function custom_note_off (line 30) | void custom_note_off(uint16_t osc) {
function custom_mod_trigger (line 35) | void custom_mod_trigger(uint16_t osc) {
function SAMPLE (line 40) | SAMPLE render_custom(SAMPLE* buf, uint16_t osc) {
function SAMPLE (line 45) | SAMPLE compute_mod_custom(uint16_t osc) {
FILE: src/delay.c
function is_power_of_two (line 6) | int is_power_of_two(int val) {
function qspi_free (line 40) | void qspi_free(void *ptr) {
function delay_line_t (line 57) | delay_line_t *new_delay_line(int len, int fixed_delay, int ram_type) {
function free_delay_line (line 82) | void free_delay_line(delay_line_t *delay_line) {
function SAMPLE (line 87) | static SAMPLE FRACTIONAL_SAMPLE(PHASOR phase, const SAMPLE *delay, int i...
function delay_line_in_out (line 98) | void delay_line_in_out(SAMPLE *in, SAMPLE *out, int n_samples, SAMPLE* m...
function SAMPLE (line 131) | static inline SAMPLE DEL_OUT(delay_line_t *delay_line, int extra_delay) {
function DEL_IN (line 137) | static inline void DEL_IN(delay_line_t *delay_line, SAMPLE val) {
function SAMPLE (line 142) | static inline SAMPLE LPF(SAMPLE samp, SAMPLE state, SAMPLE lpcoef, SAMPL...
function delay_line_in_out_fixed_delay (line 150) | void delay_line_in_out_fixed_delay(SAMPLE *in, SAMPLE *out, int n_sample...
function apply_variable_delay (line 188) | void apply_variable_delay(SAMPLE *block, delay_line_t *delay_line, SAMPL...
function apply_fixed_delay (line 192) | void apply_fixed_delay(SAMPLE *block, delay_line_t *delay_line, uint32_t...
function config_stereo_reverb (line 211) | void config_stereo_reverb(float a_liveness, float crossover_hz, float da...
function init_stereo_reverb (line 244) | void init_stereo_reverb(void) {
function stereo_reverb (line 262) | void stereo_reverb(SAMPLE *r_in, SAMPLE *l_in, SAMPLE *r_out, SAMPLE *l_...
FILE: src/envelope.c
function SAMPLE (line 9) | SAMPLE compute_mod_value(uint16_t mod_osc) {
function SAMPLE (line 35) | SAMPLE compute_mod_scale(uint16_t osc) {
function SAMPLE (line 47) | SAMPLE compute_breakpoint_scale(uint16_t osc, uint8_t bp_set, uint16_t s...
FILE: src/examples.c
function example_reset (line 9) | void example_reset(uint32_t start) {
function example_voice_alloc (line 17) | void example_voice_alloc() {
function example_voice_chord (line 57) | void example_voice_chord(uint32_t start, uint16_t patch_number) {
function example_synth_chord (line 96) | void example_synth_chord(uint32_t start, uint16_t patch_number) {
function example_sustain_pedal (line 134) | void example_sustain_pedal(uint32_t start, uint16_t patch_number) {
function example_patches (line 229) | void example_patches() {
function example_reverb (line 255) | void example_reverb() {
function example_chorus (line 261) | void example_chorus() {
function example_ks (line 268) | void example_ks(uint32_t start) {
function example_sine (line 282) | void example_sine(uint32_t start) {
function example_multimbral_fm (line 291) | void example_multimbral_fm() {
function example_drums (line 310) | void example_drums(uint32_t start, int loops) {
function example_sequencer_drums (line 414) | void example_sequencer_drums(uint32_t start) {
function example_sequencer_drums_synth (line 479) | void example_sequencer_drums_synth(uint32_t start) {
function example_fm (line 522) | void example_fm(uint32_t start) {
function beeper_init (line 573) | void beeper_init(void) {
function beeper_deinit (line 577) | void beeper_deinit(void) {
function beeper_note_on (line 581) | void beeper_note_on(uint16_t osc, float freq) {
function beeper_note_off (line 585) | void beeper_note_off(uint16_t osc) {
function beeper_mod_trigger (line 589) | void beeper_mod_trigger(uint16_t osc) {
function SAMPLE (line 593) | SAMPLE beeper_render(SAMPLE* buf, uint16_t osc) {
function SAMPLE (line 597) | SAMPLE beeper_compute_mod(uint16_t osc) {
type custom_oscillator (line 601) | struct custom_oscillator
function example_init_custom (line 611) | void example_init_custom() {
function example_custom_beep (line 615) | void example_custom_beep() {
function example_patch_from_events (line 629) | void example_patch_from_events() {
FILE: src/filters.c
function dsps_sqrtf_f32_ansi (line 21) | float dsps_sqrtf_f32_ansi(float f)
function dsps_biquad_gen_lpf_f32 (line 32) | int8_t dsps_biquad_gen_lpf_f32(SAMPLE *coeffs, float f, float qFactor)
function dsps_biquad_gen_hpf_f32 (line 91) | int8_t dsps_biquad_gen_hpf_f32(SAMPLE *coeffs, float f, float qFactor)
function dsps_biquad_gen_bpf_f32 (line 121) | int8_t dsps_biquad_gen_bpf_f32(SAMPLE *coeffs, float f, float qFactor)
function dsps_biquad_f32_ansi (line 158) | int8_t dsps_biquad_f32_ansi(const SAMPLE *input, SAMPLE *output, int len...
function dsps_biquad_f32_ansi_split_fb (line 189) | int8_t dsps_biquad_f32_ansi_split_fb(const SAMPLE *input, SAMPLE *output...
function SAMPLE (line 222) | static inline SAMPLE ABS(SAMPLE a) {
function headroom (line 229) | static inline int headroom(SAMPLE a) {
function nheadroom16 (line 244) | static inline int nheadroom16(SAMPLE a) {
function SAMPLE (line 261) | SAMPLE top16SMUL(SAMPLE a, SAMPLE b) {
function SAMPLE (line 283) | SAMPLE top16SMUL_a_part(SAMPLE a, int *p_resultdrop) {
function SAMPLE (line 294) | SAMPLE top16SMUL_after_a(SAMPLE a_processed, SAMPLE b, int resultdrop, i...
function SAMPLE (line 315) | SAMPLE top16SMUL(SAMPLE a, SAMPLE b) {
function SAMPLE (line 319) | SAMPLE top16SMUL_a_part(SAMPLE a, int *p_adropped) {
function SAMPLE (line 324) | SAMPLE top16SMUL_after_a(SAMPLE a_processed, SAMPLE b, int adropped_unus...
function SAMPLE (line 330) | SAMPLE scan_max(SAMPLE* block, int len) {
function SAMPLE (line 347) | SAMPLE dsps_biquad_f32_ansi_split_fb_once(const SAMPLE *input, SAMPLE *o...
function SAMPLE (line 394) | SAMPLE dsps_biquad_f32_ansi_split_fb_twice(const SAMPLE *input, SAMPLE *...
function dsps_biquad_f32_ansi_commuted (line 454) | int8_t dsps_biquad_f32_ansi_commuted(const SAMPLE *input, SAMPLE *output...
function filters_deinit (line 468) | void filters_deinit() {
function filters_init (line 479) | void filters_init() {
function parametric_eq_process (line 514) | void parametric_eq_process(SAMPLE *block) {
function parametric_eq_process_old (line 519) | void parametric_eq_process_old(SAMPLE *block) {
function parametric_eq_process_full (line 537) | void parametric_eq_process_full(SAMPLE *block) {
function SAMPLE (line 584) | inline static SAMPLE MAXABS2(SAMPLE a, SAMPLE b) {
function parametric_eq_process_top16block (line 591) | void parametric_eq_process_top16block(SAMPLE *block) {
function hpf_buf (line 657) | void hpf_buf(SAMPLE *buf, SAMPLE *state) {
function check_overflow (line 676) | void check_overflow(SAMPLE* block, int osc, char *msg) {
function SAMPLE (line 700) | SAMPLE block_norm(SAMPLE* block, int len, int bits) {
function SAMPLE (line 736) | SAMPLE block_denorm(SAMPLE* block, int len, int bits) {
function SAMPLE (line 740) | SAMPLE filter_process(SAMPLE * block, uint16_t osc, SAMPLE max_val) {
function reset_filter (line 835) | void reset_filter(uint16_t osc) {
function reset_parametric (line 844) | void reset_parametric(void) {
FILE: src/i2s.c
function amy_err_t (line 69) | amy_err_t esp32_setup_i2s(void) {
function amy_err_t (line 126) | amy_err_t esp32_setup_i2s(void) {
function amy_err_t (line 225) | amy_err_t esp32_teardown_i2s(void) {
function esp_render_task (line 247) | void esp_render_task( void * pvParameters) {
function esp_render_on_cores (line 256) | void esp_render_on_cores() {
function esp_read_i2s_input (line 286) | void esp_read_i2s_input() {
function esp_fill_audio_buffer_task (line 302) | void esp_fill_audio_buffer_task() {
function amy_platform_init (line 334) | void amy_platform_init() {
function amy_platform_deinit (line 361) | void amy_platform_deinit() {
function amy_update_tasks (line 375) | void amy_update_tasks() {
function amy_i2s_write (line 403) | size_t amy_i2s_write(const uint8_t *buffer, size_t nbytes) {
type audio_buffer_pool (line 437) | struct audio_buffer_pool
function _millis (line 439) | static inline uint32_t _millis(void)
type queue_entry_t (line 444) | typedef struct
function amy_update_tasks (line 460) | void amy_update_tasks() {
function render_other_core (line 470) | int32_t render_other_core(int32_t data) {
function amy_i2s_write (line 490) | size_t amy_i2s_write(const uint8_t *buffer, size_t nbytes) {
type audio_buffer_pool (line 498) | struct audio_buffer_pool
type audio_buffer_format (line 505) | struct audio_buffer_format
type audio_buffer_pool (line 510) | struct audio_buffer_pool
type audio_format (line 513) | struct audio_format
type audio_i2s_config (line 514) | struct audio_i2s_config
function core1_main (line 533) | void core1_main() {
function amy_platform_init (line 542) | void amy_platform_init() {
function amy_platform_deinit (line 560) | void amy_platform_deinit() {
function amy_platform_init (line 586) | void amy_platform_init() {
function amy_platform_deinit (line 592) | void amy_platform_deinit() {
function amy_update_tasks (line 598) | void amy_update_tasks() {
function amy_i2s_write (line 617) | size_t amy_i2s_write(const uint8_t *buffer, size_t nbytes) {
FILE: src/instrument.c
type voice_fifo (line 15) | struct voice_fifo {
function voice_fifo_debug (line 25) | void voice_fifo_debug(struct voice_fifo *fifo) {
type voice_fifo (line 35) | struct voice_fifo
type voice_fifo (line 40) | struct voice_fifo
type voice_fifo (line 40) | struct voice_fifo
type voice_fifo (line 40) | struct voice_fifo
function voice_fifo_free (line 48) | void voice_fifo_free(struct voice_fifo *fifo) {
function voice_fifo_empty (line 52) | bool voice_fifo_empty(struct voice_fifo *fifo) {
function voice_fifo_put (line 56) | void voice_fifo_put(struct voice_fifo *fifo, uint8_t val) {
function voice_fifo_get (line 67) | uint8_t voice_fifo_get(struct voice_fifo *fifo) {
function voice_fifo_remove (line 78) | void voice_fifo_remove(struct voice_fifo *fifo, uint8_t val) {
type instrument_info (line 102) | struct instrument_info {
function instrument_debug (line 126) | void instrument_debug(struct instrument_info *instrument) {
function _instrument_reset_forgotten_pool (line 143) | void _instrument_reset_forgotten_pool(struct instrument_info *instrument) {
type instrument_info (line 150) | struct instrument_info
type instrument_info (line 151) | struct instrument_info
type instrument_info (line 151) | struct instrument_info
type instrument_info (line 151) | struct instrument_info
function instrument_free (line 178) | void instrument_free(struct instrument_info *instrument) {
function _instrument_push_note_forgotten (line 184) | void _instrument_push_note_forgotten(struct instrument_info *instrument,...
function _instrument_pop_note_forgotten (line 209) | bool _instrument_pop_note_forgotten(struct instrument_info *instrument, ...
function _instrument_get_voice (line 224) | uint16_t _instrument_get_voice(struct instrument_info *instrument, bool ...
function _instrument_voice_for_note (line 236) | uint16_t _instrument_voice_for_note(struct instrument_info *instrument, ...
function _instrument_voice_off (line 244) | uint16_t _instrument_voice_off(struct instrument_info *instrument, uint1...
function instrument_note_off (line 252) | uint16_t instrument_note_off(struct instrument_info *instrument, uint16_...
function _instrument_all_notes_off (line 269) | int _instrument_all_notes_off(struct instrument_info *instrument, uint16...
function instrument_note_on (line 283) | uint16_t instrument_note_on(struct instrument_info *instrument, uint16_t...
type instrument_info (line 309) | struct instrument_info
function instruments_deinit (line 312) | void instruments_deinit() {
function instruments_init (line 319) | void instruments_init(int num_instruments) {
function instruments_reset (line 327) | void instruments_reset() {
function instruments_max_instruments (line 332) | int instruments_max_instruments() {
function instrument_release (line 336) | void instrument_release(int instrument_number) {
function instrument_number_ok (line 343) | bool instrument_number_ok(int instrument_number, const char *tag) {
function instrument_number_exists (line 351) | bool instrument_number_exists(int instrument_number, const char *tag) {
function instrument_add_new (line 361) | void instrument_add_new(int instrument_number, int num_voices, uint16_t ...
function instrument_change_number (line 369) | void instrument_change_number(int old_instrument_number, int new_instrum...
function instrument_get_num_voices (line 382) | int instrument_get_num_voices(int instrument_number, uint16_t *amy_voice...
function instrument_voice_for_note_event (line 398) | uint16_t instrument_voice_for_note_event(int instrument_number, int note...
function instrument_all_notes_off (line 421) | int instrument_all_notes_off(int instrument_number, uint16_t *amy_voices) {
function instrument_sustain (line 427) | int instrument_sustain(int instrument_number, bool sustain, uint16_t *am...
function instrument_get_patch_number (line 448) | int instrument_get_patch_number(int instrument_number) {
function instrument_get_oscs_per_voice (line 454) | int instrument_get_oscs_per_voice(int instrument_number) {
function instrument_get_flags (line 460) | uint32_t instrument_get_flags(int instrument_number) {
function instrument_noteon_delay_ms (line 466) | uint16_t instrument_noteon_delay_ms(int instrument_number) {
function instrument_set_noteon_delay_ms (line 475) | void instrument_set_noteon_delay_ms(int instrument_number, uint16_t note...
function instrument_grab_midi_notes (line 481) | bool instrument_grab_midi_notes(int instrument_number) {
function instrument_set_grab_midi_notes (line 490) | void instrument_set_grab_midi_notes(int instrument_number, bool grab_mid...
function instrument_bank_number (line 496) | int instrument_bank_number(int instrument_number) {
function instrument_set_bank_number (line 505) | void instrument_set_bank_number(int instrument_number, int bank_number) {
FILE: src/interp_partials.c
type interp_partials_voice_t (line 6) | typedef struct {
function partials_note_on (line 43) | void partials_note_on(uint16_t osc) {
function partials_note_off (line 62) | void partials_note_off(uint16_t osc) {
function SAMPLE (line 75) | SAMPLE render_partials(SAMPLE *buf, uint16_t osc) {
function _max_partials_for_partials_voice (line 112) | int _max_partials_for_partials_voice(const interp_partials_voice_t *part...
function interp_partials_max_partials_for_patch (line 120) | int interp_partials_max_partials_for_patch(int interp_partials_patch_num...
function _cumulate_scaled_harmonic_params (line 125) | void _cumulate_scaled_harmonic_params(float *harm_param, int harmonic_in...
function _harmonic_base_index_for_pitch_vel (line 134) | int _harmonic_base_index_for_pitch_vel(int pitch_index, int vel_index, c...
function _logfreq_of_midi_cents (line 142) | float _logfreq_of_midi_cents(float midi_cents) {
function _env_lin_of_db (line 147) | float _env_lin_of_db(float db) {
function _osc_on_with_harm_param (line 153) | void _osc_on_with_harm_param(uint16_t o, float *harm_param, const interp...
function interp_partials_note_on (line 189) | void interp_partials_note_on(uint16_t osc) {
function interp_partials_note_off (line 259) | void interp_partials_note_off(uint16_t osc) {
FILE: src/libminiaudio-audio.c
function main_loop__em (line 43) | void main_loop__em()
function amy_update_tasks (line 60) | void amy_update_tasks() {
function amy_platform_init (line 63) | void amy_platform_init() {
function amy_platform_deinit (line 66) | void amy_platform_deinit() {
function amy_i2s_write (line 69) | size_t amy_i2s_write(const uint8_t *buffer, size_t nbytes) {
function amy_print_devices (line 82) | void amy_print_devices() {
function data_callback (line 123) | static void data_callback(ma_device* pDevice, void* pOutput, const void*...
function amy_err_t (line 175) | amy_err_t miniaudio_init() {
function miniaudio_deinit (line 247) | void miniaudio_deinit(void) {
function DWORD (line 257) | static DWORD WINAPI miniaudio_run(LPVOID lpParam) {
function miniaudio_start (line 265) | void miniaudio_start(void) {
function miniaudio_stop (line 271) | void miniaudio_stop(void) {
function miniaudio_start (line 288) | void miniaudio_start(void) {
function miniaudio_stop (line 295) | void miniaudio_stop(void) {
function amy_live_start_web_audioin (line 303) | void amy_live_start_web_audioin() {
function amy_live_start_web (line 309) | void amy_live_start_web() {
function amy_live_stop (line 315) | void amy_live_stop() {
FILE: src/log2_exp2.c
function SAMPLE (line 7) | static inline SAMPLE lut_val(SAMPLE frac, const LUTSAMPLE *table, const ...
function SAMPLE (line 15) | SAMPLE log2_lut(SAMPLE x) {
function SAMPLE (line 31) | SAMPLE exp2_lut(SAMPLE x) {
FILE: src/midi_mappings.c
function juno_filter_midi_handler (line 8) | void juno_filter_midi_handler(uint8_t * bytes, uint16_t len, uint8_t is_...
type cc_mapping (line 34) | struct cc_mapping {
type cc_mapping (line 45) | struct cc_mapping
function cc_mapping_print (line 47) | void cc_mapping_print(struct cc_mapping *mapping) {
type cc_mapping (line 52) | struct cc_mapping
type cc_mapping (line 52) | struct cc_mapping
type cc_mapping (line 53) | struct cc_mapping
type cc_mapping (line 53) | struct cc_mapping
type cc_mapping (line 53) | struct cc_mapping
type cc_mapping (line 54) | struct cc_mapping
function cc_mapping_debug (line 68) | void cc_mapping_debug(void) {
function cc_mapping_free (line 77) | void cc_mapping_free(struct cc_mapping **p_mapping) {
function midi_mappings_init (line 85) | void midi_mappings_init(void) {
function midi_mappings_deinit (line 89) | void midi_mappings_deinit(void) {
function midi_clear_channel_mappings (line 96) | void midi_clear_channel_mappings(int channel) {
type cc_mapping (line 107) | struct cc_mapping
type cc_mapping (line 109) | struct cc_mapping
function midi_clear_control_code (line 117) | int midi_clear_control_code(int channel, int code) {
function midi_store_control_code (line 128) | int midi_store_control_code(int channel, int code, int is_log, float min...
function midi_fetch_control_code_command (line 145) | bool midi_fetch_control_code_command(int channel, int code, char *s, siz...
function map_cc_value (line 156) | float map_cc_value(struct cc_mapping *mapping, uint8_t value) {
function substitute_cc_special_values (line 174) | void substitute_cc_special_values(char *dest, const char *src, int chann...
function midi_cc_handler (line 206) | void midi_cc_handler(uint8_t * bytes, uint16_t len, uint8_t is_sysex) {
FILE: src/miniaudio.h
type ma_int8 (line 3755) | typedef int8_t ma_int8;
type ma_uint8 (line 3756) | typedef uint8_t ma_uint8;
type ma_int16 (line 3757) | typedef int16_t ma_int16;
type ma_uint16 (line 3758) | typedef uint16_t ma_uint16;
type ma_int32 (line 3759) | typedef int32_t ma_int32;
type ma_uint32 (line 3760) | typedef uint32_t ma_uint32;
type ma_int64 (line 3761) | typedef int64_t ma_int64;
type ma_uint64 (line 3762) | typedef uint64_t ma_uint64;
type ma_int8 (line 3764) | typedef signed char ma_int8;
type ma_uint8 (line 3765) | typedef unsigned char ma_uint8;
type ma_int16 (line 3766) | typedef signed short ma_int16;
type ma_uint16 (line 3767) | typedef unsigned short ma_uint16;
type ma_int32 (line 3768) | typedef signed int ma_int32;
type ma_uint32 (line 3769) | typedef unsigned int ma_uint32;
type ma_int64 (line 3771) | typedef signed __int64 ma_int64;
type ma_uint64 (line 3772) | typedef unsigned __int64 ma_uint64;
type ma_int64 (line 3781) | typedef signed long long ma_int64;
type ma_uint64 (line 3782) | typedef unsigned long long ma_uint64;
type ma_uint64 (line 3790) | typedef ma_uint64 ma_uintptr;
type ma_uint32 (line 3792) | typedef ma_uint32 ma_uintptr;
type ma_uint8 (line 3795) | typedef ma_uint8 ma_bool8;
type ma_uint32 (line 3796) | typedef ma_uint32 ma_bool32;
type ma_float (line 3801) | typedef float ma_float;
type ma_double (line 3802) | typedef double ma_double;
type ma_uint16 (line 3820) | typedef ma_uint16 wchar_t;
type pthread_t (line 3858) | typedef pthread_t ma_pthread_t;
type pthread_mutex_t (line 3859) | typedef pthread_mutex_t ma_pthread_mutex_t;
type pthread_cond_t (line 3860) | typedef pthread_cond_t ma_pthread_cond_t;
type ma_uintptr (line 3862) | typedef ma_uintptr ma_pthread_t;
type ma_pthread_mutex_t (line 3863) | typedef union ma_pthread_mutex_t { char __data[40]; ma_uint64 ...
type ma_pthread_cond_t (line 3864) | typedef union ma_pthread_cond_t { char __data[48]; ma_uint64 ...
type wchar_t (line 4006) | typedef wchar_t ma_wchar_win32;
type ma_uint16 (line 4008) | typedef ma_uint16 ma_wchar_win32;
type ma_log_level (line 4037) | typedef enum
type ma_context (line 4072) | typedef struct ma_context ma_context;
type ma_device (line 4073) | typedef struct ma_device ma_device;
type ma_uint8 (line 4075) | typedef ma_uint8 ma_channel;
type _ma_channel_position (line 4076) | typedef enum
type ma_result (line 4135) | typedef enum
type ma_stream_format (line 4228) | typedef enum
type ma_stream_layout (line 4233) | typedef enum
type ma_dither_mode (line 4239) | typedef enum
type ma_format (line 4246) | typedef enum
type ma_standard_sample_rate (line 4261) | typedef enum
type ma_channel_mix_mode (line 4289) | typedef enum
type ma_standard_channel_map (line 4297) | typedef enum
type ma_performance_profile (line 4310) | typedef enum
type ma_allocation_callbacks (line 4317) | typedef struct
type ma_lcg (line 4325) | typedef struct
type ma_uint32 (line 4389) | typedef ma_uint32 ma_spinlock;
type ma_thread_priority (line 4393) | typedef enum
type ma_pthread_t (line 4406) | typedef ma_pthread_t ma_thread;
type ma_handle (line 4408) | typedef ma_handle ma_thread;
type ma_pthread_mutex_t (line 4412) | typedef ma_pthread_mutex_t ma_mutex;
type ma_handle (line 4414) | typedef ma_handle ma_mutex;
type ma_event (line 4418) | typedef struct
type ma_handle (line 4425) | typedef ma_handle ma_event;
type ma_semaphore (line 4429) | typedef struct
type ma_handle (line 4436) | typedef ma_handle ma_semaphore;
type ma_log_callback (line 4504) | typedef struct
type ma_log (line 4513) | typedef struct
type ma_biquad_coefficient (line 4537) | typedef union
type ma_biquad_config (line 4543) | typedef struct
type ma_biquad (line 4557) | typedef struct
type ma_lpf1_config (line 4589) | typedef struct
type ma_lpf1 (line 4601) | typedef struct
type ma_lpf2 (line 4622) | typedef struct
type ma_lpf_config (line 4637) | typedef struct
type ma_lpf (line 4648) | typedef struct
type ma_hpf1_config (line 4678) | typedef struct
type ma_hpf1 (line 4690) | typedef struct
type ma_hpf2 (line 4710) | typedef struct
type ma_hpf_config (line 4724) | typedef struct
type ma_hpf (line 4735) | typedef struct
type ma_bpf2_config (line 4764) | typedef struct
type ma_bpf2 (line 4775) | typedef struct
type ma_bpf_config (line 4789) | typedef struct
type ma_bpf (line 4800) | typedef struct
type ma_notch2_config (line 4826) | typedef struct
type ma_notch2 (line 4837) | typedef struct
type ma_peak2_config (line 4856) | typedef struct
type ma_peak2 (line 4868) | typedef struct
type ma_loshelf2_config (line 4887) | typedef struct
type ma_loshelf2 (line 4899) | typedef struct
type ma_hishelf2_config (line 4918) | typedef struct
type ma_hishelf2 (line 4930) | typedef struct
type ma_delay_config (line 4948) | typedef struct
type ma_delay (line 4962) | typedef struct
type ma_gainer_config (line 4982) | typedef struct
type ma_gainer (line 4991) | typedef struct
type ma_pan_mode (line 5017) | typedef enum
type ma_panner_config (line 5023) | typedef struct
type ma_panner (line 5034) | typedef struct
type ma_fader_config (line 5052) | typedef struct
type ma_fader (line 5061) | typedef struct
type ma_vec3f (line 5080) | typedef struct
type ma_atomic_vec3f (line 5087) | typedef struct
type ma_attenuation_model (line 5093) | typedef enum
type ma_positioning (line 5101) | typedef enum
type ma_handedness (line 5107) | typedef enum
type ma_spatializer_listener_config (line 5114) | typedef struct
type ma_spatializer_listener (line 5129) | typedef struct
type ma_spatializer_config (line 5163) | typedef struct
type ma_spatializer (line 5188) | typedef struct
type ma_linear_resampler_config (line 5275) | typedef struct
type ma_linear_resampler (line 5287) | typedef struct
type ma_resampler_config (line 5325) | typedef struct ma_resampler_config ma_resampler_config;
type ma_resampling_backend (line 5327) | typedef void ma_resampling_backend;
type ma_resampling_backend_vtable (line 5328) | typedef struct
type ma_resample_algorithm (line 5342) | typedef enum
type ma_resampler_config (line 5348) | struct ma_resampler_config
type ma_resampler (line 5365) | typedef struct
type ma_channel_conversion_path (line 5470) | typedef enum
type ma_mono_expansion_mode (line 5480) | typedef enum
type ma_channel_converter_config (line 5488) | typedef struct
type ma_channel_converter (line 5502) | typedef struct
type ma_data_converter_config (line 5537) | typedef struct
type ma_data_converter_execution_path (line 5559) | typedef enum
type ma_data_converter (line 5569) | typedef struct
type ma_data_source (line 5777) | typedef void ma_data_source;
type ma_data_source_vtable (line 5781) | typedef struct
type ma_data_source (line 5792) | typedef ma_data_source* (* ma_data_source_get_next_proc)(ma_data_source*...
type ma_data_source_config (line 5794) | typedef struct
type ma_data_source_base (line 5802) | typedef struct
type ma_audio_buffer_ref (line 5839) | typedef struct
type ma_audio_buffer_config (line 5864) | typedef struct
type ma_audio_buffer (line 5876) | typedef struct
type ma_paged_audio_buffer_page (line 5910) | typedef struct ma_paged_audio_buffer_page ma_paged_audio_buffer_page;
type ma_paged_audio_buffer_page (line 5911) | struct ma_paged_audio_buffer_page
type ma_paged_audio_buffer_data (line 5918) | typedef struct
type ma_paged_audio_buffer_config (line 5937) | typedef struct
type ma_paged_audio_buffer (line 5945) | typedef struct
type ma_rb (line 5968) | typedef struct
type ma_pcm_rb (line 6000) | typedef struct
type ma_duplex_rb (line 6042) | typedef struct
function MA_INLINE (line 6110) | static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_u...
type ma_fence (line 6202) | typedef struct
type ma_async_notification (line 6221) | typedef void ma_async_notification;
type ma_async_notification_callbacks (line 6223) | typedef struct
type ma_async_notification_poll (line 6236) | typedef struct
type ma_async_notification_event (line 6251) | typedef struct
type ma_slot_allocator_config (line 6289) | typedef struct
type ma_slot_allocator_group (line 6297) | typedef struct
type ma_slot_allocator (line 6302) | typedef struct
type ma_job (line 6322) | typedef struct ma_job ma_job;
type ma_result (line 6328) | typedef ma_result (* ma_job_proc)(ma_job* pJob);
type ma_job_type (line 6331) | typedef enum
type ma_job (line 6355) | struct ma_job
type ma_job_queue_flags (line 6483) | typedef enum
type ma_job_queue_config (line 6488) | typedef struct
type ma_job_queue (line 6497) | typedef struct
type ma_device_state (line 6637) | typedef enum
type ma_IMMNotificationClient (line 6651) | typedef struct
type ma_backend (line 6660) | typedef enum
type ma_device_job_thread_config (line 6689) | typedef struct
type ma_device_job_thread (line 6698) | typedef struct
type ma_device_notification_type (line 6713) | typedef enum
type ma_device_notification (line 6723) | typedef struct
type ma_device_type (line 6857) | typedef enum
type ma_share_mode (line 6865) | typedef enum
type ma_ios_session_category (line 6872) | typedef enum
type ma_ios_session_category_option (line 6885) | typedef enum
type ma_opensl_stream_type (line 6897) | typedef enum
type ma_opensl_recording_preset (line 6909) | typedef enum
type ma_wasapi_usage (line 6920) | typedef enum
type ma_aaudio_usage (line 6928) | typedef enum
type ma_aaudio_content_type (line 6950) | typedef enum
type ma_aaudio_input_preset (line 6960) | typedef enum
type ma_aaudio_allowed_capture_policy (line 6971) | typedef enum
type ma_timer (line 6979) | typedef union
type ma_device_id (line 6985) | typedef union
type ma_context_config (line 7010) | typedef struct ma_context_config ma_context_config;
type ma_device_config (line 7011) | typedef struct ma_device_config ma_device_config;
type ma_backend_callbacks (line 7012) | typedef struct ma_backend_callbacks ma_backend_callbacks;
type ma_device_info (line 7020) | typedef struct
type ma_device_config (line 7037) | struct ma_device_config
type ma_bool32 (line 7139) | typedef ma_bool32 (* ma_enum_devices_callback_proc)(ma_context* pContext...
type ma_device_descriptor (line 7145) | typedef struct
type ma_backend_callbacks (line 7226) | struct ma_backend_callbacks
type ma_context_config (line 7243) | struct ma_context_config
type ma_context_command__wasapi (line 7276) | typedef struct
type ma_context (line 7301) | struct ma_context
type ma_device (line 7708) | struct ma_device
function MA_INLINE (line 9707) | static MA_INLINE float* ma_offset_pcm_frames_ptr_f32(float* p, ma_uint64...
function MA_INLINE (line 9708) | static MA_INLINE const float* ma_offset_pcm_frames_const_ptr_f32(const f...
type ma_vfs (line 9793) | typedef void ma_vfs;
type ma_handle (line 9794) | typedef ma_handle ma_vfs_file;
type ma_open_mode_flags (line 9796) | typedef enum
type ma_seek_origin (line 9802) | typedef enum
type ma_file_info (line 9809) | typedef struct
type ma_vfs_callbacks (line 9814) | typedef struct
type ma_default_vfs (line 9836) | typedef struct
type ma_result (line 9846) | typedef ma_result (* ma_read_proc)(void* pUserData, void* pBufferOut, si...
type ma_result (line 9847) | typedef ma_result (* ma_seek_proc)(void* pUserData, ma_int64 offset, ma_...
type ma_result (line 9848) | typedef ma_result (* ma_tell_proc)(void* pUserData, ma_int64* pCursor);
type ma_encoding_format (line 9853) | typedef enum
type ma_decoder (line 9873) | typedef struct ma_decoder ma_decoder;
type ma_decoding_backend_config (line 9876) | typedef struct
type ma_decoding_backend_vtable (line 9885) | typedef struct
type ma_result (line 9895) | typedef ma_result (* ma_decoder_read_proc)(ma_decoder* pDecoder, void* p...
type ma_result (line 9896) | typedef ma_result (* ma_decoder_seek_proc)(ma_decoder* pDecoder, ma_int6...
type ma_result (line 9897) | typedef ma_result (* ma_decoder_tell_proc)(ma_decoder* pDecoder, ma_int6...
type ma_decoder_config (line 9899) | typedef struct
type ma_decoder (line 9916) | struct ma_decoder
type ma_encoder (line 10038) | typedef struct ma_encoder ma_encoder;
type ma_result (line 10040) | typedef ma_result (* ma_encoder_write_proc) (ma_encoder* pEnco...
type ma_result (line 10041) | typedef ma_result (* ma_encoder_seek_proc) (ma_encoder* pEnco...
type ma_result (line 10042) | typedef ma_result (* ma_encoder_init_proc) (ma_encoder* pEnco...
type ma_result (line 10044) | typedef ma_result (* ma_encoder_write_pcm_frames_proc)(ma_encoder* pEnco...
type ma_encoder_config (line 10046) | typedef struct
type ma_encoder (line 10057) | struct ma_encoder
type ma_waveform_type (line 10094) | typedef enum
type ma_waveform_config (line 10102) | typedef struct
type ma_waveform (line 10114) | typedef struct
type ma_pulsewave_config (line 10131) | typedef struct
type ma_pulsewave (line 10143) | typedef struct
type ma_noise_type (line 10158) | typedef enum
type ma_noise_config (line 10166) | typedef struct
type ma_noise (line 10178) | typedef struct
type ma_resource_manager (line 10226) | typedef struct ma_resource_manager ma_resource_manager;
type ma_resource_manager_data_buffer_node (line 10227) | typedef struct ma_resource_manager_data_buffer_node ma_resource_manager_...
type ma_resource_manager_data_buffer (line 10228) | typedef struct ma_resource_manager_data_buffer ma_resource_manager_...
type ma_resource_manager_data_stream (line 10229) | typedef struct ma_resource_manager_data_stream ma_resource_manager_...
type ma_resource_manager_data_source (line 10230) | typedef struct ma_resource_manager_data_source ma_resource_manager_...
type ma_resource_manager_data_source_flags (line 10232) | typedef enum
type ma_resource_manager_pipeline_stage_notification (line 10245) | typedef struct
type ma_resource_manager_pipeline_notifications (line 10251) | typedef struct
type ma_resource_manager_flags (line 10287) | typedef enum
type ma_resource_manager_data_source_config (line 10296) | typedef struct
type ma_resource_manager_data_supply_type (line 10313) | typedef enum
type ma_resource_manager_data_supply (line 10321) | typedef struct
type ma_resource_manager_data_buffer_node (line 10349) | struct ma_resource_manager_data_buffer_node
type ma_resource_manager_data_buffer (line 10363) | struct ma_resource_manager_data_buffer
type ma_resource_manager_data_stream (line 10384) | struct ma_resource_manager_data_stream
type ma_resource_manager_data_source (line 10412) | struct ma_resource_manager_data_source
type ma_resource_manager_config (line 10425) | typedef struct
type ma_resource_manager (line 10444) | struct ma_resource_manager
type ma_node_graph (line 10550) | typedef struct ma_node_graph ma_node_graph;
type ma_node (line 10551) | typedef void ma_node;
type ma_node_flags (line 10555) | typedef enum
type ma_node_state (line 10566) | typedef enum
type ma_node_vtable (line 10573) | typedef struct
type ma_node_config (line 10616) | typedef struct
type ma_node_output_bus (line 10633) | typedef struct ma_node_output_bus ma_node_output_bus;
type ma_node_output_bus (line 10634) | struct ma_node_output_bus
type ma_node_input_bus (line 10657) | typedef struct ma_node_input_bus ma_node_input_bus;
type ma_node_input_bus (line 10658) | struct ma_node_input_bus
type ma_node_base (line 10670) | typedef struct ma_node_base ma_node_base;
type ma_node_base (line 10671) | struct ma_node_base
type ma_node_graph_config (line 10724) | typedef struct
type ma_node_graph (line 10733) | struct ma_node_graph
type ma_data_source_node_config (line 10755) | typedef struct
type ma_data_source_node (line 10764) | typedef struct
type ma_splitter_node_config (line 10777) | typedef struct
type ma_splitter_node (line 10787) | typedef struct
type ma_biquad_node_config (line 10799) | typedef struct
type ma_biquad_node (line 10808) | typedef struct
type ma_lpf_node_config (line 10822) | typedef struct
type ma_lpf_node (line 10831) | typedef struct
type ma_hpf_node_config (line 10845) | typedef struct
type ma_hpf_node (line 10854) | typedef struct
type ma_bpf_node_config (line 10868) | typedef struct
type ma_bpf_node (line 10877) | typedef struct
type ma_notch_node_config (line 10891) | typedef struct
type ma_notch_node (line 10900) | typedef struct
type ma_peak_node_config (line 10914) | typedef struct
type ma_peak_node (line 10923) | typedef struct
type ma_loshelf_node_config (line 10937) | typedef struct
type ma_loshelf_node (line 10946) | typedef struct
type ma_hishelf_node_config (line 10960) | typedef struct
type ma_hishelf_node (line 10969) | typedef struct
type ma_delay_node_config (line 10980) | typedef struct
type ma_delay_node (line 10989) | typedef struct
type ma_engine (line 11013) | typedef struct ma_engine ma_engine;
type ma_sound (line 11014) | typedef struct ma_sound ma_sound;
type ma_sound_flags (line 11018) | typedef enum
type ma_engine_node_type (line 11039) | typedef enum
type ma_engine_node_config (line 11045) | typedef struct
type ma_engine_node (line 11063) | typedef struct
type ma_sound_config (line 11108) | typedef struct
type ma_sound (line 11137) | struct ma_sound
type ma_sound_inlined (line 11157) | typedef struct ma_sound_inlined ma_sound_inlined;
type ma_sound_inlined (line 11158) | struct ma_sound_inlined
type ma_sound_config (line 11166) | typedef ma_sound_config ma_sound_group_config;
type ma_sound (line 11167) | typedef ma_sound ma_sound_group;
type ma_engine_config (line 11174) | typedef struct
type ma_engine (line 11207) | struct ma_engine
type ma_IUnknown (line 11472) | typedef struct ma_IUnknown ma_IUnknown;
function MA_INLINE (line 11601) | static MA_INLINE void ma_cpuid(int info[4], int fid)
function ma_xgetbv (line 11610) | static MA_INLINE unsigned __int64 ma_xgetbv(int reg)
function MA_INLINE (line 11618) | static MA_INLINE void ma_cpuid(int info[4], int fid)
function MA_INLINE (line 11641) | static MA_INLINE ma_uint64 ma_xgetbv(int reg)
function MA_INLINE (line 11661) | static MA_INLINE ma_bool32 ma_has_sse2(void)
function MA_INLINE (line 11687) | static MA_INLINE ma_bool32 ma_has_avx()
function MA_INLINE (line 11721) | static MA_INLINE ma_bool32 ma_has_avx2(void)
function MA_INLINE (line 11756) | static MA_INLINE ma_bool32 ma_has_neon(void)
function MA_INLINE (line 11825) | static MA_INLINE ma_bool32 ma_is_little_endian(void)
function MA_INLINE (line 11835) | static MA_INLINE ma_bool32 ma_is_big_endian(void)
function ma_sleep__win32 (line 11875) | static void ma_sleep__win32(ma_uint32 milliseconds)
function ma_sleep__posix (line 11881) | static void ma_sleep__posix(ma_uint32 milliseconds)
function MA_INLINE (line 11902) | static MA_INLINE void ma_sleep(ma_uint32 milliseconds)
function MA_INLINE (line 11913) | static MA_INLINE void ma_yield(void)
function ma_disable_denormals (line 11948) | static MA_INLINE unsigned int ma_disable_denormals(void)
function MA_INLINE (line 11997) | static MA_INLINE void ma_restore_denormals(unsigned int prevState)
function ma_android_sdk_version (line 12038) | int ma_android_sdk_version()
function MA_INLINE (line 12145) | static MA_INLINE ma_bool32 ma_is_standard_sample_rate(ma_uint32 sampleRate)
function MA_API (line 12176) | MA_API void ma_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* ...
function MA_API (line 12191) | MA_API const char* ma_version_string(void)
function MA_INLINE (line 12216) | static MA_INLINE void ma_zero_memory_default(void* p, size_t sz)
function MA_INLINE (line 12252) | static MA_INLINE double ma_sind(double x)
function MA_INLINE (line 12258) | static MA_INLINE double ma_expd(double x)
function MA_INLINE (line 12264) | static MA_INLINE double ma_logd(double x)
function MA_INLINE (line 12270) | static MA_INLINE double ma_powd(double x, double y)
function MA_INLINE (line 12276) | static MA_INLINE double ma_sqrtd(double x)
function MA_INLINE (line 12283) | static MA_INLINE float ma_rsqrtf(float x)
function MA_INLINE (line 12317) | static MA_INLINE float ma_sinf(float x)
function MA_INLINE (line 12322) | static MA_INLINE double ma_cosd(double x)
function MA_INLINE (line 12327) | static MA_INLINE float ma_cosf(float x)
function MA_INLINE (line 12332) | static MA_INLINE double ma_log10d(double x)
function MA_INLINE (line 12337) | static MA_INLINE float ma_powf(float x, float y)
function MA_INLINE (line 12342) | static MA_INLINE float ma_log10f(float x)
function MA_INLINE (line 12348) | static MA_INLINE double ma_degrees_to_radians(double degrees)
function MA_INLINE (line 12353) | static MA_INLINE double ma_radians_to_degrees(double radians)
function MA_INLINE (line 12358) | static MA_INLINE float ma_degrees_to_radians_f(float degrees)
function MA_INLINE (line 12363) | static MA_INLINE float ma_radians_to_degrees_f(float radians)
function ma_strcpy_s (line 12380) | int ma_strcpy_s(char* dst, size_t dstSizeInBytes, const char* src)
function ma_wcscpy_s (line 12408) | int ma_wcscpy_s(wchar_t* dst, size_t dstCap, const wchar_t* src)
function ma_strncpy_s (line 12437) | int ma_strncpy_s(char* dst, size_t dstSizeInBytes, const char* src, size...
function ma_strcat_s (line 12471) | int ma_strcat_s(char* dst, size_t dstSizeInBytes, const char* src)
function ma_strncat_s (line 12513) | int ma_strncat_s(char* dst, size_t dstSizeInBytes, const char* src, size...
function ma_itoa_s (line 12559) | int ma_itoa_s(int value, char* dst, size_t dstSizeInBytes, int radix)
function ma_strcmp (line 12628) | int ma_strcmp(const char* str1, const char* str2)
function ma_strappend (line 12651) | int ma_strappend(char* dst, size_t dstSize, const char* srcA, const char...
function wchar_t (line 12688) | wchar_t* ma_copy_string_w(const wchar_t* src, const ma_allocation_callba...
function ma_result (line 12704) | static ma_result ma_result_from_errno(int e)
function MA_API (line 13107) | MA_API ma_result ma_fopen(FILE** ppFile, const char* pFilePath, const ch...
function MA_API (line 13169) | MA_API ma_result ma_wfopen(FILE** ppFile, const wchar_t* pFilePath, cons...
function MA_INLINE (line 13253) | static MA_INLINE void ma_copy_memory_64(void* dst, const void* src, ma_u...
function MA_INLINE (line 13273) | static MA_INLINE void ma_zero_memory_64(void* dst, ma_uint64 sizeInBytes)
function ma_next_power_of_2 (line 13294) | static MA_INLINE unsigned int ma_next_power_of_2(unsigned int x)
function ma_prev_power_of_2 (line 13307) | static MA_INLINE unsigned int ma_prev_power_of_2(unsigned int x)
function ma_round_to_power_of_2 (line 13312) | static MA_INLINE unsigned int ma_round_to_power_of_2(unsigned int x)
function ma_count_set_bits (line 13323) | static MA_INLINE unsigned int ma_count_set_bits(unsigned int x)
function ma__free_default (line 13356) | static void ma__free_default(void* p, void* pUserData)
function ma_allocation_callbacks (line 13362) | static ma_allocation_callbacks ma_allocation_callbacks_init_default(void)
function ma_result (line 13373) | static ma_result ma_allocation_callbacks_init_copy(ma_allocation_callbac...
function MA_API (line 13404) | MA_API const char* ma_log_level_to_string(ma_uint32 logLevel)
function ma_log_callback_debug (line 13426) | void ma_log_callback_debug(void* pUserData, ma_uint32 level, const char*...
function MA_API (line 13445) | MA_API ma_log_callback ma_log_callback_init(ma_log_callback_proc onLog, ...
function MA_API (line 13457) | MA_API ma_result ma_log_init(const ma_allocation_callbacks* pAllocationC...
function MA_API (line 13486) | MA_API void ma_log_uninit(ma_log* pLog)
function ma_log_lock (line 13497) | static void ma_log_lock(ma_log* pLog)
function ma_log_unlock (line 13506) | static void ma_log_unlock(ma_log* pLog)
function MA_API (line 13515) | MA_API ma_result ma_log_register_callback(ma_log* pLog, ma_log_callback ...
function MA_API (line 13537) | MA_API ma_result ma_log_unregister_callback(ma_log* pLog, ma_log_callbac...
function MA_API (line 13566) | MA_API ma_result ma_log_post(ma_log* pLog, ma_uint32 level, const char* ...
function ma_vscprintf (line 13592) | static int ma_vscprintf(const ma_allocation_callbacks* pAllocationCallba...
function MA_API (line 13632) | MA_API ma_result ma_log_postv(ma_log* pLog, ma_uint32 level, const char*...
function MA_API (line 13738) | MA_API ma_result ma_log_postf(ma_log* pLog, ma_uint32 level, const char*...
function MA_INLINE (line 13758) | static MA_INLINE ma_uint8 ma_clip_u8(ma_int32 x)
function MA_INLINE (line 13763) | static MA_INLINE ma_int16 ma_clip_s16(ma_int32 x)
function MA_INLINE (line 13768) | static MA_INLINE ma_int64 ma_clip_s24(ma_int64 x)
function MA_INLINE (line 13773) | static MA_INLINE ma_int32 ma_clip_s32(ma_int64 x)
function MA_INLINE (line 13784) | static MA_INLINE float ma_clip_f32(float x)
function MA_INLINE (line 13792) | static MA_INLINE float ma_mix_f32(float x, float y, float a)
function MA_INLINE (line 13796) | static MA_INLINE float ma_mix_f32_fast(float x, float y, float a)
function MA_INLINE (line 13805) | static MA_INLINE __m128 ma_mix_f32_fast__sse2(__m128 x, __m128 y, __m128 a)
function MA_INLINE (line 13811) | static MA_INLINE __m256 ma_mix_f32_fast__avx2(__m256 x, __m256 y, __m256 a)
function MA_INLINE (line 13817) | static MA_INLINE float32x4_t ma_mix_f32_fast__neon(float32x4_t x, float3...
function MA_INLINE (line 13824) | static MA_INLINE double ma_mix_f64(double x, double y, double a)
function MA_INLINE (line 13828) | static MA_INLINE double ma_mix_f64_fast(double x, double y, double a)
function MA_INLINE (line 13833) | static MA_INLINE float ma_scale_to_range_f32(float x, float lo, float hi)
function MA_INLINE (line 13842) | static MA_INLINE ma_uint32 ma_gcf_u32(ma_uint32 a, ma_uint32 b)
function ma_uint32 (line 13858) | static ma_uint32 ma_ffs_32(ma_uint32 x)
function MA_INLINE (line 13872) | static MA_INLINE ma_int16 ma_float_to_fixed_16(float x)
function MA_INLINE (line 13898) | static MA_INLINE void ma_lcg_seed(ma_lcg* pLCG, ma_int32 seed)
function MA_INLINE (line 13904) | static MA_INLINE ma_int32 ma_lcg_rand_s32(ma_lcg* pLCG)
function MA_INLINE (line 13910) | static MA_INLINE ma_uint32 ma_lcg_rand_u32(ma_lcg* pLCG)
function MA_INLINE (line 13915) | static MA_INLINE ma_int16 ma_lcg_rand_s16(ma_lcg* pLCG)
function MA_INLINE (line 13920) | static MA_INLINE double ma_lcg_rand_f64(ma_lcg* pLCG)
function MA_INLINE (line 13925) | static MA_INLINE float ma_lcg_rand_f32(ma_lcg* pLCG)
function MA_INLINE (line 13930) | static MA_INLINE float ma_lcg_rand_range_f32(ma_lcg* pLCG, float lo, flo...
function MA_INLINE (line 13935) | static MA_INLINE ma_int32 ma_lcg_rand_range_s32(ma_lcg* pLCG, ma_int32 l...
function MA_INLINE (line 13946) | static MA_INLINE void ma_seed(ma_int32 seed)
function MA_INLINE (line 13951) | static MA_INLINE ma_int32 ma_rand_s32(void)
function MA_INLINE (line 13956) | static MA_INLINE ma_uint32 ma_rand_u32(void)
function MA_INLINE (line 13961) | static MA_INLINE double ma_rand_f64(void)
function MA_INLINE (line 13966) | static MA_INLINE float ma_rand_f32(void)
function MA_INLINE (line 13971) | static MA_INLINE float ma_rand_range_f32(float lo, float hi)
function MA_INLINE (line 13976) | static MA_INLINE ma_int32 ma_rand_range_s32(ma_int32 lo, ma_int32 hi)
function MA_INLINE (line 13982) | static MA_INLINE float ma_dither_f32_rectangle(float ditherMin, float di...
function MA_INLINE (line 13987) | static MA_INLINE float ma_dither_f32_triangle(float ditherMin, float dit...
function MA_INLINE (line 13994) | static MA_INLINE float ma_dither_f32(ma_dither_mode ditherMode, float di...
function MA_INLINE (line 14006) | static MA_INLINE ma_int32 ma_dither_s32(ma_dither_mode ditherMode, ma_in...
type ma_atomic_memory_order (line 14039) | typedef int ma_atomic_memory_order;
function MA_INLINE (line 14231) | static MA_INLINE ma_uint8 __stdcall ma_atomic_exchange_explicit_8(volati...
function MA_INLINE (line 14242) | static MA_INLINE ma_uint16 __stdcall ma_atomic_exchange_explicit_16(vola...
function MA_INLINE (line 14253) | static MA_INLINE ma_uint32 __stdcall ma_atomic_exchange_explicit_32(vola...
function MA_INLINE (line 14264) | static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(vola...
function MA_INLINE (line 14277) | static MA_INLINE ma_uint64 __stdcall ma_atomic_exchange_explicit_64(vola...
function MA_INLINE (line 14332) | static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_add_explicit_8(volat...
function MA_INLINE (line 14343) | static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_add_explicit_16(vol...
function MA_INLINE (line 14354) | static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_add_explicit_32(vol...
function MA_INLINE (line 14365) | static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(vol...
function MA_INLINE (line 14378) | static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_add_explicit_64(vol...
function MA_INLINE (line 14391) | static MA_INLINE void __stdcall ma_atomic_thread_fence(ma_atomic_memory_...
function MA_INLINE (line 14404) | static MA_INLINE void ma_atomic_thread_fence(ma_atomic_memory_order order)
function MA_INLINE (line 14414) | static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_ui...
function MA_INLINE (line 14425) | static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_...
function MA_INLINE (line 14436) | static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_...
function MA_INLINE (line 14447) | static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_...
function MA_INLINE (line 14470) | static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_sub_explicit_8(volat...
function MA_INLINE (line 14483) | static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_sub_explicit_16(vol...
function MA_INLINE (line 14496) | static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_sub_explicit_32(vol...
function MA_INLINE (line 14509) | static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_sub_explicit_64(vol...
function MA_INLINE (line 14522) | static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_and_explicit_8(volat...
function MA_INLINE (line 14539) | static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_and_explicit_16(vol...
function MA_INLINE (line 14556) | static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_and_explicit_32(vol...
function MA_INLINE (line 14573) | static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_and_explicit_64(vol...
function MA_INLINE (line 14590) | static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_xor_explicit_8(volat...
function MA_INLINE (line 14607) | static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_xor_explicit_16(vol...
function MA_INLINE (line 14624) | static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_xor_explicit_32(vol...
function MA_INLINE (line 14641) | static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_xor_explicit_64(vol...
function MA_INLINE (line 14658) | static MA_INLINE ma_uint8 __stdcall ma_atomic_fetch_or_explicit_8(volati...
function MA_INLINE (line 14675) | static MA_INLINE ma_uint16 __stdcall ma_atomic_fetch_or_explicit_16(vola...
function MA_INLINE (line 14692) | static MA_INLINE ma_uint32 __stdcall ma_atomic_fetch_or_explicit_32(vola...
function MA_INLINE (line 14709) | static MA_INLINE ma_uint64 __stdcall ma_atomic_fetch_or_explicit_64(vola...
type ma_uint8 (line 14750) | typedef ma_uint8 ma_atomic_flag;
type ma_uint32 (line 14755) | typedef ma_uint32 ma_atomic_flag;
function MA_INLINE (line 14824) | static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8...
function MA_INLINE (line 14829) | static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uin...
function MA_INLINE (line 14834) | static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uin...
function MA_INLINE (line 14839) | static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uin...
type ma_uint8 (line 14844) | typedef ma_uint8 ma_atomic_flag;
function MA_INLINE (line 14858) | static MA_INLINE ma_uint8 ma_atomic_exchange_explicit_8(volatile ma_uint...
function MA_INLINE (line 14865) | static MA_INLINE ma_uint16 ma_atomic_exchange_explicit_16(volatile ma_ui...
function MA_INLINE (line 14874) | static MA_INLINE ma_uint32 ma_atomic_exchange_explicit_32(volatile ma_ui...
function MA_INLINE (line 14883) | static MA_INLINE ma_uint64 ma_atomic_exchange_explicit_64(volatile ma_ui...
function MA_INLINE (line 14892) | static MA_INLINE ma_uint8 ma_atomic_fetch_add_explicit_8(volatile ma_uin...
function MA_INLINE (line 14897) | static MA_INLINE ma_uint16 ma_atomic_fetch_add_explicit_16(volatile ma_u...
function MA_INLINE (line 14902) | static MA_INLINE ma_uint32 ma_atomic_fetch_add_explicit_32(volatile ma_u...
function MA_INLINE (line 14907) | static MA_INLINE ma_uint64 ma_atomic_fetch_add_explicit_64(volatile ma_u...
function MA_INLINE (line 14912) | static MA_INLINE ma_uint8 ma_atomic_fetch_sub_explicit_8(volatile ma_uin...
function MA_INLINE (line 14917) | static MA_INLINE ma_uint16 ma_atomic_fetch_sub_explicit_16(volatile ma_u...
function MA_INLINE (line 14922) | static MA_INLINE ma_uint32 ma_atomic_fetch_sub_explicit_32(volatile ma_u...
function MA_INLINE (line 14927) | static MA_INLINE ma_uint64 ma_atomic_fetch_sub_explicit_64(volatile ma_u...
function MA_INLINE (line 14932) | static MA_INLINE ma_uint8 ma_atomic_fetch_or_explicit_8(volatile ma_uint...
function MA_INLINE (line 14937) | static MA_INLINE ma_uint16 ma_atomic_fetch_or_explicit_16(volatile ma_ui...
function MA_INLINE (line 14942) | static MA_INLINE ma_uint32 ma_atomic_fetch_or_explicit_32(volatile ma_ui...
function MA_INLINE (line 14947) | static MA_INLINE ma_uint64 ma_atomic_fetch_or_explicit_64(volatile ma_ui...
function MA_INLINE (line 14952) | static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uin...
function MA_INLINE (line 14957) | static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_u...
function MA_INLINE (line 14962) | static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_u...
function MA_INLINE (line 14967) | static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_u...
function MA_INLINE (line 14972) | static MA_INLINE ma_uint8 ma_atomic_fetch_and_explicit_8(volatile ma_uin...
function MA_INLINE (line 14977) | static MA_INLINE ma_uint16 ma_atomic_fetch_and_explicit_16(volatile ma_u...
function MA_INLINE (line 14982) | static MA_INLINE ma_uint32 ma_atomic_fetch_and_explicit_32(volatile ma_u...
function MA_INLINE (line 14987) | static MA_INLINE ma_uint64 ma_atomic_fetch_and_explicit_64(volatile ma_u...
function MA_INLINE (line 15004) | static MA_INLINE ma_uint8 ma_atomic_compare_and_swap_8(volatile ma_uint8...
function MA_INLINE (line 15014) | static MA_INLINE ma_uint16 ma_atomic_compare_and_swap_16(volatile ma_uin...
function MA_INLINE (line 15024) | static MA_INLINE ma_uint32 ma_atomic_compare_and_swap_32(volatile ma_uin...
function MA_INLINE (line 15034) | static MA_INLINE ma_uint64 ma_atomic_compare_and_swap_64(volatile ma_uin...
function MA_INLINE (line 15049) | static MA_INLINE ma_uint8 ma_atomic_exchange_explicit_8(volatile ma_uint...
function MA_INLINE (line 15060) | static MA_INLINE ma_uint16 ma_atomic_exchange_explicit_16(volatile ma_ui...
function MA_INLINE (line 15071) | static MA_INLINE ma_uint32 ma_atomic_exchange_explicit_32(volatile ma_ui...
function MA_INLINE (line 15082) | static MA_INLINE ma_uint64 ma_atomic_exchange_explicit_64(volatile ma_ui...
function MA_INLINE (line 15097) | static MA_INLINE ma_uint8 ma_atomic_fetch_add_explicit_8(volatile ma_uin...
function MA_INLINE (line 15108) | static MA_INLINE ma_uint16 ma_atomic_fetch_add_explicit_16(volatile ma_u...
function MA_INLINE (line 15119) | static MA_INLINE ma_uint32 ma_atomic_fetch_add_explicit_32(volatile ma_u...
function MA_INLINE (line 15130) | static MA_INLINE ma_uint64 ma_atomic_fetch_add_explicit_64(volatile ma_u...
function MA_INLINE (line 15148) | static MA_INLINE ma_uint8 ma_atomic_fetch_sub_explicit_8(volatile ma_uin...
function MA_INLINE (line 15159) | static MA_INLINE ma_uint16 ma_atomic_fetch_sub_explicit_16(volatile ma_u...
function MA_INLINE (line 15170) | static MA_INLINE ma_uint32 ma_atomic_fetch_sub_explicit_32(volatile ma_u...
function MA_INLINE (line 15181) | static MA_INLINE ma_uint64 ma_atomic_fetch_sub_explicit_64(volatile ma_u...
function MA_INLINE (line 15192) | static MA_INLINE ma_uint8 ma_atomic_fetch_and_explicit_8(volatile ma_uin...
function MA_INLINE (line 15203) | static MA_INLINE ma_uint16 ma_atomic_fetch_and_explicit_16(volatile ma_u...
function MA_INLINE (line 15214) | static MA_INLINE ma_uint32 ma_atomic_fetch_and_explicit_32(volatile ma_u...
function MA_INLINE (line 15225) | static MA_INLINE ma_uint64 ma_atomic_fetch_and_explicit_64(volatile ma_u...
function MA_INLINE (line 15236) | static MA_INLINE ma_uint8 ma_atomic_fetch_xor_explicit_8(volatile ma_uin...
function MA_INLINE (line 15247) | static MA_INLINE ma_uint16 ma_atomic_fetch_xor_explicit_16(volatile ma_u...
function MA_INLINE (line 15258) | static MA_INLINE ma_uint32 ma_atomic_fetch_xor_explicit_32(volatile ma_u...
function MA_INLINE (line 15269) | static MA_INLINE ma_uint64 ma_atomic_fetch_xor_explicit_64(volatile ma_u...
function MA_INLINE (line 15280) | static MA_INLINE ma_uint8 ma_atomic_fetch_or_explicit_8(volatile ma_uint...
function MA_INLINE (line 15291) | static MA_INLINE ma_uint16 ma_atomic_fetch_or_explicit_16(volatile ma_ui...
function MA_INLINE (line 15302) | static MA_INLINE ma_uint32 ma_atomic_fetch_or_explicit_32(volatile ma_ui...
function MA_INLINE (line 15313) | static MA_INLINE ma_uint64 ma_atomic_fetch_or_explicit_64(volatile ma_ui...
function MA_INLINE (line 15326) | static MA_INLINE ma_uint8 ma_atomic_load_explicit_8(volatile const ma_ui...
function MA_INLINE (line 15331) | static MA_INLINE ma_uint16 ma_atomic_load_explicit_16(volatile const ma_...
function MA_INLINE (line 15336) | static MA_INLINE ma_uint32 ma_atomic_load_explicit_32(volatile const ma_...
function MA_INLINE (line 15341) | static MA_INLINE ma_uint64 ma_atomic_load_explicit_64(volatile const ma_...
type ma_uint8 (line 15358) | typedef ma_uint8 ma_atomic_flag;
function MA_INLINE (line 15365) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_8(...
function MA_INLINE (line 15382) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_16...
function MA_INLINE (line 15399) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_32...
function MA_INLINE (line 15416) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_64...
function MA_INLINE (line 15438) | static MA_INLINE ma_bool32 ma_atomic_is_lock_free_8(volatile void* ptr)
function MA_INLINE (line 15443) | static MA_INLINE ma_bool32 ma_atomic_is_lock_free_16(volatile void* ptr)
function MA_INLINE (line 15448) | static MA_INLINE ma_bool32 ma_atomic_is_lock_free_32(volatile void* ptr)
function MA_INLINE (line 15453) | static MA_INLINE ma_bool32 ma_atomic_is_lock_free_64(volatile void* ptr)
function MA_INLINE (line 15468) | static MA_INLINE ma_bool32 ma_atomic_is_lock_free_ptr(volatile void** ptr)
function MA_INLINE (line 15472) | static MA_INLINE void* ma_atomic_load_explicit_ptr(volatile void** ptr, ...
function MA_INLINE (line 15476) | static MA_INLINE void ma_atomic_store_explicit_ptr(volatile void** dst, ...
function MA_INLINE (line 15480) | static MA_INLINE void* ma_atomic_exchange_explicit_ptr(volatile void** d...
function MA_INLINE (line 15484) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_pt...
function MA_INLINE (line 15488) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(...
function MA_INLINE (line 15492) | static MA_INLINE void* ma_atomic_compare_and_swap_ptr(volatile void** ds...
function MA_INLINE (line 15497) | static MA_INLINE ma_bool32 ma_atomic_is_lock_free_ptr(volatile void** ptr)
function MA_INLINE (line 15501) | static MA_INLINE void* ma_atomic_load_explicit_ptr(volatile void** ptr, ...
function MA_INLINE (line 15505) | static MA_INLINE void ma_atomic_store_explicit_ptr(volatile void** dst, ...
function MA_INLINE (line 15509) | static MA_INLINE void* ma_atomic_exchange_explicit_ptr(volatile void** d...
function MA_INLINE (line 15513) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_pt...
function MA_INLINE (line 15517) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_ptr(...
function MA_INLINE (line 15521) | static MA_INLINE void* ma_atomic_compare_and_swap_ptr(volatile void** ds...
type ma_atomic_if32 (line 15683) | typedef union
type ma_atomic_if64 (line 15688) | typedef union
function MA_INLINE (line 15695) | static MA_INLINE void ma_atomic_store_explicit_f32(volatile float* dst, ...
function MA_INLINE (line 15701) | static MA_INLINE void ma_atomic_store_explicit_f64(volatile double* dst,...
function MA_INLINE (line 15707) | static MA_INLINE float ma_atomic_load_explicit_f32(volatile const float*...
function MA_INLINE (line 15713) | static MA_INLINE double ma_atomic_load_explicit_f64(volatile const doubl...
function MA_INLINE (line 15719) | static MA_INLINE float ma_atomic_exchange_explicit_f32(volatile float* d...
function MA_INLINE (line 15727) | static MA_INLINE double ma_atomic_exchange_explicit_f64(volatile double*...
function MA_INLINE (line 15735) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f3...
function MA_INLINE (line 15741) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_strong_explicit_f6...
function MA_INLINE (line 15747) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f32(...
function MA_INLINE (line 15753) | static MA_INLINE ma_bool32 ma_atomic_compare_exchange_weak_explicit_f64(...
function MA_INLINE (line 15759) | static MA_INLINE float ma_atomic_fetch_add_explicit_f32(volatile float* ...
function MA_INLINE (line 15767) | static MA_INLINE double ma_atomic_fetch_add_explicit_f64(volatile double...
function MA_INLINE (line 15775) | static MA_INLINE float ma_atomic_fetch_sub_explicit_f32(volatile float* ...
function MA_INLINE (line 15783) | static MA_INLINE double ma_atomic_fetch_sub_explicit_f64(volatile double...
function MA_INLINE (line 15791) | static MA_INLINE float ma_atomic_fetch_or_explicit_f32(volatile float* d...
function MA_INLINE (line 15799) | static MA_INLINE double ma_atomic_fetch_or_explicit_f64(volatile double*...
function MA_INLINE (line 15807) | static MA_INLINE float ma_atomic_fetch_xor_explicit_f32(volatile float* ...
function MA_INLINE (line 15815) | static MA_INLINE double ma_atomic_fetch_xor_explicit_f64(volatile double...
function MA_INLINE (line 15823) | static MA_INLINE float ma_atomic_fetch_and_explicit_f32(volatile float* ...
function MA_INLINE (line 15831) | static MA_INLINE double ma_atomic_fetch_and_explicit_f64(volatile double...
function MA_INLINE (line 15861) | static MA_INLINE float ma_atomic_compare_and_swap_f32(volatile float* ds...
function MA_INLINE (line 15870) | static MA_INLINE double ma_atomic_compare_and_swap_f64(volatile double* ...
type ma_atomic_flag (line 15879) | typedef ma_atomic_flag ma_atomic_spinlock;
function MA_INLINE (line 15880) | static MA_INLINE void ma_atomic_spinlock_lock(volatile ma_atomic_spinloc...
function MA_INLINE (line 15890) | static MA_INLINE void ma_atomic_spinlock_unlock(volatile ma_atomic_spinl...
function MA_API (line 15978) | MA_API ma_uint64 ma_calculate_frame_count_after_resampling(ma_uint32 sam...
function ma_result (line 16012) | static ma_result ma_result_from_GetLastError(DWORD error)
function MA_INLINE (line 16040) | static MA_INLINE ma_result ma_spinlock_lock_ex(volatile ma_spinlock* pSp...
function MA_API (line 16061) | MA_API ma_result ma_spinlock_lock(volatile ma_spinlock* pSpinlock)
function MA_API (line 16066) | MA_API ma_result ma_spinlock_lock_noyield(volatile ma_spinlock* pSpinlock)
function MA_API (line 16071) | MA_API ma_result ma_spinlock_unlock(volatile ma_spinlock* pSpinlock)
type ma_thread_result (line 16088) | typedef unsigned long ma_thread_result;
function ma_result (line 16094) | static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_p...
function ma_thread_wait__posix (line 16181) | static void ma_thread_wait__posix(ma_thread* pThread)
function ma_result (line 16187) | static ma_result ma_mutex_init__posix(ma_mutex* pMutex)
function ma_mutex_uninit__posix (line 16205) | static void ma_mutex_uninit__posix(ma_mutex* pMutex)
function ma_mutex_lock__posix (line 16210) | static void ma_mutex_lock__posix(ma_mutex* pMutex)
function ma_mutex_unlock__posix (line 16215) | static void ma_mutex_unlock__posix(ma_mutex* pMutex)
function ma_result (line 16221) | static ma_result ma_event_init__posix(ma_event* pEvent)
function ma_event_uninit__posix (line 16240) | static void ma_event_uninit__posix(ma_event* pEvent)
function ma_result (line 16246) | static ma_result ma_event_wait__posix(ma_event* pEvent)
function ma_result (line 16260) | static ma_result ma_event_signal__posix(ma_event* pEvent)
function ma_result (line 16273) | static ma_result ma_semaphore_init__posix(int initialValue, ma_semaphore...
function ma_semaphore_uninit__posix (line 16297) | static void ma_semaphore_uninit__posix(ma_semaphore* pSemaphore)
function ma_result (line 16307) | static ma_result ma_semaphore_wait__posix(ma_semaphore* pSemaphore)
function ma_result (line 16327) | static ma_result ma_semaphore_release__posix(ma_semaphore* pSemaphore)
function ma_thread_priority_to_win32 (line 16343) | static int ma_thread_priority_to_win32(ma_thread_priority priority)
function ma_result (line 16357) | static ma_result ma_thread_create__win32(ma_thread* pThread, ma_thread_p...
function ma_thread_wait__win32 (line 16371) | static void ma_thread_wait__win32(ma_thread* pThread)
function ma_result (line 16378) | static ma_result ma_mutex_init__win32(ma_mutex* pMutex)
function ma_mutex_uninit__win32 (line 16388) | static void ma_mutex_uninit__win32(ma_mutex* pMutex)
function ma_mutex_lock__win32 (line 16393) | static void ma_mutex_lock__win32(ma_mutex* pMutex)
function ma_mutex_unlock__win32 (line 16398) | static void ma_mutex_unlock__win32(ma_mutex* pMutex)
function ma_result (line 16404) | static ma_result ma_event_init__win32(ma_event* pEvent)
function ma_event_uninit__win32 (line 16414) | static void ma_event_uninit__win32(ma_event* pEvent)
function ma_result (line 16419) | static ma_result ma_event_wait__win32(ma_event* pEvent)
function ma_result (line 16433) | static ma_result ma_event_signal__win32(ma_event* pEvent)
function ma_result (line 16444) | static ma_result ma_semaphore_init__win32(int initialValue, ma_semaphore...
function ma_semaphore_uninit__win32 (line 16454) | static void ma_semaphore_uninit__win32(ma_semaphore* pSemaphore)
function ma_result (line 16459) | static ma_result ma_semaphore_wait__win32(ma_semaphore* pSemaphore)
function ma_result (line 16473) | static ma_result ma_semaphore_release__win32(ma_semaphore* pSemaphore)
type ma_thread_proxy_data (line 16484) | typedef struct
function ma_result (line 16517) | static ma_result ma_thread_create(ma_thread* pThread, ma_thread_priority...
function ma_thread_wait (line 16555) | static void ma_thread_wait(ma_thread* pThread)
function MA_API (line 16569) | MA_API ma_result ma_mutex_init(ma_mutex* pMutex)
function MA_API (line 16583) | MA_API void ma_mutex_uninit(ma_mutex* pMutex)
function MA_API (line 16596) | MA_API void ma_mutex_lock(ma_mutex* pMutex)
function MA_API (line 16610) | MA_API void ma_mutex_unlock(ma_mutex* pMutex)
function MA_API (line 16625) | MA_API ma_result ma_event_init(ma_event* pEvent)
function ma_result (line 16640) | static ma_result ma_event_alloc_and_init(ma_event** ppEvent, ma_allocati...
function MA_API (line 16667) | MA_API void ma_event_uninit(ma_event* pEvent)
function ma_event_uninit_and_free (line 16681) | static void ma_event_uninit_and_free(ma_event* pEvent, ma_allocation_cal...
function MA_API (line 16692) | MA_API ma_result ma_event_wait(ma_event* pEvent)
function MA_API (line 16706) | MA_API ma_result ma_event_signal(ma_event* pEvent)
function MA_API (line 16721) | MA_API ma_result ma_semaphore_init(int initialValue, ma_semaphore* pSema...
function MA_API (line 16735) | MA_API void ma_semaphore_uninit(ma_semaphore* pSemaphore)
function MA_API (line 16749) | MA_API ma_result ma_semaphore_wait(ma_semaphore* pSemaphore)
function MA_API (line 16763) | MA_API ma_result ma_semaphore_release(ma_semaphore* pSemaphore)
function MA_API (line 16787) | MA_API ma_result ma_fence_init(ma_fence* pFence)
function MA_API (line 16810) | MA_API void ma_fence_uninit(ma_fence* pFence)
function MA_API (line 16825) | MA_API ma_result ma_fence_acquire(ma_fence* pFence)
function MA_API (line 16855) | MA_API ma_result ma_fence_release(ma_fence* pFence)
function MA_API (line 16892) | MA_API ma_result ma_fence_wait(ma_fence* pFence)
function MA_API (line 16928) | MA_API ma_result ma_async_notification_signal(ma_async_notification* pNo...
function ma_async_notification_poll__on_signal (line 16945) | static void ma_async_notification_poll__on_signal(ma_async_notification*...
function MA_API (line 16950) | MA_API ma_result ma_async_notification_poll_init(ma_async_notification_p...
function MA_API (line 16962) | MA_API ma_bool32 ma_async_notification_poll_is_signalled(const ma_async_...
function ma_async_notification_event__on_signal (line 16972) | static void ma_async_notification_event__on_signal(ma_async_notification...
function MA_API (line 16977) | MA_API ma_result ma_async_notification_event_init(ma_async_notification_...
function MA_API (line 17003) | MA_API ma_result ma_async_notification_event_uninit(ma_async_notificatio...
function MA_API (line 17021) | MA_API ma_result ma_async_notification_event_wait(ma_async_notification_...
function MA_API (line 17038) | MA_API ma_result ma_async_notification_event_signal(ma_async_notificatio...
function MA_API (line 17062) | MA_API ma_slot_allocator_config ma_slot_allocator_config_init(ma_uint32 ...
function MA_INLINE (line 17073) | static MA_INLINE ma_uint32 ma_slot_allocator_calculate_group_capacity(ma...
function MA_INLINE (line 17083) | static MA_INLINE ma_uint32 ma_slot_allocator_group_capacity(const ma_slo...
type ma_slot_allocator_heap_layout (line 17089) | typedef struct
function ma_result (line 17096) | static ma_result ma_slot_allocator_get_heap_layout(const ma_slot_allocat...
function MA_API (line 17123) | MA_API ma_result ma_slot_allocator_get_heap_size(const ma_slot_allocator...
function MA_API (line 17144) | MA_API ma_result ma_slot_allocator_init_preallocated(const ma_slot_alloc...
function MA_API (line 17174) | MA_API ma_result ma_slot_allocator_init(const ma_slot_allocator_config* ...
function MA_API (line 17204) | MA_API void ma_slot_allocator_uninit(ma_slot_allocator* pAllocator, cons...
function MA_API (line 17215) | MA_API ma_result ma_slot_allocator_alloc(ma_slot_allocator* pAllocator, ...
function MA_API (line 17281) | MA_API ma_result ma_slot_allocator_free(ma_slot_allocator* pAllocator, m...
function MA_INLINE (line 17330) | static MA_INLINE ma_uint32 ma_job_extract_refcount(ma_uint64 toc)
function MA_INLINE (line 17335) | static MA_INLINE ma_uint16 ma_job_extract_slot(ma_uint64 toc)
function MA_INLINE (line 17340) | static MA_INLINE ma_uint16 ma_job_extract_code(ma_uint64 toc)
function MA_INLINE (line 17345) | static MA_INLINE ma_uint64 ma_job_toc_to_allocation(ma_uint64 toc)
function MA_INLINE (line 17350) | static MA_INLINE ma_uint64 ma_job_set_refcount(ma_uint64 toc, ma_uint32 ...
function MA_API (line 17360) | MA_API ma_job ma_job_init(ma_uint16 code)
function MA_API (line 17413) | MA_API ma_result ma_job_process(ma_job* pJob)
function ma_result (line 17426) | static ma_result ma_job_process__noop(ma_job* pJob)
function ma_result (line 17436) | static ma_result ma_job_process__quit(ma_job* pJob)
function ma_result (line 17441) | static ma_result ma_job_process__custom(ma_job* pJob)
function MA_API (line 17455) | MA_API ma_job_queue_config ma_job_queue_config_init(ma_uint32 flags, ma_...
type ma_job_queue_heap_layout (line 17466) | typedef struct
function ma_result (line 17473) | static ma_result ma_job_queue_get_heap_layout(const ma_job_queue_config*...
function MA_API (line 17513) | MA_API ma_result ma_job_queue_get_heap_size(const ma_job_queue_config* p...
function MA_API (line 17534) | MA_API ma_result ma_job_queue_init_preallocated(const ma_job_queue_confi...
function MA_API (line 17589) | MA_API ma_result ma_job_queue_init(const ma_job_queue_config* pConfig, c...
function MA_API (line 17619) | MA_API void ma_job_queue_uninit(ma_job_queue* pQueue, const ma_allocatio...
function ma_bool32 (line 17645) | static ma_bool32 ma_job_queue_cas(volatile ma_uint64* dst, ma_uint64 exp...
function MA_API (line 17651) | MA_API ma_result ma_job_queue_post(ma_job_queue* pQueue, const ma_job* p...
function MA_API (line 17722) | MA_API ma_result ma_job_queue_next(ma_job_queue* pQueue, ma_job* pJob)
function MA_API (line 17815) | MA_API ma_handle ma_dlopen(ma_log* pLog, const char* filename)
function MA_API (line 17856) | MA_API void ma_dlclose(ma_log* pLog, ma_handle handle)
function MA_API (line 17873) | MA_API ma_proc ma_dlsym(ma_log* pLog, ma_handle handle, const char* symbol)
function MA_API (line 17944) | MA_API void ma_device_info_add_native_data_format(ma_device_info* pDevic...
type ma_backend_info (line 17960) | typedef struct
function MA_API (line 17985) | MA_API const char* ma_get_backend_name(ma_backend backend)
function MA_API (line 17994) | MA_API ma_result ma_get_backend_from_name(const char* pBackendName, ma_b...
function MA_API (line 18016) | MA_API ma_bool32 ma_is_backend_enabled(ma_backend backend)
function MA_API (line 18131) | MA_API ma_result ma_get_enabled_backends(ma_backend* pBackends, size_t b...
function MA_API (line 18165) | MA_API ma_bool32 ma_is_loopback_supported(ma_backend backend)
function ma_result (line 18259) | static ma_result ma_result_from_HRESULT(HRESULT hr)
type MA_PROPVARIANT (line 18364) | typedef struct
type const (line 18390) | typedef HRESULT (WINAPI * MA_PFN_CoCreateInstance)(const IID* rclsid, vo...
type ulOptions (line 18400) | typedef LONG (WINAPI * MA_PFN_RegOpenKeyExA)(HKEY hKey, const char* l...
type DWORD (line 18402) | typedef LONG (WINAPI * MA_PFN_RegQueryValueExA)(HKEY hKey, const char...
function MA_API (line 18406) | MA_API size_t ma_strlen_WCHAR(const WCHAR* str)
function MA_API (line 18416) | MA_API int ma_strcmp_WCHAR(const WCHAR *s1, const WCHAR *s2)
function MA_API (line 18426) | MA_API int ma_strcpy_s_WCHAR(WCHAR* dst, size_t dstCap, const WCHAR* src)
function ma_timer_init (line 18469) | static void ma_timer_init(ma_timer* pTimer)
function ma_timer_get_time_in_seconds (line 18481) | static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
function ma_timer_init (line 18492) | static void ma_timer_init(ma_timer* pTimer)
function ma_timer_get_time_in_seconds (line 18501) | static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
function MA_INLINE (line 18509) | static MA_INLINE void ma_timer_init(ma_timer* pTimer)
function MA_INLINE (line 18514) | static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer)
function ma_timer_init (line 18526) | static void ma_timer_init(ma_timer* pTimer)
function ma_timer_get_time_in_seconds (line 18534) | static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
function ma_timer_init (line 18548) | static void ma_timer_init(ma_timer* pTimer)
function ma_timer_get_time_in_seconds (line 18556) | static double ma_timer_get_time_in_seconds(ma_timer* pTimer)
function ma_uint32 (line 18575) | static ma_uint32 ma_get_closest_standard_sample_rate(ma_uint32 sampleRat...
function ma_device_disable_denormals (line 18606) | static MA_INLINE unsigned int ma_device_disable_denormals(ma_device* pDe...
function MA_INLINE (line 18617) | static MA_INLINE void ma_device_restore_denormals(ma_device* pDevice, un...
function ma_device_notification (line 18629) | static ma_device_notification ma_device_notification_init(ma_device* pDe...
function ma_device__on_notification (line 18640) | static void ma_device__on_notification(ma_device_notification notification)
function ma_device__on_notification_started (line 18656) | static void ma_device__on_notification_started(ma_device* pDevice)
function ma_device__on_notification_stopped (line 18661) | static void ma_device__on_notification_stopped(ma_device* pDevice)
function ma_device__on_notification_rerouted (line 18668) | static void ma_device__on_notification_rerouted(ma_device* pDevice)
function EMSCRIPTEN_KEEPALIVE (line 18675) | EMSCRIPTEN_KEEPALIVE
function ma_device__on_data_inner (line 18683) | static void ma_device__on_data_inner(ma_device* pDevice, void* pFramesOu...
function ma_device__on_data (line 18695) | static void ma_device__on_data(ma_device* pDevice, void* pFramesOut, con...
function ma_device__handle_data_callback (line 18797) | static void ma_device__handle_data_callback(ma_device* pDevice, void* pF...
function ma_device__read_frames_from_client (line 18848) | static void ma_device__read_frames_from_client(ma_device* pDevice, ma_ui...
function ma_device__send_frames_to_client (line 18954) | static void ma_device__send_frames_to_client(ma_device* pDevice, ma_uint...
function ma_result (line 19001) | static ma_result ma_device__handle_duplex_callback_capture(ma_device* pD...
function ma_result (line 19058) | static ma_result ma_device__handle_duplex_callback_playback(ma_device* p...
function MA_INLINE (line 19128) | static MA_INLINE void ma_device__set_state(ma_device* pDevice, ma_device...
function MA_API (line 19143) | MA_API ma_uint32 ma_get_format_priority_index(ma_format format) /* Lower...
function ma_bool32 (line 19158) | static ma_bool32 ma_device_descriptor_is_valid(const ma_device_descripto...
function ma_result (line 19180) | static ma_result ma_device_audio_thread__default_read_write(ma_device* p...
function ma_thread_result (line 19384) | static ma_thread_result MA_THREADCALL ma_device_thread__null(void* pData)
function ma_result (line 19444) | static ma_result ma_device_do_operation__null(ma_device* pDevice, ma_uin...
function ma_uint64 (line 19482) | static ma_uint64 ma_device_get_total_run_time_in_frames__null(ma_device*...
function ma_result (line 19494) | static ma_result ma_context_enumerate_devices__null(ma_context* pContext...
function ma_result (line 19524) | static ma_result ma_context_get_device_info__null(ma_context* pContext, ...
function ma_result (line 19553) | static ma_result ma_device_uninit__null(ma_device* pDevice)
function ma_result (line 19571) | static ma_result ma_device_init__null(ma_device* pDevice, const ma_devic...
function ma_result (line 19635) | static ma_result ma_device_start__null(ma_device* pDevice)
function ma_result (line 19645) | static ma_result ma_device_stop__null(ma_device* pDevice)
function ma_bool32 (line 19655) | static ma_bool32 ma_device_is_started__null(ma_device* pDevice)
function ma_result (line 19662) | static ma_result ma_device_write__null(ma_device* pDevice, const void* p...
function ma_result (line 19742) | static ma_result ma_device_read__null(ma_device* pDevice, void* pPCMFram...
function ma_result (line 19813) | static ma_result ma_context_uninit__null(ma_context* pContext)
function ma_result (line 19822) | static ma_result ma_context_init__null(ma_context* pContext, const ma_co...
type DWORD_PTR (line 19869) | typedef size_t DWORD_PTR;
type MA_WAVEFORMATEX (line 19928) | typedef struct
type MA_WAVEFORMATEXTENSIBLE (line 19939) | typedef struct
function ma_uint8 (line 19973) | static ma_uint8 ma_channel_id_to_ma__win32(DWORD id)
function DWORD (line 20000) | static DWORD ma_channel_id_to_win32(DWORD id)
function DWORD (line 20028) | static DWORD ma_channel_map_to_channel_mask__win32(const ma_channel* pCh...
function ma_channel_mask_to_channel_map__win32 (line 20041) | static void ma_channel_mask_to_channel_map__win32(DWORD dwChannelMask, m...
function ma_bool32 (line 20067) | static ma_bool32 ma_is_guid_equal(const void* a, const void* b)
function MA_INLINE (line 20075) | static MA_INLINE ma_bool32 ma_is_guid_null(const void* guid)
function ma_format (line 20081) | static ma_format ma_format_from_WAVEFORMATEX(const MA_WAVEFORMATEX* pWF)
type ma_OSVERSIONINFOEXW (line 20173) | typedef struct {
type PROPERTYKEY (line 20194) | typedef struct
function MA_INLINE (line 20203) | static MA_INLINE void ma_PropVariantInit(MA_PROPVARIANT* pProp)
type ma_IMMDeviceEnumerator (line 20238) | typedef struct ma_IMMDeviceEnumerator ma_IMMDeviceE...
type ma_IMMDeviceCollection (line 20239) | typedef struct ma_IMMDeviceCollection ma_IMMDeviceC...
type ma_IMMDevice (line 20240) | typedef struct ma_IMMDevice ma_IMMDevice;
type ma_IActivateAudioInterfaceCompletionHandler (line 20242) | typedef struct ma_IActivateAudioInterfaceCompletionHandler ma_IActivateA...
type ma_IActivateAudioInterfaceAsyncOperation (line 20243) | typedef struct ma_IActivateAudioInterfaceAsyncOperation ma_IActivateA...
type ma_IPropertyStore (line 20245) | typedef struct ma_IPropertyStore ma_IPropertyS...
type ma_IAudioClient (line 20246) | typedef struct ma_IAudioClient ma_IAudioClient;
type ma_IAudioClient2 (line 20247) | typedef struct ma_IAudioClient2 ma_IAudioClie...
type ma_IAudioClient3 (line 20248) | typedef struct ma_IAudioClient3 ma_IAudioClie...
type ma_IAudioRenderClient (line 20249) | typedef struct ma_IAudioRenderClient ma_IAudioRend...
type ma_IAudioCaptureClient (line 20250) | typedef struct ma_IAudioCaptureClient ma_IAudioCapt...
type ma_int64 (line 20252) | typedef ma_int64 MA_REFERENCE_...
type ma_EDataFlow (line 20270) | typedef enum
type ma_ERole (line 20277) | typedef enum
type MA_AUDCLNT_SHAREMODE (line 20284) | typedef enum
type MA_AUDIO_STREAM_CATEGORY (line 20290) | typedef enum
type ma_AudioClientProperties (line 20295) | typedef struct
type ma_IUnknownVtbl (line 20303) | typedef struct
type ma_IUnknown (line 20310) | struct ma_IUnknown
function MA_INLINE (line 20314) | static MA_INLINE HRESULT ma_IUnknown_QueryInterface(ma_IUnknown* pThis, ...
function MA_INLINE (line 20315) | static MA_INLINE ULONG ma_IUnknown_AddRef(ma_IUnknown* pThis) ...
function MA_INLINE (line 20316) | static MA_INLINE ULONG ma_IUnknown_Release(ma_IUnknown* pThis) ...
type ma_IMMNotificationClientVtbl (line 20320) | typedef struct
type ma_IMMDeviceEnumeratorVtbl (line 20336) | typedef struct
type ma_IMMDeviceEnumerator (line 20350) | struct ma_IMMDeviceEnumerator
function MA_INLINE (line 20354) | static MA_INLINE HRESULT ma_IMMDeviceEnumerator_QueryInterface(ma_IMMDev...
function MA_INLINE (line 20355) | static MA_INLINE ULONG ma_IMMDeviceEnumerator_AddRef(ma_IMMDeviceEnume...
function MA_INLINE (line 20356) | static MA_INLINE ULONG ma_IMMDeviceEnumerator_Release(ma_IMMDeviceEnum...
function MA_INLINE (line 20357) | static MA_INLINE HRESULT ma_IMMDeviceEnumerator_EnumAudioEndpoints(ma_IM...
function MA_INLINE (line 20358) | static MA_INLINE HRESULT ma_IMMDeviceEnumerator_GetDefaultAudioEndpoint(...
function MA_INLINE (line 20359) | static MA_INLINE HRESULT ma_IMMDeviceEnumerator_GetDevice(ma_IMMDeviceEn...
function MA_INLINE (line 20360) | static MA_INLINE HRESULT ma_IMMDeviceEnumerator_RegisterEndpointNotifica...
function MA_INLINE (line 20361) | static MA_INLINE HRESULT ma_IMMDeviceEnumerator_UnregisterEndpointNotifi...
type ma_IMMDeviceCollectionVtbl (line 20365) | typedef struct
type ma_IMMDeviceCollection (line 20376) | struct ma_IMMDeviceCollection
function MA_INLINE (line 20380) | static MA_INLINE HRESULT ma_IMMDeviceCollection_QueryInterface(ma_IMMDev...
function MA_INLINE (line 20381) | static MA_INLINE ULONG ma_IMMDeviceCollection_AddRef(ma_IMMDeviceColle...
function MA_INLINE (line 20382) | static MA_INLINE ULONG ma_IMMDeviceCollection_Release(ma_IMMDeviceColl...
function MA_INLINE (line 20383) | static MA_INLINE HRESULT ma_IMMDeviceCollection_GetCount(ma_IMMDeviceCol...
function MA_INLINE (line 20384) | static MA_INLINE HRESULT ma_IMMDeviceCollection_Item(ma_IMMDeviceCollect...
type ma_IMMDeviceVtbl (line 20388) | typedef struct
type ma_IMMDevice (line 20401) | struct ma_IMMDevice
function MA_INLINE (line 20405) | static MA_INLINE HRESULT ma_IMMDevice_QueryInterface(ma_IMMDevice* pThis...
function MA_INLINE (line 20406) | static MA_INLINE ULONG ma_IMMDevice_AddRef(ma_IMMDevice* pThis) ...
function MA_INLINE (line 20407) | static MA_INLINE ULONG ma_IMMDevice_Release(ma_IMMDevice* pThis) ...
function MA_INLINE (line 20408) | static MA_INLINE HRESULT ma_IMMDevice_Activate(ma_IMMDevice* pThis, cons...
function MA_INLINE (line 20409) | static MA_INLINE HRESULT ma_IMMDevice_OpenPropertyStore(ma_IMMDevice* pT...
function MA_INLINE (line 20410) | static MA_INLINE HRESULT ma_IMMDevice_GetId(ma_IMMDevice* pThis, WCHAR**...
function MA_INLINE (line 20411) | static MA_INLINE HRESULT ma_IMMDevice_GetState(ma_IMMDevice* pThis, DWOR...
type ma_IActivateAudioInterfaceAsyncOperationVtbl (line 20414) | typedef struct
type ma_IActivateAudioInterfaceAsyncOperation (line 20424) | struct ma_IActivateAudioInterfaceAsyncOperation
function MA_INLINE (line 20428) | static MA_INLINE HRESULT ma_IActivateAudioInterfaceAsyncOperation_QueryI...
function MA_INLINE (line 20429) | static MA_INLINE ULONG ma_IActivateAudioInterfaceAsyncOperation_AddRef...
function MA_INLINE (line 20430) | static MA_INLINE ULONG ma_IActivateAudioInterfaceAsyncOperation_Releas...
function MA_INLINE (line 20431) | static MA_INLINE HRESULT ma_IActivateAudioInterfaceAsyncOperation_GetAct...
type ma_IPropertyStoreVtbl (line 20435) | typedef struct
type ma_IPropertyStore (line 20449) | struct ma_IPropertyStore
function MA_INLINE (line 20453) | static MA_INLINE HRESULT ma_IPropertyStore_QueryInterface(ma_IPropertySt...
function MA_INLINE (line 20454) | static MA_INLINE ULONG ma_IPropertyStore_AddRef(ma_IPropertyStore* pTh...
function MA_INLINE (line 20455) | static MA_INLINE ULONG ma_IPropertyStore_Release(ma_IPropertyStore* pT...
function MA_INLINE (line 20456) | static MA_INLINE HRESULT ma_IPropertyStore_GetCount(ma_IPropertyStore* p...
function MA_INLINE (line 20457) | static MA_INLINE HRESULT ma_IPropertyStore_GetAt(ma_IPropertyStore* pThi...
function MA_INLINE (line 20458) | static MA_INLINE HRESULT ma_IPropertyStore_GetValue(ma_IPropertyStore* p...
function MA_INLINE (line 20459) | static MA_INLINE HRESULT ma_IPropertyStore_SetValue(ma_IPropertyStore* p...
function MA_INLINE (line 20460) | static MA_INLINE HRESULT ma_IPropertyStore_Commit(ma_IPropertyStore* pTh...
type ma_IAudioClientVtbl (line 20464) | typedef struct
type ma_IAudioClient (line 20485) | struct ma_IAudioClient
function MA_INLINE (line 20489) | static MA_INLINE HRESULT ma_IAudioClient_QueryInterface(ma_IAudioClient*...
function MA_INLINE (line 20490) | static MA_INLINE ULONG ma_IAudioClient_AddRef(ma_IAudioClient* pThis) ...
function MA_INLINE (line 20491) | static MA_INLINE ULONG ma_IAudioClient_Release(ma_IAudioClient* pThis)...
function MA_INLINE (line 20492) | static MA_INLINE HRESULT ma_IAudioClient_Initialize(ma_IAudioClient* pTh...
function MA_INLINE (line 20493) | static MA_INLINE HRESULT ma_IAudioClient_GetBufferSize(ma_IAudioClient* ...
function MA_INLINE (line 20494) | static MA_INLINE HRESULT ma_IAudioClient_GetStreamLatency(ma_IAudioClien...
function MA_INLINE (line 20495) | static MA_INLINE HRESULT ma_IAudioClient_GetCurrentPadding(ma_IAudioClie...
function MA_INLINE (line 20496) | static MA_INLINE HRESULT ma_IAudioClient_IsFormatSupported(ma_IAudioClie...
function MA_INLINE (line 20497) | static MA_INLINE HRESULT ma_IAudioClient_GetMixFormat(ma_IAudioClient* p...
function MA_INLINE (line 20498) | static MA_INLINE HRESULT ma_IAudioClient_GetDevicePeriod(ma_IAudioClient...
function MA_INLINE (line 20499) | static MA_INLINE HRESULT ma_IAudioClient_Start(ma_IAudioClient* pThis) ...
function MA_INLINE (line 20500) | static MA_INLINE HRESULT ma_IAudioClient_Stop(ma_IAudioClient* pThis) ...
function MA_INLINE (line 20501) | static MA_INLINE HRESULT ma_IAudioClient_Reset(ma_IAudioClient* pThis) ...
function MA_INLINE (line 20502) | static MA_INLINE HRESULT ma_IAudioClient_SetEventHandle(ma_IAudioClient*...
function MA_INLINE (line 20503) | static MA_INLINE HRESULT ma_IAudioClient_GetService(ma_IAudioClient* pTh...
type ma_IAudioClient2Vtbl (line 20506) | typedef struct
type ma_IAudioClient2 (line 20532) | struct ma_IAudioClient2
function MA_INLINE (line 20536) | static MA_INLINE HRESULT ma_IAudioClient2_QueryInterface(ma_IAudioClient...
function MA_INLINE (line 20537) | static MA_INLINE ULONG ma_IAudioClient2_AddRef(ma_IAudioClient2* pThis...
function MA_INLINE (line 20538) | static MA_INLINE ULONG ma_IAudioClient2_Release(ma_IAudioClient2* pThi...
function MA_INLINE (line 20539) | static MA_INLINE HRESULT ma_IAudioClient2_Initialize(ma_IAudioClient2* p...
function MA_INLINE (line 20540) | static MA_INLINE HRESULT ma_IAudioClient2_GetBufferSize(ma_IAudioClient2...
function MA_INLINE (line 20541) | static MA_INLINE HRESULT ma_IAudioClient2_GetStreamLatency(ma_IAudioClie...
function MA_INLINE (line 20542) | static MA_INLINE HRESULT ma_IAudioClient2_GetCurrentPadding(ma_IAudioCli...
function MA_INLINE (line 20543) | static MA_INLINE HRESULT ma_IAudioClient2_IsFormatSupported(ma_IAudioCli...
function MA_INLINE (line 20544) | static MA_INLINE HRESULT ma_IAudioClient2_GetMixFormat(ma_IAudioClient2*...
function MA_INLINE (line 20545) | static MA_INLINE HRESULT ma_IAudioClient2_GetDevicePeriod(ma_IAudioClien...
function MA_INLINE (line 20546) | static MA_INLINE HRESULT ma_IAudioClient2_Start(ma_IAudioClient2* pThis)...
function MA_INLINE (line 20547) | static MA_INLINE HRESULT ma_IAudioClient2_Stop(ma_IAudioClient2* pThis) ...
function MA_INLINE (line 20548) | static MA_INLINE HRESULT ma_IAudioClient2_Reset(ma_IAudioClient2* pThis)...
function MA_INLINE (line 20549) | static MA_INLINE HRESULT ma_IAudioClient2_SetEventHandle(ma_IAudioClient...
function MA_INLINE (line 20550) | static MA_INLINE HRESULT ma_IAudioClient2_GetService(ma_IAudioClient2* p...
function MA_INLINE (line 20551) | static MA_INLINE HRESULT ma_IAudioClient2_IsOffloadCapable(ma_IAudioClie...
function MA_INLINE (line 20552) | static MA_INLINE HRESULT ma_IAudioClient2_SetClientProperties(ma_IAudioC...
function MA_INLINE (line 20553) | static MA_INLINE HRESULT ma_IAudioClient2_GetBufferSizeLimits(ma_IAudioC...
type ma_IAudioClient3Vtbl (line 20557) | typedef struct
type ma_IAudioClient3 (line 20588) | struct ma_IAudioClient3
function MA_INLINE (line 20592) | static MA_INLINE HRESULT ma_IAudioClient3_QueryInterface(ma_IAudioClient...
function MA_INLINE (line 20593) | static MA_INLINE ULONG ma_IAudioClient3_AddRef(ma_IAudioClient3* pThis...
function MA_INLINE (line 20594) | static MA_INLINE ULONG ma_IAudioClient3_Release(ma_IAudioClient3* pThi...
function MA_INLINE (line 20595) | static MA_INLINE HRESULT ma_IAudioClient3_Initialize(ma_IAudioClient3* p...
function MA_INLINE (line 20596) | static MA_INLINE HRESULT ma_IAudioClient3_GetBufferSize(ma_IAudioClient3...
function MA_INLINE (line 20597) | static MA_INLINE HRESULT ma_IAudioClient3_GetStreamLatency(ma_IAudioClie...
function MA_INLINE (line 20598) | static MA_INLINE HRESULT ma_IAudioClient3_GetCurrentPadding(ma_IAudioCli...
function MA_INLINE (line 20599) | static MA_INLINE HRESULT ma_IAudioClient3_IsFormatSupported(ma_IAudioCli...
function MA_INLINE (line 20600) | static MA_INLINE HRESULT ma_IAudioClient3_GetMixFormat(ma_IAudioClient3*...
function MA_INLINE (line 20601) | static MA_INLINE HRESULT ma_IAudioClient3_GetDevicePeriod(ma_IAudioClien...
function MA_INLINE (line 20602) | static MA_INLINE HRESULT ma_IAudioClient3_Start(ma_IAudioClient3* pThis)...
function MA_INLINE (line 20603) | static MA_INLINE HRESULT ma_IAudioClient3_Stop(ma_IAudioClient3* pThis) ...
function MA_INLINE (line 20604) | static MA_INLINE HRESULT ma_IAudioClient3_Reset(ma_IAudioClient3* pThis)...
function MA_INLINE (line 20605) | static MA_INLINE HRESULT ma_IAudioClient3_SetEventHandle(ma_IAudioClient...
function MA_INLINE (line 20606) | static MA_INLINE HRESULT ma_IAudioClient3_GetService(ma_IAudioClient3* p...
function MA_INLINE (line 20607) | static MA_INLINE HRESULT ma_IAudioClient3_IsOffloadCapable(ma_IAudioClie...
function MA_INLINE (line 20608) | static MA_INLINE HRESULT ma_IAudioClient3_SetClientProperties(ma_IAudioC...
function MA_INLINE (line 20609) | static MA_INLINE HRESULT ma_IAudioClient3_GetBufferSizeLimits(ma_IAudioC...
function MA_INLINE (line 20610) | static MA_INLINE HRESULT ma_IAudioClient3_GetSharedModeEnginePeriod(ma_I...
function MA_INLINE (line 20611) | static MA_INLINE HRESULT ma_IAudioClient3_GetCurrentSharedModeEnginePeri...
function MA_INLINE (line 20612) | static MA_INLINE HRESULT ma_IAudioClient3_InitializeSharedAudioStream(ma...
type ma_IAudioRenderClientVtbl (line 20616) | typedef struct
type ma_IAudioRenderClient (line 20627) | struct ma_IAudioRenderClient
function MA_INLINE (line 20631) | static MA_INLINE HRESULT ma_IAudioRenderClient_QueryInterface(ma_IAudioR...
function MA_INLINE (line 20632) | static MA_INLINE ULONG ma_IAudioRenderClient_AddRef(ma_IAudioRenderCli...
function MA_INLINE (line 20633) | static MA_INLINE ULONG ma_IAudioRenderClient_Release(ma_IAudioRenderCl...
function MA_INLINE (line 20634) | static MA_INLINE HRESULT ma_IAudioRenderClient_GetBuffer(ma_IAudioRender...
function MA_INLINE (line 20635) | static MA_INLINE HRESULT ma_IAudioRenderClient_ReleaseBuffer(ma_IAudioRe...
type ma_IAudioCaptureClientVtbl (line 20639) | typedef struct
type ma_IAudioCaptureClient (line 20651) | struct ma_IAudioCaptureClient
function MA_INLINE (line 20655) | static MA_INLINE HRESULT ma_IAudioCaptureClient_QueryInterface(ma_IAudio...
function MA_INLINE (line 20656) | static MA_INLINE ULONG ma_IAudioCaptureClient_AddRef(ma_IAudioCaptureC...
function MA_INLINE (line 20657) | static MA_INLINE ULONG ma_IAudioCaptureClient_Release(ma_IAudioCapture...
function MA_INLINE (line 20658) | static MA_INLINE HRESULT ma_IAudioCaptureClient_GetBuffer(ma_IAudioCaptu...
function MA_INLINE (line 20659) | static MA_INLINE HRESULT ma_IAudioCaptureClient_ReleaseBuffer(ma_IAudioC...
function MA_INLINE (line 20660) | static MA_INLINE HRESULT ma_IAudioCaptureClient_GetNextPacketSize(ma_IAu...
type const (line 20664) | typedef HRESULT (WINAPI * MA_PFN_ActivateAudioInterfaceAsync)(const wcha...
type ma_completion_handler_uwp (line 20672) | typedef struct ma_completion_handler_uwp ma_completion_handler_uwp;
type ma_completion_handler_uwp_vtbl (line 20674) | typedef struct
type ma_completion_handler_uwp (line 20684) | struct ma_completion_handler_uwp
function HRESULT (line 20691) | static HRESULT STDMETHODCALLTYPE ma_completion_handler_uwp_QueryInterfac...
function ULONG (line 20708) | static ULONG STDMETHODCALLTYPE ma_completion_handler_uwp_AddRef(ma_compl...
function ULONG (line 20713) | static ULONG STDMETHODCALLTYPE ma_completion_handler_uwp_Release(ma_comp...
function HRESULT (line 20723) | static HRESULT STDMETHODCALLTYPE ma_completion_handler_uwp_ActivateCompl...
function ma_result (line 20738) | static ma_result ma_completion_handler_uwp_init(ma_completion_handler_uw...
function ma_completion_handler_uwp_uninit (line 20753) | static void ma_completion_handler_uwp_uninit(ma_completion_handler_uwp* ...
function ma_completion_handler_uwp_wait (line 20760) | static void ma_completion_handler_uwp_wait(ma_completion_handler_uwp* pH...
function HRESULT (line 20768) | static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_QueryInterface...
function ULONG (line 20785) | static ULONG STDMETHODCALLTYPE ma_IMMNotificationClient_AddRef(ma_IMMNot...
function ULONG (line 20790) | static ULONG STDMETHODCALLTYPE ma_IMMNotificationClient_Release(ma_IMMNo...
function HRESULT (line 20800) | static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceStateC...
function HRESULT (line 20884) | static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceAdded(...
function HRESULT (line 20896) | static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceRemove...
function HRESULT (line 20908) | static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDevic...
function HRESULT (line 21011) | static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnPropertyValu...
type ma_IMMDevice (line 21049) | typedef ma_IMMDevice ma_WASAPIDeviceInterface;
type ma_IUnknown (line 21051) | typedef ma_IUnknown ma_WASAPIDeviceInterface;
function ma_context_command__wasapi (line 21059) | static ma_context_command__wasapi ma_context_init_command__wasapi(int code)
function ma_result (line 21069) | static ma_result ma_context_post_command__wasapi(ma_context* pContext, c...
function ma_result (line 21117) | static ma_result ma_context_next_command__wasapi(ma_context* pContext, m...
function ma_thread_result (line 21138) | static ma_thread_result MA_THREADCALL ma_context_command_thread__wasapi(...
function ma_result (line 21203) | static ma_result ma_device_create_IAudioClient_service__wasapi(ma_contex...
function ma_result (line 21222) | static ma_result ma_device_release_IAudioClient_service__wasapi(ma_devic...
function ma_add_native_data_format_to_device_info_from_WAVEFORMATEX (line 21239) | static void ma_add_native_data_format_to_device_info_from_WAVEFORMATEX(c...
function ma_result (line 21255) | static ma_result ma_context_get_device_info_from_IAudioClient__wasapi(ma...
function ma_EDataFlow (line 21382) | static ma_EDataFlow ma_device_type_to_EDataFlow(ma_device_type deviceType)
function ma_result (line 21394) | static ma_result ma_context_create_IMMDeviceEnumerator__wasapi(ma_contex...
function WCHAR (line 21415) | static WCHAR* ma_context_get_default_device_id_from_IMMDeviceEnumerator_...
function WCHAR (line 21451) | static WCHAR* ma_context_get_default_device_id__wasapi(ma_context* pCont...
function ma_result (line 21470) | static ma_result ma_context_get_MMDevice__wasapi(ma_context* pContext, m...
function ma_result (line 21499) | static ma_result ma_context_get_device_id_from_MMDevice__wasapi(ma_conte...
function ma_result (line 21526) | static ma_result ma_context_get_device_info_from_MMDevice__wasapi(ma_con...
function ma_result (line 21581) | static ma_result ma_context_enumerate_devices_by_type__wasapi(ma_context...
function ma_result (line 21641) | static ma_result ma_context_get_IAudioClient_Desktop__wasapi(ma_context*...
function ma_result (line 21663) | static ma_result ma_context_get_IAudioClient_UWP__wasapi(ma_context* pCo...
type MA_AUDIOCLIENT_ACTIVATION_TYPE (line 21747) | typedef enum
type MA_PROCESS_LOOPBACK_MODE (line 21754) | typedef enum
type MA_AUDIOCLIENT_PROCESS_LOOPBACK_PARAMS (line 21761) | typedef struct
type MA_AUDIOCLIENT_ACTIVATION_PARAMS (line 21778) | typedef struct
function ma_result (line 21794) | static ma_result ma_context_get_IAudioClient__wasapi(ma_context* pContex...
function ma_result (line 21848) | static ma_result ma_context_enumerate_devices__wasapi(ma_context* pConte...
function ma_result (line 21901) | static ma_result ma_context_get_device_info__wasapi(ma_context* pContext...
function ma_result (line 21951) | static ma_result ma_device_uninit__wasapi(ma_device* pDevice)
type ma_device_init_internal_data__wasapi (line 22001) | typedef struct
function ma_result (line 22034) | static ma_result ma_device_init_internal__wasapi(ma_context* pContext, m...
function ma_result (line 22516) | static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_...
function ma_result (line 22637) | static ma_result ma_device_init__wasapi(ma_device* pDevice, const ma_dev...
function ma_result (line 22866) | static ma_result ma_device__get_available_frames__wasapi(ma_device* pDev...
function ma_result (line 22922) | static ma_result ma_device_reroute__wasapi(ma_device* pDevice, ma_device...
function ma_result (line 22946) | static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
function ma_result (line 22981) | static ma_result ma_device_start__wasapi(ma_device* pDevice)
function ma_result (line 22997) | static ma_result ma_device_stop__wasapi_nolock(ma_device* pDevice)
function ma_result (line 23100) | static ma_result ma_device_stop__wasapi(ma_device* pDevice)
function ma_result (line 23121) | static ma_result ma_device_read__wasapi(ma_device* pDevice, void* pFrame...
function ma_result (line 23318) | static ma_result ma_device_write__wasapi(ma_device* pDevice, const void*...
function ma_result (line 23411) | static ma_result ma_device_data_loop_wakeup__wasapi(ma_device* pDevice)
function ma_result (line 23427) | static ma_result ma_context_uninit__wasapi(ma_context* pContext)
function ma_result (line 23458) | static ma_result ma_context_init__wasapi(ma_context* pContext, const ma_...
type MA_DSBUFFERDESC (line 23662) | typedef struct
type MA_DSCBUFFERDESC (line 23672) | typedef struct
type MA_DSCAPS (line 23683) | typedef struct
type MA_DSBCAPS (line 23711) | typedef struct
type MA_DSCCAPS (line 23720) | typedef struct
type MA_DSCBCAPS (line 23728) | typedef struct
type MA_DSBPOSITIONNOTIFY (line 23736) | typedef struct
type ma_IDirectSound (line 23742) | typedef struct ma_IDirectSound ma_IDirectSound;
type ma_IDirectSoundBuffer (line 23743) | typedef struct ma_IDirectSoundBuffer ma_IDirectSoundBuffer;
type ma_IDirectSoundCapture (line 23744) | typedef struct ma_IDirectSoundCapture ma_IDirectSoundCapture;
type ma_IDirectSoundCaptureBuffer (line 23745) | typedef struct ma_IDirectSoundCaptureBuffer ma_IDirectSoundCaptureBuffer;
type ma_IDirectSoundNotify (line 23746) | typedef struct ma_IDirectSoundNotify ma_IDirectSoundNotify;
type ma_IDirectSoundVtbl (line 23757) | typedef struct
type ma_IDirectSound (line 23774) | struct ma_IDirectSound
function MA_INLINE (line 23778) | static MA_INLINE HRESULT ma_IDirectSound_QueryInterface(ma_IDirectSound*...
function MA_INLINE (line 23779) | static MA_INLINE ULONG ma_IDirectSound_AddRef(ma_IDirectSound* pThis) ...
function MA_INLINE (line 23780) | static MA_INLINE ULONG ma_IDirectSound_Release(ma_IDirectSound* pThis)...
function MA_INLINE (line 23781) | static MA_INLINE HRESULT ma_IDirectSound_CreateSoundBuffer(ma_IDirectSou...
function MA_INLINE (line 23782) | static MA_INLINE HRESULT ma_IDirectSound_GetCaps(ma_IDirectSound* pThis,...
function MA_INLINE (line 23783) | static MA_INLINE HRESULT ma_IDirectSound_DuplicateSoundBuffer(ma_IDirect...
function MA_INLINE (line 23784) | static MA_INLINE HRESULT ma_IDirectSound_SetCooperativeLevel(ma_IDirectS...
function MA_INLINE (line 23785) | static MA_INLINE HRESULT ma_IDirectSound_Compact(ma_IDirectSound* pThis)...
function MA_INLINE (line 23786) | static MA_INLINE HRESULT ma_IDirectSound_GetSpeakerConfig(ma_IDirectSoun...
function MA_INLINE (line 23787) | static MA_INLINE HRESULT ma_IDirectSound_SetSpeakerConfig(ma_IDirectSoun...
function MA_INLINE (line 23788) | static MA_INLINE HRESULT ma_IDirectSound_Initialize(ma_IDirectSound* pTh...
type ma_IDirectSoundBufferVtbl (line 23792) | typedef struct
type ma_IDirectSoundBuffer (line 23819) | struct ma_IDirectSoundBuffer
function MA_INLINE (line 23823) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_QueryInterface(ma_IDirect...
function MA_INLINE (line 23824) | static MA_INLINE ULONG ma_IDirectSoundBuffer_AddRef(ma_IDirectSoundBuf...
function MA_INLINE (line 23825) | static MA_INLINE ULONG ma_IDirectSoundBuffer_Release(ma_IDirectSoundBu...
function MA_INLINE (line 23826) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetCaps(ma_IDirectSoundBu...
function MA_INLINE (line 23827) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetCurrentPosition(ma_IDi...
function MA_INLINE (line 23828) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetFormat(ma_IDirectSound...
function MA_INLINE (line 23829) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetVolume(ma_IDirectSound...
function MA_INLINE (line 23830) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetPan(ma_IDirectSoundBuf...
function MA_INLINE (line 23831) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetFrequency(ma_IDirectSo...
function MA_INLINE (line 23832) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_GetStatus(ma_IDirectSound...
function MA_INLINE (line 23833) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_Initialize(ma_IDirectSoun...
function MA_INLINE (line 23834) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_Lock(ma_IDirectSoundBuffe...
function MA_INLINE (line 23835) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_Play(ma_IDirectSoundBuffe...
function MA_INLINE (line 23836) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_SetCurrentPosition(ma_IDi...
function MA_INLINE (line 23837) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_SetFormat(ma_IDirectSound...
function MA_INLINE (line 23838) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_SetVolume(ma_IDirectSound...
function MA_INLINE (line 23839) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_SetPan(ma_IDirectSoundBuf...
function MA_INLINE (line 23840) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_SetFrequency(ma_IDirectSo...
function MA_INLINE (line 23841) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_Stop(ma_IDirectSoundBuffe...
function MA_INLINE (line 23842) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_Unlock(ma_IDirectSoundBuf...
function MA_INLINE (line 23843) | static MA_INLINE HRESULT ma_IDirectSoundBuffer_Restore(ma_IDirectSoundBu...
type ma_IDirectSoundCaptureVtbl (line 23847) | typedef struct
type ma_IDirectSoundCapture (line 23859) | struct ma_IDirectSoundCapture
function MA_INLINE (line 23863) | static MA_INLINE HRESULT ma_IDirectSoundCapture_QueryInterface (ma_I...
function MA_INLINE (line 23864) | static MA_INLINE ULONG ma_IDirectSoundCapture_AddRef (ma_I...
function MA_INLINE (line 23865) | static MA_INLINE ULONG ma_IDirectSoundCapture_Release (ma_I...
function MA_INLINE (line 23866) | static MA_INLINE HRESULT ma_IDirectSoundCapture_CreateCaptureBuffer(ma_I...
function MA_INLINE (line 23867) | static MA_INLINE HRESULT ma_IDirectSoundCapture_GetCaps (ma_I...
function MA_INLINE (line 23868) | static MA_INLINE HRESULT ma_IDirectSoundCapture_Initialize (ma_I...
type ma_IDirectSoundCaptureBufferVtbl (line 23872) | typedef struct
type ma_IDirectSoundCaptureBuffer (line 23890) | struct ma_IDirectSoundCaptureBuffer
function MA_INLINE (line 23894) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_QueryInterface(ma_...
function MA_INLINE (line 23895) | static MA_INLINE ULONG ma_IDirectSoundCaptureBuffer_AddRef(ma_IDirectS...
function MA_INLINE (line 23896) | static MA_INLINE ULONG ma_IDirectSoundCaptureBuffer_Release(ma_IDirect...
function MA_INLINE (line 23897) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_GetCaps(ma_IDirect...
function MA_INLINE (line 23898) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_GetCurrentPosition...
function MA_INLINE (line 23899) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_GetFormat(ma_IDire...
function MA_INLINE (line 23900) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_GetStatus(ma_IDire...
function MA_INLINE (line 23901) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_Initialize(ma_IDir...
function MA_INLINE (line 23902) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_Lock(ma_IDirectSou...
function MA_INLINE (line 23903) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_Start(ma_IDirectSo...
function MA_INLINE (line 23904) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_Stop(ma_IDirectSou...
function MA_INLINE (line 23905) | static MA_INLINE HRESULT ma_IDirectSoundCaptureBuffer_Unlock(ma_IDirectS...
type ma_IDirectSoundNotifyVtbl (line 23909) | typedef struct
type ma_IDirectSoundNotify (line 23919) | struct ma_IDirectSoundNotify
function MA_INLINE (line 23923) | static MA_INLINE HRESULT ma_IDirectSoundNotify_QueryInterface(ma_IDirect...
function MA_INLINE (line 23924) | static MA_INLINE ULONG ma_IDirectSoundNotify_AddRef(ma_IDirectSoundNot...
function MA_INLINE (line 23925) | static MA_INLINE ULONG ma_IDirectSoundNotify_Release(ma_IDirectSoundNo...
function MA_INLINE (line 23926) | static MA_INLINE HRESULT ma_IDirectSoundNotify_SetNotificationPositions(...
type const (line 23929) | typedef BOOL (CALLBACK * ma_DSEnumCallbackAProc) (GUID* p...
function ma_uint32 (line 23935) | static ma_uint32 ma_get_best_sample_rate_within_range(ma_uint32 sampleRa...
function ma_get_channels_from_speaker_config__dsound (line 23969) | static void ma_get_channels_from_speaker_config__dsound(DWORD speakerCon...
function ma_result (line 24011) | static ma_result ma_context_create_IDirectSound__dsound(ma_context* pCon...
function ma_result (line 24044) | static ma_result ma_context_create_IDirectSoundCapture__dsound(ma_contex...
function ma_result (line 24070) | static ma_result ma_context_get_format_info_for_IDirectSoundCapture__dso...
type ma_context_enumerate_devices_callback_data__dsound (line 24173) | typedef struct
function BOOL (line 24182) | static BOOL CALLBACK ma_context_enumerate_devices_callback__dsound(GUID*...
function ma_result (line 24213) | static ma_result ma_context_enumerate_devices__dsound(ma_context* pConte...
type ma_context_get_device_info_callback_data__dsound (line 24241) | typedef struct
function BOOL (line 24248) | static BOOL CALLBACK ma_context_get_device_info_callback__dsound(GUID* l...
function ma_result (line 24274) | static ma_result ma_context_get_device_info__dsound(ma_context* pContext...
function ma_result (line 24429) | static ma_result ma_device_uninit__dsound(ma_device* pDevice)
function ma_result (line 24453) | static ma_result ma_config_to_WAVEFORMATEXTENSIBLE(ma_format format, ma_...
function ma_uint32 (line 24504) | static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__dso...
function ma_result (line 24521) | static ma_result ma_device_init__dsound(ma_device* pDevice, const ma_dev...
function ma_result (line 24796) | static ma_result ma_device_data_loop__dsound(ma_device* pDevice)
function ma_result (line 25310) | static ma_result ma_context_uninit__dsound(ma_context* pContext)
function ma_result (line 25320) | static ma_result ma_context_init__dsound(ma_context* pContext, const ma_...
type UINT (line 25399) | typedef UINT MA_MMRESULT;
type UINT (line 25400) | typedef UINT MA_MMVERSION;
type MA_WAVEINCAPSA (line 25402) | typedef struct
type MA_WAVEOUTCAPSA (line 25413) | typedef struct
type MA_WAVEHDR (line 25425) | typedef struct tagWAVEHDR
type MA_WAVEOUTCAPS2A (line 25437) | typedef struct
type MA_WAVEINCAPS2A (line 25452) | typedef struct
type const (line 25468) | typedef MA_MMRESULT (WINAPI * MA_PFN_waveOutOpen)(MA_HWAVEOUT* phwo, UIN...
type const (line 25476) | typedef MA_MMRESULT (WINAPI * MA_PFN_waveInOpen)(MA_HWAVEIN* phwi, UINT ...
function ma_result (line 25484) | static ma_result ma_result_from_MMRESULT(MA_MMRESULT resultMM)
function ma_uint32 (line 25520) | static ma_uint32 ma_get_period_size_in_bytes(ma_uint32 periodSizeInFrame...
type MA_WAVECAPSA (line 25530) | typedef struct
function ma_result (line 25538) | static ma_result ma_get_best_info_from_formats_flags__winmm(DWORD dwForm...
function ma_result (line 25618) | static ma_result ma_formats_flags_to_WAVEFORMATEX__winmm(DWORD dwFormats...
function ma_result (line 25643) | static ma_result ma_context_get_device_info_from_WAVECAPS(ma_context* pC...
function ma_result (line 25739) | static ma_result ma_context_get_device_info_from_WAVEOUTCAPS2(ma_context...
function ma_result (line 25754) | static ma_result ma_context_get_device_info_from_WAVEINCAPS2(ma_context*...
function ma_result (line 25770) | static ma_result ma_context_enumerate_devices__winmm(ma_context* pContex...
function ma_result (line 25841) | static ma_result ma_context_get_device_info__winmm(ma_context* pContext,...
function ma_result (line 25885) | static ma_result ma_device_uninit__winmm(ma_device* pDevice)
function ma_uint32 (line 25907) | static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__win...
function ma_result (line 25921) | static ma_result ma_device_init__winmm(ma_device* pDevice, const ma_devi...
function ma_result (line 26141) | static ma_result ma_device_start__winmm(ma_device* pDevice)
function ma_result (line 26182) | static ma_result ma_device_stop__winmm(ma_device* pDevice)
function ma_result (line 26228) | static ma_result ma_device_write__winmm(ma_device* pDevice, const void* ...
function ma_result (line 26320) | static ma_result ma_device_read__winmm(ma_device* pDevice, void* pPCMFra...
function ma_result (line 26409) | static ma_result ma_context_uninit__winmm(ma_context* pContext)
function ma_result (line 26418) | static ma_result ma_context_init__winmm(ma_context* pContext, const ma_c...
type snd_pcm_uframes_t (line 26493) | typedef snd_pcm_uframes_t ma_snd_pcm_uframes_t;
type snd_pcm_sframes_t (line 26494) | typedef snd_pcm_sframes_t ma_snd_pcm_sframes_t;
type snd_pcm_stream_t (line 26495) | typedef snd_pcm_stream_t ma_snd_pcm_stream_t;
type snd_pcm_format_t (line 26496) | typedef snd_pcm_format_t ma_snd_pcm_format_t;
type snd_pcm_access_t (line 26497) | typedef snd_pcm_access_t ma_snd_pcm_access_t;
type snd_pcm_t (line 26498) | typedef snd_pcm_t ma_snd_pcm_t;
type snd_pcm_hw_params_t (line 26499) | typedef snd_pcm_hw_params_t ma_snd_pcm_hw_params_t;
type snd_pcm_sw_params_t (line 26500) | typedef snd_pcm_sw_params_t ma_snd_pcm_sw_params_t;
type snd_pcm_format_mask_t (line 26501) | typedef snd_pcm_format_mask_t ma_snd_pcm_format_mask_t;
type snd_pcm_info_t (line 26502) | typedef snd_pcm_info_t ma_snd_pcm_info_t;
type snd_pcm_channel_area_t (line 26503) | typedef snd_pcm_channel_area_t ma_snd_pcm_channel_area_t;
type snd_pcm_chmap_t (line 26504) | typedef snd_pcm_chmap_t ma_snd_pcm_chmap_t;
type snd_pcm_state_t (line 26505) | typedef snd_pcm_state_t ma_snd_pcm_state_t;
type ma_snd_pcm_uframes_t (line 26581) | typedef unsigned long ma_snd_pcm_uframes_t;
type ma_snd_pcm_sframes_t (line 26582) | typedef long ma_snd_pcm_sframes_t;
type ma_snd_pcm_stream_t (line 26583) | typedef int ma_snd_pcm_stream_t;
type ma_snd_pcm_format_t (line 26584) | typedef int ma_snd_pcm_format_t;
type ma_snd_pcm_access_t (line 26585) | typedef int ma_snd_pcm_access_t;
type ma_snd_pcm_state_t (line 26586) | typedef int ma_snd_pcm_state_t;
type ma_snd_pcm_t (line 26587) | typedef struct ma_snd_pcm_t ma_snd_pcm_t;
type ma_snd_pcm_hw_params_t (line 26588) | typedef struct ma_snd_pcm_hw_params_t ma_snd_pcm_hw_params_t;
type ma_snd_pcm_sw_params_t (line 26589) | typedef struct ma_snd_pcm_sw_params_t ma_snd_pcm_sw_params_t;
type ma_snd_pcm_format_mask_t (line 26590) | typedef struct ma_snd_pcm_format_mask_t ma_snd_pcm_format_mask_t;
type ma_snd_pcm_info_t (line 26591) | typedef struct ma_snd_pcm_info_t ma_snd_pcm_info_t;
type ma_snd_pcm_channel_area_t (line 26592) | typedef struct
type ma_snd_pcm_chmap_t (line 26598) | typedef struct
type ma_snd_pcm_chmap_t (line 26728) | typedef ma_snd_pcm_chmap_t * (* ma_snd_pcm_get_chmap_proc) ...
type ma_snd_pcm_state_t (line 26729) | typedef ma_snd_pcm_state_t (* ma_snd_pcm_state_proc) ...
type ma_snd_pcm_sframes_t (line 26740) | typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_mmap_commit_proc) ...
type ma_snd_pcm_sframes_t (line 26742) | typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_readi_proc) ...
type ma_snd_pcm_sframes_t (line 26743) | typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_writei_proc) ...
type ma_snd_pcm_sframes_t (line 26744) | typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_avail_proc) ...
type ma_snd_pcm_sframes_t (line 26745) | typedef ma_snd_pcm_sframes_t (* ma_snd_pcm_avail_update_proc) ...
type pollfd (line 26751) | struct pollfd
type pollfd (line 26753) | struct pollfd
function ma_snd_pcm_format_t (line 26775) | static ma_snd_pcm_format_t ma_convert_ma_format_to_alsa_format(ma_format...
function ma_format (line 26798) | static ma_format ma_format_from_alsa(ma_snd_pcm_format_t formatALSA)
function ma_channel (line 26825) | static ma_channel ma_convert_alsa_channel_position_to_ma_channel(unsigne...
function ma_bool32 (line 26861) | static ma_bool32 ma_is_common_device_name__alsa(const char* name)
function ma_bool32 (line 26874) | static ma_bool32 ma_is_playback_device_blacklisted__alsa(const char* name)
function ma_bool32 (line 26886) | static ma_bool32 ma_is_capture_device_blacklisted__alsa(const char* name)
function ma_bool32 (line 26898) | static ma_bool32 ma_is_device_blacklisted__alsa(ma_device_type deviceTyp...
function ma_bool32 (line 26930) | static ma_bool32 ma_is_device_name_in_hw_format__alsa(const char* hwid)
function ma_convert_device_name_to_hw_format__alsa (line 26974) | static int ma_convert_device_name_to_hw_format__alsa(ma_context* pContex...
function ma_bool32 (line 27036) | static ma_bool32 ma_does_id_exist_in_list__alsa(ma_device_id* pUniqueIDs...
function ma_result (line 27052) | static ma_result ma_context_open_pcm__alsa(ma_context* pContext, ma_shar...
function ma_result (line 27172) | static ma_result ma_context_enumerate_devices__alsa(ma_context* pContext...
type ma_context_get_device_info_enum_callback_data__alsa (line 27342) | typedef struct
function ma_bool32 (line 27351) | static ma_bool32 ma_context_get_device_info_enum_callback__alsa(ma_conte...
function ma_context_test_rate_and_add_native_data_format__alsa (line 27372) | static void ma_context_test_rate_and_add_native_data_format__alsa(ma_con...
function ma_context_iterate_rates_and_add_native_data_format__alsa (line 27387) | static void ma_context_iterate_rates_and_add_native_data_format__alsa(ma...
function ma_result (line 27420) | static ma_result ma_context_get_device_info__alsa(ma_context* pContext, ...
function ma_result (line 27558) | static ma_result ma_device_uninit__alsa(ma_device* pDevice)
function ma_result (line 27577) | static ma_result ma_device_init_by_type__alsa(ma_device* pDevice, const ...
function ma_result (line 28015) | static ma_result ma_device_init__alsa(ma_device* pDevice, const ma_devic...
function ma_result (line 28042) | static ma_result ma_device_start__alsa(ma_device* pDevice)
function ma_result (line 28061) | static ma_result ma_device_stop__alsa(ma_device* pDevice)
function ma_result (line 28115) | static ma_result ma_device_wait__alsa(ma_device* pDevice, ma_snd_pcm_t* ...
function ma_result (line 28170) | static ma_result ma_device_wait_read__alsa(ma_device* pDevice)
function ma_result (line 28175) | static ma_result ma_device_wait_write__alsa(ma_device* pDevice)
function ma_result (line 28180) | static ma_result ma_device_read__alsa(ma_device* pDevice, void* pFramesO...
function ma_result (line 28236) | static ma_result ma_device_write__alsa(ma_device* pDevice, const void* p...
function ma_result (line 28298) | static ma_result ma_device_data_loop_wakeup__alsa(ma_device* pDevice)
function ma_result (line 28325) | static ma_result ma_context_uninit__alsa(ma_context* pContext)
function ma_result (line 28342) | static ma_result ma_context_init__alsa(ma_context* pContext, const ma_co...
type pa_context_flags_t (line 28745) | typedef pa_context_flags_t ma_pa_context_flags_t;
type pa_stream_flags_t (line 28750) | typedef pa_stream_flags_t ma_pa_stream_flags_t;
type pa_sink_flags_t (line 28773) | typedef pa_sink_flags_t ma_pa_sink_flags_t;
type pa_source_flags_t (line 28785) | typedef pa_source_flags_t ma_pa_source_flags_t;
type pa_context_state_t (line 28796) | typedef pa_context_state_t ma_pa_context_state_t;
type pa_stream_state_t (line 28805) | typedef pa_stream_state_t ma_pa_stream_state_t;
type pa_operation_state_t (line 28812) | typedef pa_operation_state_t ma_pa_operation_state_t;
type pa_sink_state_t (line 28817) | typedef pa_sink_state_t ma_pa_sink_state_t;
type pa_source_state_t (line 28823) | typedef pa_source_state_t ma_pa_source_state_t;
type pa_seek_mode_t (line 28829) | typedef pa_seek_mode_t ma_pa_seek_mode_t;
type pa_channel_position_t (line 28835) | typedef pa_channel_position_t ma_pa_channel_position_t;
type pa_channel_map_def_t (line 28893) | typedef pa_channel_map_def_t ma_pa_channel_map_def_t;
type pa_sample_format_t (line 28901) | typedef pa_sample_format_t ma_pa_sample_format_t;
type pa_mainloop (line 28917) | typedef pa_mainloop ma_pa_mainloop;
type pa_threaded_mainloop (line 28918) | typedef pa_threaded_mainloop ma_pa_threaded_mainloop;
type pa_mainloop_api (line 28919) | typedef pa_mainloop_api ma_pa_mainloop_api;
type pa_context (line 28920) | typedef pa_context ma_pa_context;
type pa_operation (line 28921) | typedef pa_operation ma_pa_operation;
type pa_stream (line 28922) | typedef pa_stream ma_pa_stream;
type pa_spawn_api (line 28923) | typedef pa_spawn_api ma_pa_spawn_api;
type pa_buffer_attr (line 28924) | typedef pa_buffer_attr ma_pa_buffer_attr;
type pa_channel_map (line 28925) | typedef pa_channel_map ma_pa_channel_map;
type pa_cvolume (line 28926) | typedef pa_cvolume ma_pa_cvolume;
type pa_sample_spec (line 28927) | typedef pa_sample_spec ma_pa_sample_spec;
type pa_sink_info (line 28928) | typedef pa_sink_info ma_pa_sink_info;
type pa_source_info (line 28929) | typedef pa_source_info ma_pa_source_info;
type pa_context_notify_cb_t (line 28931) | typedef pa_context_notify_cb_t ma_pa_context_notify_cb_t;
type pa_sink_info_cb_t (line 28932) | typedef pa_sink_info_cb_t ma_pa_sink_info_cb_t;
type pa_source_info_cb_t (line 28933) | typedef pa_source_info_cb_t ma_pa_source_info_cb_t;
type pa_stream_success_cb_t (line 28934) | typedef pa_stream_success_cb_t ma_pa_stream_success_cb_t;
type pa_stream_request_cb_t (line 28935) | typedef pa_stream_request_cb_t ma_pa_stream_request_cb_t;
type pa_stream_notify_cb_t (line 28936) | typedef pa_stream_notify_cb_t ma_pa_stream_notify_cb_t;
type pa_free_cb_t (line 28937) | typedef pa_free_cb_t ma_pa_free_cb_t;
type ma_pa_context_flags_t (line 28948) | typedef int ma_pa_context_flags_t;
type ma_pa_stream_flags_t (line 28953) | typedef int ma_pa_stream_flags_t;
type ma_pa_sink_flags_t (line 28976) | typedef int ma_pa_sink_flags_t;
type ma_pa_source_flags_t (line 28988) | typedef int ma_pa_source_flags_t;
type ma_pa_context_state_t (line 28999) | typedef int ma_pa_context_state_t;
type ma_pa_stream_state_t (line 29008) | typedef int ma_pa_stream_state_t;
type ma_pa_operation_state_t (line 29015) | typedef int ma_pa_operation_state_t;
type ma_pa_sink_state_t (line 29020) | typedef int ma_pa_sink_state_t;
type ma_pa_source_state_t (line 29026) | typedef int ma_pa_source_state_t;
type ma_pa_seek_mode_t (line 29032) | typedef int ma_pa_seek_mode_t;
type ma_pa_channel_position_t (line 29038) | typedef int ma_pa_channel_position_t;
type ma_pa_channel_map_def_t (line 29096) | typedef int ma_pa_channel_map_def_t;
type ma_pa_sample_format_t (line 29104) | typedef int ma_pa_sample_format_t;
type ma_pa_mainloop (line 29120) | typedef struct ma_pa_mainloop ma_pa_mainloop;
type ma_pa_threaded_mainloop (line 29121) | typedef struct ma_pa_threaded_mainloop ma_pa_threaded_mainloop;
type ma_pa_mainloop_api (line 29122) | typedef struct ma_pa_mainloop_api ma_pa_mainloop_api;
type ma_pa_context (line 29123) | typedef struct ma_pa_context ma_pa_context;
type ma_pa_operation (line 29124) | typedef struct ma_pa_operation ma_pa_operation;
type ma_pa_stream (line 29125) | typedef struct ma_pa_stream ma_pa_stream;
type ma_pa_spawn_api (line 29126) | typedef struct ma_pa_spawn_api ma_pa_spawn_api;
type ma_pa_buffer_attr (line 29128) | typedef struct
type ma_pa_channel_map (line 29137) | typedef struct
type ma_pa_cvolume (line 29143) | typedef struct
type ma_pa_sample_spec (line 29149) | typedef struct
type ma_pa_sink_info (line 29156) | typedef struct
type ma_pa_source_info (line 29184) | typedef struct
type ma_pa_mainloop (line 29222) | typedef ma_pa_mainloop* (* ma_pa_mainloop_new_proc) ...
type ma_pa_mainloop_api (line 29225) | typedef ma_pa_mainloop_api* (* ma_pa_mainloop_get_api_proc) ...
type ma_pa_threaded_mainloop (line 29228) | typedef ma_pa_threaded_mainloop* (* ma_pa_threaded_mainloop_new_proc) ...
type ma_pa_mainloop_api (line 29238) | typedef ma_pa_mainloop_api* (* ma_pa_threaded_mainloop_get_api_proc...
type ma_pa_context (line 29241) | typedef ma_pa_context* (* ma_pa_context_new_proc) ...
type ma_pa_context_state_t (line 29246) | typedef ma_pa_context_state_t (* ma_pa_context_get_state_proc) ...
type ma_pa_operation (line 29247) | typedef ma_pa_operation* (* ma_pa_context_get_sink_info_list_pro...
type ma_pa_operation (line 29248) | typedef ma_pa_operation* (* ma_pa_context_get_source_info_list_p...
type ma_pa_operation (line 29249) | typedef ma_pa_operation* (* ma_pa_context_get_sink_info_by_name_...
type ma_pa_operation (line 29250) | typedef ma_pa_operation* (* ma_pa_context_get_source_info_by_nam...
type ma_pa_operation_state_t (line 29252) | typedef ma_pa_operation_state_t (* ma_pa_operation_get_state_proc) ...
type ma_pa_channel_map (line 29253) | typedef ma_pa_channel_map* (* ma_pa_channel_map_init_extend_proc) ...
type ma_pa_stream (line 29256) | typedef ma_pa_stream* (* ma_pa_stream_new_proc) ...
type ma_pa_stream_state_t (line 29261) | typedef ma_pa_stream_state_t (* ma_pa_stream_get_state_proc) ...
type ma_pa_sample_spec (line 29262) | typedef const ma_pa_sample_spec* (* ma_pa_stream_get_sample_spec_proc) ...
type ma_pa_channel_map (line 29263) | typedef const ma_pa_channel_map* (* ma_pa_stream_get_channel_map_proc) ...
type ma_pa_buffer_attr (line 29264) | typedef const ma_pa_buffer_attr* (* ma_pa_stream_get_buffer_attr_proc) ...
type ma_pa_operation (line 29265) | typedef ma_pa_operation* (* ma_pa_stream_set_buffer_attr_proc) ...
type ma_pa_operation (line 29272) | typedef ma_pa_operation* (* ma_pa_stream_flush_proc) ...
type ma_pa_operation (line 29273) | typedef ma_pa_operation* (* ma_pa_stream_drain_proc) ...
type ma_pa_operation (line 29275) | typedef ma_pa_operation* (* ma_pa_stream_cork_proc) ...
type ma_pa_operation (line 29276) | typedef ma_pa_operation* (* ma_pa_stream_trigger_proc) ...
type ma_pulse_device_enum_data (line 29284) | typedef struct
function ma_result (line 29291) | static ma_result ma_result_from_pulse(int result)
function ma_pa_sample_format_t (line 29307) | static ma_pa_sample_format_t ma_format_to_pulse(ma_format format)
function ma_format (line 29335) | static ma_format ma_format_from_pulse(ma_pa_sample_format_t format)
function ma_channel (line 29362) | static ma_channel ma_channel_position_from_pulse(ma_pa_channel_position_...
function ma_pa_channel_position_t (line 29423) | static ma_pa_channel_position_t ma_channel_position_to_pulse(ma_channel ...
function ma_result (line 29465) | static ma_result ma_wait_for_operation__pulse(ma_context* pContext, ma_p...
function ma_result (line 29488) | static ma_result ma_wait_for_operation_and_unref__pulse(ma_context* pCon...
function ma_result (line 29502) | static ma_result ma_wait_for_pa_context_to_connect__pulse(ma_context* pC...
function ma_result (line 29528) | static ma_result ma_wait_for_pa_stream_to_connect__pulse(ma_context* pCo...
function ma_result (line 29554) | static ma_result ma_init_pa_mainloop_and_pa_context__pulse(ma_context* p...
function ma_device_sink_info_callback (line 29600) | static void ma_device_sink_info_callback(ma_pa_context* pPulseContext, c...
function ma_device_source_info_callback (line 29624) | static void ma_device_source_info_callback(ma_pa_context* pPulseContext,...
function ma_device_sink_name_callback (line 29649) | static void ma_device_sink_name_callback(ma_pa_context* pPulseContext, c...
function ma_device_source_name_callback (line 29665) | static void ma_device_source_name_callback(ma_pa_context* pPulseContext,...
function ma_result (line 29682) | static ma_result ma_context_get_sink_info__pulse(ma_context* pContext, c...
function ma_result (line 29694) | static ma_result ma_context_get_source_info__pulse(ma_context* pContext,...
function ma_result (line 29706) | static ma_result ma_context_get_default_device_index__pulse(ma_context* ...
type ma_context_enumerate_devices_callback_data__pulse (line 29745) | typedef struct
function ma_context_enumerate_devices_sink_callback__pulse (line 29755) | static void ma_context_enumerate_devices_sink_callback__pulse(ma_pa_cont...
function ma_context_enumerate_devices_source_callback__pulse (line 29787) | static void ma_context_enumerate_devices_source_callback__pulse(ma_pa_co...
function ma_result (line 29819) | static ma_result ma_context_enumerate_devices__pulse(ma_context* pContex...
type ma_context_get_device_info_callback_data__pulse (line 29877) | typedef struct
function ma_context_get_device_info_sink_callback__pulse (line 29884) | static void ma_context_get_device_info_sink_callback__pulse(ma_pa_contex...
function ma_context_get_device_info_source_callback__pulse (line 29921) | static void ma_context_get_device_info_source_callback__pulse(ma_pa_cont...
function ma_result (line 29958) | static ma_result ma_context_get_device_info__pulse(ma_context* pContext,...
function ma_result (line 30000) | static ma_result ma_device_uninit__pulse(ma_device* pDevice)
function ma_pa_buffer_attr (line 30030) | static ma_pa_buffer_attr ma_device__pa_buffer_attr_new(ma_uint32 periodS...
function ma_pa_stream (line 30042) | static ma_pa_stream* ma_device__pa_stream_new__pulse(ma_device* pDevice,...
function ma_device_on_read__pulse (line 30059) | static void ma_device_on_read__pulse(ma_pa_stream* pStream, size_t byteC...
function ma_result (line 30117) | static ma_result ma_device_write_to_stream__pulse(ma_device* pDevice, ma...
function ma_device_on_write__pulse (line 30177) | static void ma_device_on_write__pulse(ma_pa_stream* pStream, size_t byte...
function ma_device_on_suspended__pulse (line 30221) | static void ma_device_on_suspended__pulse(ma_pa_stream* pStream, void* p...
function ma_device_on_rerouted__pulse (line 30244) | static void ma_device_on_rerouted__pulse(ma_pa_stream* pStream, void* pU...
function ma_uint32 (line 30254) | static ma_uint32 ma_calculate_period_size_in_frames_from_descriptor__pul...
function ma_result (line 30280) | static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_devi...
function ma_pulse_operation_complete_callback (line 30693) | static void ma_pulse_operation_complete_callback(ma_pa_stream* pStream, ...
function ma_result (line 30703) | static ma_result ma_device__cork_stream__pulse(ma_device* pDevice, ma_de...
function ma_result (line 30741) | static ma_result ma_device_start__pulse(ma_device* pDevice)
function ma_result (line 30771) | static ma_result ma_device_stop__pulse(ma_device* pDevice)
function ma_result (line 30805) | static ma_result ma_device_data_loop__pulse(ma_device* pDevice)
function ma_result (line 30828) | static ma_result ma_device_data_loop_wakeup__pulse(ma_device* pDevice)
function ma_result (line 30837) | static ma_result ma_context_uninit__pulse(ma_context* pContext)
function ma_result (line 30856) | static ma_result ma_context_init__pulse(ma_context* pContext, const ma_c...
type jack_nframes_t (line 31117) | typedef jack_nframes_t ma_jack_nframes_t;
type jack_options_t (line 31118) | typedef jack_options_t ma_jack_options_t;
type jack_status_t (line 31119) | typedef jack_status_t ma_jack_status_t;
type jack_client_t (line 31120) | typedef jack_client_t ma_jack_client_t;
Condensed preview — 156 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8,617K chars).
[
{
"path": ".claude/launch.json",
"chars": 213,
"preview": "{\n \"version\": \"0.0.1\",\n \"configurations\": [\n {\n \"name\": \"amy-docs\",\n \"runtimeExecutable\": \"python3\",\n "
},
{
"path": ".github/workflows/arduino.yml",
"chars": 1485,
"preview": "name: Arduino CI\n\non:\n push:\n branches: [ \"main\" ]\n pull_request:\n branches: [ \"main\" ]\n\njobs:\n compile:\n ru"
},
{
"path": ".github/workflows/c-cpp.yml",
"chars": 551,
"preview": "name: C/C++ CI\n\non:\n push:\n branches: [ \"main\" ]\n pull_request:\n branches: [ \"main\" ]\n\njobs:\n test:\n runs-on"
},
{
"path": ".github/workflows/godot-addon.yml",
"chars": 3607,
"preview": "name: Build Godot Addon\n\non:\n push:\n tags:\n - '*'\n workflow_dispatch:\n\npermissions:\n contents: write\n\njobs:\n "
},
{
"path": ".gitignore",
"chars": 634,
"preview": "uv.lock\namy-example\namy-message\ntests/tst\namy-piano\nsrc/build/\n*.DS_Store*\nloris-1.8/\n__pycache__/\nsrc/dist/\nsrc/amy.egg"
},
{
"path": "CLAUDE.md",
"chars": 2290,
"preview": "# AMY Development Notes\n\n## Releases\n\nWhen creating a new release:\n1. Update the version in `library.properties` to matc"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3348,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "LICENSE",
"chars": 1090,
"preview": "MIT License\n\nCopyright (c) 2022 Brian Whitman and Daniel PW Ellis\n\nPermission is hereby granted, free of charge, to any "
},
{
"path": "Makefile",
"chars": 4776,
"preview": "# Makefile for AMY , including an example\n\nTARGET = amy-example amy-message amy-piano\nLIBS = -lm -pthread\n\nUNAME_S := "
},
{
"path": "README.md",
"chars": 10039,
"preview": "# AMY - The high-performance fixed-point music synthesizer library\n\nAMY is a fast and small music synthesizer library wr"
},
{
"path": "amy/__init__.py",
"chars": 21115,
"preview": "# AMY module\nfrom .constants import *\nfrom . import examples\nimport collections\nimport time\ndef _get_synth_commands_stub"
},
{
"path": "amy/constants.py",
"chars": 2600,
"preview": "MAX_FILENAME_LEN=127\nAMY_BLOCK_SIZE=128\nBLOCK_SIZE_BITS=7\nAMY_BLOCK_SIZE=256\nBLOCK_SIZE_BITS=8\nAMY_SAMPLE_RATE=48000\nAMY"
},
{
"path": "amy/examples.py",
"chars": 10021,
"preview": "#!/usr/bin/env python3\n# examples.py\n# sound examples and patch examples\n\nimport amy\nfrom time import sleep\n\n\nclass Patc"
},
{
"path": "amy/fm.py",
"chars": 18599,
"preview": "# fm.py\n# Some code to try to convert DX7 patches into AMY commands\n\nimport numpy as np\nimport time\nimport amy\nfrom data"
},
{
"path": "amy/headers.py",
"chars": 26029,
"preview": "# headers.py\n# Generate headers for AMY\nimport sys\nimport glob\nimport numpy as np\nimport amy\n\nfrom . import constants\n\nd"
},
{
"path": "amy/juno.py",
"chars": 28561,
"preview": "# juno.py\n# Convert juno-106 sysex patches to Amy\n\n\nimport amy\nimport json\nimport math\nimport time\n\nfrom . import consta"
},
{
"path": "amy/piano.py",
"chars": 8755,
"preview": "\n# piano.py\n# examples from piano.html\nimport amy\nfrom . import piano_params\n\ndef piano_example(base_note=72, volume=5, "
},
{
"path": "amy/piano_params.py",
"chars": 91400,
"preview": "# Notes params generated by piano_heterodyne.ipynb\nnotes_params = {\"sample_times_ms\": [4, 8, 12, 16, 24, 32, 48, 64, 96,"
},
{
"path": "amy/sineclock.py",
"chars": 1726,
"preview": "import amy, math, datetime\n\ntry:\n amy.live(playback_device_id=1)\n running_amyboard = False\nexcept:\n running_amyboard "
},
{
"path": "amy/test.py",
"chars": 48347,
"preview": "import sys\nimport os\nimport random\nimport string\nimport tempfile\n\nimport numpy as np\nimport scipy.io.wavfile as wav\n\nimp"
},
{
"path": "amy/timing.py",
"chars": 9985,
"preview": "import sys\nimport os\n\nimport numpy as np\nimport scipy.io.wavfile as wav\n\nimport amy\n\n\ndef wavread(filename):\n \"\"\"Read i"
},
{
"path": "amy/wave.py",
"chars": 21190,
"preview": "\"\"\"Stuff to parse WAVE files.\n\nUsage.\n\nReading WAVE files:\n f = wave.open(file, 'r')\nwhere file is either the name "
},
{
"path": "amy/xanadu.py",
"chars": 6380,
"preview": "# AMYboard Sketch\n# Top-level code runs once at boot. loop() runs repeatedly (~60ms).\n\n\n\"\"\"Joseph T. Kung's XANADU, impl"
},
{
"path": "daisy/Makefile",
"chars": 897,
"preview": "# Project Name\nTARGET = amy_daisy\nAMY = ${HOME}/github/shorepine/tulipcc/amy/src\nAPP_TYPE=BOOT_SRAM\nOPT = -O3\n\n\n# Source"
},
{
"path": "daisy/amy_daisy.cpp",
"chars": 5371,
"preview": "// amy_daisy.cpp\n// Core daisy function to run AMY on the Daisy hardware/firmware environment.\n\n#include \"daisy_seed.h\"\n"
},
{
"path": "docs/amy.aw.js",
"chars": 9025,
"preview": "// This file is the main bootstrap script for Wasm Audio Worklets loaded in an\n// Emscripten application. Build with -s"
},
{
"path": "docs/amy.js",
"chars": 67207,
"preview": "var amyModule=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var modu"
},
{
"path": "docs/amy.ww.js",
"chars": 2270,
"preview": "// N.B. The contents of this file are duplicated in src/library_wasm_worker.js\n// in variable \"_wasmWorkerBlobUrl\" (wher"
},
{
"path": "docs/amyrepl.css",
"chars": 5401,
"preview": "\n/*.modal-backdrop.fade.show { z-index: inherit; }*/\n\n\n/*\nSolarized theme for code-mirror\nhttp://ethanschoonover.com/sol"
},
{
"path": "docs/amyrepl.js",
"chars": 3118,
"preview": "\n// Manage Micropython and AMY running together, for a web REPL experience\nvar mp = null;\nvar editors = [];\nvar run_at_s"
},
{
"path": "docs/api.md",
"chars": 23694,
"preview": "# AMY synthesizer API\n\nThis page collects the current API for [AMY](https://github.com/shorepine/amy).\n\n[**Please see ou"
},
{
"path": "docs/arduino.md",
"chars": 6762,
"preview": "# Arduino Setup for AMY\n\nAMY is on the Arduino Libraries repository. Simply search for \"AMY\" in the Library Manager and "
},
{
"path": "docs/billie_jean.md",
"chars": 15906,
"preview": "# Making \"Billie Jean\" with AMY_Arduino\ndan.ellis@gmail.com 2025-11-03\n\nAMY is a music synthesizer library that allows y"
},
{
"path": "docs/chunk.py",
"chars": 5372,
"preview": "\"\"\"Simple class to read IFF chunks.\n\nAn IFF chunk (used in formats such as AIFF, TIFF, RMFF (RealMedia File\nFormat)) has"
},
{
"path": "docs/enable-threads.js",
"chars": 3046,
"preview": "// NOTE: This file creates a service worker that cross-origin-isolates the page (read more here: https://web.dev/coop-co"
},
{
"path": "docs/godot.md",
"chars": 7423,
"preview": "# AMY in Godot\n\nThe AMY synthesizer engine works as a [GDExtension](https://docs.godotengine.org/en/stable/tutorials/scr"
},
{
"path": "docs/index.html",
"chars": 1807,
"preview": "<!-- thank you to https://github.com/elf-audio/cpp-to-webaudio-example -->\n<!doctype html>\n<html lang=\"en-us\">\n <head"
},
{
"path": "docs/juno_patches.md",
"chars": 7236,
"preview": "# Understanding Juno Patches\n\n[AMY](https://github.com/shorepine/amy) can be used to simulate many analog synthesizers, "
},
{
"path": "docs/micropython.mjs",
"chars": 232006,
"preview": "// This code implements the `-sMODULARIZE` settings by taking the generated\n// JS program code (INNER_JS_CODE) and wrapp"
},
{
"path": "docs/midi.md",
"chars": 3095,
"preview": "# AMY MIDI Mode\n\nAMY assigns `synth`s between 1 and 16 to MIDI channels and listens to MIDI messages on those synths. Fo"
},
{
"path": "docs/minimal.html",
"chars": 1918,
"preview": "<html>\n<head>\n\t<title>Minimal AMY web synth example</title>\n <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.1.3"
},
{
"path": "docs/piano.html",
"chars": 41355,
"preview": "<!doctype html>\n<html>\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initia"
},
{
"path": "docs/repl.html",
"chars": 11927,
"preview": "<!doctype html>\n<html lang=\"en-us\">\n<head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"Content-Type\" content=\"text/"
},
{
"path": "docs/server.py",
"chars": 893,
"preview": "#!/usr/bin/env python\n\n# Attribution: https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-"
},
{
"path": "docs/style.css",
"chars": 2673,
"preview": "\nbody {\n font-family: Helvetica, Arial, sans-serif;\n margin:10px;\n/* display: flex;\n flex-direction: colum"
},
{
"path": "docs/synth.md",
"chars": 31303,
"preview": "# AMY Synthesizer Details\n\n[**Please see our interactive AMY tutorial for more tips on using AMY**](https://shorepine.gi"
},
{
"path": "docs/tutorial.html",
"chars": 19739,
"preview": "<!doctype html>\n<html>\n <head>\n <link rel=\"stylesheet\" href=\"amyrepl.css\"/>\n <title>AMY Synthesizer Tutorial<"
},
{
"path": "docs/upgrading.md",
"chars": 3052,
"preview": "# Upgrading between versions of AMY\n\nHere we will post breaking APIs between releases of AMY and tips on porting.\n\n\n## 1"
},
{
"path": "examples/AMY_ESP32_manual_I2S/AMY_ESP32_manual_I2S.ino",
"chars": 5064,
"preview": "// AMY_MIDI_Synth modified to test out new amy_update that returns the pointer to samples.\n// It then handles passing of"
},
{
"path": "examples/AMY_MIDI_Synth/AMY_MIDI_Synth.ino",
"chars": 3613,
"preview": "#include <AMY-Arduino.h>\n\n// Simple AMY synth setup that just sets up the default MIDI synth.\n// Plug a MIDI keyboard in"
},
{
"path": "examples/AMY_USB_Host_MIDI/AMY_USB_Host_MIDI.ino",
"chars": 2354,
"preview": "#include <AMY-Arduino.h>\n#include <USBConnection.h> // ESP32_Host_MIDI\n\n// USB Host MIDI synth for ESP32-S3 / ESP32-S2 "
},
{
"path": "examples/AMY_custom_osc/AMY_custom_osc.ino",
"chars": 4678,
"preview": "#include <AMY-Arduino.h>\n\n// Example of using the AMY \"custom oscillator\" from Arduino.\n\n// Custom osc types are defined"
},
{
"path": "examples/AMY_pico_PWM/AMY_pico_PWM.ino",
"chars": 1993,
"preview": "#include <AMY-Arduino.h>\n\n// AMY_pico_PWM\n//\n// Runs AMY using arduino-pico's PWM audio output.\n// This version responds"
},
{
"path": "examples/BillieJeanDrums/BillieJeanDrums.ino",
"chars": 2431,
"preview": "// BillieJeanDrums - Making a simple drum pattern with AMY.\n// see https://github.com/shorepine/amy/blob/main/docs/billi"
},
{
"path": "examples/BillieJeanDrumsBass/BillieJeanDrumsBass.ino",
"chars": 2889,
"preview": "// BillieJeanDrumsBass - Use different synthesizers to add a bass line along with the drums\n// see https://github.com/sh"
},
{
"path": "examples/BillieJeanScheduled/BillieJeanScheduled.ino",
"chars": 4224,
"preview": "// BillieJeanScheduled - playing drums, bass, and chords using the AMY scheduler for timing\n// see https://github.com/sh"
},
{
"path": "experiments/Piano.ff.D5.json",
"chars": 6019,
"preview": "[[588.7303322461809, [[0, 0.0003183759280936712], [4, 0.05942463446834628], [4, 0.019017213920200938], [3, 0.07456424206"
},
{
"path": "experiments/compare_test_wavs.ipynb",
"chars": 102274,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 2,\n \"id\": \"ad51c589-8c0c-4677-b145-ad5ab4710e70\",\n \""
},
{
"path": "experiments/dx7_simulator.py",
"chars": 14352,
"preview": "\"\"\"Simulates the DX7 FM algorithms fully in Python.\"\"\"\n\nimport numpy as np\nimport fm\n\n# We add a (1 - z^-1)/(1 - 0.995 z"
},
{
"path": "experiments/make_piano_examples.ipynb",
"chars": 14492,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"id\": \"e208aa51-4e26-4487-b80d-df83fdc00277\",\n \"metadata\": {},\n \"so"
},
{
"path": "experiments/piano-params.json",
"chars": 152475,
"preview": "{\"sample_times_ms\": [4, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096], \"not"
},
{
"path": "experiments/piano-partials.ipynb",
"chars": 728012,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 2,\n \"id\": \"f3feaa02\",\n \"metadata\": {},\n \"outputs\":"
},
{
"path": "experiments/piano_examples.py",
"chars": 2717,
"preview": "import sys\nimport os\n\nimport numpy as np\nimport scipy.io.wavfile as wav\n\nimport amy\n\nfrom experiments import tulip_piano"
},
{
"path": "experiments/piano_heterodyne.ipynb",
"chars": 86896,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"id\": \"11018e82-afc7-4937-8914-a23d5286f656\",\n "
},
{
"path": "experiments/piano_params.py",
"chars": 91400,
"preview": "# Notes params generated by piano_heterodyne.ipynb\nnotes_params = {\"sample_times_ms\": [4, 8, 12, 16, 24, 32, 48, 64, 96,"
},
{
"path": "experiments/track02-C4-bps.json",
"chars": 3422,
"preview": "{\"1\": [[0, 0.03646117968209008], [17, 1.4790503289019412], [116, 1.7464818747653081], [1364, 0.32805053827525693], [511,"
},
{
"path": "experiments/tulip_piano.py",
"chars": 9308,
"preview": "\"\"\"Piano notes generated on amy/tulip.\"\"\"\n# Uses the partials amplitude breakpoints and residual written by piano-partia"
},
{
"path": "godot/SConstruct",
"chars": 3517,
"preview": "#!/usr/bin/env python\n\"\"\"\nBuild script for the AMY Synthesizer GDExtension.\n\nAMY C source lookup order:\n 1. AMY_SRC_PAT"
},
{
"path": "godot/amy.gd",
"chars": 9288,
"preview": "class_name Amy\nextends Node\n## AMY Synthesizer for Godot.\n##\n## High-level GDScript API that mirrors AMY's Python interf"
},
{
"path": "godot/amy.gdextension",
"chars": 607,
"preview": "[configuration]\n\nentry_symbol = \"amy_library_init\"\ncompatibility_minimum = \"4.3\"\n\n[libraries]\n\nmacos.debug = \"res://addo"
},
{
"path": "godot/install.gd",
"chars": 2480,
"preview": "@tool\nextends EditorScript\n## AMY Synthesizer Addon - Web Export Setup\n##\n## Run this script once (via File > Run) to co"
},
{
"path": "godot/src/amy_gdextension.cpp",
"chars": 7477,
"preview": "#include \"amy_gdextension.h\"\n#include <godot_cpp/core/class_db.hpp>\n#include <godot_cpp/variant/utility_functions.hpp>\n\n"
},
{
"path": "godot/src/amy_gdextension.h",
"chars": 1838,
"preview": "#ifndef AMY_GDEXTENSION_H\n#define AMY_GDEXTENSION_H\n\n#include <godot_cpp/classes/node.hpp>\n#include <godot_cpp/classes/a"
},
{
"path": "godot/src/amy_platform_stubs.c",
"chars": 1177,
"preview": "// Stub implementations for AMY platform/hardware functions.\n// We don't need I2S or MIDI hardware - Godot handles all a"
},
{
"path": "godot/src/register_types.cpp",
"chars": 1071,
"preview": "#include \"register_types.h\"\n#include \"amy_gdextension.h\"\n\n#include <gdextension_interface.h>\n#include <godot_cpp/core/de"
},
{
"path": "godot/src/register_types.h",
"chars": 283,
"preview": "#ifndef AMY_REGISTER_TYPES_H\n#define AMY_REGISTER_TYPES_H\n\n#include <godot_cpp/core/class_db.hpp>\n\nusing namespace godot"
},
{
"path": "godot/web/custom_shell.html",
"chars": 5253,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, u"
},
{
"path": "godot/web/godot_amy_bridge.js",
"chars": 3397,
"preview": "// godot_amy_bridge.js\n// Thin bridge between Godot's JavaScriptBridge and AMY's WASM module.\n// AMY handles its own aud"
},
{
"path": "library.properties",
"chars": 533,
"preview": "name=AMY Synthesizer\nversion=1.2.4\nauthor=Brian Whitman <brian@variogram.com>, DAn Ellis <dan.ellis@gmail.com>\nmaintaine"
},
{
"path": "pyproject.toml",
"chars": 128,
"preview": "[project]\nname = \"amy\"\nversion = \"0.1.0\"\ndescription = \"AMY synthesizer\"\nreadme = \"README.md\"\ndependencies = ['numpy', '"
},
{
"path": "requirements.txt",
"chars": 13,
"preview": "numpy\nscipy\n\n"
},
{
"path": "scripts/gen_amy_js_api.py",
"chars": 8479,
"preview": "#!/usr/bin/env python3\n\"\"\"Generate amy_api.generated.js from amy/__init__.py and amy/constants.py.\n\nReads the _KW_MAP_LI"
},
{
"path": "scripts/gen_patches_js.py",
"chars": 3263,
"preview": "#!/usr/bin/env python3\n\"\"\"Generate patches.generated.js from src/patches.h.\n\nParses patch names and patch command string"
},
{
"path": "setup.py",
"chars": 1277,
"preview": "from distutils.core import setup, Extension\nfrom setuptools import find_packages\nimport glob\nimport os\n# the c++ extensi"
},
{
"path": "setup_godot.sh",
"chars": 38917,
"preview": "#!/usr/bin/env bash\n#\n# setup_godot.sh — Build and install the AMY GDExtension addon into a Godot project.\n#\n# Usage:\n# "
},
{
"path": "src/AMY-Arduino.h",
"chars": 150,
"preview": "// AMY-Arduino.h\n// connector for Arduino\n\n#ifndef AMYARDUINOH\n#define AMYARDUINOH\n\n#include \"Arduino.h\"\n\nextern \"C\" {\n "
},
{
"path": "src/algorithms.c",
"chars": 8249,
"preview": "// algorithms.c\n#include \"amy.h\"\n\n// Thank you MFSA for the DX7 op structure , borrowed here \\/ \\/ \\/ \nenum FmOperatorFl"
},
{
"path": "src/amy-example.c",
"chars": 7983,
"preview": "// amy-example.c\n// a simple C example that plays audio using AMY out your speaker \n\n#ifndef ARDUINO\n\n#include \"amy.h\"\n#"
},
{
"path": "src/amy-message.c",
"chars": 2392,
"preview": "// amy-message.c\n// hacked from amy-example.c, this code shows using miniaudio and allows entry it AMY ASCII commands.\n#"
},
{
"path": "src/amy-piano.c",
"chars": 26493,
"preview": "// amy-example.c\n// a simple C example that plays audio using AMY out your speaker \n#ifndef ARDUINO \n\n#include \"amy.h\"\n#"
},
{
"path": "src/amy.c",
"chars": 93706,
"preview": "// DAn Ellis and Brian Whitman\n// brian@variogr.am / dan.ellis@gmail.com\n\n#include \"amy.h\"\n\n#ifdef AMY_DEBUG\n\nconst char"
},
{
"path": "src/amy.h",
"chars": 37486,
"preview": "#ifndef __AMY_H\n#define __AMY_H\n\n#include <stdio.h>\n#include <stddef.h>\n#include <stdint.h>\n#include <stdbool.h>\n#includ"
},
{
"path": "src/amy_connector.js",
"chars": 4322,
"preview": "// amy_connector.js\n// helpers for JS to communicate with AMY, including webMIDI\n\nvar amy_add_message = null;\nvar amy_re"
},
{
"path": "src/amy_fixedpoint.h",
"chars": 12019,
"preview": "// amy_fixedpoint.h - common definitions for fixed-point arithmetic.\n\n// We use 3 fixed-point formats:\n// - Lookup tabl"
},
{
"path": "src/amy_midi.c",
"chars": 25796,
"preview": "// midi.c\n// i deal with parsing and receiving midi on many platforms\n\n#include \"amy.h\"\n#if defined(TULIP) || defined(AM"
},
{
"path": "src/amy_midi.h",
"chars": 1674,
"preview": "// midi.h\n\n#ifndef __MIDI_H\n#define __MIDI_H\n\n#ifdef ESP_PLATFORM \n#include \"driver/uart.h\"\n#include \"soc/uart_reg.h\"\n#i"
},
{
"path": "src/api.c",
"chars": 13348,
"preview": "// api.c\n// C callable entry points to amy\n\n#include \"amy.h\"\n\namy_config_t amy_default_config() {\n amy_config_t c;\n "
},
{
"path": "src/clipping_lookup_table.h",
"chars": 30443,
"preview": "// Automatically generated.\n// Clipping lookup table\n#ifndef __CLIPPING_TABLE\n#define __CLIPPING_TABLE\n#define FIRST_NON"
},
{
"path": "src/custom.c",
"chars": 967,
"preview": "// custom.c\n\n#include \"amy.h\"\n#include <assert.h>\n\nstruct custom_oscillator* custom_osc = NULL;\n\nvoid amy_set_custom(str"
},
{
"path": "src/delay.c",
"chars": 13025,
"preview": "#include \"amy.h\"\n\n\n#include \"delay.h\"\n\nint is_power_of_two(int val) {\n // Returns log_2(val) if val == 2**n, else -1."
},
{
"path": "src/delay.h",
"chars": 919,
"preview": "#ifndef _DELAY_H\n\n// How many bits used for fractional part of delay line index.\n#define DELAY_INDEX_FRAC_BITS 15\n// The"
},
{
"path": "src/envelope.c",
"chars": 10812,
"preview": "// envelope.c\n// VCA -- handle modulation and ADSR\n\n#include \"amy.h\"\n\nextern const int16_t pcm[];\n\n\nSAMPLE compute_mod_v"
},
{
"path": "src/examples.c",
"chars": 16423,
"preview": "// examples.c\n// sound examples\n\n#include \"amy.h\"\n\n// set by the arch\nextern void delay_ms(uint32_t ms);\n\nvoid example_r"
},
{
"path": "src/examples.h",
"chars": 825,
"preview": "// examples.h\n// examples.c\n// sound examples\n\n#include \"amy.h\"\n\n\nvoid example_reverb();\nvoid example_chorus();\nvoid exa"
},
{
"path": "src/filters.c",
"chars": 30943,
"preview": "#include \"amy.h\"\n#include \"assert.h\"\n\n#ifndef M_PI\n #define M_PI 3.14159265358979323846\n#endif\n\n// Filters tend to ge"
},
{
"path": "src/i2s.c",
"chars": 22048,
"preview": "// i2s.c\n// handle i2s audio in & out on many platforms\n// esp32 --> esp32, esp32-s3, esp32-p4 \n// AMYBOARD, which is a "
},
{
"path": "src/instrument.c",
"chars": 22531,
"preview": "// instrument.c\n//\n// An instrument is a set of voices with voice-allocation logic.\n// The user calls instrument_note_on"
},
{
"path": "src/interp_partials.c",
"chars": 14974,
"preview": "// interp_partials - AMY kernel-side implementation of the interpolated partials-based synthesis originally implemented "
},
{
"path": "src/interp_partials.h",
"chars": 157484,
"preview": "// Automatically generated.\n// Piano interpolated partials data table\n#ifndef __INTERP_PARTIALS_H\n#define __INTERP_PARTI"
},
{
"path": "src/libminiaudio-audio.c",
"chars": 9677,
"preview": "// libminiaudio-audio.c\n// functions for running AMY on a computer\n#if !defined(ESP_PLATFORM) && !defined(PICO_ON_DEVICE"
},
{
"path": "src/libminiaudio-audio.h",
"chars": 138,
"preview": "// libminiaudio-audio.h\n\n#ifndef __LIBMINIAUDIO_AUDIO_H\n#define __LIBMINIAUDIO_AUDIO_H\n#include \"amy.h\"\n\nvoid amy_print_"
},
{
"path": "src/log2_exp2.c",
"chars": 1268,
"preview": "// Lookup-table versions of log2/exp2.\n\n#include \"amy.h\"\n#include \"log2_exp2_fxpt_lutable.h\"\n\n\nstatic inline SAMPLE lut_"
},
{
"path": "src/log2_exp2_fxpt_lutable.h",
"chars": 3720,
"preview": "// Automatically-generated LUTset\n#ifndef LUTSET_EXP_LUT_FXPT_DEFINED\n#define LUTSET_EXP_LUT_FXPT_DEFINED\n\nconst int16_t"
},
{
"path": "src/macos_midi.m",
"chars": 5680,
"preview": "#ifndef __EMSCRIPTEN__\n#define unichar OSX_UNICHAR\n#import <Foundation/Foundation.h>\n#import <CoreGraphics/CoreGraphics."
},
{
"path": "src/midi_mappings.c",
"chars": 8072,
"preview": "// midi_mappings.c\n// example midi mappings for controllers\n\n#include \"amy.h\"\n\n#include <assert.h> // for buffer overr"
},
{
"path": "src/miniaudio.h",
"chars": 3985140,
"preview": "/*\nAudio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file."
},
{
"path": "src/oscillators.c",
"chars": 31277,
"preview": "#include \"amy.h\"\n\n\n// For checking assumptions about bitwidths.\n#include <assert.h>\n\n#include \"sine_lutset_fxpt.h\"\n#incl"
},
{
"path": "src/parse.c",
"chars": 27981,
"preview": "// parse.c\n// handle parsing wire strings\n\n#include \"amy.h\"\n#include \"transfer.h\" // for amy_dump_state_to_sysex, amy_d"
},
{
"path": "src/patches.c",
"chars": 55889,
"preview": "// patches.c\n// baked in AMY string patches (Juno-6 & DX7 for now)\n\n#include \"amy.h\"\n#include \"patches.h\"\n\n#include <ass"
},
{
"path": "src/patches.h",
"chars": 120754,
"preview": "// Automatically generated.\n// DX7 and juno 106 and custom patch table\n#ifndef __PATCHESH\n#define __PATCHESH\nstatic cons"
},
{
"path": "src/pcm.c",
"chars": 18392,
"preview": "// pcm.c\n\n#include \"amy.h\"\n#include \"transfer.h\"\n\n#ifdef __EMSCRIPTEN__\n#include \"emscripten.h\"\n#endif\n\n#ifdef AMY_DAISY"
},
{
"path": "src/pcm_samples_tiny.h",
"chars": 1241502,
"preview": "// Automatically generated by amy.headers.generate_pcm_header()\n#ifndef __PCM_SAMPLES_H\n#define __PCM_SAMPLES_H\nconst in"
},
{
"path": "src/pcm_tiny.h",
"chars": 2072,
"preview": "// Automatically generated by amy.headers.generate_pcm_header()\n#ifndef __PCM_H\n#define __PCM_H\n#define PCM_AMY_SAMPLE_R"
},
{
"path": "src/pico-audio/audio.cpp",
"chars": 9193,
"preview": "#if (defined PICO_RP2350) || (defined PICO_RP2040)\n/*\n * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n *\n * SPDX-Licen"
},
{
"path": "src/pico-audio/audio.h",
"chars": 9336,
"preview": "#if (defined PICO_RP2350) || (defined PICO_RP2040)\n/*\n * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n *\n * SPDX-Licen"
},
{
"path": "src/pico-audio/audio_i2s.c",
"chars": 14558,
"preview": "/*\n * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n *\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n#if (defined ARDUI"
},
{
"path": "src/pico-audio/audio_i2s.h",
"chars": 4696,
"preview": "/*\n * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n *\n * SPDX-License-Identifier: BSD-3-Clause\n */\n#if (defined ARDUIN"
},
{
"path": "src/pico-audio/audio_i2s.pio",
"chars": 2892,
"preview": ";\n; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n;\n; SPDX-License-Identifier: BSD-3-Clause\n;\n\n; Transmit a mono or ste"
},
{
"path": "src/pico-audio/audio_i2s.pio.h",
"chars": 3605,
"preview": "#if (defined PICO_RP2350) || (defined PICO_RP2040)\n// -------------------------------------------------- //\n// This file"
},
{
"path": "src/pico-audio/buffer.c",
"chars": 497,
"preview": "#if (defined PICO_RP2350) || (defined PICO_RP2040)\n#if 1\n/*\n * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n *\n * SPDX"
},
{
"path": "src/pico-audio/buffer.h",
"chars": 2311,
"preview": "/*\n * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n *\n * SPDX-License-Identifier: BSD-3-Clause\n */\n#if 1\n#ifdef ARDUIN"
},
{
"path": "src/pico-audio/sample_conversion.h",
"chars": 10188,
"preview": "/*\n * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.\n *\n * SPDX-License-Identifier: BSD-3-Clause\n */\n#if (defined PICO_R"
},
{
"path": "src/pico_extras_import.cmake",
"chars": 2950,
"preview": "# This is a copy of <PICO_EXTRAS_PATH>/external/pico_extras_import.cmake\n\n# This can be dropped into an external project"
},
{
"path": "src/pico_sdk_import.cmake",
"chars": 3165,
"preview": "# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake\n\n# This can be dropped into an external project to he"
},
{
"path": "src/pico_support.cpp",
"chars": 6184,
"preview": "// pico_support.cpp\n\n#if (defined ARDUINO_ARCH_RP2040) || (defined ARDUINO_ARCH_RP2350)\n\n// ------------- I2S ----------"
},
{
"path": "src/pyamy.c",
"chars": 10737,
"preview": "#if !defined(ESP_PLATFORM) && !defined(PICO_ON_DEVICE) && !defined(ARDUINO)\n\n#include <Python.h>\n#include <math.h>\n#incl"
},
{
"path": "src/saw_lutset_fxpt.h",
"chars": 52457,
"preview": "// Automatically-generated LUTset\n#ifndef LUTSET_SAW_FXPT_DEFINED\n#define LUTSET_SAW_FXPT_DEFINED\n\n#ifndef LUTENTRY_FXPT"
},
{
"path": "src/sequencer.c",
"chars": 9834,
"preview": "#include \"sequencer.h\"\n#include \"amy.h\"\n\n#ifdef __EMSCRIPTEN__\n#include <emscripten.h>\n#endif\n\nuint32_t sequencer_ticks("
},
{
"path": "src/sequencer.h",
"chars": 455,
"preview": "// sequencer.h\n#ifndef __SEQUENCERH\n#define __SEQUENCERH\n\n#include \"amy.h\"\n#define MIDI_SEQUENCER_PPQ 24 // MIDI clock"
},
{
"path": "src/sine_lutset_fxpt.h",
"chars": 2185,
"preview": "// Automatically-generated LUTset\n#ifndef LUTSET_SINE_FXPT_DEFINED\n#define LUTSET_SINE_FXPT_DEFINED\n\n#ifndef LUTENTRY_FX"
},
{
"path": "src/teensy_support.cpp",
"chars": 2398,
"preview": "// teensy_support.cpp\n#ifdef __IMXRT1062__\n\n#include \"teensy_support.h\"\n#include <Audio.h>\n#include \"amy.h\"\n\nAudioOutput"
},
{
"path": "src/teensy_support.h",
"chars": 48,
"preview": "// teensy_support.h\n#ifdef __IMXRT1062__\n\n#endif"
},
{
"path": "src/transfer.c",
"chars": 28216,
"preview": "// transfer.c\n// data transfer over AMY messages\n\n#include <stdlib.h>\n#include <ctype.h>\n#include \"transfer.h\"\n#include "
},
{
"path": "src/transfer.h",
"chars": 2331,
"preview": "// transfer.h\n// data transfer over AMY messages\n// b64 stuff from https://github.com/jwerle/b64.c\n\n// bytes -> b64 leng"
},
{
"path": "src/triangle_lutset_fxpt.h",
"chars": 14069,
"preview": "// Automatically-generated LUTset\n#ifndef LUTSET_TRIANGLE_FXPT_DEFINED\n#define LUTSET_TRIANGLE_FXPT_DEFINED\n\n#ifndef LUT"
},
{
"path": "src/usb.c",
"chars": 7015,
"preview": "// usb.c\n// tinyusb stuff\n\n#include \"amy.h\"\n\n#if defined(AMY_MCU) && (!defined(ARDUINO) || defined(AMYBOARD_ARDUINO))\n\n#"
},
{
"path": "src/usb.h",
"chars": 1503,
"preview": "// usb.h\n// tinyusb stuff\n\n#if defined(AMY_MCU) && (!defined(ARDUINO) || defined(AMYBOARD_ARDUINO))\n\n#include \"class/aud"
},
{
"path": "valgrind.suppressions",
"chars": 493,
"preview": "{\n libpulse_common\n Memcheck:Leak\n match-leak-kinds: reachable\n ...\n obj:/usr/lib/aarch64-linux-gnu/pulseaudio"
},
{
"path": "windows/CMakeLists.txt",
"chars": 1292,
"preview": "cmake_minimum_required(VERSION 3.10)\nproject(amy_sine C)\n\nset(CMAKE_C_STANDARD 11)\n\nset(AMY_SRC_DIR \"${CMAKE_CURRENT_SOU"
},
{
"path": "windows/README.md",
"chars": 915,
"preview": "# AMY on Windows\n\nA minimal example that plays a 440Hz sine wave using AMY on Windows.\n\n## Prerequisites\n\nInstall **Visu"
},
{
"path": "windows/amy_sine.c",
"chars": 884,
"preview": "// amy_sine.c - simplest possible AMY example for Windows\n// Plays a 440Hz sine wave through your default audio device.\n"
},
{
"path": "windows/build.bat",
"chars": 805,
"preview": "@echo off\ncall \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x64\nif "
}
]
// ... and 4 more files (download for full content)
About this extraction
This page contains the full source code of the shorepine/amy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 156 files (8.0 MB), approximately 2.1M tokens, and a symbol index with 5164 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.