如何使用pyaudio反转音频 [英] How to reverse audio with pyaudio

查看:74
本文介绍了如何使用pyaudio反转音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一段时间以来,我一直在修补 pyaudio ,试图反转简单的wave文件但没有成功.

I've been tinkering around with pyaudio for a while now, trying to reverse a simple wave file with no success.

在(我的)理论中,我只需要从头到尾遍历整个文件,每次pyaudio回调(1024帧)都会从文件中的相应索引中获取音频数据,反转生成的字符串并进行播放.

In (my) theory I would only have to iterate from end to beginning through the file with every callback of pyaudio (1024 frames) fetch the audio data from the according index in the file, reverse the resulting string and play it.

这是我的代码(仅pyaudio回调和文件处理,其余未与示例代码保持一致):

Here is my code (only pyaudio callback and file handling, the rest is untouched from the example code):

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

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

I know this will crash when it reaches the file beginning, but it should play 40 × 1024 frames of reversed audio...

推荐答案

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

If the file you want reversed is small enough to fit in memory, your best bet would be loading it entirely and reversing the data, then streaming it:

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

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

However, if the file is too big to fit in memory, you'll need some way of reading the file backwards and feed into the sound system. That's an entirely different problem, because it involves some low level I/O programming to handle the backward reading.

看到完整的代码后,我看不到任何错误.该代码可以在我的计算机上正常运行,只是在播放结束时失败.但是,您可以做两件事.首先,您可以使用以下方法转到wavefile的末尾以播放整个声音:

after seeing your full code, I don't see any errors. The code runs properly in my computer, only to fail at the ending of the playback. However, you can do two things. First, you can go to the end of the wavefile to play the entire sound backwards, using this:

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

第二,您必须修改回调,以使当搜索头超出文件开头时它不会失败:

Second, you have to modify the callback so it doesn't fail when the seek head goes beyond the beginning of the file:

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)

除此之外,它还可以.

这篇关于如何使用pyaudio反转音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆