gpt4 book ai didi

python - PyAudio 回调仅被调用一次

转载 作者:太空宇宙 更新时间:2023-11-03 21:47:08 26 4
gpt4 key购买 nike

我正在尝试创建一个简单的应用程序,该应用程序加载 wav 文件(键盘的每个音符一个)并在按下(或播放)MIDI 音符时播放特定的文件。到目前为止,我已经在两个单独的线程中使用 mido 创建了一个 midi 输入流,并使用 pyaudio 创建了一个音频流。目标是让 midi 流更新当前播放的音符,并回调 pyaudio 流来检查事件音符并播放这些音符。 midi 流工作正常,但我的音频流似乎只在脚本启动时调用回调一次(print(notes))。知道如何让音频流回调不断更新吗?

import wave
from io import BytesIO
import os
from mido import MidiFile
import pyaudio
from time import sleep
from threading import Thread
import numpy

# Pipe: active, released
# Rank: many pipes
# Stop: one or more ranks
# Manual: multiple ranks
# Organ: multiple manuals

pipes = []
notes = []
p = pyaudio.PyAudio()


def mapRange(num, inMin, inMax, outMin, outMax):
return int((num - inMin) * (outMax - outMin) / (inMax - inMin) + outMin)

def callback(in_data, frame_count, time_info, status):
data = bytes(frame_count)
print(notes)
for note in notes:
pipedata = bytes()
if len(data) != 0:
data1 = numpy.fromstring(data, numpy.int16)
data2 = numpy.fromstring(note['sample'].readframes(frame_count), numpy.int16)
pipedata = (data1 * 0.5 + data2 * 0.5).astype(numpy.int16)
else:
data2 = numpy.fromstring(note['sample'].readframes(frame_count), numpy.int16)
pipedata = data2.astype(numpy.int16)
data = pipedata.tostring()
return (data, pyaudio.paContinue)

stream = p.open(format=pyaudio.paInt24,
channels=2,
rate=48000,
output=True,
stream_callback=callback,
start=True)

# start the stream (4)
stream.start_stream()

for root, dirs, files in os.walk("samples"):
for filename in files:
file_on_disk = open(os.path.join(root, filename), 'rb')
pipes.append(
{"sample": wave.open(BytesIO(file_on_disk.read()), 'rb')})
for msg in MidiFile('test.mid').play():
if msg.type == "note_on":
notes.append(pipes[mapRange(msg.note, 36, 96, 0, 56)])
print("on")
if msg.type == "note_off":
#notes[mapRange(msg.note, 36, 96, 0, 56)] = False
print("off")

# wait for stream to finish (5)
while stream.is_active():
sleep(0.1)

# stop stream (6)
stream.stop_stream()
stream.close()

# close PyAudio (7)
p.terminate()

最佳答案

我也遇到过这个问题,并发现这个问题希望找到答案,最终自己解决了。

回调返回的数据必须与帧数匹配(p.open中的frames_per_buffer参数)。我发现您没有指定,所以我认为默认值是 1024。

问题是,frames_per_buffer 并不代表字节,而是代表实际帧。因此,由于您将格式指定为 pyaudio.paInt24,这意味着一帧由 3 个字节 (24/8) 表示。因此,在您的回调中,您应该返回 3072 字节,否则回调将不会因某种原因再次被调用。

如果您使用阻塞模式并且不在stream.write() 中写入这3072 字节,则会导致缓慢且噼啪作响的音频的奇怪效果。

关于python - PyAudio 回调仅被调用一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52415883/

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