#python #sound-synthesis
Вопрос:
Я пытаюсь создать программный синтезатор на Python с помощью Pysound. Первый шаг-заставить Pysound выводить wav-файлы. У меня также есть окно Tkinter, в котором пользователь может взаимодействовать с Pysound. Вот код, который у меня есть:
#import libs
from tkinter import *
from tkinter import ttk
from pysound import buffer
from pysound import soundfile
from pysound import oscillators
from pysound import envelopes
from playsound import playsound
from time import sleep
def save():
data=""
data2=""
#create buffers
params = buffer.BufferParams()
buffer.create_buffer(params,value=0.0)
#voice 1
env1=envelopes.attack_decay(params, attack=params.t2s(int(A1.get())/10))
if selectedWave1=="Sine":
data = oscillators.sine_wave(params,frequency=400,amplitude=env)
elif selectedWave1=="Saw":
data = oscillators.saw_wave(params,frequency=400,amplitude=env)
elif selectedWave1=="Square":
data = oscillators.square_wave(params,frequency=400,amplitude=env)
elif selectedWave1=="Noise":
data = oscillators.noise(params,frequency=400,amplitude=env)
#voice 2
env2=envelopes.attack_decay(params, attack=params.t2s(int(A2.get())/10))
if selectedWave2=="Sine":
data2=oscillators.sine_wave(params,frequency=400,amplitude=env2)
elif selectedWave2=="Saw":
data2=oscillators.saw_wave(params,frequency=400,amplitude=env2)
elif selectedWave2=="Square":
data2=oscillators.square_wave(params,frequency=400,amplitude=env2)
elif selectedWave2=="Noise":
data2=oscillators.noise(params,frequency=400,amplitude=env2)
#save files
soundfile.save(params, 'voice2.wav', data)
soundfile.save(params,'voice1.wav',data2)
#create win
win=Tk()
win.geometry("800x450") #set size
win.title("Synthetica") #set title
win.configure(bg="#010") #set background colour
#create string vars for components
selectedWave1=StringVar()
selectedWave2=StringVar()
A1=StringVar()
D1=StringVar()
A2=StringVar()
D2=StringVar()
currentPreset=StringVar()
#create components
lblVoice1=Label(win,font=("Trebuchet MS",10),text="Voice 1:",bg="#010",fg="#fff")
lblWave1=Label(win,font=("Trebuchet MS",10),text="Waveform:",bg="#010",fg="#fff")
lblA1=Label(win,font=("Trebuchet MS",10),text="Attack:",bg="#010",fg="#fff")
lblD1=Label(win,font=("Trebuchet MS",10),text="Decay:",bg="#010",fg="#fff")
comboWave1=ttk.Combobox(win,font=("Trebuchet MS",10),width=10,textvariable=selectedWave1)
spinA1=Spinbox(win, font=("Trebuchet MS",10),width=5,from_=0,to=255,textvariable=A1)
spinD1=Spinbox(win, font=("Trebuchet MS",10),width=5,from_=0,to=255,textvariable=D1)
lblVoice2=Label(win,font=("Trebuchet MS",10),text="Voice 2:",bg="#010",fg="#fff")
lblWave2=Label(win,font=("Trebuchet MS",10),text="Waveform:",bg="#010",fg="#fff")
lblA2=Label(win,font=("Trebuchet MS",10),text="Attack:",bg="#010",fg="#fff")
lblD2=Label(win,font=("Trebuchet MS",10),text="Decay:",bg="#010",fg="#fff")
comboWave2=ttk.Combobox(win,font=("Trebuchet MS",10),width=10,textvariable=selectedWave2)
spinA2=Spinbox(win, font=("Trebuchet MS",10),width=5,from_=0,to=255,textvariable=A2)
spinD2=Spinbox(win, font=("Trebuchet MS",10),width=5,from_=0,to=255,textvariable=D2)
lblPreset=Label(win,font=("Trebuchet MS",10),text="Current Preset:",bg="#010",fg="#fff")
comboPreset=ttk.Combobox(win,font=("Trebuchet MS",10),width=10,textvariable=currentPreset)
txtPresetName=Entry(win,font=("Trebuchet MS",10),bg="#fff",fg="#010")
btnSavePreset=Button(win,font=("Trebuchet MS",10),text="Save New Preset",bg="#fff",fg="#010",command=save)
#place components
lblVoice1.place(x=10,y=10)
lblWave1.place(x=10,y=40)
lblA1.place(x=10,y=70)
lblD1.place(x=10,y=100)
comboWave1.place(x=100,y=40)
spinA1.place(x=100,y=70)
spinD1.place(x=100,y=100)
lblVoice2.place(x=200,y=10)
lblWave2.place(x=200,y=40)
lblA2.place(x=200,y=70)
lblD2.place(x=200,y=100)
comboWave2.place(x=300,y=40)
spinA2.place(x=300,y=70)
spinD2.place(x=300,y=100)
lblPreset.place(x=500,y=40)
comboPreset.place(x=600,y=40)
txtPresetName.place(x=500,y=100)
btnSavePreset.place(x=500,y=130)
#set options for comboboxes
comboWave1["values"]="Sine","Saw","Square","Noise"
comboWave2["values"]="Sine","Saw","Square","Noise"
win.mainloop()
Он выводит 0-секундный wav-файл для голоса 1 и голоса 2, и я не знаю, почему.
Я получил эти сообщения об ошибках
synthetica-C1.py:41: DeprecationWarning: tostring() is deprecated. Use tobytes() instead.
soundfile.save(params, 'voice2.wav', data)
synthetica-C1.py:42: DeprecationWarning: tostring() is deprecated. Use tobytes() instead.
soundfile.save(params,'voice1.wav',data2)
но я получал те же самые, что и раньше, и звуковой файл был в порядке. Он перестал работать, как только я изменил раздел ниже, чтобы фактически принимать пользовательский ввод для типа волны с помощью операторов if. До этого пользователь имел контроль только над оболочкой атаки.
Почему он выводит пустой файл?
Комментарии:
1. Опечатка в
env1=envelopes.attack_decay
иamplitude=env
?2. @simon Я исправил это, но это все равно не сработало. В нем говорилось, что на данные ссылаются перед объявлением, поэтому я объявил их пустой строкой в первой строке функции save (). Я думаю, что это может привести к созданию пустых файлов, но без этого он выдает ошибку.
3. Попробуйте стереть эту строку:
buffer.create_buffer(params,value=0.0)
4. Вы также можете попробовать
params = buffer.create_buffer(params,value=0.0)