Почему pysound выводит пустые файлы wav?

#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)