如何使用pyaudio反转音频

Max*_*ner 2 python audio reverse pyaudio

我一直在修补pyaudio一段时间,试图扭转一个简单的波形文件但没有成功.

在(我的)理论中,我只需要通过文件从一端到另一端迭代,每次回调pyaudio(1024帧)从文件中的相应索引中获取音频数据,反转生成的字符串并播放它.

这是我的代码(只有pyaudio回调和文件处理,其余部分不受示例代码的影响):

import pyaudio
import wave
import time
import sys

if len(sys.argv) < 2:
    print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
    sys.exit(-1)


index = 40*1024
wf = wave.open(sys.argv[1], 'rb')
wf.setpos(index)
p = pyaudio.PyAudio()


def callback(in_data, frame_count, time_info, status):
    global index
    data = wf.readframes(frame_count)
    data = data[::-1]
    index-=1024
    wf.setpos(index)

    return (data, pyaudio.paContinue)

stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                channels=wf.getnchannels(),
                rate=wf.getframerate(),
                output=True,
                stream_callback=callback)


stream.start_stream()

while stream.is_active():
    time.sleep(0.1)

stream.stop_stream()
stream.close()
wf.close()

p.terminate()
Run Code Online (Sandbox Code Playgroud)

我知道当它到达文件开头会崩溃,但它应该播放40×1024帧的反向音频......

Jos*_*ino 5

如果你想要反转的文件足够小以适应内存,你最好的选择是完全加载它并反转数据,然后流式传输:

import pyaudio
import wave

wavefile_name = 'wavefile.wav'
wf = wave.open(wavefile_name, 'rb')

p = pyaudio.PyAudio()
stream = p.open(format =
                p.get_format_from_width(wf.getsampwidth()),
                channels = wf.getnchannels(),
                rate = wf.getframerate(),
                output = True)

full_data = []
data = wf.readframes(1024)

while data:    
    full_data.append(data)
    data = wf.readframes(1024)

data = ''.join(full_data)[::-1]

for i in range(0, len(data), 1024):
    stream.write(data[i:i+1024])
Run Code Online (Sandbox Code Playgroud)

但是,如果文件太大而无法放入内存,则需要某种方式向后读取文件并将其输入音响系统.这是一个完全不同的问题,因为它涉及一些低级I/O编程来处理向后读取.


编辑:看到完整的代码后,我没有看到任何错误.代码在我的计算机中正常运行,但只在播放结束时失败.但是,你可以做两件事.首先,你可以到波形文件的末尾向后播放整个声音,使用:

wf = wave.open(sys.argv[1], 'rb')
index = wf.getnframes() - 1024
wf.setpos(index)
Run Code Online (Sandbox Code Playgroud)

其次,您必须修改回调,以便在搜索头超出文件开头时不会失败:

def callback(in_data, frame_count, time_info, status):
    global index
    data = wf.readframes(frame_count)
    data = data[::-1]
    index-=1024
    if index < 0:
        return (data, pyaudio.paAbort)
    else:
        wf.setpos(max(index,0))
        return (data, pyaudio.paContinue)
Run Code Online (Sandbox Code Playgroud)

除此之外,它工作得很好.