本文主要实现对我上一个博客python编程实现分帧数据的fft变换得到的fft变换的数据进行ifft变换,得到原始分帧数据。
原始分帧的语音数据进行fft变换得到fft数据,现在通过ifft变换,将fft变换的数据还原为原始语音分帧数据。
通过调用ifft包实现。
#语音数据进行ifft(调包和不调包)
import numpy as np
import getopt
import sys
import wave
def main(argv):
try:
opts, args = getopt.getopt(argv, "-i:-o:h", ["input=", "output=","help"])
except getopt.GetoptError:
print('输入格式错误,输入为语音数据文件,输出为进行ifft变换之后的数据文件')
print('命令行运行方式:python wavtxtifft.py -i fft_Englishframe1.txt -o ifft_Englishframe1.txt')
sys.exit()
# 处理 返回值options是以元组为元素的列表。
for opt, arg in opts:
if opt in ("-h", "--help"):
print("对音频数据进行IFFT变换")
print('命令行运行方式:')
print('分帧数据ifft变换:python wavtxtifft.py -i fft_Englishframe1.txt -o ifft_Englishframe1.txt')
sys.exit()
elif opt in ("-i", "--input"):
input = arg
elif opt in ("-o", "--output"):
output = arg
fft_data = np.loadtxt(input, dtype=np.complex) #输入数据格式为complex(复数格式)
print('原始fft数据:\n',fft_data)
ifft_data = np.fft.ifft(fft_data)
'''
逆向快速傅里叶变换(IFFT)的计算原理是将频域(注意频域是复数)数据进行取共轭复数(虚部取反),然后再进行FFT变换,这样便将频域信号转换到时域。
因为FFT变换的结果是复数,所以从频域进行FFT变换过来的结果也是复数,而此时只需取复数的实部,便是原时域信号。
先将要做Ifft的数据取共轭,然后fft,结果再除以N(N为数据长度),结果就是ifft的结果。不过和直接ifft算法相比有精度上的误差。
'''
ifft_data = np.real(ifft_data) # 取出实部(进行ifft变换后,虚部为0,取出实部即为进行fft变换前的原始分帧数据)
ifft_data = np.round(ifft_data) # 返回浮点数的四舍五入值。
print('ifft变换后的数据:\n',ifft_data)
length = len(ifft_data.T)#得到数据文件列数,(前提是数据不止一列,如果数据只有一列,则得到的是数据的个数)
print('文件列数=',length)
fft_len = len(ifft_data)#数据文件行数
print('文件行数=',fft_len)
file = open(output, 'w+')
m = (ifft_data.T).ndim # 判断数据是一维还是多维(对数据取转置,再判断维度,即判断输入数据列数为1列还是多列,1列和多列处理方法不一样)
if m==1: #如果数据为1列
for i in range(fft_len):
s = str(ifft_data[i]).replace('[', ").replace('[',")
s = s.replace('(', '').replace(')', '') + ' ' # 去除小括号,每个数据加空格
s = s.replace("'", ").replace(',',") + '\n' # 去除单引号,逗号,每行末尾追加换行符
s = float(s)
s = int(s)
s = str(s)
file.write(s) # 数据存文件
file.write('\n') # 每行读取完以后换行
file.close()
else: #数据列数大于1列
for i in range(fft_len):
for j in range(length):
#for j in range(4):
s = str(ifft_data[i,j]).replace('[', '').replace(']','')
s = s.replace('(', '').replace(')', '') + ' ' # 去除小括号,每个数据加空格
s = s.replace("'", '').replace(',','')
s = float(s)
s = int(s)
s = str(s)
file.write(s) #数据存文件
file.write(' ') #每个数据写入后,在数据后面加个空格
file.write('\n') # 每行读取完以后换行
file.close()
if __name__ == "__main__":
# sys.argv[1:]为要处理的参数列表,sys.argv[0]为脚本名,所以用sys.argv[1:]过滤掉脚本名。
main(sys.argv[1:])
#python wavtxtifft.py -i fft_Englishframe1.txt -o ifft_Englishframe1.txt
python wavtxtifft.py -h
结果:
对音频数据进行IFFT变换
命令行运行方式:
分帧数据ifft变换:python wavtxtifft.py -i fft_Englishframe1.txt -o ifft_Englishframe1.txt
程序在pycharm上编辑,运行,采用命令行方式,即pycharm软件左下角有一个Terminal,点击即可在里面的命令行运行程序。
输入命令:
python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt
结果:
原始fft数据:
[[-48. +0.j 6. +6.j 36. +0.j 6. -6.j]
[-38. +0.j 8.+18.j -2. +0.j 8.-18.j]
[-42. +0.j 10. -4.j -34. +0.j 10. +4.j]
...
[ 0. +0.j -14.+18.j -4. +0.j -14.-18.j]
[ 76. +0.j -26.+18.j 0. +0.j -26.-18.j]
[ 94. +0.j -2.-28.j 38. +0.j -2.+28.j]]
ifft变换后的数据:
[[ 0. -24. -6. -18.]
[ -6. -18. -14. 0.]
[-14. 0. -24. -4.]
...
[ -8. -8. 6. 10.]
[ 6. 10. 32. 28.]
[ 32. 28. 34. 0.]]
文件列数= 4
文件行数= 265651
将进行ifft还原的原始分帧数据保存在txt文件中,保存文件结果:
原始语音分帧数据:
通过比较发现,ifft数据相比原始数据,结果正确。