Python 音频帧音高变化

Posted

技术标签:

【中文标题】Python 音频帧音高变化【英文标题】:Python Audio Frame Pitch Change 【发布时间】:2011-06-13 05:00:35 【问题描述】:

我正在尝试使用 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()

【问题讨论】:

我是否遗漏了什么或者data3 应该是data(在对stream.write 的调用中)? 【参考方案1】:

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)

【讨论】:

知道了...完美。非常感谢你们。 这太好了,超级有帮助,谢谢!除了,我认为有一个错字 - 第三行不应该是“chunkout = wave.struct.pack[...]”吗? @scubbo - 谢谢。我认为应该是struct.pack 而不是wave.struct.pack,但是是的,你是对的。 @mtrw 你如何改变你想要的音高变化量? (+1)。 @Neil - 此答案仅涉及问题的数据格式部分。音高转换是一个巨大的话题,我对此知之甚少。您可能想在dsp.stackexchange.com 上提问。【参考方案2】:

要更改音高,您必须对多个帧执行FFT,然后按频率移动数据(将数据移动到不同的频率区间)并执行逆 FFT。

如果您不介意声音片段在降低音高时变长(或在增加音高时变高),您可以resample 帧。例如,您可以将每帧加倍(在流中插入每帧的副本),从而降低播放速度和音调。然后,您可以通过改进重采样算法以使用某种插值和/或过滤来提高音频质量。

【讨论】:

我尝试在之后立即执行 FTT 和 IFFT...返回静态。数组中还应该有虚构的组件吗? 不,如果您对真实信号执行 FFT,然后执行 IFFT,则结果将是真实信号。 嘿...好吧,我想问题出在拆包而不是 FTT 上。我已将代码更新为现在的代码。 您能解释一下您将如何处理“将数据移动到不同频率的引脚”部分吗?要更改音高,您是否只需按某个常数缩放数据数组中的所有值? 如果您的 FFT 数据在数组 x[1]...x[N] 中,那么您会将所有元素向上移动 y[n] = x[n-k],或向下移动 y[n ] = x[n+k]。音高的变化为 k*f/2,其中 f 是采样率。

以上是关于Python 音频帧音高变化的主要内容,如果未能解决你的问题,请参考以下文章

Python改变wav文件的音高[关闭]

是否可以更改音频队列的播放音高

librosa音频处理教程

添加效果后导出音频文件

从音频文件中提取音高特征

如何将提取的音高值保存在 csv 文件中?