구축 방법 — Signal Processing · v0.1 · 2026-10-26
■ 방법
- 탭 4개: Sampling & Aliasing / Fourier Transform / Digital Filters / Spectrogram. 탭마다 개요·체험 2개·요약·참고문헌
- 표본화: 사인 f(0.5–40 Hz)를 fs(2–40 Hz)로 1초 표본화, 앞뒤 40개 표본을 더 써서 sinc 보간으로 복원. 보이는 주파수 = |f − fs·round(f/fs)|. 수레바퀴: 살 6개, 장 사이 회전을 ±30°로 접어 보이는 회전 속도 계산
- 푸리에: N = 256, fs = 128 Hz(2초), 직접 쓴 radix-2 FFT. 한쪽 진폭 = 2|X[k]|/Σw. 스펙트럼을 눌러 사인 성분(최대 6개) 더하기·빼기. 누설: 직사각·Hann·Blackman 창, dB
- 필터(fs 200 Hz): 이동 평균(N = round(0.443·fs/fc)), 지수 평균(α = 1 − e^(−2πfc/fs)), 창 씌운 sinc FIR(Hamming, 홀수 계수), 2차 버터워스(쌍선형 변환, RBJ 식). |H(f)|는 계수에서 직접. 앞뒤로 두 번(zero-phase)은 양 끝을 끝값 150개로 늘린 뒤 거름
- 스펙트로그램: 8 kHz, 2초 시험 신호(처프 300→1,700 Hz, 2,500 Hz 20 ms, 1,000·1,060 Hz 두 음). 창 32–4,096, hop = 창/4, 색은 최댓값 아래 70 dB. 두 음이 갈라지는지는 1.5초 무렵 열에서 사이가 3 dB 이상 꺼지는지로 판정
- 그려서 만드는 소리: 시간–주파수 경로를 선형 보간, 위상을 쌓아 사인 합성(8 kHz). 마이크는 getUserMedia로 2초, 구간 평균으로 8 kHz로 줄임. 녹음은 화면 안에서만 계산, 전송·저장 없음
- 직접 쓴 JavaScript(sp-core.js, sp.js), 외부 라이브러리 없음 · LLM 없음
■ 데이터
- 모든 신호는 브라우저에서 시드 고정 난수로 합성. 외부 자료 없음
- 마이크 녹음(누를 때만)은 브라우저 메모리에서만 씀
■ 검증
- tests/signal-processing/core-test.mjs 16항목 통과
- FFT = 직접 DFT(64점, 최대 차이 2.7e-13) · 파스발 정리 · 빈 중앙 사인 진폭 1.5·0.7 정확(직사각·Hann)
- 9 Hz를 10 Hz로 표본화하면 스펙트럼 봉우리 0.996 Hz(1 Hz)
- 필터 DC 이득 1(네 종류), 버터워스 차단 주파수에서 −3.0103 dB, 30 Hz 정상 상태 진폭 = |H(30)|
- scipy 1.18.1 대조: butter(2, 10, fs=200) 계수 1e-8 이내, firwin(51, 10, fs=200, hamming) 1e-12 이내
- 처프 STFT 봉우리 250 → 1,641 Hz로 증가
■ 범위
- 1차원 실수 신호, 저역 필터만(고역·대역은 같은 원리), 실시간 오디오 처리 지연은 다루지 않음
■ 출처
- Shannon (1949), Nyquist (1928), Cooley & Tukey (1965), Harris (1978), Butterworth (1930), Gabor (1946), Allen (1977), Oppenheim & Schafer (2010), Smith (1997, 2011), Bristow-Johnson Audio EQ Cookbook, Gustafsson (1996)
■ 이력
- 2026-10-26 · v0.1 · 처음 만듦 · 공개 준비 중
How it's built — Signal Processing · v0.1 · 2026-10-26
■ Method
- Four tabs: Sampling & Aliasing / Fourier Transform / Digital Filters / Spectrogram. Each tab has an overview, two hands-on parts, a summary and references
- Sampling: a sine f (0.5–40 Hz) sampled at fs (2–40 Hz) for 1 s, rebuilt by sinc interpolation using 40 extra samples on each side. Apparent frequency = |f − fs·round(f/fs)|. Wagon wheel: six spokes, rotation between frames folded to ±30° to get the apparent speed
- Fourier: N = 256, fs = 128 Hz (2 s), hand-written radix-2 FFT. One-sided amplitude = 2|X[k]|/Σw. Click the spectrum to add or remove sine components (up to 6). Leakage: rectangular, Hann, Blackman windows, in dB
- Filters (fs 200 Hz): moving average (N = round(0.443·fs/fc)), exponential average (α = 1 − e^(−2πfc/fs)), windowed-sinc FIR (Hamming, odd taps), 2nd-order Butterworth (bilinear transform, RBJ formulas). |H(f)| directly from coefficients. Forward–backward (zero-phase) pads both ends with 150 copies of the end values
- Spectrogram: 8 kHz, 2 s test signal (chirp 300→1,700 Hz, 2,500 Hz 20 ms burst, two tones 1,000 and 1,060 Hz). Window 32–4,096, hop = window/4, colors span 70 dB below the maximum. Whether the two tones separate is judged by a dip of at least 3 dB between them in the column near 1.5 s
- Sound from a drawing: the time–frequency path is linearly interpolated and sine phase accumulated (8 kHz). The microphone records 2 s via getUserMedia, reduced to 8 kHz by block averaging. The recording is only computed on screen, never sent or stored
- Hand-written JavaScript (sp-core.js, sp.js), no external libraries · no LLM
■ Data
- All signals are synthesized in the browser with seeded random numbers. No external data
- A microphone recording (only when pressed) is used only in browser memory
■ Validation
- tests/signal-processing/core-test.mjs, 16 checks pass
- FFT = direct DFT (64 points, max difference 2.7e-13) · Parseval · on-bin sine amplitudes 1.5 and 0.7 exact (rectangular, Hann)
- Sampling 9 Hz at 10 Hz puts the spectral peak at 0.996 Hz (1 Hz)
- Filter DC gain 1 (all four), Butterworth −3.0103 dB at the cutoff, 30 Hz steady-state amplitude = |H(30)|
- Against scipy 1.18.1: butter(2, 10, fs=200) coefficients within 1e-8, firwin(51, 10, fs=200, hamming) within 1e-12
- Chirp STFT peak rises from 250 to 1,641 Hz
■ Scope
- One-dimensional real signals, low-pass filters only (high- and band-pass follow the same idea); real-time audio latency is not covered
■ Sources
- Shannon (1949), Nyquist (1928), Cooley & Tukey (1965), Harris (1978), Butterworth (1930), Gabor (1946), Allen (1977), Oppenheim & Schafer (2010), Smith (1997, 2011), Bristow-Johnson Audio EQ Cookbook, Gustafsson (1996)
■ History
- 2026-10-26 · v0.1 · first version · not yet public