Merge branch 'main' of https://github.com/adafruit/circuitpython into wifi-power-management
This commit is contained in:
commit
b1ce99a97d
70 changed files with 1238 additions and 174 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6b678f15e378edce820f2ffdef3286b3e55449e7
|
Subproject commit 8bca037b052a4a4dc46a56a25a1b802652ee3f47
|
||||||
|
|
@ -160,11 +160,6 @@ static const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
|
||||||
|
|
||||||
// CIRCUITPY-CHANGE: Remove these in CircuitPython 10.0.0
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_obj) },
|
|
||||||
};
|
};
|
||||||
static MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);
|
static MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 51b4032f6809e5b4177d95ef5d70520352081eb8
|
Subproject commit 1ba6e0d0fa1fc0512692615a7c95281fdc0671b0
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 46340b3772b03a2acc584cbcb30ad801c902dc42
|
Subproject commit f7971b6cf1d2f1c88a84561cdb6fb9419073c120
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit ea32f33ada7ad6da33cead40a2d7393a9d60c029
|
Subproject commit 43a67c2672796324c4465ff41ef1d14bd4883db3
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit b74b18efd391e830d165125738441d2710485028
|
Subproject commit 24705c799e7df85fa6f0094e196788d3c8c99c87
|
||||||
|
|
@ -114,6 +114,10 @@ msgstr "%q berisi pin duplikat"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q gagal: %d"
|
msgstr "%q gagal: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q dalam %q harus bertipe %q, bukan %q"
|
msgstr "%q dalam %q harus bertipe %q, bukan %q"
|
||||||
|
|
@ -236,7 +240,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q harus bertipe %q, %q, atau %q, bukan %q"
|
msgstr "%q harus bertipe %q, %q, atau %q, bukan %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q harus bertipe %q, %q, atau %q, bukan %q"
|
msgstr "%q harus bertipe %q, %q, atau %q, bukan %q"
|
||||||
|
|
||||||
|
|
@ -2636,6 +2641,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,10 @@ msgstr ""
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -224,7 +228,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -2587,6 +2592,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,10 @@ msgstr "%q obsahuje duplicitní piny"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q: selhání %d"
|
msgstr "%q: selhání %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q v %q musí být typu %q, ne %q"
|
msgstr "%q v %q musí být typu %q, ne %q"
|
||||||
|
|
@ -235,7 +239,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q musí být typu %q, ne %q"
|
msgstr "%q musí být typu %q, ne %q"
|
||||||
|
|
||||||
|
|
@ -2616,6 +2621,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "počet bitů nesmí přesáhnout 32"
|
msgstr "počet bitů nesmí přesáhnout 32"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ msgstr "%q enthält doppelte Pins"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q Fehler: %d"
|
msgstr "%q Fehler: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q in %q muss von Typ %q sein, nicht %q"
|
msgstr "%q in %q muss von Typ %q sein, nicht %q"
|
||||||
|
|
@ -238,7 +242,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q muss vom Typ %q, %q oder %q sein, und nicht %q"
|
msgstr "%q muss vom Typ %q, %q oder %q sein, und nicht %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q muss von Typ %q sein, nicht %q"
|
msgstr "%q muss von Typ %q sein, nicht %q"
|
||||||
|
|
||||||
|
|
@ -2648,6 +2653,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "bits müssen 32 oder kleiner sein"
|
msgstr "bits müssen 32 oder kleiner sein"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,10 @@ msgstr "%q περιέχει διπλότυπα pins"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q αποτυχία: %d"
|
msgstr "%q αποτυχία: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q στο %q πρέπει να είναι τύπου %q, όχι %q"
|
msgstr "%q στο %q πρέπει να είναι τύπου %q, όχι %q"
|
||||||
|
|
@ -239,7 +243,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q πρέπει να είναι τύπου %q, όχι %q"
|
msgstr "%q πρέπει να είναι τύπου %q, όχι %q"
|
||||||
|
|
||||||
|
|
@ -2615,6 +2620,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"PO-Revision-Date: 2025-03-06 13:42+0000\n"
|
"PO-Revision-Date: 2025-04-19 15:42+0000\n"
|
||||||
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
|
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
|
||||||
"Language-Team: none\n"
|
"Language-Team: none\n"
|
||||||
"Language: en_GB\n"
|
"Language: en_GB\n"
|
||||||
|
|
@ -15,7 +15,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.10.3-dev\n"
|
"X-Generator: Weblate 5.11.1-dev\n"
|
||||||
|
|
||||||
#: main.c
|
#: main.c
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
@ -115,6 +115,10 @@ msgstr "%q contains duplicate pins"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q failure: %d"
|
msgstr "%q failure: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q in %q must be of type %q, not %q"
|
msgstr "%q in %q must be of type %q, not %q"
|
||||||
|
|
@ -237,7 +241,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q must be of type %q, %q, or %q, not %q"
|
msgstr "%q must be of type %q, %q, or %q, not %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q must be of type %q, not %q"
|
msgstr "%q must be of type %q, not %q"
|
||||||
|
|
||||||
|
|
@ -805,7 +810,7 @@ msgstr "Cannot record to a file"
|
||||||
|
|
||||||
#: shared-module/storage/__init__.c
|
#: shared-module/storage/__init__.c
|
||||||
msgid "Cannot remount path when visible via USB."
|
msgid "Cannot remount path when visible via USB."
|
||||||
msgstr ""
|
msgstr "Cannot remount path when visible via USB."
|
||||||
|
|
||||||
#: shared-bindings/digitalio/DigitalInOut.c
|
#: shared-bindings/digitalio/DigitalInOut.c
|
||||||
msgid "Cannot set value when direction is input."
|
msgid "Cannot set value when direction is input."
|
||||||
|
|
@ -1391,7 +1396,7 @@ msgstr "MITM security is not supported"
|
||||||
#: ports/stm/common-hal/sdioio/SDCard.c
|
#: ports/stm/common-hal/sdioio/SDCard.c
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "MMC/SDIO Clock Error %x"
|
msgid "MMC/SDIO Clock Error %x"
|
||||||
msgstr ""
|
msgstr "MMC/SDIO Clock Error %x"
|
||||||
|
|
||||||
#: shared-bindings/is31fl3741/IS31FL3741.c
|
#: shared-bindings/is31fl3741/IS31FL3741.c
|
||||||
msgid "Mapping must be a tuple"
|
msgid "Mapping must be a tuple"
|
||||||
|
|
@ -1581,7 +1586,7 @@ msgstr "No pulldown on pin; 1Mohm recommended"
|
||||||
|
|
||||||
#: shared-module/touchio/TouchIn.c
|
#: shared-module/touchio/TouchIn.c
|
||||||
msgid "No pullup on pin; 1Mohm recommended"
|
msgid "No pullup on pin; 1Mohm recommended"
|
||||||
msgstr ""
|
msgstr "No pullup on pin; 1Mohm recommended"
|
||||||
|
|
||||||
#: py/moderrno.c
|
#: py/moderrno.c
|
||||||
msgid "No space left on device"
|
msgid "No space left on device"
|
||||||
|
|
@ -2620,6 +2625,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "bits must be 32 or less"
|
msgstr "bits must be 32 or less"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,10 @@ msgstr "%q contiene pines duplicados"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q fallo: %d"
|
msgstr "%q fallo: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q en %q debe ser del tipo %q, no %q"
|
msgstr "%q en %q debe ser del tipo %q, no %q"
|
||||||
|
|
@ -239,7 +243,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q debe ser de tipo %q, %q, o %q, no %q"
|
msgstr "%q debe ser de tipo %q, %q, o %q, no %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q debe ser del tipo %q, y no %q"
|
msgstr "%q debe ser del tipo %q, y no %q"
|
||||||
|
|
||||||
|
|
@ -2657,6 +2662,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "los bits deben ser 32 o menos"
|
msgstr "los bits deben ser 32 o menos"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,10 @@ msgstr ""
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -227,7 +231,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -2606,6 +2611,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,10 @@ msgstr "%q contient des broches en double"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "Échec de %q : %d"
|
msgstr "Échec de %q : %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q dans %q doit être de type %q, pas %q"
|
msgstr "%q dans %q doit être de type %q, pas %q"
|
||||||
|
|
@ -238,7 +242,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q doit être de type %q, %q ou %q, pas %q"
|
msgstr "%q doit être de type %q, %q ou %q, pas %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q doit être de type %q, pas %q"
|
msgstr "%q doit être de type %q, pas %q"
|
||||||
|
|
||||||
|
|
@ -2667,6 +2672,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "les bits doivent être 32 ou moins"
|
msgstr "les bits doivent être 32 ou moins"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,10 @@ msgstr ""
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -226,7 +230,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -2589,6 +2594,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,10 @@ msgstr ""
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q fallito: %d"
|
msgstr "%q fallito: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -228,7 +232,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -2604,6 +2609,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ msgstr "%q に重複するピンがあります"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q 失敗: %d"
|
msgstr "%q 失敗: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q 内の %q は %q 型である必要があり、 %q 型は使用できません"
|
msgstr "%q 内の %q は %q 型である必要があり、 %q 型は使用できません"
|
||||||
|
|
@ -239,7 +243,8 @@ msgstr ""
|
||||||
"%q は %q 型や %q 型または %q 型である必要があります、 %q 型は使用できません"
|
"%q は %q 型や %q 型または %q 型である必要があります、 %q 型は使用できません"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q は %q 型である必要があります、 %q 型は使用できません"
|
msgstr "%q は %q 型である必要があります、 %q 型は使用できません"
|
||||||
|
|
||||||
|
|
@ -2612,6 +2617,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ msgstr "%q에 중복된 핀이 포함"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q 실패: %d"
|
msgstr "%q 실패: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q의 %q는 %q가 아니라 %q 유형이어야 합니다"
|
msgstr "%q의 %q는 %q가 아니라 %q 유형이어야 합니다"
|
||||||
|
|
@ -243,7 +247,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q는 %q가 아니라 %q 유형이어야 합니다"
|
msgstr "%q는 %q가 아니라 %q 유형이어야 합니다"
|
||||||
|
|
||||||
|
|
@ -2665,6 +2670,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,10 @@ msgstr ""
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q fout: %d"
|
msgstr "%q fout: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -224,7 +228,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -2605,6 +2610,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,10 @@ msgstr "%q zawiera zduplikowane piny"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q niepowodzenie: %d"
|
msgstr "%q niepowodzenie: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q w %q musi być typu %q, a nie %q"
|
msgstr "%q w %q musi być typu %q, a nie %q"
|
||||||
|
|
@ -232,7 +236,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q musi być typu %q, a nie %q"
|
msgstr "%q musi być typu %q, a nie %q"
|
||||||
|
|
||||||
|
|
@ -2617,6 +2622,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ msgstr "%q contém pinos duplicados"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q falha: %d"
|
msgstr "%q falha: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q em %q deve ser do tipo %q e não %q"
|
msgstr "%q em %q deve ser do tipo %q e não %q"
|
||||||
|
|
@ -237,7 +241,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q deve ser do tipo %q, %q ou %q e não %q"
|
msgstr "%q deve ser do tipo %q, %q ou %q e não %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q deve ser do tipo %q e não %q"
|
msgstr "%q deve ser do tipo %q e não %q"
|
||||||
|
|
||||||
|
|
@ -2663,6 +2668,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "bits deve ser 32 ou menos"
|
msgstr "bits deve ser 32 ou menos"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,10 @@ msgstr "%q содержит пины дупликаты"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q сбой: %d"
|
msgstr "%q сбой: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q в %q должно быть типа %q, а не %q"
|
msgstr "%q в %q должно быть типа %q, а не %q"
|
||||||
|
|
@ -239,7 +243,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q должен иметь тип %q, %q или %q, а не %q"
|
msgstr "%q должен иметь тип %q, %q или %q, а не %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q должно быть типа %q, а не %q"
|
msgstr "%q должно быть типа %q, а не %q"
|
||||||
|
|
||||||
|
|
@ -2659,6 +2664,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "биты должны быть 32 или менее"
|
msgstr "биты должны быть 32 или менее"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,10 @@ msgstr "%q innehåller dubblettstift"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q-fel: %d"
|
msgstr "%q-fel: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q i %q måste vara av typen %q, inte %q"
|
msgstr "%q i %q måste vara av typen %q, inte %q"
|
||||||
|
|
@ -238,7 +242,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q måste vara av typen %q, %q, eller %q, inte %q"
|
msgstr "%q måste vara av typen %q, %q, eller %q, inte %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q måste vara av typen %q, inte %q"
|
msgstr "%q måste vara av typen %q, inte %q"
|
||||||
|
|
||||||
|
|
@ -2631,6 +2636,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "bits måste vara 32 eller färre"
|
msgstr "bits måste vara 32 eller färre"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ msgstr "%q yinelenen pinler içeriyor"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q hata: %d"
|
msgstr "%q hata: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -237,7 +241,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -2611,6 +2616,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ msgstr ""
|
||||||
"Project-Id-Version: circuitpython-cn\n"
|
"Project-Id-Version: circuitpython-cn\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
|
"POT-Creation-Date: 2021-01-04 12:55-0600\n"
|
||||||
"PO-Revision-Date: 2025-02-24 05:02+0000\n"
|
"PO-Revision-Date: 2025-04-10 22:01+0000\n"
|
||||||
"Last-Translator: hexthat <hexthat@gmail.com>\n"
|
"Last-Translator: hexthat <hexthat@gmail.com>\n"
|
||||||
"Language-Team: Chinese Hanyu Pinyin\n"
|
"Language-Team: Chinese Hanyu Pinyin\n"
|
||||||
"Language: zh_Latn_pinyin\n"
|
"Language: zh_Latn_pinyin\n"
|
||||||
|
|
@ -15,7 +15,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
"X-Generator: Weblate 5.10.1-dev\n"
|
"X-Generator: Weblate 5.11-dev\n"
|
||||||
|
|
||||||
#: main.c
|
#: main.c
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
@ -116,6 +116,10 @@ msgstr "%q bāo hán chóng fù de yǐn jiǎo"
|
||||||
msgid "%q failure: %d"
|
msgid "%q failure: %d"
|
||||||
msgstr "%q Shībài: %d"
|
msgstr "%q Shībài: %d"
|
||||||
|
|
||||||
|
#: shared-module/audiodelays/MultiTapDelay.c
|
||||||
|
msgid "%q in %q must be of type %q or %q, not %q"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
#: py/argcheck.c shared-module/audiofilters/Filter.c
|
||||||
msgid "%q in %q must be of type %q, not %q"
|
msgid "%q in %q must be of type %q, not %q"
|
||||||
msgstr "%q zhōng de %q bì xū shì %q lèi xíng, ér bù shì %q"
|
msgstr "%q zhōng de %q bì xū shì %q lèi xíng, ér bù shì %q"
|
||||||
|
|
@ -239,7 +243,8 @@ msgid "%q must be of type %q, %q, or %q, not %q"
|
||||||
msgstr "%q bìxūshì %q, %q huò %q lèixíng, érbùshì %q"
|
msgstr "%q bìxūshì %q, %q huò %q lèixíng, érbùshì %q"
|
||||||
|
|
||||||
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c
|
||||||
#: shared-module/synthio/Note.c shared-module/synthio/__init__.c
|
#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c
|
||||||
|
#: shared-module/synthio/__init__.c
|
||||||
msgid "%q must be of type %q, not %q"
|
msgid "%q must be of type %q, not %q"
|
||||||
msgstr "%q de lèi xíng bì xū shì %q, ér bù shì %q"
|
msgstr "%q de lèi xíng bì xū shì %q, ér bù shì %q"
|
||||||
|
|
||||||
|
|
@ -810,7 +815,7 @@ msgstr "Wúfǎ jìlù dào wénjiàn"
|
||||||
|
|
||||||
#: shared-module/storage/__init__.c
|
#: shared-module/storage/__init__.c
|
||||||
msgid "Cannot remount path when visible via USB."
|
msgid "Cannot remount path when visible via USB."
|
||||||
msgstr ""
|
msgstr "tōngguò USB kějiàn shí wúfǎ chóngxīn guàzǎi lùjìng."
|
||||||
|
|
||||||
#: shared-bindings/digitalio/DigitalInOut.c
|
#: shared-bindings/digitalio/DigitalInOut.c
|
||||||
msgid "Cannot set value when direction is input."
|
msgid "Cannot set value when direction is input."
|
||||||
|
|
@ -1061,7 +1066,7 @@ msgstr "Wúfǎ shìfàng mutex, err 0x%04x"
|
||||||
|
|
||||||
#: ports/zephyr-cp/common-hal/wifi/Radio.c
|
#: ports/zephyr-cp/common-hal/wifi/Radio.c
|
||||||
msgid "Failed to set hostname"
|
msgid "Failed to set hostname"
|
||||||
msgstr ""
|
msgstr "wúfǎ shèzhì zhǔjīmíng"
|
||||||
|
|
||||||
#: ports/espressif/common-hal/audioio/AudioOut.c
|
#: ports/espressif/common-hal/audioio/AudioOut.c
|
||||||
msgid "Failed to start async audio"
|
msgid "Failed to start async audio"
|
||||||
|
|
@ -1405,7 +1410,7 @@ msgstr "bù zhīchí MITM ānquánxìng"
|
||||||
#: ports/stm/common-hal/sdioio/SDCard.c
|
#: ports/stm/common-hal/sdioio/SDCard.c
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "MMC/SDIO Clock Error %x"
|
msgid "MMC/SDIO Clock Error %x"
|
||||||
msgstr ""
|
msgstr "MMC/SDIO shízhōngcuòwù %x"
|
||||||
|
|
||||||
#: shared-bindings/is31fl3741/IS31FL3741.c
|
#: shared-bindings/is31fl3741/IS31FL3741.c
|
||||||
msgid "Mapping must be a tuple"
|
msgid "Mapping must be a tuple"
|
||||||
|
|
@ -1595,7 +1600,7 @@ msgstr "Yǐn jiǎo shàng méiyǒu xiàlā; 1Mohm tuījiàn"
|
||||||
|
|
||||||
#: shared-module/touchio/TouchIn.c
|
#: shared-module/touchio/TouchIn.c
|
||||||
msgid "No pullup on pin; 1Mohm recommended"
|
msgid "No pullup on pin; 1Mohm recommended"
|
||||||
msgstr ""
|
msgstr "Yǐn jiǎo shàng wú shàng lā diànzǔ; jiànyì shǐyòng 1Mohm"
|
||||||
|
|
||||||
#: py/moderrno.c
|
#: py/moderrno.c
|
||||||
msgid "No space left on device"
|
msgid "No space left on device"
|
||||||
|
|
@ -2638,6 +2643,7 @@ msgid "bits must be 32 or less"
|
||||||
msgstr "wèi bì xū shì 32 huò gèng shǎo"
|
msgstr "wèi bì xū shì 32 huò gèng shǎo"
|
||||||
|
|
||||||
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c
|
||||||
|
#: shared-bindings/audiodelays/MultiTapDelay.c
|
||||||
#: shared-bindings/audiodelays/PitchShift.c
|
#: shared-bindings/audiodelays/PitchShift.c
|
||||||
#: shared-bindings/audiofilters/Distortion.c
|
#: shared-bindings/audiofilters/Distortion.c
|
||||||
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
#: shared-bindings/audiofilters/Filter.c shared-bindings/audiomixer/Mixer.c
|
||||||
|
|
|
||||||
4
main.c
4
main.c
|
|
@ -903,12 +903,8 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
port_post_boot_py(true);
|
|
||||||
|
|
||||||
cleanup_after_vm(_exec_result.exception);
|
cleanup_after_vm(_exec_result.exception);
|
||||||
_exec_result.exception = NULL;
|
_exec_result.exception = NULL;
|
||||||
|
|
||||||
port_post_boot_py(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_repl(safe_mode_t safe_mode) {
|
static int run_repl(safe_mode_t safe_mode) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,6 @@
|
||||||
#include "shared-bindings/alarm/touch/TouchAlarm.h"
|
#include "shared-bindings/alarm/touch/TouchAlarm.h"
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
|
|
||||||
void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) {
|
NORETURN void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) {
|
||||||
mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_TouchAlarm);
|
mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_TouchAlarm);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,11 @@
|
||||||
#define CIRCUITPY_DEFAULT_STACK_SIZE 3584
|
#define CIRCUITPY_DEFAULT_STACK_SIZE 3584
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CIRCUITPY_PYSTACK_SIZE
|
||||||
|
// Default for most boards is 2048 starting with CircuitPython 10, but on SAMD21, keep it at previous lower value.
|
||||||
|
#define CIRCUITPY_PYSTACK_SIZE 1536
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SAMD21_BOD33_LEVEL
|
#ifndef SAMD21_BOD33_LEVEL
|
||||||
// Set brownout detection to ~2.7V. Default from factory is 1.7V,
|
// Set brownout detection to ~2.7V. Default from factory is 1.7V,
|
||||||
// which is too low for proper operation of external SPI flash chips
|
// which is too low for proper operation of external SPI flash chips
|
||||||
|
|
|
||||||
|
|
@ -686,7 +686,7 @@ void port_idle_until_interrupt(void) {
|
||||||
/**
|
/**
|
||||||
* \brief Default interrupt handler for unused IRQs.
|
* \brief Default interrupt handler for unused IRQs.
|
||||||
*/
|
*/
|
||||||
__attribute__((used)) void HardFault_Handler(void) {
|
__attribute__((used)) NORETURN void HardFault_Handler(void) {
|
||||||
#ifdef ENABLE_MICRO_TRACE_BUFFER
|
#ifdef ENABLE_MICRO_TRACE_BUFFER
|
||||||
// Turn off the micro trace buffer so we don't fill it up in the infinite
|
// Turn off the micro trace buffer so we don't fill it up in the infinite
|
||||||
// loop below.
|
// loop below.
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "common-hal/microcontroller/__init__.h"
|
#include "common-hal/microcontroller/__init__.h"
|
||||||
#include "peripherals/broadcom/defines.h"
|
#include "peripherals/broadcom/defines.h"
|
||||||
#include "peripherals/broadcom/interrupts.h"
|
#include "peripherals/broadcom/interrupts.h"
|
||||||
|
#include "supervisor/port.h"
|
||||||
|
|
||||||
#include "mphalport.h"
|
#include "mphalport.h"
|
||||||
|
|
||||||
|
|
@ -39,6 +40,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_mcu_reset(void) {
|
void common_hal_mcu_reset(void) {
|
||||||
|
reset_cpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The singleton microcontroller.Processor object, bound to microcontroller.cpu
|
// The singleton microcontroller.Processor object, bound to microcontroller.cpu
|
||||||
|
|
|
||||||
|
|
@ -324,8 +324,12 @@ void port_free(void *ptr) {
|
||||||
heap_caps_free(ptr);
|
heap_caps_free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *port_realloc(void *ptr, size_t size) {
|
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||||
return heap_caps_realloc(ptr, size, MALLOC_CAP_8BIT);
|
size_t caps = MALLOC_CAP_8BIT;
|
||||||
|
if (dma_capable) {
|
||||||
|
caps |= MALLOC_CAP_DMA;
|
||||||
|
}
|
||||||
|
return heap_caps_realloc(ptr, size, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t port_heap_get_largest_free_size(void) {
|
size_t port_heap_get_largest_free_size(void) {
|
||||||
|
|
@ -493,11 +497,17 @@ void port_idle_until_interrupt(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_post_boot_py(bool heap_valid) {
|
#if CIRCUITPY_WIFI
|
||||||
if (!heap_valid && filesystem_present()) {
|
void port_boot_info(void) {
|
||||||
|
uint8_t mac[6];
|
||||||
|
esp_wifi_get_mac(ESP_IF_WIFI_STA, mac);
|
||||||
|
mp_printf(&mp_plat_print, "MAC");
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
mp_printf(&mp_plat_print, ":%02X", mac[i]);
|
||||||
}
|
}
|
||||||
|
mp_printf(&mp_plat_print, "\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Wrap main in app_main that the IDF expects.
|
// Wrap main in app_main that the IDF expects.
|
||||||
extern void main(void);
|
extern void main(void);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#define MICROPY_HW_MCU_NAME "nRF52840"
|
#define MICROPY_HW_MCU_NAME "nRF52840"
|
||||||
|
|
||||||
// TG-Gui requires a deeper call stack than normal CircuitPython, this is intentional overkill
|
// TG-Gui requires a deeper call stack than normal CircuitPython, this is intentional overkill
|
||||||
#define CIRCUITPY_PYSTACK_SIZE 8192 // 1536 is the normal size, (32 bytes/frame * 48 frames)
|
#define CIRCUITPY_PYSTACK_SIZE 8192
|
||||||
|
|
||||||
// the board has a 32mhz crystal but NOT a 32khz one
|
// the board has a 32mhz crystal but NOT a 32khz one
|
||||||
#define BOARD_HAS_32KHZ_XTAL 0
|
#define BOARD_HAS_32KHZ_XTAL 0
|
||||||
|
|
|
||||||
|
|
@ -227,12 +227,7 @@ audio_dma_result audio_dma_setup_playback(
|
||||||
max_buffer_length /= dma->sample_spacing;
|
max_buffer_length /= dma->sample_spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0],
|
dma->buffer[0] = (uint8_t *)port_realloc(dma->buffer[0], max_buffer_length, true);
|
||||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
|
||||||
dma->buffer_length[0], // Old size
|
|
||||||
#endif
|
|
||||||
max_buffer_length);
|
|
||||||
|
|
||||||
dma->buffer_length[0] = max_buffer_length;
|
dma->buffer_length[0] = max_buffer_length;
|
||||||
|
|
||||||
if (dma->buffer[0] == NULL) {
|
if (dma->buffer[0] == NULL) {
|
||||||
|
|
@ -240,12 +235,7 @@ audio_dma_result audio_dma_setup_playback(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!single_buffer) {
|
if (!single_buffer) {
|
||||||
dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1],
|
dma->buffer[1] = (uint8_t *)port_realloc(dma->buffer[1], max_buffer_length, true);
|
||||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
|
||||||
dma->buffer_length[1], // Old size
|
|
||||||
#endif
|
|
||||||
max_buffer_length);
|
|
||||||
|
|
||||||
dma->buffer_length[1] = max_buffer_length;
|
dma->buffer_length[1] = max_buffer_length;
|
||||||
|
|
||||||
if (dma->buffer[1] == NULL) {
|
if (dma->buffer[1] == NULL) {
|
||||||
|
|
@ -439,21 +429,11 @@ void audio_dma_init(audio_dma_t *dma) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_dma_deinit(audio_dma_t *dma) {
|
void audio_dma_deinit(audio_dma_t *dma) {
|
||||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
port_free(dma->buffer[0]);
|
||||||
m_free(dma->buffer[0], dma->buffer_length[0]);
|
|
||||||
#else
|
|
||||||
m_free(dma->buffer[0]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dma->buffer[0] = NULL;
|
dma->buffer[0] = NULL;
|
||||||
dma->buffer_length[0] = 0;
|
dma->buffer_length[0] = 0;
|
||||||
|
|
||||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
port_free(dma->buffer[1]);
|
||||||
m_free(dma->buffer[1], dma->buffer_length[1]);
|
|
||||||
#else
|
|
||||||
m_free(dma->buffer[1]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dma->buffer[1] = NULL;
|
dma->buffer[1] = NULL;
|
||||||
dma->buffer_length[1] = 0;
|
dma->buffer_length[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mp_obj_t sample;
|
mp_obj_t sample;
|
||||||
uint8_t *buffer[2];
|
uint8_t *buffer[2]; // Allocated through port_malloc so they are dma-able
|
||||||
size_t buffer_length[2];
|
size_t buffer_length[2];
|
||||||
uint32_t channels_to_load_mask;
|
uint32_t channels_to_load_mask;
|
||||||
uint32_t output_register_address;
|
uint32_t output_register_address;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@
|
||||||
|
|
||||||
#define CIRCUITPY_PROCESSOR_COUNT (2)
|
#define CIRCUITPY_PROCESSOR_COUNT (2)
|
||||||
|
|
||||||
|
// For many RP2 boards BOOTSEL is not connected to a GPIO pin.
|
||||||
|
#ifndef CIRCUITPY_BOOT_BUTTON
|
||||||
|
#define CIRCUITPY_BOOT_BUTTON_NO_GPIO (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CIRCUITPY_USB_HOST
|
#if CIRCUITPY_USB_HOST
|
||||||
#define CIRCUITPY_USB_HOST_INSTANCE 1
|
#define CIRCUITPY_USB_HOST_INSTANCE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
@ -56,6 +57,13 @@
|
||||||
#include "RP2350.h" // CMSIS
|
#include "RP2350.h" // CMSIS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CIRCUITPY_BOOT_BUTTON_NO_GPIO
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "hardware/sync.h"
|
||||||
|
#include "hardware/structs/ioqspi.h"
|
||||||
|
#include "hardware/structs/sio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "supervisor/shared/serial.h"
|
#include "supervisor/shared/serial.h"
|
||||||
|
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
@ -89,8 +97,7 @@ extern uint32_t _ld_itcm_size;
|
||||||
extern uint32_t _ld_itcm_flash_copy;
|
extern uint32_t _ld_itcm_flash_copy;
|
||||||
|
|
||||||
static tlsf_t _heap = NULL;
|
static tlsf_t _heap = NULL;
|
||||||
static pool_t _ram_pool = NULL;
|
static tlsf_t _psram_heap = NULL;
|
||||||
static pool_t _psram_pool = NULL;
|
|
||||||
static size_t _psram_size = 0;
|
static size_t _psram_size = 0;
|
||||||
|
|
||||||
#ifdef CIRCUITPY_PSRAM_CHIP_SELECT
|
#ifdef CIRCUITPY_PSRAM_CHIP_SELECT
|
||||||
|
|
@ -245,10 +252,9 @@ static void _port_heap_init(void) {
|
||||||
uint32_t *heap_bottom = port_heap_get_bottom();
|
uint32_t *heap_bottom = port_heap_get_bottom();
|
||||||
uint32_t *heap_top = port_heap_get_top();
|
uint32_t *heap_top = port_heap_get_top();
|
||||||
size_t size = (heap_top - heap_bottom) * sizeof(uint32_t);
|
size_t size = (heap_top - heap_bottom) * sizeof(uint32_t);
|
||||||
_heap = tlsf_create_with_pool(heap_bottom, size, 64 * 1024 * 1024);
|
_heap = tlsf_create_with_pool(heap_bottom, size, size);
|
||||||
_ram_pool = tlsf_get_pool(_heap);
|
|
||||||
if (_psram_size > 0) {
|
if (_psram_size > 0) {
|
||||||
_psram_pool = tlsf_add_pool(_heap, (void *)0x11000000, _psram_size);
|
_psram_heap = tlsf_create_with_pool((void *)0x11000000, _psram_size, _psram_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,15 +263,31 @@ void port_heap_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *port_malloc(size_t size, bool dma_capable) {
|
void *port_malloc(size_t size, bool dma_capable) {
|
||||||
|
if (!dma_capable && _psram_size > 0) {
|
||||||
|
void *block = tlsf_malloc(_psram_heap, size);
|
||||||
|
if (block) {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
}
|
||||||
void *block = tlsf_malloc(_heap, size);
|
void *block = tlsf_malloc(_heap, size);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
void port_free(void *ptr) {
|
void port_free(void *ptr) {
|
||||||
|
if (((size_t)ptr) < SRAM_BASE) {
|
||||||
|
tlsf_free(_psram_heap, ptr);
|
||||||
|
} else {
|
||||||
tlsf_free(_heap, ptr);
|
tlsf_free(_heap, ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *port_realloc(void *ptr, size_t size) {
|
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||||
|
if (_psram_size > 0 && ((ptr != NULL && ((size_t)ptr) < SRAM_BASE) || (ptr == NULL && !dma_capable))) {
|
||||||
|
void *block = tlsf_realloc(_psram_heap, ptr, size);
|
||||||
|
if (block) {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
}
|
||||||
return tlsf_realloc(_heap, ptr, size);
|
return tlsf_realloc(_heap, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,12 +301,13 @@ static bool max_size_walker(void *ptr, size_t size, int used, void *user) {
|
||||||
|
|
||||||
size_t port_heap_get_largest_free_size(void) {
|
size_t port_heap_get_largest_free_size(void) {
|
||||||
size_t max_size = 0;
|
size_t max_size = 0;
|
||||||
tlsf_walk_pool(_ram_pool, max_size_walker, &max_size);
|
tlsf_walk_pool(tlsf_get_pool(_heap), max_size_walker, &max_size);
|
||||||
if (_psram_pool != NULL) {
|
max_size = tlsf_fit_size(_heap, max_size);
|
||||||
tlsf_walk_pool(_psram_pool, max_size_walker, &max_size);
|
if (_psram_heap != NULL) {
|
||||||
|
tlsf_walk_pool(tlsf_get_pool(_psram_heap), max_size_walker, &max_size);
|
||||||
|
max_size = tlsf_fit_size(_psram_heap, max_size);
|
||||||
}
|
}
|
||||||
// IDF does this. Not sure why.
|
return max_size;
|
||||||
return tlsf_fit_size(_heap, max_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_mode_t port_init(void) {
|
safe_mode_t port_init(void) {
|
||||||
|
|
@ -549,7 +572,7 @@ void port_idle_until_interrupt(void) {
|
||||||
/**
|
/**
|
||||||
* \brief Default interrupt handler for unused IRQs.
|
* \brief Default interrupt handler for unused IRQs.
|
||||||
*/
|
*/
|
||||||
extern void isr_hardfault(void); // provide a prototype to avoid a missing-prototypes diagnostic
|
extern NORETURN void isr_hardfault(void); // provide a prototype to avoid a missing-prototypes diagnostic
|
||||||
__attribute__((used)) void __not_in_flash_func(isr_hardfault)(void) {
|
__attribute__((used)) void __not_in_flash_func(isr_hardfault)(void) {
|
||||||
// Only safe mode from core 0 which is running CircuitPython. Core 1 faulting
|
// Only safe mode from core 0 which is running CircuitPython. Core 1 faulting
|
||||||
// should not be fatal to CP. (Fingers crossed.)
|
// should not be fatal to CP. (Fingers crossed.)
|
||||||
|
|
@ -576,3 +599,53 @@ void port_boot_info(void) {
|
||||||
mp_printf(&mp_plat_print, "\n");
|
mp_printf(&mp_plat_print, "\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CIRCUITPY_BOOT_BUTTON_NO_GPIO
|
||||||
|
bool __no_inline_not_in_flash_func(port_boot_button_pressed)(void) {
|
||||||
|
// Sense the state of the boot button. Because this function
|
||||||
|
// disables flash, it cannot be safely called once the second
|
||||||
|
// core has been started. When the BOOTSEL button is sensed as
|
||||||
|
// pressed, return is delayed until the button is released and
|
||||||
|
// a delay has passed in order to debounce the button.
|
||||||
|
const uint32_t CS_PIN_INDEX = 1;
|
||||||
|
#if defined(PICO_RP2040)
|
||||||
|
const uint32_t CS_BIT = 1u << 1;
|
||||||
|
#else
|
||||||
|
const uint32_t CS_BIT = SIO_GPIO_HI_IN_QSPI_CSN_BITS;
|
||||||
|
#endif
|
||||||
|
uint32_t int_state = save_and_disable_interrupts();
|
||||||
|
// Wait for any outstanding XIP activity to finish. Flash
|
||||||
|
// must be quiescent before disabling the chip select. Since
|
||||||
|
// there's no XIP busy indication we can test, we delay a
|
||||||
|
// generous 5 ms to allow any XIP activity to finish.
|
||||||
|
busy_wait_us(5000);
|
||||||
|
// Float the flash chip select pin. The line will HI-Z due to
|
||||||
|
// the external 10K pull-up resistor.
|
||||||
|
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||||
|
GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||||
|
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||||
|
// Delay 100 us to allow the CS line to stabilize. If BOOTSEL is
|
||||||
|
// pressed, the line will be pulled low by the button and its
|
||||||
|
// 1K external resistor to ground.
|
||||||
|
busy_wait_us(100);
|
||||||
|
bool button_pressed = !(sio_hw->gpio_hi_in & CS_BIT);
|
||||||
|
// Wait for the button to be released.
|
||||||
|
if (button_pressed) {
|
||||||
|
while (!(sio_hw->gpio_hi_in & CS_BIT)) {
|
||||||
|
tight_loop_contents();
|
||||||
|
}
|
||||||
|
// Wait for 50 ms to debounce the button.
|
||||||
|
busy_wait_us(50000);
|
||||||
|
}
|
||||||
|
// Restore the flash chip select pin to its original state.
|
||||||
|
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||||
|
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||||
|
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||||
|
// Delay 5 ms to allow the flash chip to re-enable and for the
|
||||||
|
// flash CS pin to stabilize.
|
||||||
|
busy_wait_us(5000);
|
||||||
|
// Restore the interrupt state.
|
||||||
|
restore_interrupts(int_state);
|
||||||
|
return button_pressed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ void port_free(void *ptr) {
|
||||||
tlsf_free(_heap, ptr);
|
tlsf_free(_heap, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *port_realloc(void *ptr, size_t size) {
|
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||||
return tlsf_realloc(_heap, ptr, size);
|
return tlsf_realloc(_heap, ptr, size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ SRC_BITMAP := \
|
||||||
shared-bindings/audiodelays/Echo.c \
|
shared-bindings/audiodelays/Echo.c \
|
||||||
shared-bindings/audiodelays/Chorus.c \
|
shared-bindings/audiodelays/Chorus.c \
|
||||||
shared-bindings/audiodelays/PitchShift.c \
|
shared-bindings/audiodelays/PitchShift.c \
|
||||||
|
shared-bindings/audiodelays/MultiTapDelay.c \
|
||||||
shared-bindings/audiodelays/__init__.c \
|
shared-bindings/audiodelays/__init__.c \
|
||||||
shared-bindings/audiofilters/Distortion.c \
|
shared-bindings/audiofilters/Distortion.c \
|
||||||
shared-bindings/audiofilters/Filter.c \
|
shared-bindings/audiofilters/Filter.c \
|
||||||
|
|
@ -80,6 +81,7 @@ SRC_BITMAP := \
|
||||||
shared-module/audiodelays/Echo.c \
|
shared-module/audiodelays/Echo.c \
|
||||||
shared-module/audiodelays/Chorus.c \
|
shared-module/audiodelays/Chorus.c \
|
||||||
shared-module/audiodelays/PitchShift.c \
|
shared-module/audiodelays/PitchShift.c \
|
||||||
|
shared-module/audiodelays/MultiTapDelay.c \
|
||||||
shared-module/audiodelays/__init__.c \
|
shared-module/audiodelays/__init__.c \
|
||||||
shared-module/audiofilters/Distortion.c \
|
shared-module/audiofilters/Distortion.c \
|
||||||
shared-module/audiofilters/Filter.c \
|
shared-module/audiofilters/Filter.c \
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,6 @@ async def build_circuitpython():
|
||||||
portdir / "common-hal/microcontroller/Pin.c",
|
portdir / "common-hal/microcontroller/Pin.c",
|
||||||
portdir / "common-hal/microcontroller/Processor.c",
|
portdir / "common-hal/microcontroller/Processor.c",
|
||||||
portdir / "common-hal/os/__init__.c",
|
portdir / "common-hal/os/__init__.c",
|
||||||
"supervisor/stub/misc.c",
|
|
||||||
"shared/readline/readline.c",
|
"shared/readline/readline.c",
|
||||||
"shared/runtime/context_manager_helpers.c",
|
"shared/runtime/context_manager_helpers.c",
|
||||||
"shared/runtime/pyexec.c",
|
"shared/runtime/pyexec.c",
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ void port_free(void *ptr) {
|
||||||
tlsf_free(heap, ptr);
|
tlsf_free(heap, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *port_realloc(void *ptr, size_t size) {
|
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||||
return tlsf_realloc(heap, ptr, size);
|
return tlsf_realloc(heap, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -667,6 +667,7 @@ SRC_SHARED_MODULE_ALL = \
|
||||||
audiodelays/Echo.c \
|
audiodelays/Echo.c \
|
||||||
audiodelays/Chorus.c \
|
audiodelays/Chorus.c \
|
||||||
audiodelays/PitchShift.c \
|
audiodelays/PitchShift.c \
|
||||||
|
audiodelays/MultiTapDelay.c \
|
||||||
audiodelays/__init__.c \
|
audiodelays/__init__.c \
|
||||||
audiofilters/Distortion.c \
|
audiofilters/Distortion.c \
|
||||||
audiofilters/Filter.c \
|
audiofilters/Filter.c \
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,7 @@ typedef long mp_off_t;
|
||||||
#define CIRCUITPY_CONSOLE_UART (1)
|
#define CIRCUITPY_CONSOLE_UART (1)
|
||||||
#ifndef CIRCUITPY_CONSOLE_UART_BAUDRATE
|
#ifndef CIRCUITPY_CONSOLE_UART_BAUDRATE
|
||||||
#define CIRCUITPY_CONSOLE_UART_BAUDRATE (115200)
|
#define CIRCUITPY_CONSOLE_UART_BAUDRATE (115200)
|
||||||
|
#endif
|
||||||
#if !defined(CIRCUITPY_CONSOLE_UART_PRINTF)
|
#if !defined(CIRCUITPY_CONSOLE_UART_PRINTF)
|
||||||
#define CIRCUITPY_CONSOLE_UART_PRINTF(...) mp_printf(&console_uart_print, __VA_ARGS__)
|
#define CIRCUITPY_CONSOLE_UART_PRINTF(...) mp_printf(&console_uart_print, __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -353,7 +354,6 @@ typedef long mp_off_t;
|
||||||
#if !defined(CIRCUITPY_CONSOLE_UART_TIMESTAMP)
|
#if !defined(CIRCUITPY_CONSOLE_UART_TIMESTAMP)
|
||||||
#define CIRCUITPY_CONSOLE_UART_TIMESTAMP (0)
|
#define CIRCUITPY_CONSOLE_UART_TIMESTAMP (0)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#define CIRCUITPY_CONSOLE_UART (0)
|
#define CIRCUITPY_CONSOLE_UART (0)
|
||||||
#define CIRCUITPY_CONSOLE_UART_PRINTF(...) (void)0
|
#define CIRCUITPY_CONSOLE_UART_PRINTF(...) (void)0
|
||||||
|
|
@ -452,7 +452,7 @@ void background_callback_run_all(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CIRCUITPY_PYSTACK_SIZE
|
#ifndef CIRCUITPY_PYSTACK_SIZE
|
||||||
#define CIRCUITPY_PYSTACK_SIZE 1536
|
#define CIRCUITPY_PYSTACK_SIZE 2048
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The VM heap starts at this size and doubles in size as needed until it runs
|
// The VM heap starts at this size and doubles in size as needed until it runs
|
||||||
|
|
@ -635,6 +635,15 @@ void background_callback_run_all(void);
|
||||||
#define CIRCUITPY_SAVES_PARTITION_SIZE 0
|
#define CIRCUITPY_SAVES_PARTITION_SIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Boards that have a boot button connected to a GPIO pin should set
|
||||||
|
// CIRCUITPY_BOOT_BUTTON_NO_GPIO to 1.
|
||||||
|
#ifndef CIRCUITPY_BOOT_BUTTON_NO_GPIO
|
||||||
|
#define CIRCUITPY_BOOT_BUTTON_NO_GPIO (0)
|
||||||
|
#endif
|
||||||
|
#if defined(CIRCUITPY_BOOT_BUTTON) && CIRCUITPY_BOOT_BUTTON_NO_GPIO
|
||||||
|
#error "CIRCUITPY_BOOT_BUTTON and CIRCUITPY_BOOT_BUTTON_NO_GPIO are mutually exclusive"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(__ZEPHYR__)
|
#if defined(__GNUC__) && !defined(__ZEPHYR__)
|
||||||
#if __GNUC__ < CIRCUITPY_MIN_GCC_VERSION
|
#if __GNUC__ < CIRCUITPY_MIN_GCC_VERSION
|
||||||
// (the 3 level scheme here is required to get expansion & stringization
|
// (the 3 level scheme here is required to get expansion & stringization
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
#include "shared-bindings/time/__init__.h"
|
#include "shared-bindings/time/__init__.h"
|
||||||
|
|
||||||
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
|
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
|
||||||
mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
|
NORETURN mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("RTC is not supported on this board"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("RTC is not supported on this board"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,6 @@
|
||||||
#include "shared-bindings/util.h"
|
#include "shared-bindings/util.h"
|
||||||
#include "shared-module/synthio/block.h"
|
#include "shared-module/synthio/block.h"
|
||||||
|
|
||||||
#define DECAY_DEFAULT 0.7f
|
|
||||||
#define MIX_DEFAULT 0.5f
|
|
||||||
|
|
||||||
//| class Echo:
|
//| class Echo:
|
||||||
//| """An Echo effect"""
|
//| """An Echo effect"""
|
||||||
//|
|
//|
|
||||||
|
|
@ -28,7 +25,7 @@
|
||||||
//| max_delay_ms: int = 500,
|
//| max_delay_ms: int = 500,
|
||||||
//| delay_ms: synthio.BlockInput = 250.0,
|
//| delay_ms: synthio.BlockInput = 250.0,
|
||||||
//| decay: synthio.BlockInput = 0.7,
|
//| decay: synthio.BlockInput = 0.7,
|
||||||
//| mix: synthio.BlockInput = 0.5,
|
//| mix: synthio.BlockInput = 0.25,
|
||||||
//| buffer_size: int = 512,
|
//| buffer_size: int = 512,
|
||||||
//| sample_rate: int = 8000,
|
//| sample_rate: int = 8000,
|
||||||
//| bits_per_sample: int = 16,
|
//| bits_per_sample: int = 16,
|
||||||
|
|
@ -163,7 +160,7 @@ MP_PROPERTY_GETSET(audiodelays_echo_delay_ms_obj,
|
||||||
(mp_obj_t)&audiodelays_echo_set_delay_ms_obj);
|
(mp_obj_t)&audiodelays_echo_set_delay_ms_obj);
|
||||||
|
|
||||||
//| decay: synthio.BlockInput
|
//| decay: synthio.BlockInput
|
||||||
//| """The rate the echo decays between 0 and 1 where 1 is forever and 0 is no echo."""
|
//| """The rate the echo fades between 0 and 1 where 0 is instant and 1 is never."""
|
||||||
static mp_obj_t audiodelays_echo_obj_get_decay(mp_obj_t self_in) {
|
static mp_obj_t audiodelays_echo_obj_get_decay(mp_obj_t self_in) {
|
||||||
return common_hal_audiodelays_echo_get_decay(self_in);
|
return common_hal_audiodelays_echo_get_decay(self_in);
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +178,7 @@ MP_PROPERTY_GETSET(audiodelays_echo_decay_obj,
|
||||||
(mp_obj_t)&audiodelays_echo_set_decay_obj);
|
(mp_obj_t)&audiodelays_echo_set_decay_obj);
|
||||||
|
|
||||||
//| mix: synthio.BlockInput
|
//| mix: synthio.BlockInput
|
||||||
//| """The rate the echo mix between 0 and 1 where 0 is only sample and 1 is all effect."""
|
//| """The rate the echo mix between 0 and 1 where 0 is only sample, 0.5 is an equal mix of the sample and the effect and 1 is all effect."""
|
||||||
static mp_obj_t audiodelays_echo_obj_get_mix(mp_obj_t self_in) {
|
static mp_obj_t audiodelays_echo_obj_get_mix(mp_obj_t self_in) {
|
||||||
return common_hal_audiodelays_echo_get_mix(self_in);
|
return common_hal_audiodelays_echo_get_mix(self_in);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
306
shared-bindings/audiodelays/MultiTapDelay.c
Normal file
306
shared-bindings/audiodelays/MultiTapDelay.c
Normal file
|
|
@ -0,0 +1,306 @@
|
||||||
|
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "shared-bindings/audiodelays/MultiTapDelay.h"
|
||||||
|
#include "shared-bindings/audiocore/__init__.h"
|
||||||
|
#include "shared-module/audiodelays/MultiTapDelay.h"
|
||||||
|
|
||||||
|
#include "shared/runtime/context_manager_helpers.h"
|
||||||
|
#include "py/binary.h"
|
||||||
|
#include "py/objproperty.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "shared-bindings/util.h"
|
||||||
|
#include "shared-module/synthio/block.h"
|
||||||
|
|
||||||
|
//| class MultiTapDelay:
|
||||||
|
//| """A delay with multiple buffer positions to create a rhythmic effect."""
|
||||||
|
//|
|
||||||
|
//| def __init__(
|
||||||
|
//| self,
|
||||||
|
//| max_delay_ms: int = 500,
|
||||||
|
//| delay_ms: synthio.BlockInput = 250.0,
|
||||||
|
//| decay: synthio.BlockInput = 0.7,
|
||||||
|
//| mix: synthio.BlockInput = 0.25,
|
||||||
|
//| taps: Optional[Tuple[float|Tuple[float, float], ...]] = None,
|
||||||
|
//| buffer_size: int = 512,
|
||||||
|
//| sample_rate: int = 8000,
|
||||||
|
//| bits_per_sample: int = 16,
|
||||||
|
//| samples_signed: bool = True,
|
||||||
|
//| channel_count: int = 1,
|
||||||
|
//| ) -> None:
|
||||||
|
//| """Create a delay effect where you hear the original sample play back at varying times, or "taps".
|
||||||
|
//| These tap positions and levels can be used to create rhythmic effects.
|
||||||
|
//| The timing of the delay can be changed at runtime with the delay_ms parameter but the delay can
|
||||||
|
//| never exceed the max_delay_ms parameter. The maximum delay you can set is limited by available
|
||||||
|
//| memory.
|
||||||
|
//|
|
||||||
|
//| Each time the delay plays back the volume is reduced by the decay setting (delay * decay).
|
||||||
|
//|
|
||||||
|
//| The mix parameter allows you to change how much of the unchanged sample passes through to
|
||||||
|
//| the output to how much of the effect audio you hear as the output.
|
||||||
|
//|
|
||||||
|
//| :param int max_delay_ms: The maximum time the delay can be in milliseconds.
|
||||||
|
//| :param float delay_ms: The current time of the delay in milliseconds. Must be less than max_delay_ms.
|
||||||
|
//| :param synthio.BlockInput decay: The rate the delay fades. 0.0 = instant; 1.0 = never.
|
||||||
|
//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0).
|
||||||
|
//| :param tuple taps: The positions and levels to tap into the delay buffer.
|
||||||
|
//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use.
|
||||||
|
//| :param int sample_rate: The sample rate to be used.
|
||||||
|
//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo.
|
||||||
|
//| :param int bits_per_sample: The bits per sample of the effect.
|
||||||
|
//| :param bool samples_signed: Effect is signed (True) or unsigned (False).
|
||||||
|
//|
|
||||||
|
//| Playing adding a multi-tap delay to a synth::
|
||||||
|
//|
|
||||||
|
//| import time
|
||||||
|
//| import board
|
||||||
|
//| import audiobusio
|
||||||
|
//| import synthio
|
||||||
|
//| import audiodelays
|
||||||
|
//|
|
||||||
|
//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22)
|
||||||
|
//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100)
|
||||||
|
//| effect = audiodelays.MultiTapDelay(max_delay_ms=500, delay_ms=500, decay=0.65, mix=0.5, taps=((2/3, 0.7), 1), buffer_size=1024, channel_count=1, sample_rate=44100)
|
||||||
|
//| effect.play(synth)
|
||||||
|
//| audio.play(effect)
|
||||||
|
//|
|
||||||
|
//| note = synthio.Note(261)
|
||||||
|
//| while True:
|
||||||
|
//| synth.press(note)
|
||||||
|
//| time.sleep(0.05)
|
||||||
|
//| synth.release(note)
|
||||||
|
//| time.sleep(5)"""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||||
|
enum { ARG_max_delay_ms, ARG_delay_ms, ARG_decay, ARG_mix, ARG_taps, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_max_delay_ms, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 500 } },
|
||||||
|
{ MP_QSTR_delay_ms, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(250) } },
|
||||||
|
{ MP_QSTR_decay, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} },
|
||||||
|
{ MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} },
|
||||||
|
{ MP_QSTR_taps, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
||||||
|
{ MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} },
|
||||||
|
{ MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} },
|
||||||
|
{ MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} },
|
||||||
|
{ MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
|
||||||
|
{ MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
mp_int_t max_delay_ms = mp_arg_validate_int_range(args[ARG_max_delay_ms].u_int, 1, 4000, MP_QSTR_max_delay_ms);
|
||||||
|
|
||||||
|
mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count);
|
||||||
|
mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate);
|
||||||
|
mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int;
|
||||||
|
if (bits_per_sample != 8 && bits_per_sample != 16) {
|
||||||
|
mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16"));
|
||||||
|
}
|
||||||
|
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = mp_obj_malloc(audiodelays_multi_tap_delay_obj_t, &audiodelays_multi_tap_delay_type);
|
||||||
|
common_hal_audiodelays_multi_tap_delay_construct(self, max_delay_ms, args[ARG_delay_ms].u_obj, args[ARG_decay].u_obj, args[ARG_mix].u_obj, args[ARG_taps].u_obj, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate);
|
||||||
|
|
||||||
|
return MP_OBJ_FROM_PTR(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
//| def deinit(self) -> None:
|
||||||
|
//| """Deinitialises the MultiTapDelay."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_deinit(mp_obj_t self_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
common_hal_audiodelays_multi_tap_delay_deinit(self);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_deinit_obj, audiodelays_multi_tap_delay_deinit);
|
||||||
|
|
||||||
|
static void check_for_deinit(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
audiosample_check_for_deinit(&self->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
//| def __enter__(self) -> MultiTapDelay:
|
||||||
|
//| """No-op used by Context Managers."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
// Provided by context manager helper.
|
||||||
|
|
||||||
|
//| def __exit__(self) -> None:
|
||||||
|
//| """Automatically deinitializes when exiting a context. See
|
||||||
|
//| :ref:`lifetime-and-contextmanagers` for more info."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
// Provided by context manager helper.
|
||||||
|
|
||||||
|
|
||||||
|
//| delay_ms: float
|
||||||
|
//| """Time to delay the incoming signal in milliseconds. Must be less than max_delay_ms."""
|
||||||
|
//|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_get_delay_ms(mp_obj_t self_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
return mp_obj_new_float(common_hal_audiodelays_multi_tap_delay_get_delay_ms(self));
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_delay_ms_obj, audiodelays_multi_tap_delay_obj_get_delay_ms);
|
||||||
|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_set_delay_ms(mp_obj_t self_in, mp_obj_t delay_ms_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
common_hal_audiodelays_multi_tap_delay_set_delay_ms(self, delay_ms_in);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_delay_ms_obj, audiodelays_multi_tap_delay_obj_set_delay_ms);
|
||||||
|
|
||||||
|
MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_delay_ms_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_get_delay_ms_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_set_delay_ms_obj);
|
||||||
|
|
||||||
|
//| decay: synthio.BlockInput
|
||||||
|
//| """The rate the echo fades between 0 and 1 where 0 is instant and 1 is never."""
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_get_decay(mp_obj_t self_in) {
|
||||||
|
return common_hal_audiodelays_multi_tap_delay_get_decay(self_in);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_decay_obj, audiodelays_multi_tap_delay_obj_get_decay);
|
||||||
|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_set_decay(mp_obj_t self_in, mp_obj_t decay_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
common_hal_audiodelays_multi_tap_delay_set_decay(self, decay_in);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_decay_obj, audiodelays_multi_tap_delay_obj_set_decay);
|
||||||
|
|
||||||
|
MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_decay_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_get_decay_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_set_decay_obj);
|
||||||
|
|
||||||
|
//| mix: synthio.BlockInput
|
||||||
|
//| """The mix of the effect between 0 and 1 where 0 is only sample, 0.5 is an equal mix of the sample and the effect and 1 is all effect."""
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_get_mix(mp_obj_t self_in) {
|
||||||
|
return common_hal_audiodelays_multi_tap_delay_get_mix(self_in);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_mix_obj, audiodelays_multi_tap_delay_obj_get_mix);
|
||||||
|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
common_hal_audiodelays_multi_tap_delay_set_mix(self, mix_in);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_mix_obj, audiodelays_multi_tap_delay_obj_set_mix);
|
||||||
|
|
||||||
|
MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_mix_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_get_mix_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_set_mix_obj);
|
||||||
|
|
||||||
|
//| taps: Tuple[float|int|Tuple[float|int, float|int], ...]
|
||||||
|
//| """The position or position and level of delay taps.
|
||||||
|
//| The position is a number from 0 (start) to 1 (end) as a relative position in the delay buffer.
|
||||||
|
//| The level is a number from 0 (silence) to 1 (full volume).
|
||||||
|
//| If only a float or integer is provided as an element of the tuple, the level is assumed to be 1.
|
||||||
|
//| When retrieving the value of this property, the level will always be included."""
|
||||||
|
//|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_get_taps(mp_obj_t self_in) {
|
||||||
|
return common_hal_audiodelays_multi_tap_delay_get_taps(self_in);
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_taps_obj, audiodelays_multi_tap_delay_obj_get_taps);
|
||||||
|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_set_taps(mp_obj_t self_in, mp_obj_t taps_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
common_hal_audiodelays_multi_tap_delay_set_taps(self, taps_in);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_taps_obj, audiodelays_multi_tap_delay_obj_set_taps);
|
||||||
|
|
||||||
|
MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_taps_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_get_taps_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_set_taps_obj);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//| playing: bool
|
||||||
|
//| """True when the effect is playing a sample. (read-only)"""
|
||||||
|
//|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_get_playing(mp_obj_t self_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
check_for_deinit(self);
|
||||||
|
return mp_obj_new_bool(common_hal_audiodelays_multi_tap_delay_get_playing(self));
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_playing_obj, audiodelays_multi_tap_delay_obj_get_playing);
|
||||||
|
|
||||||
|
MP_PROPERTY_GETTER(audiodelays_multi_tap_delay_playing_obj,
|
||||||
|
(mp_obj_t)&audiodelays_multi_tap_delay_get_playing_obj);
|
||||||
|
|
||||||
|
//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None:
|
||||||
|
//| """Plays the sample once when loop=False and continuously when loop=True.
|
||||||
|
//| Does not block. Use `playing` to block.
|
||||||
|
//|
|
||||||
|
//| The sample must match the encoding settings given in the constructor."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
|
enum { ARG_sample, ARG_loop };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} },
|
||||||
|
{ MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||||
|
};
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
|
||||||
|
check_for_deinit(self);
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
|
|
||||||
|
mp_obj_t sample = args[ARG_sample].u_obj;
|
||||||
|
common_hal_audiodelays_multi_tap_delay_play(self, sample, args[ARG_loop].u_bool);
|
||||||
|
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_multi_tap_delay_play_obj, 1, audiodelays_multi_tap_delay_obj_play);
|
||||||
|
|
||||||
|
//| def stop(self) -> None:
|
||||||
|
//| """Stops playback of the sample. The echo continues playing."""
|
||||||
|
//| ...
|
||||||
|
//|
|
||||||
|
//|
|
||||||
|
static mp_obj_t audiodelays_multi_tap_delay_obj_stop(mp_obj_t self_in) {
|
||||||
|
audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
|
||||||
|
common_hal_audiodelays_multi_tap_delay_stop(self);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_stop_obj, audiodelays_multi_tap_delay_obj_stop);
|
||||||
|
|
||||||
|
static const mp_rom_map_elem_t audiodelays_multi_tap_delay_locals_dict_table[] = {
|
||||||
|
// Methods
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiodelays_multi_tap_delay_deinit_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiodelays_multi_tap_delay_play_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiodelays_multi_tap_delay_stop_obj) },
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_multi_tap_delay_playing_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_delay_ms), MP_ROM_PTR(&audiodelays_multi_tap_delay_delay_ms_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_decay), MP_ROM_PTR(&audiodelays_multi_tap_delay_decay_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_multi_tap_delay_mix_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_taps), MP_ROM_PTR(&audiodelays_multi_tap_delay_taps_obj) },
|
||||||
|
AUDIOSAMPLE_FIELDS,
|
||||||
|
};
|
||||||
|
static MP_DEFINE_CONST_DICT(audiodelays_multi_tap_delay_locals_dict, audiodelays_multi_tap_delay_locals_dict_table);
|
||||||
|
|
||||||
|
static const audiosample_p_t audiodelays_multi_tap_delay_proto = {
|
||||||
|
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample)
|
||||||
|
.reset_buffer = (audiosample_reset_buffer_fun)audiodelays_multi_tap_delay_reset_buffer,
|
||||||
|
.get_buffer = (audiosample_get_buffer_fun)audiodelays_multi_tap_delay_get_buffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
MP_DEFINE_CONST_OBJ_TYPE(
|
||||||
|
audiodelays_multi_tap_delay_type,
|
||||||
|
MP_QSTR_MultiTapDelay,
|
||||||
|
MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS,
|
||||||
|
make_new, audiodelays_multi_tap_delay_make_new,
|
||||||
|
locals_dict, &audiodelays_multi_tap_delay_locals_dict,
|
||||||
|
protocol, &audiodelays_multi_tap_delay_proto
|
||||||
|
);
|
||||||
34
shared-bindings/audiodelays/MultiTapDelay.h
Normal file
34
shared-bindings/audiodelays/MultiTapDelay.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shared-module/audiodelays/MultiTapDelay.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t audiodelays_multi_tap_delay_type;
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_construct(audiodelays_multi_tap_delay_obj_t *self, uint32_t max_delay_ms,
|
||||||
|
mp_obj_t delay_ms, mp_obj_t decay, mp_obj_t mix, mp_obj_t taps,
|
||||||
|
uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed,
|
||||||
|
uint8_t channel_count, uint32_t sample_rate);
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_deinit(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
|
||||||
|
mp_float_t common_hal_audiodelays_multi_tap_delay_get_delay_ms(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_delay_ms(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t delay_ms);
|
||||||
|
|
||||||
|
mp_obj_t common_hal_audiodelays_multi_tap_delay_get_decay(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_decay(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t decay);
|
||||||
|
|
||||||
|
mp_obj_t common_hal_audiodelays_multi_tap_delay_get_mix(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_mix(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t mix);
|
||||||
|
|
||||||
|
mp_obj_t common_hal_audiodelays_multi_tap_delay_get_taps(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_taps(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t taps);
|
||||||
|
|
||||||
|
bool common_hal_audiodelays_multi_tap_delay_get_playing(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_play(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t sample, bool loop);
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_stop(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "shared-bindings/audiodelays/Echo.h"
|
#include "shared-bindings/audiodelays/Echo.h"
|
||||||
#include "shared-bindings/audiodelays/Chorus.h"
|
#include "shared-bindings/audiodelays/Chorus.h"
|
||||||
#include "shared-bindings/audiodelays/PitchShift.h"
|
#include "shared-bindings/audiodelays/PitchShift.h"
|
||||||
|
#include "shared-bindings/audiodelays/MultiTapDelay.h"
|
||||||
|
|
||||||
//| """Support for audio delay effects
|
//| """Support for audio delay effects
|
||||||
//|
|
//|
|
||||||
|
|
@ -25,6 +26,7 @@ static const mp_rom_map_elem_t audiodelays_module_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_Echo), MP_ROM_PTR(&audiodelays_echo_type) },
|
{ MP_ROM_QSTR(MP_QSTR_Echo), MP_ROM_PTR(&audiodelays_echo_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_Chorus), MP_ROM_PTR(&audiodelays_chorus_type) },
|
{ MP_ROM_QSTR(MP_QSTR_Chorus), MP_ROM_PTR(&audiodelays_chorus_type) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_PitchShift), MP_ROM_PTR(&audiodelays_pitch_shift_type) },
|
{ MP_ROM_QSTR(MP_QSTR_PitchShift), MP_ROM_PTR(&audiodelays_pitch_shift_type) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_MultiTapDelay), MP_ROM_PTR(&audiodelays_multi_tap_delay_type) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static MP_DEFINE_CONST_DICT(audiodelays_module_globals, audiodelays_module_globals_table);
|
static MP_DEFINE_CONST_DICT(audiodelays_module_globals, audiodelays_module_globals_table);
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@
|
||||||
#include "shared-bindings/util.h"
|
#include "shared-bindings/util.h"
|
||||||
#include "shared-module/synthio/block.h"
|
#include "shared-module/synthio/block.h"
|
||||||
|
|
||||||
#define MIX_DEFAULT 1.0f
|
|
||||||
|
|
||||||
//| class Filter:
|
//| class Filter:
|
||||||
//| """A Filter effect"""
|
//| """A Filter effect"""
|
||||||
//|
|
//|
|
||||||
|
|
|
||||||
|
|
@ -691,7 +691,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_polygon_obj, 0, bitmaptools_obj_draw
|
||||||
//| available in the destination bitmap.
|
//| available in the destination bitmap.
|
||||||
//|
|
//|
|
||||||
//| If x1 or y1 are not specified, they are taken as 0. If x2 or y2
|
//| If x1 or y1 are not specified, they are taken as 0. If x2 or y2
|
||||||
//| are not specified, or are given as -1, they are taken as the width
|
//| are not specified, or are given as None, they are taken as the width
|
||||||
//| and height of the image.
|
//| and height of the image.
|
||||||
//|
|
//|
|
||||||
//| The coordinates affected by the blit are ``x1 <= x < x2`` and ``y1 <= y < y2``.
|
//| The coordinates affected by the blit are ``x1 <= x < x2`` and ``y1 <= y < y2``.
|
||||||
|
|
@ -719,7 +719,7 @@ static mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, m
|
||||||
static const mp_arg_t allowed_args[] = {
|
static const mp_arg_t allowed_args[] = {
|
||||||
{ MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
{ MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||||
ALLOWED_ARGS_X1_Y1_X2_Y2(0, MP_ARG_REQUIRED),
|
ALLOWED_ARGS_X1_Y1_X2_Y2(0, 0),
|
||||||
{ MP_QSTR_skip_index, MP_ARG_OBJ, {.u_obj = mp_const_none } },
|
{ MP_QSTR_skip_index, MP_ARG_OBJ, {.u_obj = mp_const_none } },
|
||||||
};
|
};
|
||||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,8 @@ typedef struct {
|
||||||
#define ARGS_X1_Y1_X2_Y2 ARG_x1, ARG_y1, ARG_x2, ARG_y2
|
#define ARGS_X1_Y1_X2_Y2 ARG_x1, ARG_y1, ARG_x2, ARG_y2
|
||||||
#define ALLOWED_ARGS_X1_Y1_X2_Y2(if_required1, if_required2) \
|
#define ALLOWED_ARGS_X1_Y1_X2_Y2(if_required1, if_required2) \
|
||||||
{MP_QSTR_x1, if_required1 | MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0)}}, \
|
{MP_QSTR_x1, if_required1 | MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0)}}, \
|
||||||
{MP_QSTR_y1, if_required2 | MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0)}}, \
|
{MP_QSTR_y1, if_required1 | MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0)}}, \
|
||||||
{MP_QSTR_x2, if_required1 | MP_ARG_OBJ, {.u_obj = MP_ROM_NONE}}, \
|
{MP_QSTR_x2, if_required2 | MP_ARG_OBJ, {.u_obj = MP_ROM_NONE}}, \
|
||||||
{MP_QSTR_y2, if_required2 | MP_ARG_OBJ, {.u_obj = MP_ROM_NONE}}
|
{MP_QSTR_y2, if_required2 | MP_ARG_OBJ, {.u_obj = MP_ROM_NONE}}
|
||||||
|
|
||||||
bitmaptools_rect_t bitmaptools_validate_coord_range_pair(const mp_arg_val_t in[4], int width, int height);
|
bitmaptools_rect_t bitmaptools_validate_coord_range_pair(const mp_arg_val_t in[4], int width, int height);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ extern void common_hal_mcu_disable_interrupts(void);
|
||||||
extern void common_hal_mcu_enable_interrupts(void);
|
extern void common_hal_mcu_enable_interrupts(void);
|
||||||
|
|
||||||
extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode);
|
extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode);
|
||||||
extern void common_hal_mcu_reset(void);
|
NORETURN extern void common_hal_mcu_reset(void);
|
||||||
|
|
||||||
extern const mp_obj_dict_t mcu_pin_globals;
|
extern const mp_obj_dict_t mcu_pin_globals;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ void common_hal_storage_umount_path(const char *path);
|
||||||
void common_hal_storage_umount_object(mp_obj_t vfs_obj);
|
void common_hal_storage_umount_object(mp_obj_t vfs_obj);
|
||||||
void common_hal_storage_remount(const char *path, bool readonly, bool disable_concurrent_write_protection);
|
void common_hal_storage_remount(const char *path, bool readonly, bool disable_concurrent_write_protection);
|
||||||
mp_obj_t common_hal_storage_getmount(const char *path);
|
mp_obj_t common_hal_storage_getmount(const char *path);
|
||||||
void common_hal_storage_erase_filesystem(bool extended);
|
NORETURN void common_hal_storage_erase_filesystem(bool extended);
|
||||||
|
|
||||||
bool common_hal_storage_disable_usb_drive(void);
|
bool common_hal_storage_disable_usb_drive(void);
|
||||||
bool common_hal_storage_enable_usb_drive(void);
|
bool common_hal_storage_enable_usb_drive(void);
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(time_not_implemented_obj, time_not_implemented);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
|
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
|
||||||
mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
|
NORETURN mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
|
||||||
mp_raise_RuntimeError(MP_ERROR_TEXT("RTC is not supported on this board"));
|
mp_raise_RuntimeError(MP_ERROR_TEXT("RTC is not supported on this board"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@
|
||||||
#include "py/mpprint.h"
|
#include "py/mpprint.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
|
||||||
void raise_deinited_error(void);
|
NORETURN void raise_deinited_error(void);
|
||||||
void properties_print_helper(const mp_print_t *print, mp_obj_t self_in, const mp_arg_t *properties, size_t n_properties);
|
void properties_print_helper(const mp_print_t *print, mp_obj_t self_in, const mp_arg_t *properties, size_t n_properties);
|
||||||
void properties_construct_helper(mp_obj_t self_in, const mp_arg_t *args, const mp_arg_val_t *vals, size_t n_properties);
|
void properties_construct_helper(mp_obj_t self_in, const mp_arg_t *args, const mp_arg_val_t *vals, size_t n_properties);
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_
|
||||||
synthio_block_assign_slot(delay_ms, &self->delay_ms, MP_QSTR_delay_ms);
|
synthio_block_assign_slot(delay_ms, &self->delay_ms, MP_QSTR_delay_ms);
|
||||||
|
|
||||||
if (mix == MP_OBJ_NULL) {
|
if (mix == MP_OBJ_NULL) {
|
||||||
mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5));
|
mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.25));
|
||||||
}
|
}
|
||||||
synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix);
|
synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix);
|
||||||
|
|
||||||
|
|
@ -268,7 +268,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
|
||||||
|
|
||||||
// get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required
|
// get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required
|
||||||
shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count);
|
shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count);
|
||||||
mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0));
|
mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * MICROPY_FLOAT_CONST(2.0);
|
||||||
mp_float_t decay = synthio_block_slot_get_limited(&self->decay, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0));
|
mp_float_t decay = synthio_block_slot_get_limited(&self->decay, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0));
|
||||||
|
|
||||||
mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms);
|
mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms);
|
||||||
|
|
@ -323,7 +323,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
|
||||||
echo_buffer[self->echo_buffer_write_pos++] = word;
|
echo_buffer[self->echo_buffer_write_pos++] = word;
|
||||||
}
|
}
|
||||||
|
|
||||||
word = (int16_t)(echo * mix);
|
word = (int16_t)(echo * MIN(mix, MICROPY_FLOAT_CONST(1.0)));
|
||||||
|
|
||||||
if (MP_LIKELY(self->base.bits_per_sample == 16)) {
|
if (MP_LIKELY(self->base.bits_per_sample == 16)) {
|
||||||
word_buffer[i] = word;
|
word_buffer[i] = word;
|
||||||
|
|
@ -414,16 +414,17 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
word = echo + sample_word;
|
word = (int32_t)((sample_word * MIN(MICROPY_FLOAT_CONST(2.0) - mix, MICROPY_FLOAT_CONST(1.0)))
|
||||||
|
+ (echo * MIN(mix, MICROPY_FLOAT_CONST(1.0))));
|
||||||
word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2));
|
word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2));
|
||||||
|
|
||||||
if (MP_LIKELY(self->base.bits_per_sample == 16)) {
|
if (MP_LIKELY(self->base.bits_per_sample == 16)) {
|
||||||
word_buffer[i] = (int16_t)((sample_word * (MICROPY_FLOAT_CONST(1.0) - mix)) + (word * mix));
|
word_buffer[i] = (int16_t)word;
|
||||||
if (!self->base.samples_signed) {
|
if (!self->base.samples_signed) {
|
||||||
word_buffer[i] ^= 0x8000;
|
word_buffer[i] ^= 0x8000;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int8_t mixed = (int16_t)((sample_word * (MICROPY_FLOAT_CONST(1.0) - mix)) + (word * mix));
|
int8_t mixed = (int16_t)word;
|
||||||
if (self->base.samples_signed) {
|
if (self->base.samples_signed) {
|
||||||
hword_buffer[i] = mixed;
|
hword_buffer[i] = mixed;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
478
shared-module/audiodelays/MultiTapDelay.c
Normal file
478
shared-module/audiodelays/MultiTapDelay.c
Normal file
|
|
@ -0,0 +1,478 @@
|
||||||
|
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
#include "shared-bindings/audiodelays/MultiTapDelay.h"
|
||||||
|
#include "shared-bindings/audiocore/__init__.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_construct(audiodelays_multi_tap_delay_obj_t *self, uint32_t max_delay_ms,
|
||||||
|
mp_obj_t delay_ms, mp_obj_t decay, mp_obj_t mix, mp_obj_t taps,
|
||||||
|
uint32_t buffer_size, uint8_t bits_per_sample,
|
||||||
|
bool samples_signed, uint8_t channel_count, uint32_t sample_rate) {
|
||||||
|
|
||||||
|
// Basic settings every effect and audio sample has
|
||||||
|
// These are the effects values, not the source sample(s)
|
||||||
|
self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places
|
||||||
|
self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true)
|
||||||
|
self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo
|
||||||
|
self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects
|
||||||
|
self->base.single_buffer = false;
|
||||||
|
self->base.max_buffer_length = buffer_size;
|
||||||
|
|
||||||
|
// To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer
|
||||||
|
// A double buffer is set up here so the audio output can use DMA on buffer 1 while we
|
||||||
|
// write to and create buffer 2.
|
||||||
|
// This buffer is what is passed to the audio component that plays the effect.
|
||||||
|
// Samples are set sequentially. For stereo audio they are passed L/R/L/R/...
|
||||||
|
self->buffer_len = buffer_size; // in bytes
|
||||||
|
|
||||||
|
self->buffer[0] = m_malloc_maybe(self->buffer_len);
|
||||||
|
if (self->buffer[0] == NULL) {
|
||||||
|
common_hal_audiodelays_multi_tap_delay_deinit(self);
|
||||||
|
m_malloc_fail(self->buffer_len);
|
||||||
|
}
|
||||||
|
memset(self->buffer[0], 0, self->buffer_len);
|
||||||
|
|
||||||
|
self->buffer[1] = m_malloc_maybe(self->buffer_len);
|
||||||
|
if (self->buffer[1] == NULL) {
|
||||||
|
common_hal_audiodelays_multi_tap_delay_deinit(self);
|
||||||
|
m_malloc_fail(self->buffer_len);
|
||||||
|
}
|
||||||
|
memset(self->buffer[1], 0, self->buffer_len);
|
||||||
|
|
||||||
|
self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1
|
||||||
|
|
||||||
|
// Initialize other values most effects will need.
|
||||||
|
self->sample = NULL; // The current playing sample
|
||||||
|
self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played
|
||||||
|
self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!)
|
||||||
|
self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file)
|
||||||
|
self->more_data = false; // Is there still more data to read from the sample or did we finish
|
||||||
|
|
||||||
|
// The below section sets up the multi-tap delay effect's starting values. For a different effect this section will change
|
||||||
|
|
||||||
|
// If we did not receive a BlockInput we need to create a default float value
|
||||||
|
if (decay == MP_OBJ_NULL) {
|
||||||
|
decay = mp_obj_new_float(MICROPY_FLOAT_CONST(0.7));
|
||||||
|
}
|
||||||
|
synthio_block_assign_slot(decay, &self->decay, MP_QSTR_decay);
|
||||||
|
|
||||||
|
if (mix == MP_OBJ_NULL) {
|
||||||
|
mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.25));
|
||||||
|
}
|
||||||
|
synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix);
|
||||||
|
|
||||||
|
// Allocate the delay buffer for the max possible delay, delay is always 16-bit
|
||||||
|
self->max_delay_ms = max_delay_ms;
|
||||||
|
self->max_delay_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * max_delay_ms) * (self->base.channel_count * sizeof(uint16_t)); // bytes
|
||||||
|
self->delay_buffer = m_malloc_maybe(self->max_delay_buffer_len);
|
||||||
|
if (self->delay_buffer == NULL) {
|
||||||
|
common_hal_audiodelays_multi_tap_delay_deinit(self);
|
||||||
|
m_malloc_fail(self->max_delay_buffer_len);
|
||||||
|
}
|
||||||
|
memset(self->delay_buffer, 0, self->max_delay_buffer_len);
|
||||||
|
|
||||||
|
// calculate the length of a single sample in milliseconds
|
||||||
|
self->sample_ms = MICROPY_FLOAT_CONST(1000.0) / self->base.sample_rate;
|
||||||
|
|
||||||
|
// calculate everything needed for the current delay
|
||||||
|
common_hal_audiodelays_multi_tap_delay_set_delay_ms(self, delay_ms);
|
||||||
|
self->delay_buffer_pos = 0;
|
||||||
|
self->delay_buffer_right_pos = 0;
|
||||||
|
|
||||||
|
// Initialize our tap values
|
||||||
|
self->tap_positions = NULL;
|
||||||
|
self->tap_levels = NULL;
|
||||||
|
self->tap_offsets = NULL;
|
||||||
|
self->tap_len = 0;
|
||||||
|
common_hal_audiodelays_multi_tap_delay_set_taps(self, taps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_deinit(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
audiosample_mark_deinit(&self->base);
|
||||||
|
self->delay_buffer = NULL;
|
||||||
|
self->buffer[0] = NULL;
|
||||||
|
self->buffer[1] = NULL;
|
||||||
|
|
||||||
|
self->tap_positions = NULL;
|
||||||
|
self->tap_levels = NULL;
|
||||||
|
self->tap_offsets = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_float_t common_hal_audiodelays_multi_tap_delay_get_delay_ms(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
return self->delay_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_delay_ms(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t delay_ms) {
|
||||||
|
self->delay_ms = mp_obj_get_float(delay_ms);
|
||||||
|
|
||||||
|
// Require that delay is at least 1 sample long
|
||||||
|
self->delay_ms = MAX(self->delay_ms, self->sample_ms);
|
||||||
|
|
||||||
|
// Calculate the current delay buffer length in bytes
|
||||||
|
self->delay_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * self->delay_ms) * (self->base.channel_count * sizeof(uint16_t));
|
||||||
|
|
||||||
|
// Limit to valid range
|
||||||
|
if (self->delay_buffer_len > self->max_delay_buffer_len) {
|
||||||
|
self->delay_buffer_len = self->max_delay_buffer_len;
|
||||||
|
} else if (self->delay_buffer_len < self->buffer_len) {
|
||||||
|
// If the delay buffer is smaller than our audio buffer, weird things happen
|
||||||
|
self->delay_buffer_len = self->buffer_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the now unused part of the buffer or some weird artifacts appear
|
||||||
|
memset(self->delay_buffer + self->delay_buffer_len, 0, self->max_delay_buffer_len - self->delay_buffer_len);
|
||||||
|
|
||||||
|
// Update tap offsets if we have any
|
||||||
|
recalculate_tap_offsets(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t common_hal_audiodelays_multi_tap_delay_get_decay(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
return self->decay.obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_decay(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t decay) {
|
||||||
|
synthio_block_assign_slot(decay, &self->decay, MP_QSTR_decay);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t common_hal_audiodelays_multi_tap_delay_get_mix(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
return self->mix.obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_mix(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t mix) {
|
||||||
|
synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t common_hal_audiodelays_multi_tap_delay_get_taps(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
if (!self->tap_len) {
|
||||||
|
return mp_const_none;
|
||||||
|
} else {
|
||||||
|
mp_obj_tuple_t *taps = mp_obj_new_tuple(self->tap_len, NULL);
|
||||||
|
for (size_t i = 0; i < self->tap_len; i++) {
|
||||||
|
mp_obj_tuple_t *pair = mp_obj_new_tuple(2, NULL);
|
||||||
|
pair->items[0] = mp_obj_new_float(self->tap_positions[i]);
|
||||||
|
pair->items[1] = mp_obj_new_float(self->tap_levels[i]);
|
||||||
|
taps->items[i] = pair;
|
||||||
|
}
|
||||||
|
return taps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void validate_tap_value(mp_obj_t item, qstr arg_name) {
|
||||||
|
if (mp_obj_is_small_int(item)) {
|
||||||
|
mp_arg_validate_int_range(mp_obj_get_int(item), 0, 1, arg_name);
|
||||||
|
} else {
|
||||||
|
mp_arg_validate_obj_float_range(item, 0, 1, arg_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_float_t get_tap_value(mp_obj_t item) {
|
||||||
|
mp_float_t value;
|
||||||
|
if (mp_obj_is_small_int(item)) {
|
||||||
|
value = (mp_float_t)mp_obj_get_int(item);
|
||||||
|
} else {
|
||||||
|
value = mp_obj_float_get(item);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_set_taps(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t taps_in) {
|
||||||
|
if (taps_in != mp_const_none && !MP_OBJ_TYPE_HAS_SLOT(mp_obj_get_type(taps_in), iter)) {
|
||||||
|
mp_raise_TypeError_varg(
|
||||||
|
MP_ERROR_TEXT("%q must be of type %q, not %q"),
|
||||||
|
MP_QSTR_taps, MP_QSTR_iterable, mp_obj_get_type(taps_in)->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len, i;
|
||||||
|
mp_obj_t *items;
|
||||||
|
|
||||||
|
if (taps_in == mp_const_none) {
|
||||||
|
len = 0;
|
||||||
|
items = NULL;
|
||||||
|
} else {
|
||||||
|
// convert object to tuple if it wasn't before
|
||||||
|
taps_in = MP_OBJ_TYPE_GET_SLOT(&mp_type_tuple, make_new)(
|
||||||
|
&mp_type_tuple, 1, 0, &taps_in);
|
||||||
|
|
||||||
|
mp_obj_tuple_get(taps_in, &len, &items);
|
||||||
|
mp_arg_validate_length_min(len, 1, MP_QSTR_items);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
mp_obj_t item = items[i];
|
||||||
|
if (mp_obj_is_tuple_compatible(item)) {
|
||||||
|
size_t len1;
|
||||||
|
mp_obj_t *items1;
|
||||||
|
mp_obj_tuple_get(item, &len1, &items1);
|
||||||
|
mp_arg_validate_length(len1, 2, MP_QSTR_items);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < len1; j++) {
|
||||||
|
validate_tap_value(items1[j], j ? MP_QSTR_level : MP_QSTR_position);
|
||||||
|
}
|
||||||
|
} else if (mp_obj_is_float(item) || mp_obj_is_small_int(item)) {
|
||||||
|
validate_tap_value(item, MP_QSTR_position);
|
||||||
|
} else {
|
||||||
|
mp_raise_TypeError_varg(
|
||||||
|
MP_ERROR_TEXT("%q in %q must be of type %q or %q, not %q"),
|
||||||
|
MP_QSTR_object,
|
||||||
|
MP_QSTR_taps,
|
||||||
|
MP_QSTR_iterable,
|
||||||
|
MP_QSTR_float,
|
||||||
|
mp_obj_get_type(item)->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self->tap_positions = m_renew(mp_float_t,
|
||||||
|
self->tap_positions,
|
||||||
|
self->tap_len,
|
||||||
|
len);
|
||||||
|
self->tap_levels = m_renew(mp_float_t,
|
||||||
|
self->tap_levels,
|
||||||
|
self->tap_len,
|
||||||
|
len);
|
||||||
|
self->tap_offsets = m_renew(uint32_t,
|
||||||
|
self->tap_offsets,
|
||||||
|
self->tap_len,
|
||||||
|
len);
|
||||||
|
self->tap_len = len;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
mp_obj_t item = items[i];
|
||||||
|
if (mp_obj_is_tuple_compatible(item)) {
|
||||||
|
size_t len1;
|
||||||
|
mp_obj_t *items1;
|
||||||
|
mp_obj_tuple_get(item, &len1, &items1);
|
||||||
|
|
||||||
|
self->tap_positions[i] = get_tap_value(items1[0]);
|
||||||
|
self->tap_levels[i] = get_tap_value(items1[1]);
|
||||||
|
} else {
|
||||||
|
self->tap_positions[i] = get_tap_value(item);
|
||||||
|
self->tap_levels[i] = MICROPY_FLOAT_CONST(1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
recalculate_tap_offsets(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void recalculate_tap_offsets(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
if (!self->tap_len) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t delay_buffer_len = self->delay_buffer_len / self->base.channel_count / sizeof(uint16_t);
|
||||||
|
for (size_t i = 0; i < self->tap_len; i++) {
|
||||||
|
self->tap_offsets[i] = (uint32_t)(delay_buffer_len * self->tap_positions[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void audiodelays_multi_tap_delay_reset_buffer(audiodelays_multi_tap_delay_obj_t *self,
|
||||||
|
bool single_channel_output,
|
||||||
|
uint8_t channel) {
|
||||||
|
|
||||||
|
memset(self->buffer[0], 0, self->buffer_len);
|
||||||
|
memset(self->buffer[1], 0, self->buffer_len);
|
||||||
|
memset(self->delay_buffer, 0, self->max_delay_buffer_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_audiodelays_multi_tap_delay_get_playing(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
return self->sample != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_play(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t sample, bool loop) {
|
||||||
|
audiosample_must_match(&self->base, sample);
|
||||||
|
|
||||||
|
self->sample = sample;
|
||||||
|
self->loop = loop;
|
||||||
|
|
||||||
|
audiosample_reset_buffer(self->sample, false, 0);
|
||||||
|
audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length);
|
||||||
|
|
||||||
|
// Track remaining sample length in terms of bytes per sample
|
||||||
|
self->sample_buffer_length /= (self->base.bits_per_sample / 8);
|
||||||
|
// Store if we have more data in the sample to retrieve
|
||||||
|
self->more_data = result == GET_BUFFER_MORE_DATA;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void common_hal_audiodelays_multi_tap_delay_stop(audiodelays_multi_tap_delay_obj_t *self) {
|
||||||
|
// When the sample is set to stop playing do any cleanup here
|
||||||
|
// For delay we clear the sample but the delay continues until the object reading our effect stops
|
||||||
|
self->sample = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
audioio_get_buffer_result_t audiodelays_multi_tap_delay_get_buffer(audiodelays_multi_tap_delay_obj_t *self, bool single_channel_output, uint8_t channel,
|
||||||
|
uint8_t **buffer, uint32_t *buffer_length) {
|
||||||
|
|
||||||
|
if (!single_channel_output) {
|
||||||
|
channel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch our buffers to the other buffer
|
||||||
|
self->last_buf_idx = !self->last_buf_idx;
|
||||||
|
|
||||||
|
// If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer
|
||||||
|
int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx];
|
||||||
|
int8_t *hword_buffer = self->buffer[self->last_buf_idx];
|
||||||
|
uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8);
|
||||||
|
|
||||||
|
// The delay buffer is always stored as a 16-bit value internally
|
||||||
|
int16_t *delay_buffer = (int16_t *)self->delay_buffer;
|
||||||
|
uint32_t delay_buffer_len = self->delay_buffer_len / self->base.channel_count / sizeof(uint16_t);
|
||||||
|
|
||||||
|
uint32_t delay_buffer_pos = self->delay_buffer_pos;
|
||||||
|
if (single_channel_output && channel == 1) {
|
||||||
|
delay_buffer_pos = self->delay_buffer_right_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mix_down_scale = SYNTHIO_MIX_DOWN_SCALE(self->tap_len);
|
||||||
|
|
||||||
|
// Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample
|
||||||
|
while (length != 0) {
|
||||||
|
// Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample
|
||||||
|
if (self->sample_buffer_length == 0) {
|
||||||
|
if (!self->more_data) { // The sample has indicated it has no more data to play
|
||||||
|
if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start
|
||||||
|
audiosample_reset_buffer(self->sample, false, 0);
|
||||||
|
} else { // If we were not supposed to loop the sample, stop playing it but we still need to play the delay
|
||||||
|
self->sample = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self->sample) {
|
||||||
|
// Load another sample buffer to play
|
||||||
|
audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length);
|
||||||
|
// Track length in terms of words.
|
||||||
|
self->sample_buffer_length /= (self->base.bits_per_sample / 8);
|
||||||
|
self->more_data = result == GET_BUFFER_MORE_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining
|
||||||
|
uint32_t n;
|
||||||
|
if (self->sample == NULL) {
|
||||||
|
n = MIN(length, SYNTHIO_MAX_DUR * self->base.channel_count);
|
||||||
|
} else {
|
||||||
|
n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required
|
||||||
|
shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count);
|
||||||
|
mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * MICROPY_FLOAT_CONST(2.0);
|
||||||
|
mp_float_t decay = synthio_block_slot_get_limited(&self->decay, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0));
|
||||||
|
|
||||||
|
int16_t *sample_src = NULL;
|
||||||
|
int8_t *sample_hsrc = NULL;
|
||||||
|
if (self->sample != NULL) {
|
||||||
|
// we have a sample to play and delay
|
||||||
|
sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples
|
||||||
|
sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < n; i++) {
|
||||||
|
uint32_t delay_buffer_offset = delay_buffer_len * ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1));
|
||||||
|
|
||||||
|
int32_t sample_word = 0;
|
||||||
|
if (self->sample != NULL) {
|
||||||
|
if (MP_LIKELY(self->base.bits_per_sample == 16)) {
|
||||||
|
sample_word = sample_src[i];
|
||||||
|
} else {
|
||||||
|
if (self->base.samples_signed) {
|
||||||
|
sample_word = sample_hsrc[i];
|
||||||
|
} else {
|
||||||
|
// Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed
|
||||||
|
sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull words from delay buffer at tap positions, apply level and mix down
|
||||||
|
int32_t word = 0;
|
||||||
|
int32_t delay_word;
|
||||||
|
if (self->tap_len) {
|
||||||
|
size_t tap_pos;
|
||||||
|
for (size_t j = 0; j < self->tap_len; j++) {
|
||||||
|
tap_pos = (delay_buffer_pos + delay_buffer_len - self->tap_offsets[j]) % delay_buffer_len;
|
||||||
|
delay_word = delay_buffer[tap_pos + delay_buffer_offset];
|
||||||
|
word += (int32_t)(delay_word * self->tap_levels[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->tap_len > 1) {
|
||||||
|
word = synthio_mix_down_sample(word, mix_down_scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update delay buffer with sample and decay
|
||||||
|
delay_word = delay_buffer[delay_buffer_pos + delay_buffer_offset];
|
||||||
|
|
||||||
|
// If no taps are provided, use as standard delay
|
||||||
|
if (!self->tap_len) {
|
||||||
|
word = delay_word;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply decay and add sample
|
||||||
|
delay_word = (int32_t)(delay_word * decay) + sample_word;
|
||||||
|
|
||||||
|
if (MP_LIKELY(self->base.bits_per_sample == 16)) {
|
||||||
|
delay_word = synthio_mix_down_sample(delay_word, SYNTHIO_MIX_DOWN_SCALE(2));
|
||||||
|
delay_buffer[delay_buffer_pos + delay_buffer_offset] = (int16_t)delay_word;
|
||||||
|
} else {
|
||||||
|
// Do not have mix_down for 8 bit so just hard cap samples into 1 byte
|
||||||
|
delay_word = MIN(MAX(delay_word, -128), 127);
|
||||||
|
delay_buffer[delay_buffer_pos + delay_buffer_offset] = (int8_t)delay_word;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mix sample with tap output
|
||||||
|
word = (int32_t)((sample_word * MIN(MICROPY_FLOAT_CONST(2.0) - mix, MICROPY_FLOAT_CONST(1.0)))
|
||||||
|
+ (word * MIN(mix, MICROPY_FLOAT_CONST(1.0))));
|
||||||
|
word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2));
|
||||||
|
|
||||||
|
if (MP_LIKELY(self->base.bits_per_sample == 16)) {
|
||||||
|
word_buffer[i] = (int16_t)word;
|
||||||
|
if (!self->base.samples_signed) {
|
||||||
|
word_buffer[i] ^= 0x8000;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int8_t mixed = (int16_t)word;
|
||||||
|
if (self->base.samples_signed) {
|
||||||
|
hword_buffer[i] = mixed;
|
||||||
|
} else {
|
||||||
|
hword_buffer[i] = (uint8_t)mixed ^ 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((self->base.channel_count == 1 || single_channel_output || (!single_channel_output && (i % self->base.channel_count) == 1))
|
||||||
|
&& ++delay_buffer_pos >= delay_buffer_len) {
|
||||||
|
delay_buffer_pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the remaining length and the buffer positions based on how much we wrote into our buffer
|
||||||
|
length -= n;
|
||||||
|
word_buffer += n;
|
||||||
|
hword_buffer += n;
|
||||||
|
if (self->sample != NULL) {
|
||||||
|
self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8));
|
||||||
|
self->sample_buffer_length -= n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (single_channel_output && channel == 1) {
|
||||||
|
self->delay_buffer_right_pos = delay_buffer_pos;
|
||||||
|
} else {
|
||||||
|
self->delay_buffer_pos = delay_buffer_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally pass our buffer and length to the calling audio function
|
||||||
|
*buffer = (uint8_t *)self->buffer[self->last_buf_idx];
|
||||||
|
*buffer_length = self->buffer_len;
|
||||||
|
|
||||||
|
// MultiTapDelay always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h)
|
||||||
|
return GET_BUFFER_MORE_DATA;
|
||||||
|
}
|
||||||
60
shared-module/audiodelays/MultiTapDelay.h
Normal file
60
shared-module/audiodelays/MultiTapDelay.h
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
// This file is part of the CircuitPython project: https://circuitpython.org
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
#include "shared-module/audiocore/__init__.h"
|
||||||
|
#include "shared-module/synthio/__init__.h"
|
||||||
|
#include "shared-module/synthio/block.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t audiodelays_multi_tap_delay_type;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
audiosample_base_t base;
|
||||||
|
uint32_t max_delay_ms;
|
||||||
|
mp_float_t delay_ms;
|
||||||
|
mp_float_t sample_ms;
|
||||||
|
synthio_block_slot_t decay;
|
||||||
|
synthio_block_slot_t mix;
|
||||||
|
|
||||||
|
mp_float_t *tap_positions;
|
||||||
|
mp_float_t *tap_levels;
|
||||||
|
uint32_t *tap_offsets;
|
||||||
|
size_t tap_len;
|
||||||
|
|
||||||
|
int8_t *buffer[2];
|
||||||
|
uint8_t last_buf_idx;
|
||||||
|
uint32_t buffer_len; // max buffer in bytes
|
||||||
|
|
||||||
|
uint8_t *sample_remaining_buffer;
|
||||||
|
uint32_t sample_buffer_length;
|
||||||
|
|
||||||
|
bool loop;
|
||||||
|
bool more_data;
|
||||||
|
|
||||||
|
int8_t *delay_buffer;
|
||||||
|
uint32_t delay_buffer_len; // bytes
|
||||||
|
uint32_t max_delay_buffer_len; // bytes
|
||||||
|
uint32_t delay_buffer_pos;
|
||||||
|
uint32_t delay_buffer_right_pos;
|
||||||
|
|
||||||
|
mp_obj_t sample;
|
||||||
|
} audiodelays_multi_tap_delay_obj_t;
|
||||||
|
|
||||||
|
void validate_tap_value(mp_obj_t item, qstr arg_name);
|
||||||
|
mp_float_t get_tap_value(mp_obj_t item);
|
||||||
|
void recalculate_tap_offsets(audiodelays_multi_tap_delay_obj_t *self);
|
||||||
|
|
||||||
|
void audiodelays_multi_tap_delay_reset_buffer(audiodelays_multi_tap_delay_obj_t *self,
|
||||||
|
bool single_channel_output,
|
||||||
|
uint8_t channel);
|
||||||
|
|
||||||
|
audioio_get_buffer_result_t audiodelays_multi_tap_delay_get_buffer(audiodelays_multi_tap_delay_obj_t *self,
|
||||||
|
bool single_channel_output,
|
||||||
|
uint8_t channel,
|
||||||
|
uint8_t **buffer,
|
||||||
|
uint32_t *buffer_length); // length in bytes
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#define port_free free
|
#define port_free free
|
||||||
#define port_malloc(sz, hint) (malloc(sz))
|
#define port_malloc(sz, hint) (malloc(sz))
|
||||||
#define port_realloc realloc
|
#define port_realloc(ptr, size, dma_capable) realloc(ptr, size)
|
||||||
#else
|
#else
|
||||||
#include "supervisor/port_heap.h"
|
#include "supervisor/port_heap.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -48,7 +48,7 @@ static void *scratchpad_alloc(size_t sz) {
|
||||||
} else {
|
} else {
|
||||||
if (scratchpad) {
|
if (scratchpad) {
|
||||||
if (sz > scratchpad_size) {
|
if (sz > scratchpad_size) {
|
||||||
void *tmp = port_realloc(scratchpad, sz);
|
void *tmp = port_realloc(scratchpad, sz, false);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
port_free(scratchpad);
|
port_free(scratchpad);
|
||||||
scratchpad = NULL;
|
scratchpad = NULL;
|
||||||
|
|
|
||||||
|
|
@ -95,12 +95,6 @@ void port_wake_main_task_from_isr(void);
|
||||||
// CircuitPython task when others are done.
|
// CircuitPython task when others are done.
|
||||||
void port_yield(void);
|
void port_yield(void);
|
||||||
|
|
||||||
// Some ports need special handling just after completing boot.py execution.
|
|
||||||
// This function is called once while boot.py's VM is still valid, and
|
|
||||||
// then a second time after the VM is finalized.
|
|
||||||
// A default weak implementation is provided that does nothing.
|
|
||||||
void port_post_boot_py(bool heap_valid);
|
|
||||||
|
|
||||||
// Some ports want to add information to boot_out.txt.
|
// Some ports want to add information to boot_out.txt.
|
||||||
// A default weak implementation is provided that does nothing.
|
// A default weak implementation is provided that does nothing.
|
||||||
void port_boot_info(void);
|
void port_boot_info(void);
|
||||||
|
|
@ -108,3 +102,8 @@ void port_boot_info(void);
|
||||||
// Some ports want to mark additional pointers as gc roots.
|
// Some ports want to mark additional pointers as gc roots.
|
||||||
// A default weak implementation is provided that does nothing.
|
// A default weak implementation is provided that does nothing.
|
||||||
void port_gc_collect(void);
|
void port_gc_collect(void);
|
||||||
|
|
||||||
|
// Most ports that implement CIRCUITPY_BOOT_BUTTON use a generic version of
|
||||||
|
// this function to sense the button. Ports that need to can override this
|
||||||
|
// function to provide their own implementation.
|
||||||
|
bool port_boot_button_pressed(void);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,6 @@ void *port_malloc(size_t size, bool dma_capable);
|
||||||
|
|
||||||
void port_free(void *ptr);
|
void port_free(void *ptr);
|
||||||
|
|
||||||
void *port_realloc(void *ptr, size_t size);
|
void *port_realloc(void *ptr, size_t size, bool dma_capable);
|
||||||
|
|
||||||
size_t port_heap_get_largest_free_size(void);
|
size_t port_heap_get_largest_free_size(void);
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,13 @@
|
||||||
|
|
||||||
#include "shared-bindings/_bleio/__init__.h"
|
#include "shared-bindings/_bleio/__init__.h"
|
||||||
#include "shared-bindings/_bleio/Adapter.h"
|
#include "shared-bindings/_bleio/Adapter.h"
|
||||||
#if defined(CIRCUITPY_BOOT_BUTTON)
|
|
||||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
|
||||||
#include "shared-bindings/time/__init__.h"
|
|
||||||
#endif
|
|
||||||
#include "shared-bindings/microcontroller/Processor.h"
|
#include "shared-bindings/microcontroller/Processor.h"
|
||||||
#include "shared-bindings/microcontroller/ResetReason.h"
|
#include "shared-bindings/microcontroller/ResetReason.h"
|
||||||
#include "shared-module/storage/__init__.h"
|
#include "shared-module/storage/__init__.h"
|
||||||
|
|
||||||
#include "common-hal/_bleio/__init__.h"
|
#include "common-hal/_bleio/__init__.h"
|
||||||
|
|
||||||
|
#include "supervisor/port.h"
|
||||||
#include "supervisor/shared/serial.h"
|
#include "supervisor/shared/serial.h"
|
||||||
#include "supervisor/shared/status_leds.h"
|
#include "supervisor/shared/status_leds.h"
|
||||||
#include "supervisor/shared/tick.h"
|
#include "supervisor/shared/tick.h"
|
||||||
|
|
@ -238,18 +235,10 @@ void supervisor_bluetooth_init(void) {
|
||||||
new_status_color(BLACK);
|
new_status_color(BLACK);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Init the boot button every time in case it is used for LEDs.
|
if (port_boot_button_pressed()) {
|
||||||
#ifdef CIRCUITPY_BOOT_BUTTON
|
|
||||||
digitalio_digitalinout_obj_t boot_button;
|
|
||||||
common_hal_digitalio_digitalinout_construct(&boot_button, CIRCUITPY_BOOT_BUTTON);
|
|
||||||
common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP);
|
|
||||||
common_hal_time_delay_ms(1);
|
|
||||||
bool button_pressed = !common_hal_digitalio_digitalinout_get_value(&boot_button);
|
|
||||||
common_hal_digitalio_digitalinout_deinit(&boot_button);
|
|
||||||
if (button_pressed) {
|
|
||||||
boot_in_discovery_mode = true;
|
boot_in_discovery_mode = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
diff = supervisor_ticks_ms64() - start_ticks;
|
diff = supervisor_ticks_ms64() - start_ticks;
|
||||||
}
|
}
|
||||||
if (boot_in_discovery_mode) {
|
if (boot_in_discovery_mode) {
|
||||||
|
|
|
||||||
|
|
@ -23,3 +23,4 @@
|
||||||
#define CMD_ENABLE_RESET 0x66
|
#define CMD_ENABLE_RESET 0x66
|
||||||
#define CMD_RESET 0x99
|
#define CMD_RESET 0x99
|
||||||
#define CMD_WAKE 0xab
|
#define CMD_WAKE 0xab
|
||||||
|
#define CMD_GLOBAL_BLOCK_PROTECTION_UNLOCK 0x98
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,12 @@ typedef struct {
|
||||||
// status register.
|
// status register.
|
||||||
uint8_t quad_enable_bit_mask;
|
uint8_t quad_enable_bit_mask;
|
||||||
|
|
||||||
|
// Device has sector-level write protection
|
||||||
bool has_sector_protection : 1;
|
bool has_sector_protection : 1;
|
||||||
|
|
||||||
|
// Device uses global block protection lock instead of status register bits to enable sector writes
|
||||||
|
bool use_global_block_protection_lock : 1;
|
||||||
|
|
||||||
// Supports the 0x0b fast read command with 8 dummy cycles.
|
// Supports the 0x0b fast read command with 8 dummy cycles.
|
||||||
bool supports_fast_read : 1;
|
bool supports_fast_read : 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
.max_clock_speed_mhz = {{ device.max_clock_speed_mhz }}, \
|
.max_clock_speed_mhz = {{ device.max_clock_speed_mhz }}, \
|
||||||
.quad_enable_bit_mask = {{ device.quad_enable_bit_mask }}, \
|
.quad_enable_bit_mask = {{ device.quad_enable_bit_mask }}, \
|
||||||
.has_sector_protection = {{ device.has_sector_protection | lower() }}, \
|
.has_sector_protection = {{ device.has_sector_protection | lower() }}, \
|
||||||
|
.use_global_block_protection_lock = {{ device.use_global_block_protection_lock | lower() }}, \
|
||||||
.supports_fast_read = {{ device.supports_fast_read | lower() }}, \
|
.supports_fast_read = {{ device.supports_fast_read | lower() }}, \
|
||||||
.supports_qspi = {{ device["6b_quad_read"] | lower() }}, \
|
.supports_qspi = {{ device["6b_quad_read"] | lower() }}, \
|
||||||
.supports_qspi_writes = {{ device["32_qspi_write"] | lower() }}, \
|
.supports_qspi_writes = {{ device["32_qspi_write"] | lower() }}, \
|
||||||
|
|
|
||||||
|
|
@ -268,9 +268,13 @@ void supervisor_flash_init(void) {
|
||||||
write_enable();
|
write_enable();
|
||||||
|
|
||||||
// Turn off sector protection
|
// Turn off sector protection
|
||||||
|
if (flash_device->use_global_block_protection_lock) {
|
||||||
|
spi_flash_command(CMD_GLOBAL_BLOCK_PROTECTION_UNLOCK);
|
||||||
|
} else {
|
||||||
uint8_t data[1] = {0x00};
|
uint8_t data[1] = {0x00};
|
||||||
spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, data, 1);
|
spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, data, 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Turn off writes in case this is a microcontroller only reset.
|
// Turn off writes in case this is a microcontroller only reset.
|
||||||
spi_flash_command(CMD_DISABLE_WRITE);
|
spi_flash_command(CMD_DISABLE_WRITE);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,11 @@
|
||||||
|
|
||||||
#include "lib/tlsf/tlsf.h"
|
#include "lib/tlsf/tlsf.h"
|
||||||
|
|
||||||
|
#ifdef CIRCUITPY_BOOT_BUTTON
|
||||||
|
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||||
|
#include "shared-bindings/time/__init__.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static tlsf_t heap;
|
static tlsf_t heap;
|
||||||
|
|
||||||
MP_WEAK void port_wake_main_task(void) {
|
MP_WEAK void port_wake_main_task(void) {
|
||||||
|
|
@ -42,7 +47,7 @@ MP_WEAK void port_free(void *ptr) {
|
||||||
tlsf_free(heap, ptr);
|
tlsf_free(heap, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_WEAK void *port_realloc(void *ptr, size_t size) {
|
MP_WEAK void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||||
return tlsf_realloc(heap, ptr, size);
|
return tlsf_realloc(heap, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,3 +65,18 @@ MP_WEAK size_t port_heap_get_largest_free_size(void) {
|
||||||
// IDF does this. Not sure why.
|
// IDF does this. Not sure why.
|
||||||
return tlsf_fit_size(heap, max_size);
|
return tlsf_fit_size(heap, max_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MP_WEAK bool port_boot_button_pressed(void) {
|
||||||
|
#if defined(CIRCUITPY_BOOT_BUTTON)
|
||||||
|
// Init/deinit the boot button every time in case it is used for LEDs.
|
||||||
|
digitalio_digitalinout_obj_t boot_button;
|
||||||
|
common_hal_digitalio_digitalinout_construct(&boot_button, CIRCUITPY_BOOT_BUTTON);
|
||||||
|
common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP);
|
||||||
|
common_hal_time_delay_ms(1);
|
||||||
|
bool button_pressed = !common_hal_digitalio_digitalinout_get_value(&boot_button);
|
||||||
|
common_hal_digitalio_digitalinout_deinit(&boot_button);
|
||||||
|
return button_pressed;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,6 @@
|
||||||
|
|
||||||
#include "mphalport.h"
|
#include "mphalport.h"
|
||||||
|
|
||||||
#if defined(CIRCUITPY_BOOT_BUTTON)
|
|
||||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
|
||||||
#include "shared-bindings/time/__init__.h"
|
|
||||||
#endif
|
|
||||||
#include "shared-bindings/microcontroller/Processor.h"
|
#include "shared-bindings/microcontroller/Processor.h"
|
||||||
#include "shared-bindings/microcontroller/ResetReason.h"
|
#include "shared-bindings/microcontroller/ResetReason.h"
|
||||||
|
|
||||||
|
|
@ -78,19 +74,10 @@ safe_mode_t wait_for_safe_mode_reset(void) {
|
||||||
new_status_color(BLACK);
|
new_status_color(BLACK);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Init the boot button every time in case it is used for LEDs.
|
if (port_boot_button_pressed()) {
|
||||||
#ifdef CIRCUITPY_BOOT_BUTTON
|
|
||||||
digitalio_digitalinout_obj_t boot_button;
|
|
||||||
common_hal_digitalio_digitalinout_construct(&boot_button, CIRCUITPY_BOOT_BUTTON);
|
|
||||||
common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP);
|
|
||||||
common_hal_time_delay_ms(1);
|
|
||||||
bool button_pressed = !common_hal_digitalio_digitalinout_get_value(&boot_button);
|
|
||||||
common_hal_digitalio_digitalinout_deinit(&boot_button);
|
|
||||||
if (button_pressed) {
|
|
||||||
boot_in_safe_mode = true;
|
boot_in_safe_mode = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
diff = supervisor_ticks_ms64() - start_ticks;
|
diff = supervisor_ticks_ms64() - start_ticks;
|
||||||
}
|
}
|
||||||
#if CIRCUITPY_STATUS_LED
|
#if CIRCUITPY_STATUS_LED
|
||||||
|
|
@ -142,7 +129,7 @@ void print_safe_mode_message(safe_mode_t reason) {
|
||||||
case SAFE_MODE_USER:
|
case SAFE_MODE_USER:
|
||||||
#if defined(BOARD_USER_SAFE_MODE_ACTION)
|
#if defined(BOARD_USER_SAFE_MODE_ACTION)
|
||||||
message = BOARD_USER_SAFE_MODE_ACTION;
|
message = BOARD_USER_SAFE_MODE_ACTION;
|
||||||
#elif defined(CIRCUITPY_BOOT_BUTTON)
|
#elif defined(CIRCUITPY_BOOT_BUTTON) || CIRCUITPY_BOOT_BUTTON_NO_GPIO
|
||||||
message = MP_ERROR_TEXT("You pressed the BOOT button at start up");
|
message = MP_ERROR_TEXT("You pressed the BOOT button at start up");
|
||||||
#else
|
#else
|
||||||
message = MP_ERROR_TEXT("You pressed the reset button during boot.");
|
message = MP_ERROR_TEXT("You pressed the reset button during boot.");
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
// This file is part of the CircuitPython project: https://circuitpython.org
|
|
||||||
//
|
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2022 Jeff Epler for Adafruit Industries
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
#include "stdbool.h"
|
|
||||||
|
|
||||||
#include "supervisor/port.h"
|
|
||||||
#include "py/mpconfig.h"
|
|
||||||
|
|
||||||
|
|
||||||
MP_WEAK void port_post_boot_py(bool heap_valid) {
|
|
||||||
}
|
|
||||||
|
|
@ -19,7 +19,6 @@ SRC_SUPERVISOR = \
|
||||||
supervisor/shared/traceback.c \
|
supervisor/shared/traceback.c \
|
||||||
supervisor/shared/translate/translate.c \
|
supervisor/shared/translate/translate.c \
|
||||||
supervisor/shared/workflow.c \
|
supervisor/shared/workflow.c \
|
||||||
supervisor/stub/misc.c \
|
|
||||||
|
|
||||||
# For tlsf
|
# For tlsf
|
||||||
CFLAGS += -D_DEBUG=0
|
CFLAGS += -D_DEBUG=0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue