Python 音频帧音调变化

4 投票
2 回答
11671 浏览
提问于 2025-04-16 19:27

我正在尝试使用pyaudio来制作一个声音变声器。现在的设置是,我只需要输入声音,实时改变音调,然后再把声音输出。前面和最后的部分都能正常工作,我觉得我快要能改变音调了……强调一下“觉得”。

不过,我对我正在处理的数据类型不太熟悉,也不知道怎么按照我想要的方式来操作它。我看过audioop的文档,但没找到我需要的东西(虽然里面有一些我确实可以用到的内容)。我想问的是……

这些音频帧中的数据是怎么格式化的?

我该如何改变一个帧的音调(如果可以的话),或者说这样操作是否可行?

import pyaudio
import sys
import numpy as np
import wave
import audioop
import struct

chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 41000
RECORD_SECONDS = 5

p = pyaudio.PyAudio()

stream = p.open(format = FORMAT,
                channels = CHANNELS,
                rate = RATE,
                input = True,
                output = True,
                frames_per_buffer = chunk)

swidth = 2

print "* recording"



while(True):

    data = stream.read(chunk)
    data = np.array(wave.struct.unpack("%dh"%(len(data)/swidth), data))*2

    data = np.fft.rfft(data)
    #MANipulation
    data = np.fft.irfft(data)



    stream.write(data3, chunk)




print "* done"

stream.stop_stream()
stream.close()
p.terminate()

2 个回答

5

irfft这一行之后,和stream.write这一行之前,你需要用struct.pack这个方法把数据转换回16位的整数。

data = np.fft.irfft(data)
dataout = np.array(data*0.5, dtype='int16') #undo the *2 that was done at reading
chunkout = struct.pack("%dh"%(len(dataout)), *list(dataout)) #convert back to 16-bit data
stream.write(chunkout)
3

要改变音调,你需要对一系列音频片段进行一个叫做FFT的处理,然后在频率上移动数据(也就是把数据放到不同的频率区间),最后再进行一次反向FFT。

如果你不介意在降低音调时声音片段变得更长(或者在提高音调时变得更短),你可以对这些片段进行重采样。比如说,你可以把每个片段复制一遍(在音频流中插入每个片段的副本),这样就会降低播放速度和音调。之后,你可以通过改进重采样的算法,使用一些插值和/或过滤的方法来提高音质。

撰写回答