CircuitPython - воспроизведение wav файлов по кнопке независимо друг от друга [UPD]
Вот простой код, который по нажатии определенной кнопки воспроизводит присвоенный ей звук:
import board
import audiobusio
import audiocore
import time
from digitalio import DigitalInOut, Direction, Pull
a_button = DigitalInOut(board.GP1)
a_button.direction = Direction.INPUT
a_button.pull = Pull.UP
b_button = DigitalInOut(board.GP2)
b_button.direction = Direction.INPUT
b_button.pull = Pull.UP
audio = audiobusio.I2SOut(bit_clock=board.GP10, word_select=board.GP11, data=board.GP9)
f1 = open("1.wav", "rb")
wav1 = audiocore.WaveFile(f1)
f2 = open("2.wav", "rb")
wav2 = audiocore.WaveFile(f2)
while True:
if b_button.value is False:
print(b_button.value)
audio.play(wav1)
elif a_button.value is False:
print(a_button.value)
audio.play(wav2)
Вопрос состоит в том, как сделать, чтобы звуки могли воспроизводится независимо друг от друга. То есть при нажатии одновременно двух кнопок звуки звучали вместе, как например на синтезаторе. (достаточно одновременного звучания 4х каналов)
Код circuitpython воспроизводится на raspberry pico, а размер воспроизводимых файлов 20-30кб.
Оказалось, существует библиотека audiomixer и я нашел неплохой пример ее использования в качестве DJ board. Код с ее использованием выглядит так:
import time
import board
import audiocore
import audiomixer
import digitalio
import audiobusio
audio = audiobusio.I2SOut(bit_clock=board.GP10, word_select=board.GP11, data=board.GP9)
forever = 1
beats = ["1.wav", "2.wav", "3.wav"]
button1 = digitalio.DigitalInOut(board.GP1)
button1.switch_to_input(pull=digitalio.Pull.UP)
button2 = digitalio.DigitalInOut(board.GP2)
button2.switch_to_input(pull=digitalio.Pull.UP)
button3 = digitalio.DigitalInOut(board.GP3)
button3.switch_to_input(pull=digitalio.Pull.UP)
mixer = audiomixer.Mixer(voice_count=3, sample_rate=16000, channel_count=1,
bits_per_sample=16, samples_signed=True)
audio.play(mixer)
for i in range(3):
wave = audiocore.WaveFile(open(beats[i],"rb"))
mixer.voice[i].play(wave, loop=True )
mixer.voice[i].level = 0.0
while True:
if not button1.value: # button is pressed
mixer.voice[0].level = 1.0
print("button1 is played")
else:
mixer.voice[0].level = 0.0
if not button2.value: # button is pressed
mixer.voice[1].level = 1.0
print("button2 is played")
else:
mixer.voice[1].level = 0.0
if not button3.value: # button is pressed
mixer.voice[2].level = 1.0
print("button3 is played")
else:
mixer.voice[2].level = 0.0
Все было бы здорово, но проблема в том, что из за зацикливания воспроизведения звуков, при нажатии на ту или иную кнопку звук воспроизводится не с начала а с той фазы на которой он проигрывается в данный момент.
Мне же нужно, чтобы он воспроизводился при нажатии именно с начла и играл до тех пор, пока не закончится, вне зависимости от нажатия на другие кнопки.
Вопрос в том, можно ли вообще это реализовать на этой библиотеке и если да, то был бы рад любой помощи.
Ответы (1 шт):
Вообщем проблема оказалась в том, что нужно считывать факт нажатия кнопки как единичное действие. При обычном считывании нажатия "if not button1.value:" будет, факт нажатия успеет зарегистрироваться несколько десятков раз за долю секунды, поэтому нужно использовать библиотеку debouncer, которая позволяет отслеживать все фазы нажатия кнопки по отдельности.