類比訊號透過取樣 sampling 與量化 quantization 兩個步驟,擷取數位訊號,並以數學表示法討論數位訊號。
數位訊號定義為:隨著時間改變的離散訊號,也稱為離散時間訊號 Discrete-Time Signals
自然界的訊號通常都是類比訊號,因此必須先透過類比/數位轉換器 Analog/Digital Converter, A/D Converter 將類比訊號轉成數位訊號,以便電腦系統處理。過程是根據類比訊號,在時間軸上擷取離散的樣本 samples,藉以產生數位訊號。x(t) 代表類比訊號,x[n] 代表數位訊號,t 為時間,n 是索引。
取樣與量化
取樣 sampling 可定義為 \(x[n]=x(nT_s)\),\(T_s\) 稱為取樣週期 sampling period 或取樣間隔 sampling interval,單位為 second,另外 \(f_s=\frac{1}{T_s}\) 稱為取樣頻率 sampling frequency,或取樣率 sampling rate
取樣是訊號在時間軸上的數位化過程,每隔 \(T_s\) 時間,擷取一個樣本 sample,產生一個數字序列,因每個樣本來自短暫的時間框,也稱為音框 frame
取樣率 sampling frequency 解釋為:每秒取樣的次數。由於取樣頻率固定不變,又稱為均勻取樣 Uniform Sampling
ex: 弦波 \(x(t)=A cos(ωt+ϕ) = Acos(2 \pi ft+ϕ)\) ,若取樣週期 \(T_s\),取樣頻率 \(f_s\),則弦波的數位訊號可表示為
\(x[n]=x(nT_s)=A cos(2 \pi fnT_s+ϕ)=A cos(2 \pi fn/f_s+ϕ)\),n為整數
通常可假設 \(\hat{ω} = 2 \pi f/f_s\) 稱為正規化角頻率 Normalized Angular Frequency,單位是弧度 Radians,因此數位訊號也可表示為
\(x[n] = A cos(\hat{ω}n+ϕ)\)
Nyquist-Shannon 取樣定理
假設原始訊號為頻帶限制訊號 Band-Limited Signal,最高頻率為 \(f_H\),若取樣頻率為 \(f_s\) ,則 \(f_s > 2 f_H\) 時,才能保證可重建原始訊號
若取樣頻率超過原始訊號的最高頻率的兩倍,可充分表示原始訊號,如取樣頻率不足,會產生混疊 aliasing 現象。
ex: 人類聽力範圍 20Hz ~ 20k Hz,最高為 20kHz,如果 \(f_s>40kHz\) 可充分表示人類可感知的原始訊號。目前 mp3 通常設定為 44kHz or 48kHz,符合基本條件,不會發生 aliasing
根據取樣定理,取樣頻率決定了可取樣的原始最高頻率,又稱為 Nyquist 頻率。例如取樣頻率 44kHz,則 Nyquist 頻率為 22kHz
量化 Quantization
量化是將訊號的振幅 Amplitude 經過數位化轉換為數值,常用的數值範圍:
- 8 bits: 0~255 or -128~127
- 16 bits: -32768 ~ 32767
每個樣本可使用的位元數稱為位元解析度 bit resolution,或稱為位元深度 bit depth。
數學表示法
\(x=\{x[n]\}, -∞<n<∞\),n 為整數
DSP 系統中,數位訊號通常為有限 finite 數字序列,可表示為
\(x=\{x[n]\}, n=0,1,2..., N-1\) ,這是從 t=0 開始的樣本,N為樣本數
import numpy as np
import matplotlib.pyplot as plt
n = np.array( [ 0, 1, 2, 3, 4, 5 ] ) # 定義n陣列
x = np.array( [ 1, 2, 4, 3, 2, 1 ] ) # 定義x陣列
plt.stem( n, x, use_line_collection=True ) # 繪圖
plt.xlabel( 'n' )
plt.ylabel( 'x[n]' )
plt.show( )
基本的數位訊號
單位脈衝函數
Unit Impulse Function 也稱為狄拉克 δ 函數 (Dirac Delta Function),以英國物理學家 Paul Dirac 命名,定義:
\(δ(t)=0, t \neq 0\) ,且 \(\int_{-∞}^{∞}δ(t) {\rm d}t = 1\)
單位脈衝函數是連續時間函數,除了原點 t=0 以外,函數值均為 0,在時間域的積分(總面積)為 1,且集中在原點
單位脈衝
在離散時間域的 Unit Impulse 定義為
\( δ[n] = \left\{ \begin{array}{ll} 1, & \mbox{if n=0} \\ 0, & \mbox{if n≠0} \end{array} \right.\)
單位步階函數
Unit Step Function 也稱為黑維塞步階函數 (Heaviside Step Function),以英國科學家 Oliver Heaviside 命名,定義為
\( μ(t) = \left\{ \begin{array}{ll} 1, & \mbox{if t ≥0} \\ 0, & \mbox{if t<0} \end{array} \right.\)
單位步階
Unit Step 定義為
\( μ[n] = \left\{ \begin{array}{ll} 1, & \mbox{if n ≥0} \\ 0, & \mbox{if n<0} \end{array} \right.\)
單位脈衝的時間延遲 Time Delay 定義為 \(δ[n-n_0]\)
ex: \(δ[n-2]\) 的圖形為
因此 Unit Step 也可表示為
\( μ[n] = δ[n]+δ[n-1]+δ[n-2]+... = \sum_{k=0}^{n}δ[n-k]\)
單位脈衝 Unit Impulse 也可表示為
\(δ[n]=μ[n]-μ[n-1]\)
任意數位訊號都可以用單位脈衝表示為
\(x[n]=...+x[-1]δ[n+1]+x[0]δ[n]+x[1]δ[n-1]+... = \sum_{k=-∞}^{∞}x[k]δ[n-k]\)
數位語音檔
波型音訊檔案格式 Waveform Audio File Format、wave,是 Microsoft 與 IBM 制定的音訊編碼格式。另外 Apple Mac 定義了 aiff 音訊格式。
wav 是根據 Resource Interchange File Format(RIFF) ,為了存取 CD 數位音樂而設計的。前面是 header 共44 bytes,內容由多個區塊 chunks 組成,每個區塊是 4 bytes
起始位址(Bytes) | 位址範圍 | 區塊名稱 | 區塊大小 ( Bytes) | 內容 | 說明 |
---|---|---|---|---|---|
0 | 1 ~ 4 | 區塊編號 | 4 | RIFF | Marks the file as a riff file. |
4 | 5 ~ 8 | 總區塊大小 | 4 | N + 36 | File size (integer) Size of the overall file - 8 bytes |
8 | 9 ~ 12 | 檔案格式 | 4 | "WAVE" | File Type Header. For our purposes, it always equals "WAVE". |
12 | 13~16 | 子區塊 1 標籤 | 4 | "fmt " | Format chunk marker. Includes trailing null |
16 | 17~20 | 子區塊 1 大小 | 4 | 16 | Length of format data as listed above |
20 | 21~22 | 音訊格式 | 2 | 1(PCM) | Type of format (1 is PCM) |
22 | 23~24 | 通道數量 | 2 | 1: (mono), 2: stereo | Number of Channels |
24 | 25~28 | 取樣頻率 | 4 | Hz | Sample Rate, Common values are 44100 (CD), 48000 (DAT). Sample Rate = Number of Samples per second, or Hertz |
28 | 29~32 | 位元組 ByteRate | 4 | ByteRate = (Sample Rate * BitsPerSample * Channels) / 8 取樣頻率 * 位元深度 / 8 | |
32 | 33~34 | 區塊對齊 BlockAlign | 2 | 4 | (BitsPerSample * Channels) / 8 The number of bytes for one sample including all channels ex: 1 -> 8 bit mono, 2 -> 8 bit stereo/16 bit mono, 4 -> 16 bit stereo |
34 | 35~36 | 位元深度 | 2 | 16 | Bits per sample |
36 | 37~40 | 子區塊2標籤 | 4 | "data" | "data" chunk header. Marks the beginning of the data section. |
40 | 41~44 | 子區塊2大小 | 4 | N | Size of the data section, i.e. file size - 44 bytes header. |
44 | 45~ | 資料 | N | 音訊資料 |
wav 沒有採用壓縮技術,檔案大小比其他格式大,但 wav 不會發生失真的狀況。
import wave
filename = input( "Please enter file name: " )
wav = wave.open( filename, 'rb' )
num_channels = wav.getnchannels( ) # 通道數
sampwidth = wav.getsampwidth( ) # 樣本寬度
frame_rate = wav.getframerate( ) # 取樣率
num_frames = wav.getnframes( ) # 音框數
comptype = wav.getcomptype( ) # 壓縮型態
compname = wav.getcompname( ) # 壓縮名稱
print( "Number of Channels =", num_channels )
print( "Sample Width =", sampwidth )
print( "Sampling Rate =", frame_rate )
print( "Number of Frames =", num_frames )
print( "Comptype =", comptype )
print( "Compname =", compname )
wav.close( )
要讀取 wav 的資料,可改用 SciPy 的 io.wavfile 套件,讀取後以 numpy 的陣列回傳
from scipy.io import wavfile
import matplotlib.pyplot as plt
filename = input( "Please enter file name: " )
sampling_rate, x = wavfile.read( filename )
plt.plot( x )
plt.xlabel( 'n' )
plt.ylabel( 'Amplitude' )
plt.show( )
可直接取得 microphone 語音的波形
pip install PyAudio
import numpy as np
import pyaudio
import matplotlib.pyplot as plt
# sampling rate
fs = 11000
# 每次擷取樣本數 1024
CHUNK = 1024
pa = pyaudio.PyAudio( )
stream = pa.open( format = pyaudio.paInt16, channels = 1, rate = fs,
input = True, output = False, frames_per_buffer = CHUNK )
try:
while True:
data = stream.read( CHUNK )
# 字串轉換為 int16
x = np.fromstring( data, np.int16 )
plt.clf( )
plt.plot( x )
plt.axis( [ 0, CHUNK, -30000, 30000 ] )
plt.pause( 0.1 )
except KeyboardInterrupt:
print( "Quit" )
pa.close( stream )
quit( )
沒有留言:
張貼留言