將音頻信號轉換為頻域
實驗內容
將音頻信號轉換為頻域
原理
(1)音頻信號是不同頻率、幅度和相位的正弦波的復雜混合,正弦波也稱作正弦曲線,
(2)音頻信號的頻率內容中隱藏了很多資訊,事實上,一個音頻信號的性質由其頻率內容決定,世界上的語音和音樂都是基于這個事實的,
(3)使用傅里葉變換可以將音頻信號轉換為頻域
實驗程序
1.詳細步驟:
(1) 創建一個Python檔案,并匯入以下程式包:

(2) 讀取input_freq.wav音頻檔案:

(3) 對信號進行標準化:

(4) 音頻信號就是一個NumPy陣列,因此用以下代碼提取其長度:

(5) 傅里葉變換,傅里葉變換是關于中心點對稱的,因此,只需要轉換信號的前半部分,
最終目標是提取功率信號,因此,需要先將信號的值平方:

(6) 提取信號的長度:

(7) 根據信號的長度將信號乘以2:

(8) 功率信號用下面的公式獲得:

(9) X軸是時間軸,根據采樣頻率對其進行縮放,并將其轉換成秒:

(10) 繪制該信號:

運行結果


源代碼
# -*- coding: utf-8 -*-
"""
Created on Sun Sep 20 10:23:56 2020
@author: h'p
"""
import numpy as np
from scipy.io import wavfile
import matplotlib.pyplot as plt
#(2) 讀取input_freq.wav音頻檔案:
sampling_freq, audio = wavfile.read(r"C:\Users\h'p\Desktop\speaker_test_sound.wav")
# 對信號進行標準化
print(audio)
audio = audio / (2.**15)
print(type(audio))
print(audio.shape)
# 提取陣列長度
len_audio = len(audio)
# 應用傅里葉變換
transformed_signal = np.fft.fft(audio)
half_length = int(np.ceil((len_audio + 1) / 2.0) )#源代碼有誤,這里必須是int
transformed_signal = abs(transformed_signal[0:half_length])
transformed_signal /= float(len_audio)
transformed_signal **= 2
# 提取轉換信號的長度
len_ts = len(transformed_signal)
# 將部分信號乘以2
if len_audio % 2:
transformed_signal[1:len_ts] *= 2
else:
transformed_signal[1:len_ts-1] *= 2
# 獲取功率信號
power = 10 * np.log10(transformed_signal)
# 建立時間軸
x_values = np.arange(0, half_length, 1) * (sampling_freq / len_audio) / 1000.0
# 畫圖
plt.figure()
plt.plot(x_values, power, color='black')
plt.xlabel('Freq (in kHz)')
plt.ylabel('Power (in dB)')
plt.show()
實驗結論
1.實驗中使用了numpy包中的快速傅里葉變換fft,將原來的音頻信號audio進行了轉換,最紅根據功率信號的相關公式轉換成了功率,用作Y軸,同時把采樣頻率進行了轉化,對應轉換成了時間,最后畫了一個功率隨頻率變化的影像,
2.從圖中可以看出,隨著頻率的增加,功率信號越來越小,同時影像也變得越來越密集,說明采樣頻率越高,每秒鐘獲得的采樣信號越多,同時音頻也會越連續,
3. 如果采樣率很高, 用媒體播放器收聽音頻時,會感覺到信號是連續的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/237161.html
標籤:其他
下一篇:VC++鍵盤鉤子demo
