主要功能
续我上一个博客python编程实现语音数据分帧及分帧还原得到的语音分帧数据文件,继续对数据进行fft变换。
说明:本程序对输入数据为1列时能使用自己编写的fft程序进行fft,但运行效率较低,输入较大数据量不容易运行出来,同时也能调fft包实现,且效率较高。
对输入数据数据列数不为1列时只能调fft包进行fft(即自己编写的fft程序对输入数据为多列时不适用)
一 分帧数据的fft变换
程序
主要对分帧后的语音数据进行fft变换,采用调用fft包。
#语音数据进行fft(调包,只能处理大于1列数据的数据文件)
import numpy as np
import getopt
import sys
import wave
'''
说明:本程序对输入数据为1列时能使用自己编写的fft程序进行fft,但运行效率较低,输入较大数据量不容易运行出来,同时也能调fft包实现,且效率较高
对输入数据数据列数不为1列时只能调fft包进行fft(即自己编写的fft程序对输入数据为多列时不适用)
调包和不调包主要修改程序中的这两个语句:
#fft_data = np.fft.fft(wave_data)
fft_data = fft1(wave_data) #自己编写的dft函数,但只能处理一列的数据文件,且运行效率很低
上面一个语句为调fft包,下面一个语句为自己编写的fft程序
'''
def fft1(wave_data1):
fft_data=[]
k1 = np.arange(0, len(wave_data1), 1) #采样点数
x=len(wave_data1)
print('数据个数=',x)
N=len(k1)
#print('数据个数',N)
for j in k1:
fft_data1=0
for i in range(0, len(wave_data1)):
fft_data1=fft_data1+wave_data1[i]*complex(np.cos(2*np.pi*i*j/N),-np.sin(2*np.pi*i*j/N)) #f=j*fs/N ; t=i/fs
fft_data.append(fft_data1)
fft_data = np.array(fft_data)
return fft_data
def main(argv):
try:
opts, args = getopt.getopt(argv[1:], "-i:-o:h", ["input=", "output=","help"])
except getopt.GetoptError:
print('输入格式错误,输入为语音数据文件,输出为进行fft变换之后的数据文件')
print('命令行运行方式:python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt')
sys.exit()
# 处理 返回值options是以元组为元素的列表。
for opt, arg in opts:
if opt in ("-h", "--help"):
print("对音频数据进行FFT变换")
print('命令行运行方式:')
print('Englishframe1.txt为分帧后的语音数据')
print('对分帧数据运行:python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt')
print('test.txt为截取的English.txt的前256行数据')
print('调包实现:python wavtxtfft.py -i test.txt -o fft_test1.txt')
print('自己编写的fft程序实现:python wavtxtfft.py -i test.txt -o fft_test2.txt')
sys.exit()
elif opt in ("-i", "--input"):
input = arg
elif opt in ("-o", "--output"):
output = arg
wave_data = np.loadtxt(input, dtype=np.short) #读取文件数据
print(wave_data)
#fft_data = np.fft.fft(wave_data)
fft_data = fft1(wave_data) #自己编写的dft函数,但只能处理一列的数据文件,且运行效率很低
print(fft_data)
length = len(fft_data.T)#得到数据文件列数,(前提是数据不止一列,如果数据只有一列,则得到的是数据的个数)
#print('文件列数=',length)
fft_len = len(fft_data)#数据文件行数
print('文件行数=',fft_len)
file = open(output, 'w+')
m = (fft_data.T).ndim # 判断数据是一维还是多维(对数据取转置,再判断维度,即判断输入数据列数为1列还是多列,1列和多列处理方法不一样)
if m == 1: # 如果数据为1列
print('文件列数=1')
for i in range(fft_len):
s = str(fft_data[i]).replace('[', ").replace('[',")
s = s.replace('(', '').replace(')', '') + ' ' # 去除小括号,每个数据加空格
s = s.replace("'", ").replace(',',") # 去除单引号,逗号
file.write(s) # 数据存文件
file.write('\n') # 每行读取完以后换行
file.close()
else:
print('文件列数=', length)
for i in range(fft_len):
for j in range(length):
#for j in range(4):
s = str(fft_data[i,j]).replace('[', '').replace(']','')
#s = str(fft_data[i, j]).replace('[', ").replace(']',")
s = s.replace('(', '').replace(')', '') + ' ' # 去除小括号,每个数据加空格
s = s.replace("'", '').replace(',','')
file.write(s) #数据存文件
file.write('\n') # 每行读取完以后换行
file.close()
if __name__ == "__main__":
main(sys.argv) #调用函数
#English.txt为1列的原始语音数据
#python wavtxtfft.py -i English.txt -o fft_English.txt
#Englishframe1.txt为分帧后的语音数据
#python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt
#test.txt为截取的English.txt的前256行数据
#python wavtxtfft.py -i test.txt -o fft_test1.txt
#python wavtxtfft.py -i test.txt -o fft_test2.txt
查看帮助文档
python wavtxtfft.py -h
结果:
对音频数据进行FFT变换
命令行运行方式:
Englishframe1.txt为分帧后的语音数据
对分帧数据运行:python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt
test.txt为截取的English.txt的前256行数据
调包实现:python wavtxtfft.py -i test.txt -o fft_test1.txt
自己编写的fft程序实现:python wavtxtfft.py -i test.txt -o fft_test2.txt
运行
python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt
#结果
[[ 0 -24 -6 -18]
[ -6 -18 -14 0]
[-14 0 -24 -4]
...
[ -8 -8 6 10]
[ 6 10 32 28]
[ 32 28 34 0]]
[[-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]]
文件列数= 4
文件行数= 265651
保存文件结果:
分帧数据fft变换后保持原数据格式。
二 截短语音数据的fft变换(调包和不调包)
程序
输入数据为一行一个数据,分别进行调包的fft和自己编写的fft程序
#语音数据进行fft(调包,只能处理大于1列数据的数据文件)
import numpy as np
import getopt
import sys
import wave
'''
说明:本程序对输入数据为1列时能使用自己编写的fft程序进行fft,但运行效率较低,输入较大数据量不容易运行出来,同时也能调fft包实现,且效率较高
对输入数据数据列数不为1列时只能调fft包进行fft(即自己编写的fft程序对输入数据为多列时不适用)
调包和不调包主要修改程序中的这两个语句:
#fft_data = np.fft.fft(wave_data)
fft_data = fft1(wave_data) #自己编写的dft函数,但只能处理一列的数据文件,且运行效率很低
上面一个语句为调fft包,下面一个语句为自己编写的fft程序
'''
def fft1(wave_data1):
fft_data=[]
k1 = np.arange(0, len(wave_data1), 1) #采样点数
x=len(wave_data1)
print('数据个数=',x)
N=len(k1)
#print('数据个数',N)
for j in k1:
fft_data1=0
for i in range(0, len(wave_data1)):
fft_data1=fft_data1+wave_data1[i]*complex(np.cos(2*np.pi*i*j/N),-np.sin(2*np.pi*i*j/N)) #f=j*fs/N ; t=i/fs
fft_data.append(fft_data1)
fft_data = np.array(fft_data)
return fft_data
def main(argv):
try:
opts, args = getopt.getopt(argv[1:], "-i:-o:h", ["input=", "output=","help"])
except getopt.GetoptError:
print('输入格式错误,输入为语音数据文件,输出为进行fft变换之后的数据文件')
print('命令行运行方式:python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt')
sys.exit()
# 处理 返回值options是以元组为元素的列表。
for opt, arg in opts:
if opt in ("-h", "--help"):
print("对音频数据进行FFT变换")
print('命令行运行方式:')
print('Englishframe1.txt为分帧后的语音数据')
print('对分帧数据运行:python wavtxtfft.py -i Englishframe1.txt -o fft_Englishframe1.txt')
print('test.txt为截取的English.txt的前256行数据')
print('调包实现:python wavtxtfft.py -i test.txt -o fft_test1.txt')
print('自己编写的fft程序实现:python wavtxtfft.py -i test.txt -o fft_test2.txt')
sys.exit()
elif opt in ("-i", "--input"):
input = arg
elif op