FFT와 MFCC로 설계하는 오디오 특징 추출 파이프라인

FFT, STFT, Mel 필터뱅크, MFCC의 처리 흐름과 파라미터 선택, 실시간 오디오 AI 운영 시 점검할 요소를 정리한다.

2026-08-14 · 최초 발행 2024-04-29

파형을 모델 입력으로 바꾸는 과정

오디오 AI에서 파형은 그대로 모델에 넣기보다, 시간에 따른 신호를 주파수 특성으로 변환해 사용한다. FFT(Fast Fourier Transform)와 MFCC(Mel-Frequency Cepstral Coefficients)는 이 변환 경로의 핵심이다.

FFT는 시계열 신호를 주파수 영역으로 옮기는 고속 푸리에 변환 알고리즘이며, 복잡도는 O(N log N)이다. STFT는 프레임 단위로 FFT를 적용해 시간-주파수 스펙트럼을 얻는다. 창 함수를 적용하면 스펙트럼 누설(leakage)을 완화할 수 있다.

MFCC는 Mel 스케일 필터뱅크, 로그 압축, DCT(이산 코사인 변환)를 순서대로 적용해 음성 지각 특성에 정렬된 켑스트럼 계수를 뽑는다. 전통적인 음성 인식과 경량 모델에서 표준적으로 사용된다. 프리엠퍼시스(pre-emphasis)는 고주파를 증폭하고, 프레이밍과 윈도잉은 신호의 국소 정적성 가정을 뒷받침한다. 델타와 델타-델타는 시간에 따른 변화량을 담는다.

전처리부터 특징 행렬까지의 연결

입력은 프리엠퍼시스, 모노 채널 합성, 정규화를 거친다. 이 과정은 과도한 클리핑을 피하고 수치적 안정성을 확보하는 역할을 한다. 음성은 20~25 ms 프레임과 10 ms 홉으로 나누어 준정상성 가정에 맞춘다.

Hann 또는 Hamming 윈도우는 스펙트럼 누설을 줄인다. n_fft는 2의 거듭제곱을 권장하며, 예로 512와 1024를 사용할 수 있다. 이후 파워 스펙트럼 |X(f)|^2에서 에너지 특성을 얻는다.

Mel 스케일의 삼각 필터는 인간 청각의 해상도를 반영한다. 저주파에서는 해상도가 높고 고주파에서는 낮다. 로그 압축은 동적 범위를 줄여 잡음에 대한 견고성을 높인다. 로그 멜 에너지에 DCT를 적용하면 상관성을 제거하면서 저차원으로 압축할 수 있으며, 통상 12~13차를 사용한다. 리프터링(lifter)은 고차 성분을 완화한다. 델타와 델타-델타를 붙이면 13차 특징은 26/39차로 확장된다.

아니오길이 < 프레임NaN/Inf 검출입력 오디오 파일/스트림샘플레이트 일치?리샘플링(예: 16 kHz)프리엠퍼시스(α≈0.97)프레이밍(20~25 ms)윈도잉(Hann)STFT/FFT파워 스펙트럼 |X|^2Mel 필터뱅크(n_mels=40)로그 압축DCTMFCC(13차) + Δ/ΔΔ제로패딩 또는 오류 반환수치 안정화(ε 추가, 클리핑)특징 행렬(시간×차원)

스펙트럼 표현을 고르는 기준

지표 FFT/선형 스펙트럼 로그-멜 스펙트로그램 MFCC
성능(분류/ASR) 기저 피처, 모델 의존도 높음 딥러닝 입력에 표준적용 전통/경량 모델에 우수
확장성(스트리밍) 매우 용이 용이 용이
일관성(샘플레이트) SR 변화에 민감 Mel 스케일로 상대적 완화 Mel+DCT로 추가 완화
안정성(잡음) 민감 로그 압축으로 개선 차원 축소·장해 완화로 견고
운영 편의 해석 용이(주파수 기반) 시각화/디버깅 용이 저차원으로 저장/전송 효율적

온라인·오프라인 ASR에서는 로그-멜 또는 MFCC를 음향 모델 입력으로 사용한다. 키워드 스폿팅과 웨이크워드에서는 짧은 윈도우의 MFCC 13/26/39차 특징이 경량 모델 구동에 적합하다.

화자 인식과 검증에서는 MFCC에 통계 누적을 더해 i-vector/x-vector 앞단에 적용하며, 채널 변이에 대한 기본 견고성을 확보한다. 환경음과 이벤트 분류는 로그-멜 스펙트로그램을 CNN 입력으로 쓰고 전이학습과 결합할 수 있다. 음악 정보 검색(MIR)에서는 비트, 장르, 템포 분석의 기초 스펙트럼 피처로 FFT와 멜 스펙트럼을 활용한다.

처리량과 메모리 관점

1초(16 kHz) 기준으로 프레임은 약 100개이며, MFCC 13차를 사용하면 약 1,300 특징/초를 산출한다. FFT(512)는 약 0.46M op/s, 멜 필터(40×257)는 약 1.03M op/s, DCT는 약 0.05M op/s로 합계는 약 1.5M op/s 수준이다. 일반 CPU에서 실시간 처리가 가능하다.

입력 메모리는 float32 기준 약 64 KB이고, 중간 스펙트럼은 약 257×100으로 약 103 KB 수준이다. 이 경로는 노이즈와 채널 변화에 대한 견고성을 높이고, 모델 수렴 안정성과 재현성을 개선한다. 피처를 해석할 수 있어 디버깅과 모니터링에도 유리하다.

파라미터와 운영 정책

음성에는 25 ms/10 ms 조합을 권장한다. 음악 또는 잡음 분류에서는 더 큰 n_fft와 작은 홉으로 주파수 해상도를 강화할 수 있다. 잡음 환경은 더 긴 평균화를 고려하고, 음악 분석은 더 큰 n_fft와 더 촘촘한 홉 설정을 사용한다.

로그 연산 전에는 ε=1e-10을 추가하고 입력 RMS를 정규화해 볼륨 편차를 완화한다. 샘플레이트는 단일 SR, 예를 들어 16 kHz로 통일하며, 서로 다른 SR 입력은 서버단 리샘플러에서 일원화한다.

경량·전통 모델에는 MFCC가 적합하다. CNN과 Transformer 기반 딥러닝 파이프라인은 로그-멜 스펙트로그램을 사용하고, 초저지연 스트리밍에서는 FFT 또는 멜 스펙트럼을 직접 피딩하는 방식을 고려한다. 운영 지표로는 입력 클리핑 비율, 무성구간 비율, NaN/Inf 카운트를 수집하고 피처 분포 드리프트를 감지한다.

Python으로 확인하는 특징 추출

전제조건은 Python 3.10+, numpy 1.24+, librosa 0.10+, soundfile 0.12+이며, 설치 명령은 pip install numpy librosa soundfile이다.

import numpy as np
import librosa

def pre_emphasis(y, coef=0.97):
    if y.size == 0:
        raise ValueError("빈 오디오 입력")
    y = np.asarray(y, dtype=np.float32)
    return np.append(y[0], y[1:] - coef * y[:-1])

def compute_fft_mag(y, sr, n_fft=512, hop_length=160, win_length=400, window="hann"):
    # STFT 기반 프레임별 FFT 크기 스펙트럼
    S = librosa.stft(y, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window=window, center=True)
    mag = np.abs(S)  # shape: (n_fft//2+1, n_frames)
    return mag

def compute_mfcc(y, sr, target_sr=16000, n_fft=512, hop_length=160, win_length=400,
                 n_mels=40, n_mfcc=13, pre_emph=0.97, lifter=22):
    # 1) 샘플레이트 정규화
    if sr != target_sr:
        y = librosa.resample(y, orig_sr=sr, target_sr=target_sr)
        sr = target_sr
    # 2) 프리엠퍼시스
    y = pre_emphasis(y, coef=pre_emph)
    # 3) 길이 검사 및 패딩
    if y.shape[0] < win_length:
        pad = win_length - y.shape[0]
        y = np.pad(y, (0, pad))
    # 4) MFCC 계산
    # 안정성: 작은 상수 추가를 위해 power_to_db 이전 단계에서 amin 설정
    mel_spec = librosa.feature.melspectrogram(
        y=y, sr=sr, n_fft=n_fft, hop_length=hop_length, win_length=win_length,
        n_mels=n_mels, power=2.0, center=True, window='hann')
    log_mel = librosa.power_to_db(mel_spec, ref=np.max, amin=1e-10, top_db=80.0)
    mfcc = librosa.feature.mfcc(S=log_mel, n_mfcc=n_mfcc, lifter=lifter, dct_type=2, norm='ortho', htk=True)
    # 5) 델타/델타-델타
    delta = librosa.feature.delta(mfcc, order=1)
    delta2 = librosa.feature.delta(mfcc, order=2)
    mfcc_full = np.vstack([mfcc, delta, delta2])  # shape: (n_mfcc*3, n_frames)
    # 6) NaN/Inf 처리
    if not np.isfinite(mfcc_full).all():
        mfcc_full = np.nan_to_num(mfcc_full, nan=0.0, posinf=0.0, neginf=0.0)
    return mfcc_full, log_mel

if __name__ == "__main__":
    # 예시 로드
    path = "sample.wav"  # 16 kHz 모노 권장
    y, sr = librosa.load(path, sr=None, mono=True)
    # FFT 크기 스펙트럼
    mag = compute_fft_mag(y, sr)
    # MFCC + 로그멜
    mfcc_feat, log_mel = compute_mfcc(y, sr)
    print("FFT mag shape:", mag.shape)        # (freq_bins, frames)
    print("MFCC shape:", mfcc_feat.shape)     # (39, frames) 기본
    print("Log-Mel shape:", log_mel.shape)    # (n_mels, frames)

입력 RMS와 피크를 모니터링하고 클리핑 알림을 구성한다. 프레임 드롭이 발생하면 제로패딩 처리와 메트릭 기록을 함께 수행한다. 실시간 모드에서는 홉 기준 배치 처리, 예를 들어 10 ms 단위 처리를 사용해 지연을 최소화한다.

오디오 처리FFTMFCC음성 인식특징 추출