gpt4 book ai didi

python - PyAudio在线程中播放连续流,并让其更改频率

转载 作者:行者123 更新时间:2023-12-02 22:36:26 31 4
gpt4 key购买 nike

我根本没有线程的经验。

我要做的就是使用GUI播放声音并同时更改音调(频率)。

这段代码连续播放,没有任何峰值或失真:


class Stream:
def __init__(self, sample_rate):
self.p = pyaudio.PyAudio()
self.sample_rate = sample_rate

# for paFloat32 sample values must be in range [-1.0, 1.0]
self.stream = self.p.open(format=pyaudio.paFloat32,
channels=1,
rate=sample_rate,
output=True)
self.samples = 0.

def create_sine_tone(self, frequency, duration):
# generate samples, note conversion to float32 array
self.samples = (np.sin(2 * np.pi * np.arange(self.sample_rate * duration) * frequency
/ self.sample_rate)).astype(np.float32)

def play_sine_tone(self, volume=1.):
"""
:param frequency:
:param duration:
:param volume:
:param sample_rate:
:return:
"""

# play. May repeat with different volume values (if done interactively)
while 1:
self.stream.write(volume * self.samples)

def terminate(self):
self.p.terminate()

def finish(self):
self.stream.stop_stream()
self.stream.close()

此代码创建GUI。在 left_clickright_click中, create_sine_tone()创建一个新的频率波。但是,据我了解,它会修改 threadingplay_sine_tone使用的内存,并且程序崩溃。

def main():
window = Tk()
window.title("Piano reference")
window.geometry('350x200')

s = Stream(44100)

lbl = Label(window, text="A4")
lbl.grid(column=2, row=1)

def left_click(frequency):
s.create_sine_tone(frequency, 1.)
t = threading.Thread(target=s.play_sine_tone, args=(1,))
t.start()
lbl.configure(text=frequency)

def right_click(frequency):
s.create_sine_tone(frequency, 1.)
t = threading.Thread(target=s.play_sine_tone, args=(1,))
t.start()
lbl.configure(text=frequency)

btn1 = Button(window, text="<<", command=lambda: left_click(100))
btn2 = Button(window, text=">>", command=lambda: right_click(200))

btn1.grid(column=0, row=0)
btn2.grid(column=1, row=0)

window.mainloop()


如何修改wave,使程序不会崩溃?也许我可以在更改频率之前关闭线程?

最佳答案

如果您尝试做的只是播放可以使用GUI控制的不同音调,则可能不需要线程。

PySimpleGUI提供了一个基于Tkinter(和其他工具)的 super 易于使用的GUI构建器。最重要的是,它提供了基于由GUI组件驱动的事件的操作。

另一方面,pydub的使用使我们可以轻松地创建不同的音调并进行播放。
pydub _play_with_simpleaudio方法允许我们以非阻塞方式使用simpleAudio播放音调。

GUI控件:

  • '>>'选择200 Hz的倍数下一个频率。
  • '<<'选择100 Hz倍数的先前频率。
  • 'X'退出gui。

  • 我观察到的唯一问题是在频移时发出轻微的喀哒声,这可能需要进一步的工作。

    以下工作代码基于上述软件包。
    import PySimpleGUI as sg      
    from pydub.generators import Sine
    from pydub import AudioSegment
    from pydub.playback import _play_with_simpleaudio
    import time

    sr = 44100 # sample rate
    bd = 16 # bit depth
    l = 10000.0 # duration in millisec

    sg.ChangeLookAndFeel('BluePurple')
    silent = AudioSegment.silent(duration=10000)
    FREQ = 200

    def get_sine(freq):
    #create sine wave of given freq
    sine_wave = Sine(freq, sample_rate=sr, bit_depth=bd)

    #Convert waveform to audio_segment for playback and export
    sine_segment = sine_wave.to_audio_segment(duration=l)

    return sine_segment

    # Very basic window. Return values as a list
    layout = [
    [sg.Button('<<'), sg.Button('>>')],
    [sg.Text('Processing Freq [Hz]:'), sg.Text(size=(15,1), justification='center', key='-OUTPUT-')]
    ]

    window = sg.Window('Piano reference', layout)

    count = 0
    play_obj = _play_with_simpleaudio(silent)

    while 100 <= FREQ <= 20000 : # Event Loop
    count += 1
    event, values = window.Read()

    if event in (None, 'Exit'):
    break
    if event == '<<':
    if not FREQ < 100:
    FREQ -= 100
    window['-OUTPUT-'].update(FREQ)

    if event == '>>':
    if not FREQ > 20000:
    FREQ += 200
    window['-OUTPUT-'].update(FREQ)

    print(event, FREQ)

    sound = get_sine(FREQ)

    try:
    play_obj.stop()
    time.sleep(0.1)
    sound = sound.fade_in(100).fade_out(100)
    play_obj = _play_with_simpleaudio(sound)
    time.sleep(0.1)
    except KeyboardInterrupt:
    play_obj.stop_all()


    window.close()

    结果:
    $ python3 pygui3.py 
    Playing >> 400 Hz
    Playing >> 600 Hz
    Playing >> 800 Hz
    Playing << 700 Hz
    Playing << 600 Hz

    界面:

    enter image description here

    关于python - PyAudio在线程中播放连续流,并让其更改频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59137542/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com