包括对读取的音频数据的dft(离散傅里叶变换)、idft,stft(短时傅里叶变换)、istft,ssa(奇异谱分析),分帧和复原。
# coding=utf-8
"""
对音频数据的几种数据转换方式的实现
"""
import numpy as np
from scipy.fftpack import fft, ifft
import librosa
import scipy.io.wavfile as wav
def read_wav(audio_path):
'''使用scipy库下的方法读取音频文件wav,返回时间序列y(数据类型和声道数由文件本身决定)和采样率sr'''
sr, y = wav.read(filename=audio_path) #读取音频文件,返回音频采样率和时间序列
return y, sr
def write_wav(y, sr, save_path):
'''使用scipy库下的方法,将时间序列保存为wav格式,y是音频时间序列,sr是采样率,save_path="***.wav"'''
wav.write(filename=save_path, rate=sr, data=np.array(np.clip(np.round(y), -2**15, 2**15-1), dtype=np.int16))
# ————————————————————————————————DFT和逆DFT——————————————————————————————————————————————————————————————————————
def dft(audio, sr, n=None):
'''对输入音频数据进行DFT(离散傅里叶变换)
输入参数:
audio: 读取的音频时间序列数据;
sr: 是音频文件的采样率。
返回DFT后的频率数组及相应的幅值和音频文件的采样率。
'''
if(n == None):
n = audio.shape[0] # 音频时间序列的长度
y = np.fft.rfft(a=audio, n=n) # 离散傅里叶变换(DFT),返回一个长度为len(audio)/2+1的复数数组
# print(y[:10])
f = np.fft.fftfreq(n=n, d=1/sr)[:n//2+1] # 返回DFT后每个值对应的频率; 即 k*sr/n = k/d*n,k表示时间序列的索引值;(0, sr/n, 2*sr/n, ..., sr/2)
f[-1] = f[-1] * -1
return f, y, sr # 返回DFT后的频率数组及相应的幅值和音频文件的采样率
def idft(y, n=None):
'''逆DFT变换,是指将DFT得到的复数数组重新变换为音频时间序列的形式'''
# y是对音频进行DFT的结果,n是DFT时设置的值;
if(n == None):
input = np.fft.irfft(y)
else:
input = np.fft.irfft(y, n)
input = np.array(np.clip(np.round(input), -2**15, 2**15-1), dtype=np.int16)
return input
# audio, sr = read_wav("sample.wav")
# print(audio.shape)
# print(audio[1000:1010])
# f, y, sr = dft(audio, sr)
# y_inv = idft(y)
# print(y_inv.shape)
# print(y_inv[1000:1010])
# ——————————————————————————————————————————————————————————————————————————————————————————————————————————————
# ************************STFT和逆STFT*************************************************************************
def stft(audio):
"""对读取到的音