Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
a11421c
Add private Unix socket transport for AMY wire protocol
linuxificator Aug 22, 2026
d2755c9
Add Android Oboe service and hello-world client
linuxificator Aug 22, 2026
9a3e4e1
Document Android AMY integration and socket contract
linuxificator Aug 22, 2026
bd45e9b
Validate Android audio level and correct hello-world gain
linuxificator Aug 23, 2026
a12c19b
Decouple Android hello-world from AMY service API
linuxificator Aug 23, 2026
1bdc0d8
Add private Unix socket transport for AMY wire protocol
linuxificator Aug 22, 2026
4104247
Harden Unix socket transport and tests
Aug 30, 2026
237ff60
Expose Godot backend lifecycle signals
Aug 30, 2026
d90917c
Document portable service integrations
Aug 30, 2026
218dbc2
Merge portable socket API offer into Android integration
Aug 30, 2026
8738ae2
Define the Android integration service profile
Aug 30, 2026
20f714a
Align Android service with PySide NDK r27c
Aug 30, 2026
8b7cd10
Extend Android framework audio capture
Aug 30, 2026
74bed04
Add reusable sequencer groups
Sep 3, 2026
066bc1f
Expand sequencer group behavior coverage
Sep 3, 2026
83ae7f1
Document sequencer group API
Sep 3, 2026
1098528
Cover sequencer group identity and rollover
Sep 3, 2026
45fc871
Add sequencer group usage guides
Sep 3, 2026
b1e995f
Align sequencer group terminology and links
Sep 4, 2026
c3ebcae
Harden sequencer group validation and diagnostics
Sep 4, 2026
ac8ea86
Expand sequencer group edge-case coverage
Sep 4, 2026
6c9829c
Unify sequencer group tick processing
Sep 4, 2026
2c1c052
Cover sequencer group control boundaries
Sep 4, 2026
2aa4323
Clarify sequencer group contracts and errors
Sep 4, 2026
b791eb2
Cover sequencer group republish and tag edges
Sep 4, 2026
3637204
AMY_BLOCK_SIZE can be chosen at compile time
bwhitman Sep 4, 2026
90b62c6
Simplify reusable sequences around sequencer tags
Sep 4, 2026
bc3c85b
Document reusable tagged sequences
Sep 4, 2026
16c7e51
Rewrite sequence guides for the simplified API
Sep 4, 2026
db1e923
the knob is BLOCK_SIZE_BITS; AMY_BLOCK_SIZE is derived
bwhitman Sep 4, 2026
29aa50a
Make sequencer tags cumulative sequences
Sep 4, 2026
06309fa
Document cumulative sequencer tags
Sep 4, 2026
2139516
Align sequence test terminology
Sep 4, 2026
fca1579
Remove retired sequence append from Godot
Sep 4, 2026
2669c3a
Cover concurrent sequence definition generations
Sep 4, 2026
b2a8865
Move sequence version reclamation off render path
Sep 4, 2026
7c98ad2
Reclaim sequence versions at control boundary
Sep 4, 2026
b6f559a
Defer render-fired sequence reset cleanup
Sep 4, 2026
0198b50
Make sequence triggers note-like and strict
Sep 4, 2026
361ac40
Migrate first-party sequencer callers
Sep 4, 2026
3060cc0
Test sequence publication allocation failures
Sep 4, 2026
f22307a
Cover concurrent sequence publication retry
Sep 4, 2026
dcbd284
Define bounded sequence composition semantics
Sep 4, 2026
092941c
Accept note-like sequence control velocity
Sep 4, 2026
33f4c01
Preserve existing config member offsets
Sep 4, 2026
ab5f302
Document and test sequence API migration
Sep 4, 2026
36aa150
Simplify stored sequence slots
Sep 4, 2026
380f20e
Ignore generated sequence test binaries
Sep 4, 2026
4aab0fc
Use explicit run state for sequence control
Sep 4, 2026
cc2407f
Document boolean sequence run control
Sep 4, 2026
841ccd2
Expose named sequence control actions
Sep 4, 2026
f03875f
Document start stop and gate actions
Sep 4, 2026
596047b
Document reusable sequence model and compatibility
Sep 4, 2026
065a229
Separate render and external sequence dispatch
Sep 4, 2026
98873a9
Make same-tick sequence controls slot independent
Sep 4, 2026
1b1e527
Test concurrent sequence render and control
Sep 4, 2026
fc3c9e5
Reject unrepresentable sequence capacities
Sep 4, 2026
1fd5e22
Validate sequence integers without truncation
Sep 4, 2026
04db763
Define strict wrap-safe sequence timing
Sep 4, 2026
10d5976
Clarify sequence checks and terminology
Sep 4, 2026
8305129
Test sequence lifetime across the uint32 clock
Sep 4, 2026
ec94860
Preserve legacy omitted tick fields
Sep 4, 2026
f8df2b2
Align sequence controls correctly across clock wrap
Sep 4, 2026
83e883d
Cover sequence allocation failure boundaries
Sep 4, 2026
e69f537
Stress sequence publication during rendering
Sep 4, 2026
ab2a02e
Clarify sequence compatibility boundaries
Sep 4, 2026
397488b
Define M_PI portably for MSVC
Sep 5, 2026
e147751
Merge sequencer simplification
Sep 5, 2026
3872b4b
Document Windows M_PI portability fix
Sep 5, 2026
63f5c59
Merge Android and socket integration
Sep 5, 2026
30ca2d6
Document downstream Android packaging lessons
Aug 30, 2026
c58f151
Add selectable CPython PCM bank build
Aug 30, 2026
e082aa1
Support deterministic offline live configuration
Aug 31, 2026
553af87
Build Gamma9001 Omnichord service profile
Aug 30, 2026
55f7d1e
Register Gamma9001 PCM in Android service
Aug 30, 2026
d2cdf6a
Preserve socket commands under receiver backpressure
Sep 3, 2026
6edcc75
Make embedded audio geometry configurable
Sep 4, 2026
41f2753
Use ESP-IDF task entry signatures
Sep 4, 2026
166a63d
Size reusable sequences for Omnichord integrations
Sep 4, 2026
11f0c39
Update Omnichord release profile contract
Sep 5, 2026
084247a
Avoid forgotten-note buildup when note-offs are ignored
Sep 5, 2026
128bbe4
Merge ignored note-off bookkeeping fix
Sep 5, 2026
5cde3bf
Record one-shot drum bookkeeping release
Sep 5, 2026
57c92c2
Make ignored-note-off regression state based
Sep 5, 2026
f3d72df
Merge portable ignored note-off regression
Sep 5, 2026
9306a2c
Add opt-in ESP render load diagnostics
Sep 7, 2026
0bd9fea
Add shared aux reverb rooms
Sep 7, 2026
21828d8
Store ESP load diagnostics for deferred readout
Sep 7, 2026
594b5f3
Use portable reverb diagnostic formats
Sep 7, 2026
789af46
Skip disabled shared reverb processing
Sep 7, 2026
355e8dd
Expose shared reverb capacity to CPython hosts
Sep 7, 2026
a338d5a
Report ESP audio deadline pressure by interval
Sep 7, 2026
d3676ce
Attribute ESP deadline misses to render stages
Sep 7, 2026
bebd4a4
Count deltas in ESP deadline diagnostics
Sep 7, 2026
f2d71c0
Correlate deadline misses with sequencer and voices
Sep 7, 2026
c6822e1
Break down sequencer deadline cost
Sep 7, 2026
13c411d
Avoid rescanning finite sequence events each tick
Sep 7, 2026
2d6b78e
Skip irrelevant stored sequence event classes
Sep 7, 2026
e1c9892
Report active stored sequence shapes
Sep 7, 2026
09ab455
Avoid rescanning uniform periodic sequences
Sep 7, 2026
97b970b
Index active sequence executions
Sep 7, 2026
16b37fe
Keep sequence runtime state in render memory
Sep 7, 2026
b959b86
Absorb isolated ESP render jitter in DMA debt
Sep 7, 2026
e9a96c2
Use portable fences for diagnostics
Sep 7, 2026
54b107c
Merge pull request #1152 from shorepine/block-size-compile-time
dpwe Sep 8, 2026
40a76fb
Bump version to 1.2.164, rebuild web + Godot API
github-actions[bot] Sep 8, 2026
fcbb551
Bump version to 1.2.164 [skip release]
github-actions[bot] Sep 8, 2026
df7e153
Merge Shorepine AMY 1.2.164
Sep 8, 2026
f1c7f31
Reuse AMY bus summation for shared routing
Sep 8, 2026
3b990b4
Process shared reverb bus subsets on matching cores
Sep 8, 2026
ad8d40c
Follow upstream block size build option
Sep 8, 2026
b6266f3
Keep embedded block size recipes compatible
Sep 8, 2026
2af2c5d
Cover dual shared rooms and bus hook fallback
Sep 8, 2026
9be3c6d
Keep compatibility defines out of generated constants
Sep 8, 2026
a9e3229
Regenerate Godot API for shared reverbs
Sep 8, 2026
3863da2
Generalize shared rooms as aux returns
Sep 8, 2026
c638d59
Prove aux return count remains runtime configurable
Sep 8, 2026
f5999c0
Clarify generic aux return semantics
Sep 8, 2026
8a61658
Enable shared aux returns in Android service
Sep 8, 2026
53a3160
Document hosted shared aux capacity
Sep 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: Android AMY

on:
push:
branches:
- integration/amy_android
pull_request:
paths:
- "android/**"
- "src/**"
- "tests/test_amy_unix_socket.c"
- "tests/run_amy_unix_socket_test.sh"
- "tests/check_android_audio_capture.py"
- "tests/test_android_service_contract.py"
- ".github/workflows/android.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
socket-transport:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Verify Android service contract
run: python3 tests/test_android_service_contract.py
- name: Build and run private Unix socket test
run: bash tests/run_amy_unix_socket_test.sh

android-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Verify Android service contract
run: python3 tests/test_android_service_contract.py

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"

- uses: android-actions/setup-android@v3

- name: Install Android SDK components
run: |
yes | sdkmanager --licenses >/dev/null
sdkmanager \
"platforms;android-36" \
"build-tools;35.0.0" \
"ndk;27.2.12479018" \
"cmake;3.22.1"

- uses: gradle/actions/setup-gradle@v4
with:
gradle-version: "8.13"

- name: Build AMY Android AAR and hello-world APK
working-directory: android
run: gradle :amy-service:assembleDebug :hello-world:assembleDebug --stacktrace

- name: Verify transport-only hello-world packaging
run: |
APK=android/hello-world/build/outputs/apk/debug/hello-world-debug.apk
test -s "$APK"
! unzip -l "$APK" | grep -q 'libamy_hello_client.so'
test ! -e android/hello-world/src/main/cpp

- name: Upload AMY Android AAR
uses: actions/upload-artifact@v4
with:
name: amy-service-debug-aar
path: android/amy-service/build/outputs/aar/amy-service-debug.aar
if-no-files-found: error

- name: Upload AMY hello-world APK
uses: actions/upload-artifact@v4
with:
name: amy-hello-world-debug-apk
path: android/hello-world/build/outputs/apk/debug/hello-world-debug.apk
if-no-files-found: error

- name: Enable KVM for Android emulator
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
| sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- name: Emulator end-to-end smoke test
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 35
arch: x86_64
profile: pixel_2
disable-animations: true
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -no-boot-anim
script: |
adb uninstall org.amy.hello >/dev/null 2>&1 || true
adb install android/hello-world/build/outputs/apk/debug/hello-world-debug.apk
adb shell run-as org.amy.hello mkdir -p files
adb shell run-as org.amy.hello touch files/amy-audio-capture.enable
adb logcat -c
adb shell am start -W -n org.amy.hello/.MainActivity
sleep 10
adb logcat -d -s AmyAndroid:I AmyAudioCapture:I AmyService:I AmyHelloWorld:I '*:S' > /tmp/amy-first.log
test "$(grep -c 'AMY/Oboe started' /tmp/amy-first.log)" -eq 1
grep -q 'AMY output route: deviceId=' /tmp/amy-first.log
grep -q 'connected to amy.sock' /tmp/amy-first.log
test "$(grep -c 'C scale complete' /tmp/amy-first.log)" -eq 1
! grep -q 'C scale failed' /tmp/amy-first.log
grep -q 'wire: v0w0V10.0Z' /tmp/amy-first.log
test "$(grep -Ec 'wire: v0n(60|62|64|65|67|69|71|72)l1Z' /tmp/amy-first.log)" -eq 8
grep -q 'wire: v0n60l1Z' /tmp/amy-first.log
grep -q 'wire: v0n72l1Z' /tmp/amy-first.log
grep -q 'Audio capture complete:' /tmp/amy-first.log

adb uninstall org.amy.hello
adb install android/hello-world/build/outputs/apk/debug/hello-world-debug.apk
adb shell run-as org.amy.hello mkdir -p files
adb shell run-as org.amy.hello touch files/amy-audio-capture.enable
adb logcat -c
adb shell am start -W -n org.amy.hello/.MainActivity
sleep 10
adb logcat -d -s AmyAndroid:I AmyAudioCapture:I AmyService:I AmyHelloWorld:I '*:S' > /tmp/amy-second.log
test "$(grep -c 'AMY/Oboe started' /tmp/amy-second.log)" -eq 1
grep -q 'AMY output route: deviceId=' /tmp/amy-second.log
grep -q 'connected to amy.sock' /tmp/amy-second.log
test "$(grep -c 'C scale complete' /tmp/amy-second.log)" -eq 1
! grep -q 'C scale failed' /tmp/amy-second.log
grep -q 'wire: v0w0V10.0Z' /tmp/amy-second.log
test "$(grep -Ec 'wire: v0n(60|62|64|65|67|69|71|72)l1Z' /tmp/amy-second.log)" -eq 8
grep -q 'wire: v0n60l1Z' /tmp/amy-second.log
grep -q 'wire: v0n72l1Z' /tmp/amy-second.log
grep -q 'Audio capture complete:' /tmp/amy-second.log

mkdir -p android/audio-capture
adb exec-out run-as org.amy.hello cat files/amy-render.wav > android/audio-capture/amy-render.wav
adb exec-out run-as org.amy.hello cat files/amy-oboe.wav > android/audio-capture/amy-oboe.wav
adb exec-out run-as org.amy.hello cat files/amy-audio-levels.txt > android/audio-capture/amy-audio-levels.txt
test -s android/audio-capture/amy-render.wav
test -s android/audio-capture/amy-oboe.wav
test -s android/audio-capture/amy-audio-levels.txt
cat android/audio-capture/amy-audio-levels.txt

- name: Analyze captured AMY and Oboe audio levels
run: |
python3 tests/check_android_audio_capture.py \
android/audio-capture/amy-render.wav \
android/audio-capture/amy-oboe.wav

- name: Upload Android audio captures
uses: actions/upload-artifact@v4
with:
name: amy-android-audio-capture
path: android/audio-capture/
if-no-files-found: error
5 changes: 4 additions & 1 deletion .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ jobs:
- name: Validate GDScript parses
run: gdparse godot/amy.gd

- name: Test Godot backend lifecycle signals
run: python tests/test_godot_backend_signals.py

- name: Check godot/amy.gd is in sync with amy/__init__.py
run: |
if ! git diff --quiet -- godot/amy.gd; then
Expand All @@ -111,7 +114,7 @@ jobs:
python-version: '3.13'

- name: Check generated C API bindings are in sync
run: make check-c-api
run: make check-c-api js-api-test

godot-build:
# Build the Godot GDExtension for Linux. amy_midi.c is excluded from the
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/unix-socket.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Unix socket transport

on:
pull_request:
paths:
- 'src/amy_unix_socket.c'
- 'src/amy_unix_socket.h'
- 'tests/test_amy_unix_socket.c'
- 'tests/run_amy_unix_socket_test.sh'
- '.github/workflows/unix-socket.yml'

permissions:
contents: read

jobs:
linux-socket-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Compile and run Unix socket transport test
run: bash tests/run_amy_unix_socket_test.sh
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ tests/tst
tests/test_clock_wrap
tests/test_sequencer_active
tests/test_sequencer_bounds
tests/test_sequencer_sequences
tests/test_sequencer_oom
tests/test_sequencer_concurrency
tests/test_bus_config
tests/test_patch_slots
tests/test_synth_readout
Expand Down
87 changes: 82 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ EMSCRIPTEN_OPTIONS = -s WASM=1 --bind \
-s ASYNCIFY -s ASYNCIFY_STACK_SIZE=128000
PYTHON = python3

.PHONY: default all clean amy-module test ctest web deploy-web godot-api c-api check-c-api
.PHONY: default all clean amy-module test ctest build-config-test web deploy-web godot-api c-api check-c-api js-api-test

default: $(TARGET)
all: default
Expand All @@ -83,6 +83,9 @@ check-c-api:
$(PYTHON) scripts/gen_patches_js.py --check
$(PYTHON) scripts/gen_pcm_presets_js.py --check

js-api-test:
node tests/test_js_api.js

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 \
Expand All @@ -96,8 +99,14 @@ HEADERS_BUILD := $(filter-out src/patches.h,$(HEADERS))

PYTHONS = $(wildcard *.py)

# The grep below takes every NUMERIC #define out of amy.h. AMY_BLOCK_SIZE is
# the one derived define -- (1 << BLOCK_SIZE_BITS), since the block has to be
# a power of two and the bits are the knob -- so it is spelt out afterwards
# from the BLOCK_SIZE_BITS that landed, or amy.render() and the generated JS
# API would lose it.
src/patches.h: $(PYTHONS) $(HEADERS_BUILD)
cat src/amy.h | sed -e 's@^//.*@@' | tr '\t' ' ' | egrep 'define +[^ ]+ +[.0-9-]+' | sed -e 's/\([-0-9][0-9]*\.[0-9]*\)f.*/\1/' | awk '{print $$2 "=" $$3}' > amy/constants.py
echo "AMY_BLOCK_SIZE=$$((1 << $$(sed -n 's/^BLOCK_SIZE_BITS=//p' amy/constants.py | tail -1)))" >> amy/constants.py
${PYTHON} -m amy.headers

%.o: %.c $(HEADERS) src/patches.h
Expand All @@ -124,27 +133,94 @@ amy-message: $(OBJECTS) src/amy-message.o
# Plain C tests for things the audio-rendering suite can't reach -- e.g. clock
# rollovers 50 days out, which you can only hit by fast-forwarding the counters.
CTESTS = tests/test_clock_wrap tests/test_sequencer_active tests/test_sequencer_bounds \
tests/test_sequencer_sequences \
tests/test_sequencer_oom \
tests/test_sequencer_concurrency \
tests/test_bus_config tests/test_patch_slots \
tests/test_synth_readout tests/test_log2_lut tests/test_clone_on_grow \
tests/test_timebase_reset tests/test_osc_free_on_release \
tests/test_voice_osc_range tests/test_dist_coefs tests/test_dist_scope
tests/test_voice_osc_range tests/test_dist_coefs tests/test_dist_scope \
tests/test_ignore_note_offs tests/test_shared_reverb \
tests/test_reverb_limit

# Static pattern rules, so these win over the generic %.o: %.c above (which
# would compile without -Isrc and fail to find amy.h).
$(addsuffix .o,$(CTESTS)): %.o: %.c $(HEADERS) src/patches.h
SEQUENCE_SPECIAL_TESTS = tests/test_sequencer_oom tests/test_sequencer_concurrency
INSTRUMENT_SPECIAL_TEST = tests/test_ignore_note_offs
REVERB_SPECIAL_TEST = tests/test_reverb_limit
SPECIAL_TESTS = $(SEQUENCE_SPECIAL_TESTS) $(INSTRUMENT_SPECIAL_TEST) $(REVERB_SPECIAL_TEST)

$(addsuffix .o,$(filter-out $(SPECIAL_TESTS),$(CTESTS))): %.o: %.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -Isrc -c $< -o $@

$(CTESTS): %: %.o $(OBJECTS)
$(filter-out $(SPECIAL_TESTS),$(CTESTS)): %: %.o $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $< -Wall $(LIBS) -o $@

ctest: $(CTESTS)
# Build only the sequencer and its OOM test with the test-only allocation hook;
# every other test and every production target uses the ordinary object.
tests/sequencer_testing_impl.o: src/sequencer.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -DAMY_SEQUENCE_TESTING -c $< -o $@

tests/test_sequencer_oom.o: tests/test_sequencer_oom.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -DAMY_SEQUENCE_TESTING -Isrc -c $< -o $@

tests/test_sequencer_concurrency.o: tests/test_sequencer_concurrency.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -DAMY_SEQUENCE_TESTING -Isrc -c $< -o $@

$(SEQUENCE_SPECIAL_TESTS): %: %.o tests/sequencer_testing_impl.o $(filter-out src/sequencer.o,$(OBJECTS))
$(CC) $(CFLAGS) $(filter-out src/sequencer.o,$(OBJECTS)) tests/sequencer_testing_impl.o $< -Wall $(LIBS) -o $@

# Compile amy.c once with a small embedded-style built-in reverb ceiling. The
# rest of AMY is unchanged because the ceiling only guards effect allocation.
tests/amy_reverb_limit_impl.o: src/amy.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -DAMY_MAX_REVERBS=1 -c $< -o $@

tests/test_reverb_limit.o: tests/test_reverb_limit.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -DAMY_MAX_REVERBS=1 -Isrc -c $< -o $@

tests/test_reverb_limit: tests/test_reverb_limit.o tests/amy_reverb_limit_impl.o $(filter-out src/amy.o,$(OBJECTS))
$(CC) $(CFLAGS) $(filter-out src/amy.o,$(OBJECTS)) tests/amy_reverb_limit_impl.o $< -Wall $(LIBS) -o $@

# Read internal pool occupancy in this test without parsing stderr or relying
# on platform-specific file-descriptor redirection.
tests/instrument_testing_impl.o: src/instrument.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -DAMY_INSTRUMENT_TESTING -c $< -o $@

tests/test_ignore_note_offs.o: tests/test_ignore_note_offs.c $(HEADERS) src/patches.h
$(CC) $(CFLAGS) -DAMY_INSTRUMENT_TESTING -Isrc -c $< -o $@

$(INSTRUMENT_SPECIAL_TEST): %: %.o tests/instrument_testing_impl.o $(filter-out src/instrument.o,$(OBJECTS))
$(CC) $(CFLAGS) $(filter-out src/instrument.o,$(OBJECTS)) tests/instrument_testing_impl.o $< -Wall $(LIBS) -o $@

build-config-test:
$(CC) $(CFLAGS) -Isrc \
-DEXPECT_AMY_BLOCK_SIZE=256 -DEXPECT_BLOCK_SIZE_BITS=8 \
-DEXPECT_AMY_SAMPLE_RATE=44100 \
tests/test_build_config.c -o tests/test_build_config_default
./tests/test_build_config_default
$(CC) $(CFLAGS) -Isrc \
-DBLOCK_SIZE_BITS=7 -DAMY_SAMPLE_RATE=48000 \
-DEXPECT_AMY_BLOCK_SIZE=128 -DEXPECT_BLOCK_SIZE_BITS=7 \
-DEXPECT_AMY_SAMPLE_RATE=48000 \
tests/test_build_config.c -o tests/test_build_config_embedded
./tests/test_build_config_embedded
$(CC) $(CFLAGS) -Isrc \
-DAMY_BLOCK_SIZE=128 -DAMY_SAMPLE_RATE=48000 \
-DEXPECT_AMY_BLOCK_SIZE=128 -DEXPECT_BLOCK_SIZE_BITS=7 \
-DEXPECT_AMY_SAMPLE_RATE=48000 \
tests/test_build_config.c -o tests/test_build_config_legacy
./tests/test_build_config_legacy

ctest: build-config-test $(CTESTS)
@for t in $(CTESTS); do echo "== $$t"; ./$$t || exit 1; done

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} tests/test_sequence_api.py
${PYTHON} -m amy.test
${PYTHON} tests/test_python_offline_live.py

qtest: amy-module
${PYTHON} -m amy.test quiet
Expand Down Expand Up @@ -217,3 +293,4 @@ clean:
-rm -f amy/constants.py
-rm -f $(TARGET)
-rm -f tests/*.o $(CTESTS)
-rm -f tests/test_build_config_default tests/test_build_config_embedded tests/test_build_config_legacy
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@ AMY was built by [DAn Ellis](https://research.google/people/DanEllis/) and [Bria
* [**Interactive AMY tutorial**](https://shorepine.github.io/amy/tutorial.html)
* [**AMY API**](docs/api.md)
* [**AMY Synthesizer Details**](docs/synth.md)
* [**AMY Reusable Sequences**](docs/sequencer-sequences.md)
* [**Distortion in AMY**](docs/distortions.md)
* [**AMY's MIDI specification**](docs/midi.md)
* [**AMY in Arduino Getting Started**](docs/arduino.md)
* [**Windows `M_PI` portability note**](docs/windows-m-pi-portability.md)
* [**Porting AMY and local-service transports**](docs/porting.md)
* [**Other AMY web demos**](https://shorepine.github.io/amy/)

AMY supports
Expand Down Expand Up @@ -111,6 +114,12 @@ In Python:
>>> # play MIDI notes using system MIDI
```

`amy.live(audio=False, ...)` applies the same runtime configuration without
starting a system-audio callback. This is intended for deterministic offline
rendering with `c_amy.render_to_list()`; omitting `audio` retains the existing
live-audio behavior. Runtime allocation options such as `max_buses`,
`max_reverb_rooms`, and the sequencer limits use the same keyword interface.

In C:

```c
Expand Down Expand Up @@ -171,11 +180,14 @@ It's good to understand what wire messages are but you don't need to construct t
* [**Interactive AMY tutorial**](https://shorepine.github.io/amy/tutorial.html)
* [**AMY API**](docs/api.md)
* [**AMY Synthesizer Details**](docs/synth.md)
* [**AMY Reusable Sequences**](docs/sequencer-sequences.md)
* [**Distortion in AMY**](docs/distortions.md)
* [**AMY's MIDI specification**](docs/midi.md)
* [**AMY in Arduino Getting Started**](docs/arduino.md)
* [**AMY in Godot**](docs/godot.md)
* [**Porting AMY and local-service transports**](docs/porting.md)
* [**AMY on Windows**](windows/README.md)
* [**Windows `M_PI` portability note**](docs/windows-m-pi-portability.md)
* [**Other AMY web demos**](https://shorepine.github.io/amy/)

[![shore pine sound systems discord](https://raw.githubusercontent.com/shorepine/tulipcc/main/docs/pics/shorepine100.png) **Chat about AMY on our Discord!**](https://discord.gg/TzBFkUb8pG)
Loading
Loading