diff --git a/locale/ID.po b/locale/ID.po index 9c96fd3271..ab4f098d6f 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -482,11 +482,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Tidak dapat menginisialisasi UART" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -812,7 +812,7 @@ msgstr "Ukuran buffer tidak valid" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -874,7 +874,11 @@ msgstr "" msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" @@ -1133,7 +1137,7 @@ msgstr "" msgid "SDA or SCL needs a pull up" msgstr "SDA atau SCL membutuhkan pull up" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "" @@ -1206,19 +1210,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1355,10 +1359,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" @@ -1478,7 +1478,7 @@ msgstr "" msgid "bits must be 8" msgstr "bits harus memilki nilai 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -2074,6 +2074,10 @@ msgstr "label didefinis ulang" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 272f081480..a729f7e806 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -472,11 +472,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -797,7 +797,7 @@ msgstr "" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -859,7 +859,11 @@ msgstr "" msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" @@ -1113,7 +1117,7 @@ msgstr "" msgid "SDA or SCL needs a pull up" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "" @@ -1183,19 +1187,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1331,10 +1335,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "" @@ -1445,7 +1445,7 @@ msgstr "" msgid "bits must be 8" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -2040,6 +2040,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 071ec43ab2..1dd23a620b 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Pascal Deneaux\n" "Language-Team: Sebastian Plamauer, Pascal Deneaux\n" @@ -476,11 +476,11 @@ msgstr "Konnte ble_uuid nicht decodieren. Status: 0x%04x" msgid "Could not initialize UART" msgstr "Konnte UART nicht initialisieren" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Konnte first buffer nicht zuteilen" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Konnte second buffer nicht zuteilen" @@ -803,7 +803,7 @@ msgstr "Ungültige Puffergröße" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Ungültige Anzahl von Kanälen" @@ -865,7 +865,11 @@ msgstr "Ungültiger Ausführungsmodus" msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Ungültige Anzahl von Stimmen" @@ -1130,7 +1134,7 @@ msgstr "Sicherheitsmodus aktiv! Gespeicherter Code wird nicht ausgeführt\n" msgid "SDA or SCL needs a pull up" msgstr "SDA oder SCL brauchen pull up" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "Abtastrate muss positiv sein" @@ -1212,19 +1216,19 @@ msgstr "" "Die Reset-Taste wurde beim Booten von CircuitPython gedrückt. Drücke sie " "erneut um den abgesicherten Modus zu verlassen. \n" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1362,10 +1366,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "Viper-Funktionen unterstützen derzeit nicht mehr als 4 Argumente" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "Voice index zu hoch" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "" @@ -1485,7 +1485,7 @@ msgstr "bits muss 7, 8 oder 9 sein" msgid "bits must be 8" msgstr "bits müssen 8 sein" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "Es müssen 8 oder 16 bits_per_sample sein" @@ -2085,6 +2085,10 @@ msgstr "Label neu definiert" msgid "length argument not allowed for this type" msgstr "Für diesen Typ ist length nicht zulässig" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs und rhs sollten kompatibel sein" @@ -2915,6 +2919,9 @@ msgstr "" #~ msgstr "" #~ "Benutze das esptool um den flash zu löschen und Python erneut hochzuladen" +#~ msgid "Voice index too high" +#~ msgstr "Voice index zu hoch" + #~ msgid "buffer too long" #~ msgstr "Buffer zu lang" diff --git a/locale/en_US.po b/locale/en_US.po index e5425cbfc9..7678fd1f55 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -472,11 +472,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -797,7 +797,7 @@ msgstr "" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -859,7 +859,11 @@ msgstr "" msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" @@ -1113,7 +1117,7 @@ msgstr "" msgid "SDA or SCL needs a pull up" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "" @@ -1183,19 +1187,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1331,10 +1335,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "" @@ -1445,7 +1445,7 @@ msgstr "" msgid "bits must be 8" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -2040,6 +2040,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index 7db72248b6..f1e49449aa 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: @sommersoft, @MrCertainly\n" @@ -476,11 +476,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "" @@ -801,7 +801,7 @@ msgstr "" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "" @@ -863,7 +863,11 @@ msgstr "" msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "" @@ -1117,7 +1121,7 @@ msgstr "Runnin' in safe mode! Nay runnin' saved code.\n" msgid "SDA or SCL needs a pull up" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "" @@ -1187,19 +1191,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1335,10 +1339,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "Blimey! Yer code filename has two extensions\n" @@ -1449,7 +1449,7 @@ msgstr "" msgid "bits must be 8" msgstr "pieces must be of 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "" @@ -2044,6 +2044,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" diff --git a/locale/es.po b/locale/es.po index bcb0515596..fda00ed6c1 100644 --- a/locale/es.po +++ b/locale/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -480,11 +480,11 @@ msgstr "No se puede descodificar ble_uuid, err 0x%04x" msgid "Could not initialize UART" msgstr "No se puede inicializar la UART" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "No se pudo asignar el primer buffer" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "No se pudo asignar el segundo buffer" @@ -808,7 +808,7 @@ msgstr "Tamaño de buffer inválido" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "Inválido periodo de captura. Rango válido: 1 - 500" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Cuenta de canales inválida" @@ -870,7 +870,11 @@ msgstr "Modo de ejecución inválido." msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Cuenta de voces inválida" @@ -1139,7 +1143,7 @@ msgstr "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA o SCL necesitan una pull up" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "Sample rate debe ser positivo" @@ -1221,19 +1225,19 @@ msgstr "" "El botón reset fue presionado mientras arrancaba CircuitPython. Presiona " "otra vez para salir del modo seguro.\n" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "Los bits_per_sample del sample no igualan a los del mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "La cuenta de canales del sample no iguala a las del mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "El sample rate del sample no iguala al del mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "El signo del sample no iguala al del mixer" @@ -1370,10 +1374,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "funciones Viper actualmente no soportan más de 4 argumentos." -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "Index de voz demasiado alto" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "ADVERTENCIA: El nombre de archivo de tu código tiene dos extensiones\n" @@ -1492,7 +1492,7 @@ msgstr "bits deben ser 7, 8 ó 9" msgid "bits must be 8" msgstr "bits debe ser 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample debe ser 8 ó 16" @@ -2097,6 +2097,10 @@ msgstr "etiqueta redefinida" msgid "length argument not allowed for this type" msgstr "argumento length no permitido para este tipo" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs y rhs deben ser compatibles" @@ -2946,6 +2950,9 @@ msgstr "paso cero" #~ msgstr "" #~ "Usa esptool para borrar la flash y vuelve a cargar Python en su lugar" +#~ msgid "Voice index too high" +#~ msgstr "Index de voz demasiado alto" + #~ msgid "bad GATT role" #~ msgstr "mal GATT role" diff --git a/locale/fil.po b/locale/fil.po index 3e8041e6de..65c94c854b 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2018-12-20 22:15-0800\n" "Last-Translator: Timothy \n" "Language-Team: fil\n" @@ -481,11 +481,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Hindi ma-initialize ang UART" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Hindi ma-iallocate ang first buffer" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Hindi ma-iallocate ang second buffer" @@ -817,7 +817,7 @@ msgstr "Mali ang buffer size" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Maling bilang ng channel" @@ -879,7 +879,11 @@ msgstr "Mali ang run mode." msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Maling bilang ng voice" @@ -1146,7 +1150,7 @@ msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n" msgid "SDA or SCL needs a pull up" msgstr "Kailangan ng pull up resistors ang SDA o SCL" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "Sample rate ay dapat positibo" @@ -1226,19 +1230,19 @@ msgstr "" "Ang reset button ay pinindot habang nag boot ang CircuitPython. Pindutin " "ulit para lumabas sa safe mode.\n" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "Ang bits_per_sample ng sample ay hindi tugma sa mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "Ang channel count ng sample ay hindi tugma sa mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "Ang sample rate ng sample ay hindi tugma sa mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "Ang signedness ng sample hindi tugma sa mixer" @@ -1378,10 +1382,6 @@ msgstr "" "Ang mga function ng Viper ay kasalukuyang hindi sumusuporta sa higit sa 4 na " "argumento" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "Index ng Voice ay masyadong mataas" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "BABALA: Ang pangalan ng file ay may dalawang extension\n" @@ -1498,7 +1498,7 @@ msgstr "bits ay dapat 7, 8 o 9" msgid "bits must be 8" msgstr "bits ay dapat walo (8)" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample ay dapat 8 o 16" @@ -2110,6 +2110,10 @@ msgstr "ang label ay na-define ulit" msgid "length argument not allowed for this type" msgstr "length argument ay walang pahintulot sa ganitong type" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs at rhs ay dapat magkasundo" @@ -2935,6 +2939,9 @@ msgstr "zero step" #~ msgstr "" #~ "Gamitin ang esptool upang burahin ang flash at muling i-upload ang Python" +#~ msgid "Voice index too high" +#~ msgstr "Index ng Voice ay masyadong mataas" + #~ msgid "[addrinfo error %d]" #~ msgstr "[addrinfo error %d]" diff --git a/locale/fr.po b/locale/fr.po index f8345bcee7..9363f6e61f 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2019-04-14 20:05+0100\n" "Last-Translator: Pierrick Couturier \n" "Language-Team: fr\n" @@ -487,11 +487,11 @@ msgstr "Impossible de décoder le 'ble_uuid', err 0x%04x" msgid "Could not initialize UART" msgstr "L'UART n'a pu être initialisé" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Impossible d'allouer le 1er tampon" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Impossible d'allouer le 2e tampon" @@ -824,7 +824,7 @@ msgstr "Longueur de tampon invalide" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "Période de capture invalide. Gamme valide: 1 à 500" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid channel count" msgstr "Nombre de canaux invalide" @@ -887,7 +887,11 @@ msgstr "Mode de lancement invalide." msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid voice count" msgstr "Nombre de voix invalide" @@ -1161,7 +1165,7 @@ msgstr "Mode sans-échec! Le code sauvegardé n'est pas éxecuté.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA ou SCL a besoin d'une résistance de tirage ('pull up')" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Sample rate must be positive" msgstr "Le taux d'échantillonage doit être positif" @@ -1245,20 +1249,20 @@ msgstr "" "Le bouton 'reset' a été appuyé pendant le démarrage de CircuitPython. " "Appuyer de nouveau pour quitter de le mode sans-échec.\n" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" "Le 'bits_per_sample' de l'échantillon ne correspond pas à celui du mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "Le canal de l'échantillon ne correspond pas à celui du mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "L'échantillonage de l'échantillon ne correspond pas à celui du mixer" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer" @@ -1401,10 +1405,6 @@ msgid "Viper functions don't currently support more than 4 arguments" msgstr "" "les fonctions de Viper ne supportent pas plus de 4 arguments actuellement" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "Index de la voix trop grand" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "ATTENTION: le nom de fichier de votre code a deux extensions\n" @@ -1522,7 +1522,7 @@ msgstr "bits doivent être 7, 8 ou 9" msgid "bits must be 8" msgstr "les bits doivent être 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "'bits_per_sample' doivent être 8 ou 16" @@ -2142,6 +2142,10 @@ msgstr "label redéfini" msgid "length argument not allowed for this type" msgstr "argument 'length' non-permis pour ce type" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "Les parties gauches et droites doivent être compatibles" @@ -2998,6 +3002,9 @@ msgstr "'step' nul" #~ msgstr "" #~ "Utilisez 'esptool' pour effacer la flash et recharger Python à la place" +#~ msgid "Voice index too high" +#~ msgstr "Index de la voix trop grand" + #~ msgid "bad GATT role" #~ msgstr "mauvais rôle GATT" diff --git a/locale/it_IT.po b/locale/it_IT.po index 1b48a73066..3dc308111e 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin \n" "Language-Team: \n" @@ -482,11 +482,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Impossibile inizializzare l'UART" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Impossibile allocare il primo buffer" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Impossibile allocare il secondo buffer" @@ -817,7 +817,7 @@ msgstr "lunghezza del buffer non valida" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "periodo di cattura invalido. Zona valida: 1 - 500" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid channel count" msgstr "Argomento non valido" @@ -880,7 +880,11 @@ msgstr "Modalità di esecuzione non valida." msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid voice count" msgstr "Tipo di servizio non valido" @@ -1150,7 +1154,7 @@ msgstr "Modalità sicura in esecuzione! Codice salvato non in esecuzione.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA o SCL necessitano un pull-up" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Sample rate must be positive" msgstr "STA deve essere attiva" @@ -1225,19 +1229,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1375,10 +1379,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "ATTENZIONE: Il nome del sorgente ha due estensioni\n" @@ -1492,7 +1492,7 @@ msgstr "i bit devono essere 7, 8 o 9" msgid "bits must be 8" msgstr "i bit devono essere 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "i bit devono essere 7, 8 o 9" @@ -2103,6 +2103,10 @@ msgstr "etichetta ridefinita" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs e rhs devono essere compatibili" diff --git a/locale/pl.po b/locale/pl.po index c1444c1dd9..f879157182 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2019-03-19 18:37-0700\n" "Last-Translator: Radomir Dopieralski \n" "Language-Team: pl\n" @@ -475,11 +475,11 @@ msgstr "Nie można zdekodować ble_uuid, błąd 0x%04x" msgid "Could not initialize UART" msgstr "Ustawienie UART nie powiodło się" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Nie udała się alokacja pierwszego bufora" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Nie udała się alokacja drugiego bufora" @@ -802,7 +802,7 @@ msgstr "Zła wielkość bufora" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "Zły okres. Poprawny zakres to: 1 - 500" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Zła liczba kanałów" @@ -864,7 +864,11 @@ msgstr "Zły tryb uruchomienia" msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Zła liczba głosów" @@ -1123,7 +1127,7 @@ msgstr "Uruchomiony tryb bezpieczeństwa! Zapisany kod nie jest uruchamiany.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA lub SCL wymagają podciągnięcia" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "Częstotliwość próbkowania musi być dodatnia" @@ -1203,19 +1207,19 @@ msgstr "" "Przycisk reset został wciśnięty podczas startu CircuitPythona. Wciśnij go " "ponownie aby wyjść z trybu bezpieczeństwa.\n" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "Wartość bits_per_sample nie pasuje do miksera" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "Liczba kanałów nie pasuje do miksera " -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "Sample rate nie pasuje do miksera" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "Znak nie pasuje do miksera" @@ -1351,10 +1355,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "Funkcje Viper nie obsługują obecnie więcej niż 4 argumentów" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "Zbyt wysoki indeks głosu" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "UWAGA: Nazwa pliku ma dwa rozszerzenia\n" @@ -1469,7 +1469,7 @@ msgstr "bits musi być 7, 8 lub 9" msgid "bits must be 8" msgstr "bits musi być 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample musi być 8 lub 16" @@ -2065,6 +2065,10 @@ msgstr "etykieta przedefiniowana" msgid "length argument not allowed for this type" msgstr "ten typ nie pozawala na podanie długości" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lewa i prawa strona powinny być kompatybilne" @@ -2788,6 +2792,9 @@ msgstr "zerowy krok" #~ msgid "UUID integer value not in range 0 to 0xffff" #~ msgstr "Wartość UUID poza zakresem 0 do 0xffff" +#~ msgid "Voice index too high" +#~ msgstr "Zbyt wysoki indeks głosu" + #~ msgid "bad GATT role" #~ msgstr "zła rola GATT" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index a697947d99..b6b7415d8f 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -478,11 +478,11 @@ msgstr "" msgid "Could not initialize UART" msgstr "Não foi possível inicializar o UART" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Não pôde alocar primeiro buffer" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Não pôde alocar segundo buffer" @@ -810,7 +810,7 @@ msgstr "Arquivo inválido" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid channel count" msgstr "certificado inválido" @@ -873,7 +873,11 @@ msgstr "" msgid "Invalid security_mode" msgstr "" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "Invalid voice count" msgstr "certificado inválido" @@ -1133,7 +1137,7 @@ msgstr "Rodando em modo seguro! Não está executando o código salvo.\n" msgid "SDA or SCL needs a pull up" msgstr "SDA ou SCL precisa de um pull up" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "" @@ -1203,19 +1207,19 @@ msgid "" "exit safe mode.\n" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "" @@ -1352,10 +1356,6 @@ msgstr "" msgid "Viper functions don't currently support more than 4 arguments" msgstr "" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "AVISO: Seu arquivo de código tem duas extensões\n" @@ -1466,7 +1466,7 @@ msgstr "" msgid "bits must be 8" msgstr "bits devem ser 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "bits_per_sample must be 8 or 16" msgstr "bits devem ser 8" @@ -2065,6 +2065,10 @@ msgstr "" msgid "length argument not allowed for this type" msgstr "" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 62ea567412..c20572038f 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-29 18:48-0400\n" +"POT-Creation-Date: 2019-08-29 22:16-0500\n" "PO-Revision-Date: 2019-04-13 10:10-0700\n" "Last-Translator: hexthat\n" "Language-Team: Chinese Hanyu Pinyin\n" @@ -476,11 +476,11 @@ msgstr "Wúfǎ jiěmǎ kě dú_uuid, err 0x%04x" msgid "Could not initialize UART" msgstr "Wúfǎ chūshǐhuà UART" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate first buffer" msgstr "Wúfǎ fēnpèi dì yī gè huǎnchōng qū" -#: shared-module/audiocore/Mixer.c shared-module/audiocore/WaveFile.c +#: shared-module/audiocore/WaveFile.c shared-module/audiomixer/Mixer.c msgid "Couldn't allocate second buffer" msgstr "Wúfǎ fēnpèi dì èr gè huǎnchōng qū" @@ -803,7 +803,7 @@ msgstr "Wúxiào de huǎnchōng qū dàxiǎo" msgid "Invalid capture period. Valid range: 1 - 500" msgstr "Wúxiào de bǔhuò zhōuqí. Yǒuxiào fànwéi: 1-500" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid channel count" msgstr "Wúxiào de tōngdào jìshù" @@ -865,7 +865,11 @@ msgstr "Wúxiào de yùnxíng móshì." msgid "Invalid security_mode" msgstr "Ānquán móshì wúxiào" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c +msgid "Invalid voice" +msgstr "" + +#: shared-bindings/audiomixer/Mixer.c msgid "Invalid voice count" msgstr "Wúxiào de yǔyīn jìshù" @@ -1127,7 +1131,7 @@ msgstr "Zài ānquán móshì xià yùnxíng! Bù yùnxíng yǐ bǎocún de dài msgid "SDA or SCL needs a pull up" msgstr "SDA huò SCL xūyào lādòng" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "Sample rate must be positive" msgstr "Cǎiyàng lǜ bìxū wèi zhèng shù" @@ -1209,19 +1213,19 @@ msgstr "" "Qǐdòng CircuitPython shí, chóng zhì ànniǔ bèi àn xià. Zàicì àn xià yǐ tuìchū " "ānquán móshì\n" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's bits_per_sample does not match the mixer's" msgstr "Yàngběn de bits_per_sample yǔ hǔn yīn qì bù pǐpèi" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's channel count does not match the mixer's" msgstr "Yàngběn de píndào jìshù yǔ hǔn yīn qì bù xiāngfú" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's sample rate does not match the mixer's" msgstr "Yàngběn de yàngběn sùdù yǔ hǔn yīn qì de xiāngchà bù pǐpèi" -#: shared-module/audiocore/Mixer.c +#: shared-module/audiomixer/MixerVoice.c msgid "The sample's signedness does not match the mixer's" msgstr "Yàngběn de qiānmíng yǔ hǔn yīn qì de qiānmíng bù pǐpèi" @@ -1357,10 +1361,6 @@ msgstr "Zhí chángdù > zuìdà chángdù" msgid "Viper functions don't currently support more than 4 arguments" msgstr "Viper hánshù mùqián bù zhīchí chāoguò 4 gè cānshù" -#: shared-module/audiocore/Mixer.c -msgid "Voice index too high" -msgstr "Yǔyīn suǒyǐn tài gāo" - #: main.c msgid "WARNING: Your code filename has two extensions\n" msgstr "Jǐnggào: Nǐ de dàimǎ wénjiàn míng yǒu liǎng gè kuòzhǎn míng\n" @@ -1478,7 +1478,7 @@ msgstr "bǐtè bìxū shì 7,8 huò 9" msgid "bits must be 8" msgstr "bǐtè bìxū shì 8" -#: shared-bindings/audiocore/Mixer.c +#: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "měi jiàn yàngběn bìxū wèi 8 huò 16" @@ -2077,6 +2077,10 @@ msgstr "biāoqiān chóngxīn dìngyì" msgid "length argument not allowed for this type" msgstr "bù yǔnxǔ gāi lèixíng de chángdù cānshù" +#: shared-bindings/audiomixer/MixerVoice.c +msgid "level must be between 0 and 1" +msgstr "" + #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs hé rhs yīnggāi jiānróng" @@ -2817,6 +2821,9 @@ msgstr "líng bù" #~ msgid "UUID integer value not in range 0 to 0xffff" #~ msgstr "UUID zhěngshù zhí bùzài fànwéi 0 zhì 0xffff" +#~ msgid "Voice index too high" +#~ msgstr "Yǔyīn suǒyǐn tài gāo" + #~ msgid "bad GATT role" #~ msgstr "zǒng xiédìng de bùliáng juésè" diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index af33edb0eb..df0f4b8831 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -17,6 +17,7 @@ endif # Put samd21-only choices here. ifeq ($(CHIP_FAMILY),samd21) # frequencyio not yet verified as working on SAMD21. +CIRCUITPY_AUDIOMIXER = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_TOUCHIO_USE_NATIVE = 1 endif diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 55920b3f4a..02bde3effa 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -13,6 +13,7 @@ LONGINT_IMPL = MPZ # Audio via PWM CIRCUITPY_AUDIOCORE = 1 CIRCUITPY_AUDIOIO = 0 +CIRCUITPY_AUDIOMIXER = 1 CIRCUITPY_AUDIOPWMIO = 1 CIRCUITPY_AUDIOBUSIO = 1 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index b17c312f7b..b72d753904 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -114,6 +114,9 @@ endif ifeq ($(CIRCUITPY_AUDIOCORE),1) SRC_PATTERNS += audiocore/% endif +ifeq ($(CIRCUITPY_AUDIOMIXER),1) +SRC_PATTERNS += audiomixer/% +endif ifeq ($(CIRCUITPY_BITBANGIO),1) SRC_PATTERNS += bitbangio/% endif @@ -312,9 +315,11 @@ SRC_SHARED_MODULE_ALL = \ audiopwmio/__init__.c \ audioio/__init__.c \ audiocore/__init__.c \ - audiocore/Mixer.c \ audiocore/RawSample.c \ audiocore/WaveFile.c \ + audiomixer/__init__.c \ + audiomixer/Mixer.c \ + audiomixer/MixerVoice.c \ bitbangio/I2C.c \ bitbangio/OneWire.c \ bitbangio/SPI.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 5ac66665a4..2cb6178198 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -244,6 +244,13 @@ extern const struct _mp_obj_module_t audioio_module; #define AUDIOIO_MODULE #endif +#if CIRCUITPY_AUDIOMIXER +#define AUDIOMIXER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiomixer), (mp_obj_t)&audiomixer_module }, +extern const struct _mp_obj_module_t audiomixer_module; +#else +#define AUDIOMIXER_MODULE +#endif + #if CIRCUITPY_AUDIOPWMIO #define AUDIOPWMIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_audiopwmio), (mp_obj_t)&audiopwmio_module }, extern const struct _mp_obj_module_t audiopwmio_module; @@ -573,6 +580,7 @@ extern const struct _mp_obj_module_t ustack_module; AUDIOBUSIO_MODULE \ AUDIOCORE_MODULE \ AUDIOIO_MODULE \ + AUDIOMIXER_MODULE \ AUDIOPWMIO_MODULE \ BITBANGIO_MODULE \ BLEIO_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 1af71a4162..c5756f4880 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -94,6 +94,11 @@ endif endif CFLAGS += -DCIRCUITPY_AUDIOCORE=$(CIRCUITPY_AUDIOCORE) +ifndef CIRCUITPY_AUDIOMIXER +CIRCUITPY_AUDIOMIXER = $(CIRCUITPY_AUDIOIO) +endif +CFLAGS += -DCIRCUITPY_AUDIOMIXER=$(CIRCUITPY_AUDIOMIXER) + ifndef CIRCUITPY_BITBANGIO CIRCUITPY_BITBANGIO = $(CIRCUITPY_FULL_BUILD) endif diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 9bce9c7609..2cd2b67289 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -164,7 +164,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4, //| Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`. //| //| The sample itself should consist of 8 bit or 16 bit samples. //| diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c index c64759d4ff..cf05112cb7 100644 --- a/shared-bindings/audiocore/__init__.c +++ b/shared-bindings/audiocore/__init__.c @@ -31,9 +31,9 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/audiocore/__init__.h" -#include "shared-bindings/audiocore/Mixer.h" #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" +//#include "shared-bindings/audiomixer/Mixer.h" //| :mod:`audiocore` --- Support for audio samples and mixer //| ======================================================== @@ -49,14 +49,12 @@ //| .. toctree:: //| :maxdepth: 3 //| -//| Mixer //| RawSample //| WaveFile //| STATIC const mp_rom_map_elem_t audiocore_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiocore) }, - { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) }, { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) }, { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) }, }; diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index af2fce48e3..eb4ef1fc6c 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -163,7 +163,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, //| Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`. //| //| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output //| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c index bd771dda2e..7fa37d5c51 100644 --- a/shared-bindings/audioio/__init__.c +++ b/shared-bindings/audioio/__init__.c @@ -33,11 +33,14 @@ #include "shared-bindings/audioio/__init__.h" #include "shared-bindings/audioio/AudioOut.h" -#ifdef CIRCUITPY_AUDIOIO_COMPAT -#include "shared-bindings/audiocore/Mixer.h" +#if CIRCUITPY_AUDIOIO_COMPAT +#include "shared-bindings/audiomixer/Mixer.h" #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" #endif +#if CIRCUITPY_AUDIOMIXER +#include "shared-bindings/audiomixer/Mixer.h" +#endif //| :mod:`audioio` --- Support for audio input and output //| ====================================================== @@ -60,8 +63,8 @@ //| call :py:meth:`!deinit` or use a context manager. See //| :ref:`lifetime-and-contextmanagers` for more info. //| -//| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved -//| to :mod:`audiocore`. +//| Since CircuitPython 5, `RawSample` and `WaveFile` are moved +//| to :mod:`audiocore`, and `Mixer` is moved to :mod:`audiomixer`. //| //| For compatibility with CircuitPython 4.x, some builds allow the items in //| `audiocore` to be imported from `audioio`. This will be removed for all @@ -71,8 +74,10 @@ STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) }, { MP_ROM_QSTR(MP_QSTR_AudioOut), MP_ROM_PTR(&audioio_audioout_type) }, -#ifdef CIRCUITPY_AUDIOIO_COMPAT - { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) }, +#if CIRCUITPY_AUDIOIO_COMPAT + #if CIRCUITPY_AUDIOMIXER + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audiomixer_mixer_type) }, + #endif { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) }, { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) }, #endif diff --git a/shared-bindings/audiocore/Mixer.c b/shared-bindings/audiomixer/Mixer.c similarity index 52% rename from shared-bindings/audiocore/Mixer.c rename to shared-bindings/audiomixer/Mixer.c index 9ab720434b..ed7b95d9e0 100644 --- a/shared-bindings/audiocore/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -23,7 +23,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "shared-bindings/audiocore/Mixer.h" +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-bindings/audiomixer/MixerVoice.h" +#include "shared-module/audiomixer/MixerVoice.h" #include @@ -36,45 +38,51 @@ #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" -//| .. currentmodule:: audiocore +//| .. currentmodule:: audiomixer //| //| :class:`Mixer` -- Mixes one or more audio samples together //| =========================================================== //| //| Mixer mixes multiple samples into one sample. //| -//| .. class:: Mixer(channel_count=2, buffer_size=1024) +//| .. class:: Mixer(voice_count=2, buffer_size=1024, channel_count=2, bits_per_sample=16, samples_signed=True, sample_rate=8000) //| //| Create a Mixer object that can mix multiple channels with the same sample rate. +//| Samples are accessed and controlled with the mixer's `audiomixer.MixerVoice` objects. //| -//| :param int channel_count: The maximum number of samples to mix at once +//| :param int voice_count: The maximum number of voices to mix //| :param int buffer_size: The total size in bytes of the buffers to mix into +//| :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 samples being played +//| :param bool samples_signed: Samples are signed (True) or unsigned (False) +//| :param int sample_rate: The sample rate to be used for all samples //| //| Playing a wave file from flash:: //| //| import board //| import audioio //| import audiocore +//| import audiomixer //| import digitalio //| -//| # Required for CircuitPlayground Express -//| speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) -//| speaker_enable.switch_to_output(value=True) -//| +//| a = audioio.AudioOut(board.A0) //| music = audiocore.WaveFile(open("cplay-5.1-16bit-16khz.wav", "rb")) //| drum = audiocore.WaveFile(open("drum.wav", "rb")) -//| mixer = audiocore.Mixer(voice_count=2, sample_rate=16000, channel_count=1, bits_per_sample=16, samples_signed=True) -//| a = audioio.AudioOut(board.A0) +//| mixer = audiomixer.Mixer(voice_count=2, sample_rate=16000, channel_count=1, +//| bits_per_sample=16, samples_signed=True) //| //| print("playing") +//| # Have AudioOut play our Mixer source //| a.play(mixer) -//| mixer.play(music, voice=0) +//| # Play the first sample voice +//| mixer.voice[0].play(music) //| while mixer.playing: -//| mixer.play(drum, voice=1) +//| # Play the second sample voice +//| mixer.voice[1].play(drum) //| time.sleep(1) //| print("stopped") //| -STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { { MP_QSTR_voice_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 2} }, @@ -104,9 +112,15 @@ STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, if (bits_per_sample != 8 && bits_per_sample != 16) { mp_raise_ValueError(translate("bits_per_sample must be 8 or 16")); } - audioio_mixer_obj_t *self = m_new_obj_var(audioio_mixer_obj_t, audioio_mixer_voice_t, voice_count); - self->base.type = &audioio_mixer_type; - common_hal_audioio_mixer_construct(self, voice_count, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + audiomixer_mixer_obj_t *self = m_new_obj_var(audiomixer_mixer_obj_t, mp_obj_t, voice_count); + self->base.type = &audiomixer_mixer_type; + common_hal_audiomixer_mixer_construct(self, voice_count, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + for(int v=0; vvoice[v] = audiomixer_mixervoice_type.make_new(&audiomixer_mixervoice_type, 0, 0, NULL); + common_hal_audiomixer_mixervoice_set_parent(self->voice[v], self); + } + self->voice_tuple = mp_obj_new_tuple(self->voice_count, self->voice); return MP_OBJ_FROM_PTR(self); } @@ -115,15 +129,15 @@ STATIC mp_obj_t audioio_mixer_make_new(const mp_obj_type_t *type, size_t n_args, //| //| Deinitialises the Mixer and releases any hardware resources for reuse. //| -STATIC mp_obj_t audioio_mixer_deinit(mp_obj_t self_in) { - audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_audioio_mixer_deinit(self); +STATIC mp_obj_t audiomixer_mixer_deinit(mp_obj_t self_in) { + audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiomixer_mixer_deinit(self); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_deinit_obj, audioio_mixer_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_deinit_obj, audiomixer_mixer_deinit); -STATIC void check_for_deinit(audioio_mixer_obj_t *self) { - if (common_hal_audioio_mixer_deinited(self)) { +STATIC void check_for_deinit(audiomixer_mixer_obj_t *self) { + if (common_hal_audiomixer_mixer_deinited(self)) { raise_deinited_error(); } } @@ -139,75 +153,27 @@ STATIC void check_for_deinit(audioio_mixer_obj_t *self) { //| Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info. //| -STATIC mp_obj_t audioio_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t audiomixer_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; - common_hal_audioio_mixer_deinit(args[0]); + common_hal_audiomixer_mixer_deinit(args[0]); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_mixer___exit___obj, 4, 4, audioio_mixer_obj___exit__); - - -//| .. method:: play(sample, *, voice=0, loop=False) -//| -//| Plays the sample once when loop=False and continuously when loop=True. -//| Does not block. Use `playing` to block. -//| -//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. -//| -//| The sample must match the Mixer's encoding settings given in the constructor. -//| -STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_sample, ARG_voice, ARG_loop }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_voice, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, - { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, - }; - audioio_mixer_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_audioio_mixer_play(self, sample, args[ARG_voice].u_int, args[ARG_loop].u_bool); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_play_obj, 1, audioio_mixer_obj_play); - -//| .. method:: stop_voice(voice=0) -//| -//| Stops playback of the sample on the given voice. -//| -STATIC mp_obj_t audioio_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_voice }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} }, - }; - audioio_mixer_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); - - common_hal_audioio_mixer_stop_voice(self, args[ARG_voice].u_int); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_voice_obj, 1, audioio_mixer_obj_stop_voice); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomixer_mixer___exit___obj, 4, 4, audiomixer_mixer_obj___exit__); //| .. attribute:: playing //| //| True when any voice is being output. (read-only) //| -STATIC mp_obj_t audioio_mixer_obj_get_playing(mp_obj_t self_in) { - audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t audiomixer_mixer_obj_get_playing(mp_obj_t self_in) { + audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - return mp_obj_new_bool(common_hal_audioio_mixer_get_playing(self)); + return mp_obj_new_bool(common_hal_audiomixer_mixer_get_playing(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_playing_obj, audioio_mixer_obj_get_playing); +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_playing_obj, audiomixer_mixer_obj_get_playing); -const mp_obj_property_t audioio_mixer_playing_obj = { +const mp_obj_property_t audiomixer_mixer_playing_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&audioio_mixer_get_playing_obj, + .proxy = {(mp_obj_t)&audiomixer_mixer_get_playing_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; @@ -216,38 +182,118 @@ const mp_obj_property_t audioio_mixer_playing_obj = { //| //| 32 bit value that dictates how quickly samples are played in Hertz (cycles per second). //| -STATIC mp_obj_t audioio_mixer_obj_get_sample_rate(mp_obj_t self_in) { - audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t audiomixer_mixer_obj_get_sample_rate(mp_obj_t self_in) { + audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_mixer_get_sample_rate(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_audiomixer_mixer_get_sample_rate(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_sample_rate_obj, audioio_mixer_obj_get_sample_rate); +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_sample_rate_obj, audiomixer_mixer_obj_get_sample_rate); - -const mp_obj_property_t audioio_mixer_sample_rate_obj = { +const mp_obj_property_t audiomixer_mixer_sample_rate_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&audioio_mixer_get_sample_rate_obj, + .proxy = {(mp_obj_t)&audiomixer_mixer_get_sample_rate_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; -STATIC const mp_rom_map_elem_t audioio_mixer_locals_dict_table[] = { +//| .. attribute:: voice +//| +//| A tuple of the mixer's `audiomixer.MixerVoice` object(s). +//| +//| .. code-block:: python +//| +//| >>> mixer.voice +//| (,) +STATIC mp_obj_t audiomixer_mixer_obj_get_voice(mp_obj_t self_in) { + audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return self->voice_tuple; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_voice_obj, audiomixer_mixer_obj_get_voice); + +const mp_obj_property_t audiomixer_mixer_voice_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiomixer_mixer_get_voice_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: play(sample, *, voice=0, loop=False) +//| +//| Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`. +//| +//| The sample must match the Mixer's encoding settings given in the constructor. +//| +STATIC mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_voice, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_voice, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiomixer_mixer_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); + + uint8_t v = args[ARG_voice].u_int; + if (v > (self->voice_count - 1)) { + mp_raise_ValueError(translate("Invalid voice")); + } + audiomixer_mixervoice_obj_t *voice = MP_OBJ_TO_PTR(self->voice[v]); + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiomixer_mixervoice_play(voice, sample, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play); + +//| .. method:: stop_voice(voice=0) +//| +//| Stops playback of the sample on the given voice. +//| +STATIC mp_obj_t audiomixer_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_voice }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} }, + }; + audiomixer_mixer_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); + + uint8_t v = args[ARG_voice].u_int; + if (v > (self->voice_count - 1)) { + mp_raise_ValueError(translate("Invalid voice")); + } + audiomixer_mixervoice_obj_t *voice = MP_OBJ_TO_PTR(self->voice[v]); + common_hal_audiomixer_mixervoice_stop(voice); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_stop_voice_obj, 1, audiomixer_mixer_obj_stop_voice); + + +STATIC const mp_rom_map_elem_t audiomixer_mixer_locals_dict_table[] = { // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_mixer_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiomixer_mixer_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_mixer___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audioio_mixer_play_obj) }, - { MP_ROM_QSTR(MP_QSTR_stop_voice), MP_ROM_PTR(&audioio_mixer_stop_voice_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiomixer_mixer___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiomixer_mixer_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_voice), MP_ROM_PTR(&audiomixer_mixer_stop_voice_obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audioio_mixer_playing_obj) }, - { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_mixer_sample_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiomixer_mixer_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiomixer_mixer_sample_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_voice), MP_ROM_PTR(&audiomixer_mixer_voice_obj) } }; -STATIC MP_DEFINE_CONST_DICT(audioio_mixer_locals_dict, audioio_mixer_locals_dict_table); +STATIC MP_DEFINE_CONST_DICT(audiomixer_mixer_locals_dict, audiomixer_mixer_locals_dict_table); -const mp_obj_type_t audioio_mixer_type = { +const mp_obj_type_t audiomixer_mixer_type = { { &mp_type_type }, .name = MP_QSTR_Mixer, - .make_new = audioio_mixer_make_new, - .locals_dict = (mp_obj_dict_t*)&audioio_mixer_locals_dict, + .make_new = audiomixer_mixer_make_new, + .locals_dict = (mp_obj_dict_t*)&audiomixer_mixer_locals_dict, }; diff --git a/shared-bindings/audiocore/Mixer.h b/shared-bindings/audiomixer/Mixer.h similarity index 53% rename from shared-bindings/audiocore/Mixer.h rename to shared-bindings/audiomixer/Mixer.h index ef12f9a701..9eabbf61df 100644 --- a/shared-bindings/audiocore/Mixer.h +++ b/shared-bindings/audiomixer/Mixer.h @@ -24,29 +24,28 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H #include "common-hal/microcontroller/Pin.h" -#include "shared-module/audiocore/Mixer.h" +#include "shared-module/audiomixer/Mixer.h" #include "shared-bindings/audiocore/RawSample.h" -extern const mp_obj_type_t audioio_mixer_type; +extern const mp_obj_type_t audiomixer_mixer_type; +extern const mp_obj_type_t audiomixer_mixervoice_type; -void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, - uint8_t voice_count, - uint32_t buffer_size, - uint8_t bits_per_sample, - bool samples_signed, - uint8_t channel_count, - uint32_t sample_rate); +void common_hal_audiomixer_mixer_construct(audiomixer_mixer_obj_t* self, + uint8_t voice_count, + uint32_t buffer_size, + uint8_t bits_per_sample, + bool samples_signed, + uint8_t channel_count, + uint32_t sample_rate); -void common_hal_audioio_mixer_deinit(audioio_mixer_obj_t* self); -bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self); -void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, uint8_t voice, bool loop); -void common_hal_audioio_mixer_stop_voice(audioio_mixer_obj_t* self, uint8_t voice); +void common_hal_audiomixer_mixer_deinit(audiomixer_mixer_obj_t* self); +bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t* self); -bool common_hal_audioio_mixer_get_playing(audioio_mixer_obj_t* self); -uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self); +bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self); +uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* self); -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER_MIXER_H diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c new file mode 100644 index 0000000000..188f76f579 --- /dev/null +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -0,0 +1,178 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-bindings/audiomixer/MixerVoice.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: audiomixer +//| +//| :class:`MixerVoice` -- Voice objects used with Mixer +//| ===================================================== +//| +//| Used to access and control samples with `audiomixer.Mixer`. +//| +//| .. class:: MixerVoice() +//| +//| MixerVoice instance object(s) created by `audiomixer.Mixer`. +//| +// TODO: support mono or stereo voices +STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + audiomixer_mixervoice_obj_t *self = m_new_obj(audiomixer_mixervoice_obj_t); + self->base.type = &audiomixer_mixervoice_type; + + common_hal_audiomixer_mixervoice_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: play(sample, *, loop=False) +//| +//| Plays the sample once when ``loop=False``, and continuously when ``loop=True``. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiomixer.Mixer` or `audiocore.RawSample`. +//| +//| The sample must match the `audiomixer.Mixer`'s encoding settings given in the constructor. +//| +STATIC mp_obj_t audiomixer_mixervoice_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} }, + }; + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + 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_audiomixer_mixervoice_play(self, sample, args[ARG_loop].u_bool); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_play_obj, 1, audiomixer_mixervoice_obj_play); + +//| .. method:: stop() +//| +//| Stops playback of the sample on this voice. +//| +STATIC mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_voice }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} }, + }; + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + 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); + + common_hal_audiomixer_mixervoice_stop(self); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervoice_obj_stop); + +//| .. attribute:: level() +//| +//| The volume level of a voice, as a floating point number between 0 and 1. +//| +STATIC mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) { + return mp_obj_new_float(common_hal_audiomixer_mixervoice_get_level(self_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_level_obj, audiomixer_mixervoice_obj_get_level); + +STATIC mp_obj_t audiomixer_mixervoice_obj_set_level(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_level }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_level, MP_ARG_OBJ | MP_ARG_REQUIRED }, + }; + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + 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); + + float level = mp_obj_get_float(args[ARG_level].u_obj); + + if (level > 1 || level < 0) { + mp_raise_ValueError(translate("level must be between 0 and 1")); + } + + common_hal_audiomixer_mixervoice_set_level(self, level); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_set_level_obj, 1, audiomixer_mixervoice_obj_set_level); + +const mp_obj_property_t audiomixer_mixervoice_level_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiomixer_mixervoice_get_level_obj, + (mp_obj_t)&audiomixer_mixervoice_set_level_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: playing +//| +//| True when this voice is being output. (read-only) +//| + +STATIC mp_obj_t audiomixer_mixervoice_obj_get_playing(mp_obj_t self_in) { + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_audiomixer_mixervoice_get_playing(self)); + +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_playing_obj, audiomixer_mixervoice_obj_get_playing); + +const mp_obj_property_t audiomixer_mixervoice_playing_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&audiomixer_mixervoice_get_playing_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t audiomixer_mixervoice_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiomixer_mixervoice_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiomixer_mixervoice_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiomixer_mixervoice_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_level), MP_ROM_PTR(&audiomixer_mixervoice_level_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(audiomixer_mixervoice_locals_dict, audiomixer_mixervoice_locals_dict_table); + +const mp_obj_type_t audiomixer_mixervoice_type = { + { &mp_type_type }, + .name = MP_QSTR_MixerVoice, + .make_new = audiomixer_mixervoice_make_new, + .locals_dict = (mp_obj_dict_t*)&audiomixer_mixervoice_locals_dict, +}; diff --git a/shared-bindings/audiomixer/MixerVoice.h b/shared-bindings/audiomixer/MixerVoice.h new file mode 100644 index 0000000000..83098bc9dd --- /dev/null +++ b/shared-bindings/audiomixer/MixerVoice.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef SHARED_BINDINGS_AUDIOMIXER_MIXERVOICE_H_ +#define SHARED_BINDINGS_AUDIOMIXER_MIXERVOICE_H_ + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/audiocore/RawSample.h" + +#include "shared-module/audiomixer/MixerVoice.h" +#include "shared-module/audiomixer/Mixer.h" + +extern const mp_obj_type_t audiomixer_mixer_type; +extern const mp_obj_type_t audiomixer_mixervoice_type; + +void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self); +void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t* self, audiomixer_mixer_obj_t *parent); +void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t* self, mp_obj_t sample, bool loop); +void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t* self); +float common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t* self); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t* self, float gain); + +bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t* self); + +#endif /* SHARED_BINDINGS_AUDIOMIXER_MIXERVOICE_H_ */ diff --git a/shared-bindings/audiomixer/__init__.c b/shared-bindings/audiomixer/__init__.c new file mode 100644 index 0000000000..79bab440e5 --- /dev/null +++ b/shared-bindings/audiomixer/__init__.c @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Michael Schroeder + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audiomixer/Mixer.h" + +//| :mod:`audiomixer` --- Support for audio mixer +//| ======================================================== +//| +//| .. module:: audiomixer +//| :synopsis: Support for audio mixer +//| +//| The `audiomixer` module contains core classes for mixing audio sources +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Mixer +//| MixerVoice +//| + +STATIC const mp_rom_map_elem_t audiomixer_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiomixer) }, + { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audiomixer_mixer_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(audiomixer_module_globals, audiomixer_module_globals_table); + +const mp_obj_module_t audiomixer_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&audiomixer_module_globals, +}; diff --git a/shared-bindings/audiomixer/__init__.h b/shared-bindings/audiomixer/__init__.h new file mode 100644 index 0000000000..35a90441c4 --- /dev/null +++ b/shared-bindings/audiomixer/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Michael Schroeder + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER___INIT___H + +#include "py/obj.h" + +// Nothing now. + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOMIXER___INIT___H diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c index 92543d1128..60bf085002 100644 --- a/shared-bindings/audiopwmio/PWMAudioOut.c +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -166,7 +166,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiopwmio_pwmaudioout___exit___obj, //| Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| -//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiocore.Mixer`. +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, or `audiomixer.Mixer`. //| //| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output //| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c index 067cae5ddb..f9762676fd 100644 --- a/shared-module/audiocore/__init__.c +++ b/shared-module/audiocore/__init__.c @@ -27,13 +27,14 @@ #include "shared-module/audioio/__init__.h" #include "py/obj.h" -#include "shared-bindings/audiocore/Mixer.h" #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" -#include "shared-module/audiocore/Mixer.h" #include "shared-module/audiocore/RawSample.h" #include "shared-module/audiocore/WaveFile.h" +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-module/audiomixer/Mixer.h" + uint32_t audiosample_sample_rate(mp_obj_t sample_obj) { if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) { audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj); @@ -41,9 +42,11 @@ uint32_t audiosample_sample_rate(mp_obj_t sample_obj) { } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); return file->sample_rate; - } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { - audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); return mixer->sample_rate; + #endif } return 16000; } @@ -55,9 +58,11 @@ uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) { } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); return file->bits_per_sample; - } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { - audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); return mixer->bits_per_sample; + #endif } return 8; } @@ -69,9 +74,11 @@ uint8_t audiosample_channel_count(mp_obj_t sample_obj) { } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); return file->channel_count; - } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { - audioio_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj); return mixer->channel_count; + #endif } return 1; } @@ -83,9 +90,11 @@ void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); audioio_wavefile_reset_buffer(file, single_channel, audio_channel); - } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { - audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - audioio_mixer_reset_buffer(file, single_channel, audio_channel); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audiomixer_mixer_reset_buffer(file, single_channel, audio_channel); + #endif } } @@ -99,9 +108,11 @@ audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) { audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length); - } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { - audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - return audioio_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length); + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + return audiomixer_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length); + #endif } return GET_BUFFER_DONE; } @@ -117,9 +128,11 @@ void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel, audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj); audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed, max_buffer_length, spacing); - } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_mixer_type)) { - audioio_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); - audioio_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed, + #if CIRCUITPY_AUDIOMIXER + } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) { + audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj); + audiomixer_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed, max_buffer_length, spacing); + #endif } } diff --git a/shared-module/audiocore/Mixer.c b/shared-module/audiomixer/Mixer.c similarity index 51% rename from shared-module/audiocore/Mixer.c rename to shared-module/audiomixer/Mixer.c index da66bb36ec..e0fb4fab89 100644 --- a/shared-module/audiocore/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -4,6 +4,8 @@ * The MIT License (MIT) * * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * 2018 DeanM for Adafruit Industries + * 2019 Michael Schroeder * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,7 +26,8 @@ * THE SOFTWARE. */ -#include "shared-bindings/audiocore/Mixer.h" +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-bindings/audiomixer/MixerVoice.h" #include @@ -32,24 +35,24 @@ #include "shared-module/audiocore/__init__.h" #include "shared-module/audiocore/RawSample.h" -void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, - uint8_t voice_count, - uint32_t buffer_size, - uint8_t bits_per_sample, - bool samples_signed, - uint8_t channel_count, - uint32_t sample_rate) { +void common_hal_audiomixer_mixer_construct(audiomixer_mixer_obj_t* self, + uint8_t voice_count, + uint32_t buffer_size, + uint8_t bits_per_sample, + bool samples_signed, + uint8_t channel_count, + uint32_t sample_rate) { self->len = buffer_size / 2 / sizeof(uint32_t) * sizeof(uint32_t); self->first_buffer = m_malloc(self->len, false); if (self->first_buffer == NULL) { - common_hal_audioio_mixer_deinit(self); + common_hal_audiomixer_mixer_deinit(self); mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate first buffer")); } self->second_buffer = m_malloc(self->len, false); if (self->second_buffer == NULL) { - common_hal_audioio_mixer_deinit(self); + common_hal_audiomixer_mixer_deinit(self); mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate second buffer")); } @@ -58,130 +61,85 @@ void common_hal_audioio_mixer_construct(audioio_mixer_obj_t* self, self->channel_count = channel_count; self->sample_rate = sample_rate; self->voice_count = voice_count; - - for (uint8_t i = 0; i < self->voice_count; i++) { - self->voice[i].sample = NULL; - } } -void common_hal_audioio_mixer_deinit(audioio_mixer_obj_t* self) { +void common_hal_audiomixer_mixer_deinit(audiomixer_mixer_obj_t* self) { self->first_buffer = NULL; self->second_buffer = NULL; } -bool common_hal_audioio_mixer_deinited(audioio_mixer_obj_t* self) { +bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t* self) { return self->first_buffer == NULL; } -uint32_t common_hal_audioio_mixer_get_sample_rate(audioio_mixer_obj_t* self) { +uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* self) { return self->sample_rate; } -void common_hal_audioio_mixer_play(audioio_mixer_obj_t* self, mp_obj_t sample, uint8_t v, bool loop) { - if (v >= self->voice_count) { - mp_raise_ValueError(translate("Voice index too high")); - } - if (audiosample_sample_rate(sample) != self->sample_rate) { - mp_raise_ValueError(translate("The sample's sample rate does not match the mixer's")); - } - if (audiosample_channel_count(sample) != self->channel_count) { - mp_raise_ValueError(translate("The sample's channel count does not match the mixer's")); - } - if (audiosample_bits_per_sample(sample) != self->bits_per_sample) { - mp_raise_ValueError(translate("The sample's bits_per_sample does not match the mixer's")); - } - bool single_buffer; - bool samples_signed; - uint32_t max_buffer_length; - uint8_t spacing; - audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, - &max_buffer_length, &spacing); - if (samples_signed != self->samples_signed) { - mp_raise_ValueError(translate("The sample's signedness does not match the mixer's")); - } - audioio_mixer_voice_t* voice = &self->voice[v]; - voice->sample = sample; - voice->loop = loop; - - audiosample_reset_buffer(sample, false, 0); - audioio_get_buffer_result_t result = audiosample_get_buffer(sample, false, 0, (uint8_t**) &voice->remaining_buffer, &voice->buffer_length); - // Track length in terms of words. - voice->buffer_length /= sizeof(uint32_t); - voice->more_data = result == GET_BUFFER_MORE_DATA; -} - -void common_hal_audioio_mixer_stop_voice(audioio_mixer_obj_t* self, uint8_t voice) { - self->voice[voice].sample = NULL; -} - -bool common_hal_audioio_mixer_get_playing(audioio_mixer_obj_t* self) { - for (int32_t v = 0; v < self->voice_count; v++) { - if (self->voice[v].sample != NULL) { +bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self) { + for (uint8_t v = 0; v < self->voice_count; v++) { + if (common_hal_audiomixer_mixervoice_get_playing(MP_OBJ_TO_PTR(self->voice[v]))) { return true; } } return false; } -void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, - bool single_channel, - uint8_t channel) { - for (int32_t i = 0; i < self->voice_count; i++) { - self->voice[i].sample = NULL; +void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t* self, + bool single_channel, + uint8_t channel) { + for (uint8_t i = 0; i < self->voice_count; i++) { + common_hal_audiomixer_mixervoice_stop(self->voice[i]); } } uint32_t add8signed(uint32_t a, uint32_t b) { - #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) - return __QADD8(a, b); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __SHADD8(a, b); #else uint32_t result = 0; for (int8_t i = 0; i < 4; i++) { int8_t ai = a >> (sizeof(int8_t) * 8 * i); int8_t bi = b >> (sizeof(int8_t) * 8 * i); - int32_t intermediate = (int32_t) ai + bi; + int32_t intermediate = (int32_t) ai + bi / 2; if (intermediate > CHAR_MAX) { intermediate = CHAR_MAX; } else if (intermediate < CHAR_MIN) { - //intermediate = CHAR_MIN; + intermediate = CHAR_MIN; } - result |= (((uint32_t) intermediate) & 0xff) << (sizeof(int8_t) * 8 * i); + result |= ((uint32_t) intermediate & 0xff) << (sizeof(int8_t) * 8 * i); } return result; #endif } uint32_t add8unsigned(uint32_t a, uint32_t b) { - #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) - // Subtract out the DC offset, add and then shift back. - a = __USUB8(a, 0x80808080); - b = __USUB8(b, 0x80808080); - uint32_t sum = __QADD8(a, b); - return __UADD8(sum, 0x80808080); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __UHADD8(a, b); #else uint32_t result = 0; for (int8_t i = 0; i < 4; i++) { - int8_t ai = (a >> (sizeof(uint8_t) * 8 * i)) - 128; - int8_t bi = (b >> (sizeof(uint8_t) * 8 * i)) - 128; - int32_t intermediate = (int32_t) ai + bi; + uint8_t ai = (a >> (sizeof(uint8_t) * 8 * i)); + uint8_t bi = (b >> (sizeof(uint8_t) * 8 * i)); + int32_t intermediate = (int32_t) (ai + bi) / 2; if (intermediate > UCHAR_MAX) { intermediate = UCHAR_MAX; } - result |= ((uint8_t) intermediate + 128) << (sizeof(uint8_t) * 8 * i); + result |= ((uint32_t) intermediate & 0xff) << (sizeof(uint8_t) * 8 * i); } return result; #endif } uint32_t add16signed(uint32_t a, uint32_t b) { - #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) - return __QADD16(a, b); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __SHADD16(a, b); #else uint32_t result = 0; for (int8_t i = 0; i < 2; i++) { int16_t ai = a >> (sizeof(int16_t) * 8 * i); int16_t bi = b >> (sizeof(int16_t) * 8 * i); - int32_t intermediate = (int32_t) ai + bi; + int32_t intermediate = (int32_t) ai + bi / 2; if (intermediate > SHRT_MAX) { intermediate = SHRT_MAX; } else if (intermediate < SHRT_MIN) { @@ -194,32 +152,146 @@ uint32_t add16signed(uint32_t a, uint32_t b) { } uint32_t add16unsigned(uint32_t a, uint32_t b) { - #if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) - // Subtract out the DC offset, add and then shift back. - a = __USUB16(a, 0x80008000); - b = __USUB16(b, 0x80008000); - uint32_t sum = __QADD16(a, b); - return __UADD16(sum, 0x80008000); + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return __UHADD16(a, b); #else uint32_t result = 0; for (int8_t i = 0; i < 2; i++) { int16_t ai = (a >> (sizeof(uint16_t) * 8 * i)) - 0x8000; int16_t bi = (b >> (sizeof(uint16_t) * 8 * i)) - 0x8000; - int32_t intermediate = (int32_t) ai + bi; + int32_t intermediate = (int32_t) ai + bi / 2; if (intermediate > USHRT_MAX) { intermediate = USHRT_MAX; } - result |= ((uint16_t) intermediate + 0x8000) << (sizeof(int16_t) * 8 * i); + result |= ((uint32_t) intermediate & 0xffff) << (sizeof(int16_t) * 8 * i); } return result; #endif } -audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, - bool single_channel, - uint8_t channel, - uint8_t** buffer, - uint32_t* buffer_length) { +static inline uint32_t mult8unsigned(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + /* TODO: workout ARMv7 instructions + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return val; + #else*/ + uint32_t result = 0; + float mod_mul = (float) mul / (float) ((1<<15)-1); + for (int8_t i = 0; i < 4; i++) { + uint8_t ai = val >> (sizeof(uint8_t) * 8 * i); + int32_t intermediate = ai * mod_mul; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } + result |= ((uint32_t) intermediate & 0xff) << (sizeof(uint8_t) * 8 * i); + } + + return result; + //#endif +} + +static inline uint32_t mult8signed(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + /* TODO: workout ARMv7 instructions + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + return val; + #else + */ + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1<<15)-1); + for (int8_t i = 0; i < 4; i++) { + int16_t ai = val >> (sizeof(int8_t) * 8 * i); + int32_t intermediate = ai * mod_mul; + if (intermediate > CHAR_MAX) { + intermediate = CHAR_MAX; + } else if (intermediate < CHAR_MIN) { + intermediate = CHAR_MIN; + } + result |= (((uint32_t) intermediate) & 0xff) << (sizeof(int16_t) * 8 * i); + } + return result; + //#endif +} + +//TODO: +static inline uint32_t mult16unsigned(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + /* TODO: the below ARMv7m instructions "work", but the amplitude is much higher/louder + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + // there is no unsigned equivalent to the 'SMULWx' ARMv7 Thumb function, + // so we have to do it by hand. + uint32_t lo = val & 0xffff; + uint32_t hi = val >> 16; + //mp_printf(&mp_plat_print, "pre-asm: (mul: %d)\n\tval: %x\tlo: %x\thi: %x\n", mul, val, lo, hi); + uint32_t val_lo; + asm volatile("mul %0, %1, %2" : "=r" (val_lo) : "r" (mul), "r" (lo)); + asm volatile("mla %0, %1, %2, %3" : "=r" (val) : "r" (mul), "r" (hi), "r" (val_lo)); + //mp_printf(&mp_plat_print, "post-asm:\n\tval: %x\tlo: %x\n\n", val, val_lo); + return val; + #else + */ + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1<<15)-1); + for (int8_t i = 0; i < 2; i++) { + int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)) - 0x8000; + int32_t intermediate = ai * mod_mul; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= (((uint32_t) intermediate) + 0x8000) << (sizeof(int16_t) * 8 * i); + } + return result; + //#endif +} + +static inline uint32_t mult16signed(uint32_t val, int32_t mul) { + // if mul == 0, no need in wasting cycles + if (mul == 0) { + return 0; + } + #if (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) //Cortex-M4 w/FPU + int32_t hi, lo; + int32_t bits = 16; // saturate to 16 bits + int32_t shift = 0; // shift is done automatically + asm volatile("smulwb %0, %1, %2" : "=r" (lo) : "r" (mul), "r" (val)); + asm volatile("smulwt %0, %1, %2" : "=r" (hi) : "r" (mul), "r" (val)); + asm volatile("ssat %0, %1, %2, asr %3" : "=r" (lo) : "I" (bits), "r" (lo), "I" (shift)); + asm volatile("ssat %0, %1, %2, asr %3" : "=r" (hi) : "I" (bits), "r" (hi), "I" (shift)); + asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (val) : "r" (lo), "r" (hi)); // pack + return val; + #else + uint32_t result = 0; + float mod_mul = (float)mul / (float)((1<<15)-1); + for (int8_t i = 0; i < 2; i++) { + int16_t ai = val >> (sizeof(int16_t) * 8 * i); + int32_t intermediate = ai * mod_mul; + if (intermediate > SHRT_MAX) { + intermediate = SHRT_MAX; + } else if (intermediate < SHRT_MIN) { + intermediate = SHRT_MIN; + } + result |= (((uint32_t) intermediate) & 0xffff) << (sizeof(int16_t) * 8 * i); + } + return result; + #endif +} + +audioio_get_buffer_result_t audiomixer_mixer_get_buffer(audiomixer_mixer_obj_t* self, + bool single_channel, + uint8_t channel, + uint8_t** buffer, + uint32_t* buffer_length) { if (!single_channel) { channel = 0; } @@ -243,7 +315,7 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, self->use_first_buffer = !self->use_first_buffer; bool voices_active = false; for (int32_t v = 0; v < self->voice_count; v++) { - audioio_mixer_voice_t* voice = &self->voice[v]; + audiomixer_mixervoice_obj_t* voice = MP_OBJ_TO_PTR(self->voice[v]); uint32_t j = 0; bool voice_done = voice->sample == NULL; @@ -285,6 +357,21 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, sample_value = voice->remaining_buffer[j]; } + // apply the mixer level + if (!self->samples_signed) { + if (self->bits_per_sample == 8) { + sample_value = mult8unsigned(sample_value, voice->level); + } else { + sample_value = mult16unsigned(sample_value, voice->level); + } + } else { + if (self->bits_per_sample == 8) { + sample_value = mult8signed(sample_value, voice->level); + } else { + sample_value = mult16signed(sample_value, voice->level); + } + } + if (!voices_active) { word_buffer[i] = sample_value; } else { @@ -327,7 +414,7 @@ audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, return GET_BUFFER_MORE_DATA; } -void audioio_mixer_get_buffer_structure(audioio_mixer_obj_t* self, bool single_channel, +void audiomixer_mixer_get_buffer_structure(audiomixer_mixer_obj_t* self, bool single_channel, bool* single_buffer, bool* samples_signed, uint32_t* max_buffer_length, uint8_t* spacing) { *single_buffer = false; diff --git a/shared-module/audiocore/Mixer.h b/shared-module/audiomixer/Mixer.h similarity index 79% rename from shared-module/audiocore/Mixer.h rename to shared-module/audiomixer/Mixer.h index 22eb6a37fa..ab4780efc6 100644 --- a/shared-module/audiocore/Mixer.h +++ b/shared-module/audiomixer/Mixer.h @@ -24,21 +24,14 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H -#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER_MIXER_H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER_MIXER_H #include "py/obj.h" +#include "py/objtuple.h" #include "shared-module/audiocore/__init__.h" -typedef struct { - mp_obj_t sample; - bool loop; - bool more_data; - uint32_t* remaining_buffer; - uint32_t buffer_length; -} audioio_mixer_voice_t; - typedef struct { mp_obj_base_t base; uint32_t* first_buffer; @@ -55,21 +48,22 @@ typedef struct { uint32_t right_read_count; uint8_t voice_count; - audioio_mixer_voice_t voice[]; -} audioio_mixer_obj_t; + mp_obj_tuple_t *voice_tuple; + mp_obj_t voice[]; +} audiomixer_mixer_obj_t; // These are not available from Python because it may be called in an interrupt. -void audioio_mixer_reset_buffer(audioio_mixer_obj_t* self, +void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t* self, bool single_channel, uint8_t channel); -audioio_get_buffer_result_t audioio_mixer_get_buffer(audioio_mixer_obj_t* self, +audioio_get_buffer_result_t audiomixer_mixer_get_buffer(audiomixer_mixer_obj_t* self, bool single_channel, uint8_t channel, uint8_t** buffer, uint32_t* buffer_length); // length in bytes -void audioio_mixer_get_buffer_structure(audioio_mixer_obj_t* self, bool single_channel, +void audiomixer_mixer_get_buffer_structure(audiomixer_mixer_obj_t* self, bool single_channel, bool* single_buffer, bool* samples_signed, uint32_t* max_buffer_length, uint8_t* spacing); -#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MIXER_H +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER_MIXER_H diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c new file mode 100644 index 0000000000..ff05dc93e4 --- /dev/null +++ b/shared-module/audiomixer/MixerVoice.c @@ -0,0 +1,87 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "shared-bindings/audiomixer/Mixer.h" +#include "shared-module/audiomixer/MixerVoice.h" + +#include + +#include "py/runtime.h" +#include "shared-module/audiomixer/__init__.h" +#include "shared-module/audiocore/RawSample.h" + +void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self) { + self->sample = NULL; + self->level = ((1 << 15) - 1); +} + +void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t* self, audiomixer_mixer_obj_t *parent) { + self->parent = parent; +} + +float common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t* self) { + return ((float) self->level / ((1 << 15) - 1)); +} + +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t* self, float level) { + self->level = level * ((1 << 15)-1); +} + +void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t* self, mp_obj_t sample, bool loop) { + if (audiosample_sample_rate(sample) != self->parent->sample_rate) { + mp_raise_ValueError(translate("The sample's sample rate does not match the mixer's")); + } + if (audiosample_channel_count(sample) != self->parent->channel_count) { + mp_raise_ValueError(translate("The sample's channel count does not match the mixer's")); + } + if (audiosample_bits_per_sample(sample) != self->parent->bits_per_sample) { + mp_raise_ValueError(translate("The sample's bits_per_sample does not match the mixer's")); + } + bool single_buffer; + bool samples_signed; + uint32_t max_buffer_length; + uint8_t spacing; + audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, + &max_buffer_length, &spacing); + if (samples_signed != self->parent->samples_signed) { + mp_raise_ValueError(translate("The sample's signedness does not match the mixer's")); + } + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(sample, false, 0, (uint8_t**) &self->remaining_buffer, &self->buffer_length); + // Track length in terms of words. + self->buffer_length /= sizeof(uint32_t); + self->more_data = result == GET_BUFFER_MORE_DATA; +} + +bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t* self) { + return self->sample != NULL; +} + +void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t* self) { + self->sample = NULL; +} diff --git a/shared-module/audiomixer/MixerVoice.h b/shared-module/audiomixer/MixerVoice.h new file mode 100644 index 0000000000..efac191565 --- /dev/null +++ b/shared-module/audiomixer/MixerVoice.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 DeanM for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef SHARED_MODULE_AUDIOMIXER_MIXERVOICE_H_ +#define SHARED_MODULE_AUDIOMIXER_MIXERVOICE_H_ + +#include "py/obj.h" + +#include "shared-module/audiomixer/__init__.h" +#include "shared-module/audiomixer/Mixer.h" + +typedef struct { + mp_obj_base_t base; + audiomixer_mixer_obj_t *parent; + mp_obj_t sample; + bool loop; + bool more_data; + uint32_t* remaining_buffer; + uint32_t buffer_length; + int16_t level; +} audiomixer_mixervoice_obj_t; + + +#endif /* SHARED_MODULE_AUDIOMIXER_MIXERVOICE_H_ */ diff --git a/shared-module/audiomixer/__init__.c b/shared-module/audiomixer/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/audiomixer/__init__.h b/shared-module/audiomixer/__init__.h new file mode 100644 index 0000000000..35b7315588 --- /dev/null +++ b/shared-module/audiomixer/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER__INIT__H +#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER__INIT__H + +#include "shared-module/audiocore/__init__.h" + +#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOMIXER__INIT__H