[JavaScript ์ค๋์ค ์ดํํฐ ๋ง๋ค๊ธฐ] ์ค๋์ค ์ดํํฐ๋ก ๋๋ง์ ์๋ฆฌ ๋ง๋ค๊ธฐ
์ด๋ฒ ํฌ์คํ ์์๋ ์ ๋ฒ ํฌ์คํ ์ ์ด์ด HTML5 Audio API๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ๋ก ์ค๋์ค ์ดํํฐ๋ฅผ ๋ง๋๋ ๊ณผ์ ์ ๋ํด์ ํฌ์คํ ํ๋ ค๊ณ ํ๋ค. ์ ๋ฒ ํฌ์คํ ์์ ์ด๋ฏธ ์ด์ผ๊ธฐ ํ๋ฏ์ด Audio API๋ ์ฌ๋ฌ ๊ฐ์ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ์ฌ ์ค๋์ค์ ํ๋ฆ์ ๋ง๋ค์ด ๋ด๋ ๊ฒ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ผ๋ก ๊ฐ์ง๊ณ ์๊ณ , ์ดํํฐ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ํ์ํ ๋ช ๊ฐ์ ์ถ์ํ๋ ๋ ธ๋๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํด์ฃผ๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ์ด๋ ค์ธ ๊ฑด ์๋ค.
์ฐ๋ฆฌ๋ ๋จ์ง ์ฐ๋ฆฌ๊ฐ ๋ง๋๋ ค๊ณ ํ๋ ์ดํํฐ๋ค์ด ๊ฐ๊ฐ ์ด๋ค ์ญํ ์ ํ๋ฉฐ, ์ด๋ค ์๋ฆฌ๋ฅผ ๊ฐ์ง๊ณ ์๊ณ , ์ด๋ค ์ฉ๋๋ก ์ฌ์ฉ๋๋์ง๋ง ์๊ณ ์์ผ๋ฉด ๋๋ค. ์ค๋์ค์ ์ฌ์ฉํ๋ ์ดํํฐ๋ ๊ทธ ์ข ๋ฅ๊ฐ ๊ต์ฅํ ๋ง๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์ดํํฐ๋ฅผ ๋ง๋ค์ด ๋ณผ ์๋ ์๊ณ , ํ์๊ฐ ์๊ฐํ์ ๋ ๊ฐ์ฅ ๋ํ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉ๋๋ ๊ธฐ๋ณธ์ ์ธ ์ดํํฐ 5๊ฐ ์ ๋๋ฅผ ๊ตฌํํด๋ณผ ์๊ฐ์ด๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ค๋์ค๋ฅผ ๋ก๋ํ์ฌ ์์ค ๋
ธ๋(Source Node)
๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ ์ด๋ฏธ ์ ๋ฒ ํฌ์คํ
์์ ์ค๋ช
ํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ์ค๋ช
ํ์ง ์๊ฒ ๋ค. ์ด๋ฒ ํฌ์คํ
์์๋ ๋ฐ๋ก ์ดํํฐ๋ฅผ ๊ตฌํํ๋ ๋ด์ฉ๋ถํฐ ์ค๋ช
ํ๋ค. ๋ชจ๋ ์ดํํฐ๋ ๋จผ์ ํด๋น ์ดํํฐ๊ฐ ํ๋ ์ผ๊ณผ ์๋ฆฌ์ ๋ํด์ ๊ฐ๋ตํ๊ฒ ์ค๋ช
ํ๊ณ ์ดํ ๋ฌป์ง๋ ๋ฐ์ง์ง๋ ์๊ณ ๋ฐ๋ก ๊ตฌํ ๋ค์ด๊ฐ๋๋ก ํ๊ฒ ๋ค.
์, ๊ทธ๋ผ ํ๋ํ๋ ๋ฏ์ด๋ณด๋๋ก ํ์.
Compressor
์ปดํ๋ ์(Compressor)
๋ ์๋ฆฌ๊ฐ ์ผ์ ํฌ๊ธฐ ์ด์์ผ๋ก ์ปค์ง ๊ฒฝ์ฐ์ ์ด๋ฅผ ๊พน๊พน ๋๋ฌ์ ๋ค์ ์์ ์๋ฆฌ๋ก ๋ง๋๋ ์ผ์ข
์ ์์ถ๊ธฐ ์ญํ ์ ํ๋ ์ดํํฐ์ด๋ค. ์ด๋ ๊ฒ ์๋ฆฌ์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๋ ์ดํํฐ๋ฅผ ๋ค์ด๋๋ฏน ์ดํํฐ
๋ผ๊ณ ํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ค๋์ค ์์ค๋ฅผ ์ฌ์ฉํ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ปดํ๋ ์๋ฅผ ๊ฑธ์ด๋๊ณ ๋ฏน์ฑ์ ์์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ์ด๋ ์ค๋์ค ์ ํธ๊ฐ ์ผ์ ํฌ๊ธฐ ์ด์์ผ๋ก ๊ฐ์๊ธฐ ์ปค์ก์ ๋ ๋ฐ์ํ๋ ํด๋ฆฌํ(Clipping)
ํ์์ ๋ฐฉ์ดํ๊ธฐ ์ํด์์ด๊ธฐ๋ ํ๋ค. ๊ทธ๋ผ ์ฌ๊ธฐ์ ํ๊ฐ์ง ์๋ฌธ์ด ๋ค ์ ์๋๋ฐ,
์๋ ๋จ์ํ ํด๋ฆฌํ์ ๋ง๋ ๊ฑฐ๋ฉด ๊ทธ๋ฅ Gain์ ์ค์ด๋ฉด ํด๊ฒฐ๋๋ ๊ฑฐ ์๋์ผ?
๋ง๋ค. ์ฌ์ค ๊ฒ์ธ์ ์ค์ฌ๋ ์ด๋ ์ ๋ ํด๋ฆฌํ์ ๋ฐฉ์ดํ ์๋ ์๋ค. ํ์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ์์ ์ด๋ ์ ์ฌ๋ฆผ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ฌด์์ ๊ฒ์ธ์ ๋ฎ์ถ๋ฉด ์์ ์๋ฆฌ๋ ์์ ์ ๋ ฅ๋์ง๋ ์๋ ์ฌํ ์ํฉ์ด ๋ฐ์ํ๊ฒ ๋๋ค.
์๋ฅผ ๋ค์ด ์ฌ๋ฌ๋ถ์ด ๋ ธ๋๋ฐฉ์ ๊ฐ์ ๋๋ฅผ ์๊ฐํด๋ณด์. ์ผ๋ฐ์ ์ผ๋ก ๋ฐ๋ผ๋๋ฅผ ๋ถ๋ฅธ๋ค๋ฉด ๋ ธ๋์ ๋์ ๋ถ์์๋ ์์ํ ๋๋์ผ๋ก ์กฐ์ฉํ ๋ถ๋ฅด๋ค๊ฐ ํ๋ ด์์๋ ๊ณ ์์ ๋ด๊ธฐ์ํด ์ฑ๋๋ฅผ ํต๊ณผํ๋ ๊ณต๊ธฐ์ ์๋ ฅ์ด ์ฌ๋ผ๊ฐ๋ฉฐ ์๋์ด ์ปค์ง๋ค. ์ด๋ ๋ฌด์์ ๊ฒ์ธ์ ๋ฎ์ถฐ์ ๋ น์ํ๋ ๋ฐฉํฅ์ผ๋ก ์ ๊ทผํ๋ค๋ฉด ํ์ฐ์ ์ผ๋ก ๊ฐ์ฅ ํฐ ์๋ฆฌ์ธ ํ๋ ด์ ๋นต๋นต ์ง๋ฅด๋ ์๋ฆฌ์ ํฌ๊ธฐ์ ๊ฒ์ธ์ ๋ง์ถ ์ ๋ฐ์ ์๊ณ , ๊ทธ๋ฌ๋ฉด ๋์ ๋ถ์ ์์ํ ๋ถ๋ถ์ ๊ฑฐ์ ์ ๋ ฅ๋์ง ์์ ๊ฒ์ด๋ค.
์ด๋ ์ปดํ๋ ์๋ก ์ ๋ ฅ ๊ฒ์ธ์ ์ ๋นํ ์์ค์ผ๋ก ๋ํ์ฃผ๊ณ ๋๋ฌด ํฐ ์๋ฆฌ๋ ์์ถํ์ฌ ๋ ธ๋ ๋์ ๋ถ์ ์์ ์๋ฆฌ์ ํ๋ ด๋ถ์ ํฐ ์๋ฆฌ์ ๊ฒฉ์ฐจ๋ฅผ ์ขํ ์ ์ฒด์ ์ธ ์๋ฆฌ์ ํฌ๊ธฐ๋ฅผ ๋ง์ถ๊ธฐ ์ํด์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
๋ํ ํ์๊ฐ ์ปดํ๋ ์ ์๋ฆฌ๋ฅผ ์์ถํ๋ค๊ณ ํ๋๋ฐ, ์๋ฆฌ๋ฅผ ์์ถํ๋ค๋ ๊ฒ์ด ๋ญ์ง ์ ์ดํด๊ฐ ์๊ฐ ์ ์๋ค. ๋ํ์ ์ธ ์๋ก ์ฐ๋ฆฌ๊ฐ ์ผ๋ฐ์ ์ธ ์์์์ ๋ฃ๊ณ ์๋ ํฝ!
, ํ!
ํ๋ ๊น๋ํ ๋๋ผ์๋ฆฌ๊ฐ ๋ฐ๋ก ์์ถ๋ ์๋ฆฌ์ด๋ค. (๋ณดํต ์ด๋ ๊ฒ ํํ์น๋ ์๋ฆฌ๋ฅผ Damping์ด๋ผ๊ณ ํ๋ค.)
์ผ๋ฐ์ ์ผ๋ก ๋๋ผ์ ๋ น์ํ๋ฉด ๋๋ผ ํน์ ์ ํต์ด ์ธ๋ฆฌ๋ ์ํฅ์ด ๋จ๋๋ฐ, ์ด ์๋ฆฌ๋ฅผ ์ปดํ๋ ์๋ก ์์ถํ๋ฉด ์ฐ๋ฆฌ๊ฐ ์ผ๋ฐ์ ์ผ๋ก ๋ฃ๋ ๊น๋ํ ๋๋ผ์๋ฆฌ๋ก ๋ง๋ค ์ ์๋ค.
๊ทธ ์ธ์๋ ๋ฒ ์ด์ค์ ์ปดํ๋ ์๋ฅผ ์ฌ์ฉํ์ฌ ๋จ๋จํ ๋๋์ ๋ถ์ฌํ๊ฑฐ๋ ๋ฉ๋ฆฌ ์๋ ์๋ฆฌ๋ฅผ ๊ฐ๊น์ด๋ก ๋์ด์ค๊ฑฐ๋ ๊ทธ ๋ฐ๋ ์ญํ ๋ ํ ์ ์๋ ๋ฑ, ์ปดํ๋ ์๋ง ์ ์ฌ์ฉํด๋ ์๋ฆฌ์ ๊ต์ฅํ ๋ง์ ๋๋์ ๋ถ์ฌํ ์ ์๋ค. ๊ทธ๋์ ํ์์๊ฒ ์ฌ์ด๋ ์์ง๋์ด๋์ ์๋ ค์ฃผ์ จ๋ ์ ์๋๋ ์ปดํ๋ ์์ ์ค์์ฑ์ ๊ต์ฅํ ๊ฐ์กฐํ์ จ๋ ๊ธฐ์ต์ด ๋๋ค.
์ปดํ๋ ์๋ ๋ช๊ฐ์ง ๊ฐ๋ค์ ์ฌ์ฉํ์ฌ ์ ํธ๋ฅผ ์ธ์ ๋ถํฐ ์์ถํ ๊ฒ์ธ์ง, ์ด๋ ์ ๋์ ์๋๋ก ์์ถํ ๊ฒ์ธ์ง์ ๊ฐ์ ์ธํ
์ ํ ์ ์๋๋ก ์ค๊ณ๋์๋ค. HTML5 Audio API์์ ์ ๊ณตํ๋ DynamicsCompressorNode
๋ ์ด ๊ฐ๋ค์ ๋์ผํ๊ฒ ์ ๊ณตํ๊ณ ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ๋ ์ด ๊ฐ๋ค์ด ์ด๋ค ์๋ฏธ๋ฅผ ๊ฐ์ง๊ณ ์๋์ง ์์์ผ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์ด ๋
ธ๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
Threshold
Threshold
๋ ์๋ฆฌ๋ฅผ ์ด๋ ํฌ๊ธฐ๋ถํฐ ์์ถํ ๊ฒ์ธ์ง๋ฅผ ์ ํ๋ ์๊ณ์ ์ ์๋ฏธํ๋ค. ๋จ์๋ DB(๋ฐ์๋ฒจ)
์ ์ฌ์ฉํ๋ค.
Ratio
Ratio
๋ Threshold๋ฅผ ๋์ ์๋ฆฌ๊ฐ ์ด๋ ์ ๋์ ๋น์จ๋ก ์ค์ด๋ค ๊ฒ์ธ์ง๋ฅผ ์ ํ๋ ๊ฐ์ด๋ค. ์ด ๊ฐ์ ์
๋ ฅ:์ถ๋ ฅ
์ ๋น๋ฅผ ์๋ฏธํ๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ์ ์ผ๋ก๋ 2:1
, 5:1
์ ๊ฐ์ ๋น์จ๋ก ์ด์ผ๊ธฐํ๋ค.
ํ์ง๋ง HTML5 Audio API์ ์์ฑ์์๋ ๋จ์๊ฐ ์กฐ๊ธ ๋ค๋ฅด๋ค. ๊ณต์ ๋ฌธ์์๋ โ์ถ๋ ฅ ๊ฐ์ 1db๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ํด ํ์ํ db๊ฐโ์ด๋ผ๊ณ ์ ํ์๋๋ฐ ๊ทธ๋ฅ ์ด ์์ฑ์ 12
๋ฅผ ํ ๋นํ๋ฉด ์์ถ ๋น์จ์ด 12:1
๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค. (๊ณต๋์ด๋ค ํน์ง์ธ ์ด๋ ต๊ฒ ๋งํ๊ธฐ๊ฐ ๋ฐ๋ํ๋ค)
๋ณดํต ์ปดํ๋ ์๋ฅผ ์ ๋นํ ๊ฑธ์๋ค๊ณ ํ๋ฉด 4:1
์ ๋์ ๋น์จ์ ๋งํ๊ธฐ ๋๋ฌธ์ ํด๋น ์์ฑ์ ๊ธฐ๋ณธ ๊ฐ์ธ 12:1
์ ์๋นํ ํ๋ํ ์์ถ ๋น์จ์ด๋ผ๊ณ ํ ์ ์๋ค.
Attack
Attack
์ ์๋ฆฌ๋ฅผ ์ด๋ ์ ๋์ ๋น ๋ฅด๊ธฐ๋ก ์์ถํ ๊ฒ์ธ์ง๋ฅผ ์ ํ๋ ๊ฐ์ด๋ค. Threshold๋ฅผ ๋์ ๊ฐ์ ์ผ๋ง๋ ๋น ๋ฅด๊ฒ ๋๋ ค์ ๋๋ฌ ๋ด์ ์ง๋ฅผ ์ ํ๋ฉด ๋๋ค๊ณ ์๊ฐํ์. ๋ง์ ๋ถ๋ค์ด ์ฌ๊ธฐ์ ์ ํด์ฃผ๋ ์ดํ ํ์์ด โAttack์ด ์์๋๋ ์๊ฐโ์ผ๋ก ์๋ชป ์๊ณ ์๋ ๋ฐ, ์ฌ์ค ์ ํธ์ ํฌ๊ธฐ๊ฐ Threshold๋ฅผ ๋์ผ๋ฉด Attack ์์ฒด๋ ๋ฐ๋ก ์์๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ ํด์ฃผ๋ ์ดํ ํ์์ ์ ํด์ง โRatio๋ก ์ ํด์ค ๋น์จ๊น์ง ๋๋ฌํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐโ์ด๋ค.
๋จ์๋ ๋ณดํต ๋ฐ๋ฆฌ์ด(ms)
๋ฅผ ์ฌ์ฉํ์ง๋ง Audio API์์๋ ์ด(seconds)
๋ฅผ ์ฌ์ฉํ๋ค.
Release
Attack์ด ์๋ฆฌ๋ฅผ ๋๋ฅด๋ ๋น ๋ฅด๊ธฐ์๋ค๋ฉด Release
๋ ์์ถํ ์๋ฆฌ๋ฅผ ์ด๋ ์ ๋์ ๋น ๋ฅด๊ธฐ๋ก ๋ค์ ํ์ด์ค ๊ฒ์ธ๊ฐ๋ฅผ ์ ํ๋ ๊ฐ์ด๋ค. ์ด๋ ํ์ด์ฃผ๋ ๊ฐ์ ์๋ฆฌ์ ์๋ ํฌ๊ธฐ๊ฐ ์๋๋ผ ํ์ค ์๋์ธ 10db์ ๋๋ฌํ๋ ์๊ฐ์ ๋ชฉํ๋ก ํ๋ค.
Release
๋ Attack๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋จ์๋ ๋ณดํต ๋ฐ๋ฆฌ์ด(ms)
๋ฅผ ์ฌ์ฉํ์ง๋ง Audio API์์๋ ์ด(seconds)
๋ฅผ ์ฌ์ฉํ๋ค.
Knee
Knee
๋ ์ฌ์ค ๋๋ถ๋ถ์ ํ๋์จ์ด ์ปดํ๋ ์์๋ ์๋ ๊ธฐ๋ฅ์ด์ง๋ง ์ํํธ์จ์ด ์ปดํ๋ ์์์๋ ๊ฝค ์์ฃผ ๋ณผ ์ ์๋ ๊ธฐ๋ฅ์ด๋ค. ์ด ๊ฐ์ ์ปดํ๋ ์๊ฐ ์ผ๋ง๋ ์์ฐ์ค๋ฝ๊ฒ
์ ์ฉ๋ ๊ฒ์ธ์ง๋ฅผ ๊ฒฐ์ ํ๋ค.
์ ๊ทธ๋ฆผ์ ๊ทธ๋ํ์ ๊บพ์ด๋ ์ ๋๊ฐ ์ปดํ๋ ์๊ฐ ์ผ๋ง๋ ์์ํ ์ ์ฉ๋๋์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์๋ค. ์ด๋ ๋น ๋ฅด๊ฒ ํ! ์ ์ฉํ๋ ์ปดํ๋ ์
์ Hard
ํ๋ค๊ณ ํ๊ณ ์ฒ์ฒํ ์ ์ฉํ๋ ์ปดํ๋ ์
์ Soft
ํ๋ค๊ณ ํ๋ค.
Compressror ๊ตฌํํด๋ณด๊ธฐ
์ฌ์ค ์์์ ์ด์ผ๊ธฐ ํ๋ฏ์ด HTML5 Audio API๋ ์์ฒด์ ์ผ๋ก DynamicsCompressorNode
๋ฅผ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ์๋ฆฌ๋ฅผ ์์ถํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ง์ ๊ตฌํํ ํ์๊ฐ ์๋ค. ๋จ์ง ๋
ธ๋๋ฅผ ์์ฑํ ํ ์ฐ๊ฒฐํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋ ๋ฟ์ด๋ค.
์ด๋ฒ์๋ ์ฌ์ฉ์๊ฐ ์
๋ก๋ํ ์ค๋์ค ํ์ผ์์ ์ค๋์ค ๋ฒํผ๋ฅผ ์ถ์ถํ์ฌ ์์ค ๋
ธ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ <audio>
ํ๊ทธ์์ ์ถ์ถํ์ฌ ์์ค ๋
ธ๋๋ฅผ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ์งํํ๋๋ก ํ๊ฒ ๋ค. (์ด๋ ๊ฒ ํ๋ฉด ์ฝ๋๊ฐ ํจ์ฌ ๊ฐ๋จํด์ง๋ค) ์ง๊ธ ์์ฑํ ์์ค๋
ธ๋๋ ์์ผ๋ก ๋ค๋ฅธ ์ดํํฐ๋ฅผ ๊ตฌํํ ๋๋ ๊ณ์ ์ฌ์ฉํ ๊ฒ์ด๋ค.
const audioContext = new (AudioContext || webkitAudioContext)();
const audioDOM = document.getElementById('my-audio');
const sourceNode = audioContext.createMediaElementSource(audioDOM);
const threshold = -24;
const attack = 0.003;
const release = 0.25;
const ratio = 12;
const knee = 30;
const compressorNode = audioContext.createDynamicsCompressor();
compressorNode.threshold.setValueAtTime(threshold, audioContext.currentTime);
compressorNode.attack.setValueAtTime(attack, audioContext.currentTime);
compressorNode.release.setValueAtTime(release, audioContext.currentTime);
compressorNode.ratio.setValueAtTime(ratio, audioContext.currentTime);
compressorNode.knee.setValueAtTime(knee, audioContext.currentTime);
const inputGainNode = audioContext.createGain();
const outputGainNode = audioContext.createGain();
sourceNode.connect(inputGainNode);
inputGainNode.connect(compressorNode);
compressorNode.connect(outputGainNode);
outputGainNode.connect(audioContext.destination);
ํ์๋ ์์ค -> ๊ฒ์ธ -> ์ปดํ๋ ์ -> ๊ฒ์ธ
์ ์์๋ก ์ค๋์ค ์์ค์ ํ๋ฆ์ ์์ฑํ๋๋ฐ, ์ฌ์ค ์ด๊ฑด ๊ฐ์ธ์ ์ทจํฅ์ด๋ค. ํ์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ๋๋ถ๋ถ์ ์ปดํ๋ ์๋ ์ธํ ๊ฒ์ธ
๊ณผ ์์ํ ๊ฒ์ธ
์ ๋ชจ๋ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก ํ์๋ ์ด์ ๋์ผํ๊ฒ ๊ตฌํํ๋ค.
์ดํ ์์ค๋ ธ๋๋ฅผ ์ฌ์ํด๋ณด๋ฉด ์์ถ๋ ์๋ฆฌ๋ฅผ ๋ค์ ์ ์๊ธด ํ๋ฐ, ์ฌ์ค ์ฌ์ด๋ ์์ง๋์ด๊ฐ ์๋ ์ผ๋ฐ์ธ์ด ์๋ฆฌ์ ๋ฏธ์ธํ ์์ถ์ ์ ๋๋ฅผ ๋๋ผ๊ธฐ๋ ํ๋๋ฏ๋ก ์์ ๊ฐ๋ค์ ์กฐ๊ธ ๊ทน๋จ์ ์ผ๋ก ๋ฐ๊ฟ๋ณด๋ ๊ฒ์ ์ถ์ฒํ๋ค.
Reverb
๋ฆฌ๋ฒ๋ธ(Reverb)
๋ ์๋ฆฌ์ ์ธ๋ฆผ์ ํตํด ๊ณต๊ฐ๊ฐ์ ๋ถ์ฌํ๋ ๊ณต๊ฐ๊ณ ์ดํํฐ
์ด๋ค. ์๋ฆฌ์ ์ธ๋ฆผ์ ํตํด ๊ณต๊ฐ๊ฐ์ ๋ถ์ฌํ๋ค๋ ๊ฒ ์ด๋ค ์๋ฏธ์ผ๊น?
์ฌ์ค ์ฐ๋ฆฌ๋ ์๋ฆฌ๋ฅผ ๋ฃ๊ณ ํ์ฌ ์๋ ๊ณต๊ฐ์ด ๋์์ง ์ข์์ง, ์ด ๊ณต๊ฐ์ด ๊ฑฐ์น ๋ฒฝ๋ฉด์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋์ง, ์๋๋ฉด ์ ๋ฆฌ๊ฐ์ ๋งจ๋ค๋งจ๋คํ ๊ณต๊ฐ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๋์ง๋ฅผ ๋๋ต์ ์ผ๋ก ํ์ ํ ์ ์๋ค. ๊ทธ ์ฐจ์ด๊ฐ ์๋ ๋ฏธ์ธํด์ ํ๋ จ๋์ง ์์ ์ฌ๋์ด๋ผ๋ฉด ์์์ฑ๊ธฐ ํ๋ค ๋ฟ์ด๋ค.
์ด๋ป๊ฒ ์ด๋ฐ ์ผ์ด ๊ฐ๋ฅํ ๊น? ๋ฐ๋ก ์๋ฆฌ์ ๋ฐ์ฌ์ ์ํ ์ํฅ
๋๋ฌธ์ด๋ค. ๋จผ์ , ์๋ฆฌ๋ฅผ ๋ฃ๊ณ ๊ณต๊ฐ์ ํฌ๊ธฐ๋ฅผ ๊ฐ์งํ๋ ์๋ฆฌ๋ ๊ฐ๋จํ๋ค. ํ์๊ฐ ์ด๋ค ๋ฐฉ ์์์ ์๋ฆฌ๋ฅผ ์!
ํ๊ณ ์ง๋ฅธ ๋ค ์ผ๋ง ํ์ ์ฒซ๋ฒ์งธ ๋ฐ์ฌ์์ด ๋ค๋ฆฌ๋์ง๋ฅผ ๊ฐ์งํ๋ฉด ๋๋ค. ํ์ง๋ง ์ด ์ฒซ๋ฒ์งธ ๋ฐ์ฌ์์ ms
๋จ์์ ๊ต์ฅํ ๋น ๋ฅธ ์๋๋ก ๋ค์ ํ์์๊ฒ ๋์์ค๊ธฐ ๋๋ฌธ์ 1์ด, 2์ด ์ด๋ ๊ฒ ์ธ๋ ๊ฒ์ด ์๋๋ผ ๊ทธ๋ฅ ๋๊ปด์ผํ๋ ๊ฒ์ด๋ค.
์ด๋ ์ด ๋ฐ์ฌ์์ ์ด๊ธฐ ๋ฐ์ฌ์(Early Reflection)
์ด๋ผ๊ณ ํ๋ค. ํ์ง๋ง ์ฌ๊ธฐ์ ๋์ด ์๋๋ค. ์๋ฆฌ๊ฐ ํ๋ฒ ๋ฐ์ฌ๋์ด ์ฌ๋ฌ๋ถ์ ๊ท๋ก ์ ๋ฌ๋ ๋ค์๋ ๋ฐ์ฌ๋ ๊ณ์ ๋ ๊ฒ์ด๋ค. ์ด๋ ์ด ์ํฅ๋ค์ ๊ณต๊ฐ์ ์ฌ๋ฐฉํ๋ฐฉ์ผ๋ก ๋ถ๋ชํ๊ณ ๋ฐ์ฌ๋์ด ์ฌ๋ฌ๋ถ์ ๊ท๋ก ๋ค์ ๋์์ฌ ๊ฒ์ด๋ค.
์ด๋ ์ด ์ํฅ์ด ์ผ๋ง๋ ์ค๋ ๋ค๋ฆฌ๋๊ฐ, ์ผ๋ง๋ ์ ๋ช ํ๊ฒ ๋ค๋ฆฌ๋๊ฐ์ ๊ฐ์ ํน์ฑ์ด ๋ฐฉ์ ์ฌ์ง์ ๊ฒฐ์ ํ๋ค. ์ด์ผ๊ธฐ๋ง ๋ค์ผ๋ฉด ์ด๋ ๊ฒ ์๋ฆฌ๋ฅผ ๋ฃ๊ณ ๊ณต๊ฐ์ ํ๋ณํ๋ค๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ง๋ง ์ฌ๋ฌ๋ถ์ด ์ด๋ฏธ ํ์์ ๋ฃ๊ณ ์์ ์๋ ๋ชจ๋ ์ด ์๋ฆฌ๋ฅผ ์ ์ฉํ ๊ณต๊ฐ์ ์ค๊ณ๊ฐ ํจ๊ป ๋ด๊ฒจ์๋ค.
์ด๋ ๊ฒ ๋ฆฌ๋ฒ๋ธ๋ ๋ง ๊ทธ๋๋ก ์ํฅ์ ๋ง๋ค์ด๋ด๊ธฐ๋ง ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ํ๋์จ์ด ๋ฆฌ๋ฒ๋ธ ์ค์์๋ ์คํ๋ง์ด๋ ์ฒ ํ ๋ฑ์ ์ฌ๋ฃ๋ฅผ ์ฅ๋น ๋ด๋ถ์ ๋ฃ์ด๋๊ณ ์ค๋์ค๋ฅผ ์ฌ์ํ์ฌ ์ฌ๋ฃ๊ฐ ๋จ๋ฆฌ๋ฉฐ ๋ฐ์ํ ์ํฅ์ ์ฆํญํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒ๋ ์๋ค. ์ฆ, ๋ฏ์ด๋ณด๋ฉด ์ฅ๋น ๋ด๋ถ์ ์คํ๋ง์ด๋ ์ฒ ํ ํ๋ ๋ธ๋ ๋ค์ด์๋ค๋ ๊ฒ์ด๋ค. (์ด๋ฐ ๋จ์ํ ๊ตฌ์กฐ๋ก ์ข์ ์๋ฆฌ๋ฅผ ๋ฝ๋๋ค๋ ๊ฒ ๋ ๋ฌด์ญโฆ)
๊ทธ๋ฌ๋ ๋ฆฌ๋ฒ๋ธ๋ฅผ ์ํํธ์จ์ด๋ก ๊ตฌํํ ๋๋ ์ด์ผ๊ธฐ๊ฐ ์กฐ๊ธ ๋ค๋ฅด๋ค. ์ปดํจํฐ๋ ์คํ๋ง์ด๋ ์ฒ ํ์ ๋จ๋ฆผ๊ณผ ๊ฐ์ ์์ฐ์ ์ธ ์๋ ๋ก๊ทธ ์ ํธ๋ฅผ ์์ฑํ ์ ์์ผ๋ฏ๋ก ์ง์ ๊ณ์ฐ์ ํตํด ๊ตฌํํด์ผํ๋ค. ์ด๋ ์ํํธ์จ์ด ๋ฆฌ๋ฒ๋ธ๋ ํฌ๊ฒ ๋ ๊ฐ์ง ์ข
๋ฅ๋ก ๋๋์ด์ง๋๋ฐ ๋ฐ๋ก Convolution Reverb
์ Algorithm Reverb
์ด๋ค.
ํ์ง๋ง ์ด ํฌ์คํ ์์ ๋ ๋ฆฌ๋ฒ๋ธ๋ฅผ ๋ชจ๋ ๊ตฌํํ๊ธฐ์๋ ๊ธ์ด ๋๋ฌด ๊ธธ์ด์ง ๊ฒ ๊ฐ์ผ๋ฏ๋ก ์์ฌ์ด๋๋ก ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ์ ์ด์ ์ ๋ง์ถฐ ์งํํ๊ฒ ๋ค. (์๊ณ ๋ฆฌ์ฆ ๋ฆฌ๋ฒ๋ธ๋ง ํด๋ ํฌ์คํ ํ๋ ๋ถ๋์ด๋ค.)
Convolution Reverb
์ปจ๋ณผ๋ฃจ์
๋ฆฌ๋ฒ๋ธ(Convolution Reverb)
๋ ์ค์ ๊ณต๊ฐ์ ์ํฅ์ ๋
น์ํ ํ์ ์ํฅ ์ค๋์ค ์์ค์ ์๋ณธ ์ค๋์ค ์์ค๋ฅผ ์ค์ ๊ณต๊ฐ์ ์ธ๋ฆผ์ ์๋ณธ ์ค๋์ค ์์ค์ ํฉ์ฑํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ด๋ ์ค์ ๊ณต๊ฐ์ ์ํฅ์ ๋
น์ํ๋ ๋ํ์ ์ธ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๊ฒ ์ค๋ช
ํ์๋ฉด, ๋
น์ํ๊ณ ์ ํ๋ ๊ณต๊ฐ์ ์์ํ ์ฌ์ธํ(Sine Wave)
์ ์๋ฆฌ๋ฅผ ๋ฎ์ ์ฃผํ์๋ถํฐ ๋์ ์ฃผํ์๊น์ง ์ญ์ฐ์ฐ์ฑ ์ด์ด์ ํ๊ณ ๊ทธ๋ ๋ฐ์ํ๋ ์ํฅ์ ๋
น์ํ๋ ๊ฒ์ด๋ค.
์ด๋ ์ด ์ํฅ ์ ํธ๋ฅผ Impulse Response(IR)
์ด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ ๋๋ฌธ์ ์ปจ๋ณผ๋ฃจ์
๋ฆฌ๋ฒ๋ธ๋ IR ๋ฆฌ๋ฒ๋ธ
๋ผ๋ ์ด๋ฆ์ผ๋ก๋ ๋ถ๋ฆฐ๋ค. ์ด๋ ๊ฒ ๋
น์ํ IR์ ์๋ณธ ์์ค์ ์ปจ๋ณผ๋ฃจ์
(Convolution)
, ๋๋ ํฉ์ฑ๊ณฑ์ด๋ผ๊ณ ๋ถ๋ฆฌ์ฐ๋ ์ฐ์ฐ์ ํตํด ํฉ์ณ์ง๊ฒ ๋๋ค.
์ด ์ปจ๋ณผ๋ฃจ์
์ด๋ผ๋ ๊ฐ๋
์ ์ํ์ ์ผ๋ก ์ ๊ทผํ๊ธฐ ์์ํ๋ฉด ๋จธ๋ฆฌ๋ ์ํ๊ณ ๋ ํฌ์คํ
์ด ๊ธธ์ด์ง๋๊น ๊ฐ๋จํ๊ฒ ์ ์ํด๋ณด์๋ฉด, ๊ทธ๋ฅ ์๋ก ๋ค๋ฅธ ์ ๋ณด๋ค์ ์๋ ๊ฒ์ด๋ผ๊ณ ํํํ ์ ์๋ค. ์ด ํฌ์คํ
์ ์ฝ๋ ๋ถ๋ค์ ์๋ง ๊ฐ๋ฐ์ ๋ถ๋ค์ด ๋ง์ ํ
๋ ์ฐ๋ฆฌ์๊ฒ ์ข ๋ ์น์ํ ๋จธ์ ๋ฌ๋์ ์ฌ์ฉํ์ฌ ์ปจ๋ณผ๋ฃจ์
์ ์ค๋ช
ํ์๋ฉด ํ์ต ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋์ธ CNN(Convolution Neural Network)
์ ์๋ก ๋ค์ด๋ณผ ์ ์๊ฒ ๋ค.
CNN์์๋ ์ฒซ๋ฒ์งธ ๋ ์ด์ด์ ์ด๋ฏธ์ง๋ฅผ ๋๋ฒ์งธ ๋ ์ด์ด๋ก ๋ณด๋ผ ๋ ํ๋ ฌ๋ก ๊ตฌํํ ์ปค๋(๋๋ ํํฐ)์ ์ด๋ฏธ์ง๋ฅผ ์์ด์ ํผ์ฒ๋งต์ ์์ฑํ ํ ๋ค์ ๋ ์ด์ด๋ก ๋ณด๋ด๊ฒ๋๋ค. ์ด๋ ์ฒซ๋ฒ์งธ ๋ ์ด์ด์ ์ด๋ฏธ์ง์ ์ปค๋์ ์ ๋ณด๊ฐ ์์ธ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ ์ ์๋ค.
์ค๋์ค์์์ ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ๋ ์ด์ ๋ง์ฐฌ๊ฐ์ง๋ค. ์ด ๊ฒฝ์ฐ์๋ ์์ด์ผํ๋ ์ ๋ณด๊ฐ ์๋ณธ ์์ค์ IR์ด ๋ ๊ฒ ๋ฟ์ด๋ค.
์ปจ๋ณผ๋ฃจ์ ์ ์๋ณธ ์์ค์ IR์ด๋ผ๋ ๋ ์ค๋์ค ์์ค์ ์ฃผํ์ ์คํํธ๋ผ์ ๊ณฑํ๋ ๊ณผ์ ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ํตํด ๋ ์์ค ๊ฐ์ ๊ฒน์น๋ ์ฃผํ์๋ ๊ฐ์กฐ๋๊ณ ๊ฒน์น์ง ์๋ ์ฃผํ์๋ ๊ฐ์ ๋๋ค. ์ด๋ ๊ฒ ์๋ณธ ์์ค์ IR ๊ฐ ๊ฒน์น๋ ์ฃผํ์๊ฐ ๊ฐ์กฐ๋๋ฉด ์๋ณธ ์์ค๋ IR์ ์์ง์ ํน์ฑ์ ๋๊ฒ ๋๋๋ฐ, ์ด๊ฒ ๋ฐ๋ก ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ์ ์๋ฆฌ์ด๋ค.
์ฌ์ค HTML5 Audio API๋ ์ปจ๋ณผ๋ฃจ์
์ฐ์ฐ์ ๋์ ์ํํด์ฃผ๋ ConvolverNode
๋ฅผ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ์ปจ๋ณผ๋ฃจ์
์ด ๋ฌด์์ธ์ง ๋ชฐ๋ผ๋ ์ปจ๋ณผ๋ฃจ์
๋ฆฌ๋ฒ๋ธ๋ฅผ ๋ง๋๋ ๋ฐ๋ ์๋ฌด ๋ฌธ์ ๊ฐ ์๋ค.
๊ทธ๋ฌ๋ ์ ์ด๋ ์ด ์ดํํฐ๊ฐ 2๊ฐ์ ์ ํธ ์ ๋ณด๋ฅผ ๊ณฑํด์ ์๋ก์ด ์ ํธ๋ฅผ ๋ง๋ค์ด๋ด๋ ์๋ฆฌ๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ ๊ฒ์ ์์์ผ ํ์๊ฐ ์ ์ด๋ฐ ์ฝ๋๋ฅผ ์์ฑํ๋์ง๋ ์ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ต์ ์ธ ์ค๋ช ์ ํ๋ ๊ฒ์ด๋ค.
์ด์จ๋ ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ์ ๋๋ต์ ์ธ ์๋ฆฌ๋ฅผ ํ์ ํ๋ค๋ฉด ์ด์ ๋ฐ๋ก ๋ง๋ค์ด๋ณด๋๋ก ํ์.
Convolution Reverb ๊ตฌํํด๋ณด๊ธฐ
๋จผ์ HTML5 Audio API๋ ReverbNode
๊ฐ์ ๊ฑด ์ ๊ณตํ์ง ์๋๋ค. ํ์ง๋ง ์์์ ์ค๋ช
ํ๋ฏ์ด ์ปจ๋ณผ๋ฃจ์
์ฐ์ฐ์ ์ง์ํ๋ ConvolverNode
๋ฅผ ์ ๊ณตํด์ฃผ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๋ ์ํฅ ์์ค์ธ IR(Impulse Response)
๋ง ์ง์ ๋ง๋ค์ด์ฃผ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ผ๋ฐ์ ์ผ๋ก ๋ฆฌ๋ฒ๋ธ๋ wet
๊ณผ dry
๋ผ๋ ์์น๋ก ์๋ณธ ์์ค์ ์ํฅ ์์ค๋ฅผ ๋น์จ์ ๋ง๊ฒ ์์ ์ ์๋๋ก ์ ์๋๋ฏ๋ก ํ์๋ ๋์ผํ๊ฒ ์ฝ๋๋ฅผ ์์ฑํ๊ฒ ๋ค.
const mix = 0.5;
const time = 0.01;
const decay = 0.01;
๋ฆฌ๋ฒ๋ธ์ ์ฌ์ฉํ 3๊ฐ์ ๋ณ์๋ฅผ ๋จผ์ ์ค๋ช
ํ์๋ฉด, mix
๋ wet/dry์ ๋น์จ์ ์๋ฏธํ๊ณ , time
์ ์ํฅ์ ๊ธธ์ด, decay
๋ ์ํฅ์ด ๊ฐ์ํ๋ ๋น ๋ฅด๊ธฐ๋ฅผ ์๋ฏธํ๋ค. ๊ทธ๋ผ ์ด์ ์ด ๊ฐ๋ค์ ์ฌ์ฉํ์ฌ ์ง์ IR
์ ์์ฑํด๋ณด์.
function generateImpulseResponse () {
const sampleRate = audioContext.sampleRate;
const length = sampleRate * time;
const impulse = audioContext.createBuffer(2, length, sampleRate);
const leftImpulse = impulse.getChannelData(0);
const rightImpulse = impulse.getChannelData(1);
for (let i = 0; i < length; i++) {
leftImpulse[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / length, deacy);
rightImpulse[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / length, deacy);
}
return impulse;
}
๋ญ๊ฐ ๋ณต์กํด๋ณด์ด์ง๋ง ๋ฏ์ด๋ณด๋ฉด ๋ณ ๊ฑฐ ์๋ค. sampleRate
๋ ์ฐ๋ฆฌ๊ฐ ์์ฑํ๊ณ ์ ํ๋ IR
์ ์ํ๋ ์ดํธ, ์ฆ ์์ง์ ์๋ฏธํ๊ณ length
๋ sampleRate * time
, ์ฆ time
์ด ๋งํผ์ ์ํฅ์ ํํํ๊ธฐ ์ํ ๋ฒํผ์ ๊ธธ์ด๋ฅผ ์๋ฏธํ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ๋ฅ ๋ฒํผ ๋
ธ๋๋ฅผ ํ๋ ์์ฑํ ๋ค์ -1 ~ 1
์ ๋ฌด์์ ๊ฐ์ ์์ฑํ ํ 1 - i / length
์ decay
๋ฅผ ์ ๊ณฑํ ํ ๋ฐฉ๊ธ ์์ฑํ ๋์์ ๊ณฑํด์ค๋ค. ์ด๋ฌ๋ฉด i
๊ฐ์ด ์ปค์ง์๋ก ๊ฐ์ด ์์์ง ๊ฒ์ด๊ณ , deacy
๊ฐ์ด ์ปค์ง์๋ก ๋ ๋น ๋ฅด๊ฒ ์์์ง ๊ฒ์ด๋ค. ์ด๋ ์ํฅ์ ๊ฐ์ ๋ฅผ ํํ ํด์ค ๊ฒ์ด๋ค. ์ดํ ์ด ์ํ์ ๋ฐฉ๊ธ ๋ง๋ ๋ฒํผ ๋
ธ๋์ ์ญ๋ฅด๋ฅต ๋ด์์ฃผ๋ฉด ๋์ด๋ค.
์ด๋ ๊ฒ ์์ฑ๋ IR
๋ฒํผ๋ฅผ ํํ์ผ๋ก ํํํด๋ณด๋ฉด ๋๋ต ๋ค์๊ณผ ๊ฐ์ ๋ชจ์์ ๊ฐ์ง ๊ฒ์ด๋ค.
์จ, ์ด๋ ๊ฒ ๊ฐ๋จํ๊ฒ IR
๋ฅผ ์์ฑํด๋ณด์๋ค. ์ด์ ConvolverNode
๋ฅผ ์ฌ์ฉํ์ฌ ์๋ณธ ์์ค์ ์ด IR์ ํฉ์ฑํด์ฃผ๋ ๊ฒ๋ง ๋จ์๋ค. ๋ฆฌ๋ฒ๋ธ ์ดํํฐ์ ์ค๋์ค ํ๋ฆ์ ๋ง๋ค๊ธฐ ์ํด์ ํ์ํ ๋
ธ๋๋ค์ ๋จผ์ ์์ฑํด๋ณด์.
const inputNode = audioContext.createGain();
const wetGainNode = audioContext.createGain();
const dryGainNode = audioContext.createGain();
const reverbNode = audioContext.createConvolver();
const outputNode = audioContext.createGain();
์์์๋ ์ค๋ช
ํ๋ฏ์ด ์ผ๋ฐ์ ์ธ ๋ฆฌ๋ฒ๋ธ ์ดํํฐ๋ wet/dry
๋ผ๋ ์์น๋ฅผ ์ฌ์ฉํ์ฌ ์๋ณธ ์์ค์ ๋ฆฌ๋ฒ๋ธ๊ฐ ์ ์ฉ๋ ์์ค๋ฅผ ์์ด์ ์ถ๋ ฅํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์ด๋ dryํ ์์ค๋ ๋ฆฌ๋ฒ๋ธ ์ดํํฐ๋ฅผ ๊ฑฐ์น์ง ์๊ณ ๋ฐ๋ก outputNode
๋ก ์ฐ๊ฒฐ๋์ ์ถ๋ ฅ๋์ด์ผ ํ๋ฉฐ, wetํ ์์ค๋ ์ฐ๋ฆฌ๊ฐ ๋ง๋ reverbNode
๋ฅผ ํ๋ฒ ๊ฑฐ์น๊ณ outputNode
๋ก ์ถ๋ ฅ๋์ด์ผ ํ๋ค.
sourceNode.connect(inputNode);
// Dry ์์ค ๋
ธ๋ ์ฐ๊ฒฐ
inputNode.connect(dryGainNode);
dryGainNode.connect(outputNode);
dryGainNode.gain.value = 1 - mix;
// IR์ ์์ฑํ์ฌ Convolver์ ์ค๋์ค ๋ฒํผ์ ์
๋ ฅํด์ค๋ค.
reverbNode.buffer = generateImpulseResponse();
// Wet ์์ค ๋
ธ๋ ์ฐ๊ฒฐ
inputNode.connect(reverbNode);
reverbNode.connect(wetGainNode);
webGainNode.connect(outputNode);
wetGainNode.gain.vaule = mix;
outputNode.connect(audioContext.destination);
์ด๋ ๊ฒ ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ๋ฅผ ๊ฐ๋จํ๊ฒ ๊ตฌํํด๋ณด์๋ค. ์ฌ์ค ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ์ ํ๋ฆฌํฐ์ ๊ฐ์ฅ ํฐ ์ํฅ์ ๋ผ์น๋ ๊ฒ์ IR์ ํ๋ฆฌํฐ์ธ๋ฐ, ์ฐ๋ฆฌ๋ ๋์ถฉ ๋ง๋ ์ํ ์ค๋์ค๋ก IR์ ๋ง๋ค์์ผ๋ฏ๋ก ์ด ๋ฆฌ๋ฒ๋ธ์ ํ๋ฆฌํฐ๋ ์ข์ ์๊ฐ ์๋ค. ๊ทธ๋ฌ๋ ์์ค ๋ ธ๋๋ฅผ ์ฌ์ํด์ ๋ค์ด๋ณด๋ฉด ์ ๊ธฐํ๊ฒ๋ ์๋ฆฌ์ ๊ณต๊ฐ๊ฐ์ด ๋ถ์ฌ๋ ๊ฒ์ ๋ค์ด๋ณผ ์ ์๋ค.
๋ง์ฝ ๊ธฐํ๊ฐ ๋๋ค๋ฉด ๋ค์์๋ ์๊ณ ๋ฆฌ์ฆ ๋ฆฌ๋ฒ๋ธ์ ๊ตฌํ์ฒด๋ ํ๋ฒ ํฌ์คํ ํด๋ณด๋๋ก ํ๊ฒ ๋ค. ์๊ณ ๋ฆฌ์ฆ ๋ฆฌ๋ฒ๋ธ๋ ์ค์ ๊ณต๊ฐ์ ์ํฅ์ ๋ น์ํ์ฌ ์ฌ์ฉํ๋ ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ์๋ ๋ค๋ฅด๊ฒ 100% ์๊ณ ๋ฆฌ์ฆ์ผ๋ก๋ง ๊ตฌํ๋ ๋ฆฌ๋ฒ๋ธ์ด๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ ์ธ์์ ์ธ ๋๋์ด ๋๊ธฐ๋ ํ์ง๋ง ์ปจ๋ณผ๋ฃจ์ ๋ฆฌ๋ฒ๋ธ์๋ ๋ ์๋ค๋ฅธ ๋๋์ ๋ถ์ฌํ ์ ์์ผ๋ฏ๋ก ์ฌ์ด๋ ์์ง๋์ด๋ค์ ์ด ๋๊ฐ์ง ๋ฆฌ๋ฒ๋ธ์ ํน์ฑ์ ํ์ ํ๊ณ ์ ์ฌ์ ์์ ์ฌ์ฉํ๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๋ค์๊ฒ๋ ์คํ๋ ค ์ปจ๋ณผ๋ฃจ์
๋ฆฌ๋ฒ๋ธ๋ณด๋ค ์๊ณ ๋ฆฌ์ฆ ๋ฆฌ๋ฒ๋ธ ์ชฝ์ด ๋ ์ดํด๊ฐ ์๋ ์ ์์ผ๋, ConvolverNode
ํ๋์ ๋์ถฉ ๋ง๋ IR
๋ง ์์ผ๋ฉด ๋๋จธ์ง๋ ์์์ ๋ค ์ฐ์ฐํด์ฃผ๋ ์ปจ๋ณผ๋ฃจ์
๋ฆฌ๋ฒ๋ธ์๋ ๋ค๋ฅด๊ฒ ์๊ณ ๋ฆฌ์ฆ ๋ฆฌ๋ฒ๋ธ๋ ์ง์ง ๋ฐ๋ฐ๋ฅ๋ถํฐ ๋ง๋ค์ด์ผํ๋ค. ๊ทธ๋์ ์์ฝ์ง๋ง ์๊ณ ๋ฆฌ์ฆ ๋ฆฌ๋ฒ๋ธ๋ ๋ค์์ ํฌ์คํ
ํ๋๋ก ํ๊ฒ ๋ค.
๋ง์ฝ ์๊ณ ๋ฆฌ์ฆ ๋ฆฌ๋ฒ๋ธ์ ๊ตฌํ์ฒด๊ฐ ๊ถ๊ธํ์ ๋ถ์ ํ์์ ๊นํ๋ธ ๋ ํ์งํ ๋ฆฌ์์ ํ์ธํด๋ณผ ์ ์๋ค.
Delay
๋๋ ์ด(Delay)
๋ ๋ฆฌ๋ฒ๋ธ์ ๊ฐ์ ๊ณต๊ฐ๊ณ ์ดํํฐ์ด๊ณ ์๋ฆฌ๋ฅผ ๋ฐ๋ณตํด์ ๋ค๋ ค์ค๋ค๋ ์ ์ด ๊ฐ๊ธฐ ๋๋ฌธ์ ๋น์ทํ๋ค๊ณ ์๊ฐํ ์ ์์ง๋ง ๊ทธ ์๋ฆฌ์ ์ฉ๋๋ ๋ง์ด ๋ค๋ฅด๋ค.
๋จผ์ , ๋๋ ์ด๋ ๋จ์ํ ์๋ฆฌ๋ฅผ ๋ฐ๋ณตํ๋ ํจ๊ณผ์ด์ง๋ง ๋ฆฌ๋ฒ๋ธ๋ ๊ณต๊ฐ ๋ด์์์ ๋ณต์กํ ๋ฐ์ฌ์์ ํ๋ด๋ด๋ ๊ฒ์ด๋ฏ๋ก ๋๋ ์ด๋ง ์ฌ์ฉํ๋ฉด ๋ฆฌ๋ฒ๋ธ์ ๊ฐ์ ์์ฐ์ค๋ฌ์ด ๊ณต๊ฐ๊ฐ์ ํํํ๊ธฐ๊ฐ ํ๋ค๋ค.
๋ฐฉ๊ธ ๋ง๋ค์ด๋ดค๋ ๋ฆฌ๋ฒ๋ธ ์ดํํฐ๋ ์ฌ์ค์ ์ธ ๊ณต๊ฐ ํํ์ด ๋ชฉ์ ์ด๊ธฐ ๋๋ฌธ์ ์ปจ๋ณผ๋ฃจ์
์ด๋ ๋ณต์กํ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ง๋ง ๋๋ ์ด๋ ๊ทธ๋ฅ ์๋ณธ ์์ค๋ฅผ ์ ๊น ์ง์ฐ์์ผฐ๋ค๊ฐ n
์ด ํ์ ๋ค์ ํ์ด์ฃผ๋ฉด์ ์กฐ๊ธ์ฉ ์๋ฆฌ๋ฅผ ์๊ฒ ํด์ฃผ๋ฉด ๋์ด๋ค.
๋๋ ์ด๋ ์ด๋ ๊ฒ ๊ฐ๋จํ ์๋ฆฌ๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ง๋๋ ๊ฒ ์ญ์ ๊ทธ๋ ๊ฒ ์ด๋ ต์ง ์๋ค.
Delay ๊ตฌํํด๋ณด๊ธฐ
HTML5์ Audio API๋ ์ธํ์ผ๋ก ๋ฐ์ ์ ํธ๋ฅผ ์ง์ฐ์์ผ์ ๋ค์ ์ถ๋ ฅํ๋ Delay Node
๋ฅผ ์ ๊ณตํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๋ ์ด ๋
ธ๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ๋๋ ์ด ์ดํํฐ๋ฅผ ๊ตฌํํ ์ ์๋ค.
๊ทธ๋ฌ๋ ๋จ์ํ DelayNode
๋ง ์ฌ์ฉํ๋ค๋ฉด ๋จ ํ๋ฒ์ ์ง์ฐ๋ง ๋ฐ์์ํฌ ์ ์๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๋ ํ๊ฐ์ง ์์์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋๋ ์ด๋ฅผ ๊ตฌํํ ๊ฒ์ด๋ค. ๋จผ์ ๋๋ ์ด์ ํ์ํ ๋ณ์๋ค์ ์ ์ธํด๋ณด๋๋ก ํ์.
const mix = 0.5;
const feedback = 0.5;
const time = 0.3;
๋ฆฌ๋ฒ๋ธ์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋๋ถ๋ถ์ ๋๋ ์ด ์ดํํฐ๋ wet/dry
๊ฐ์ ์ฌ์ฉํ์ฌ ์๋ณธ ์์ค์ ๋๋ ์ด๋ ์์ค๋ฅผ ์์ด์ ์ถ๋ ฅํด์ฃผ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ํ์๋ ๋์ผํ๊ฒ ๊ตฌํํด์ค ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ feedback
๋ณ์๋ ์๋ณธ ์์ค๊ฐ ํ๋ฒ ๋๋ ์ด๋ ๋ ๊ฐ์์ํฌ ์๋์ด๊ณ time
๋ณ์๋ ๋ฉ์๋ฆฌ๋ค์ ๊ฐ๊ฒฉ์ ์๋ฏธํ๋ค. ๋๋ ์ด์ ์ฌ์ฉํ ๋ณ์๋ค์ ๋ชจ๋ ์ ์ธํ๋ค๋ฉด ์ด์ ๋
ธ๋๋ค์ ๋ง๋ค ์ฐจ๋ ์ด๋ค.
const inputNode = audioContext.createGain();
const wetGainNode = audioContext.createGain();
const dryGainNode = audioContext.createGain();
const feedbackNode = audioContext.createGain();
const delayNode = audioContext.createDelay();
const outputNode = audioContext.createGain();
webGainNode
์ dryGainNode
๋ ๋ฆฌ๋ฒ๋ธ์ ๋์ผํ๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ๋์ด๊ฐ๊ณ , ์๋ก์ด ๋
ธ๋์ธ feedbackNode
์ delayNode
์ ์ง์คํด๋ณด์. ์ฌ์ค์ ๋๋ ์ด ์ดํํฐ๋ ์ด ๋๊ฐ์ ๋
ธ๋๊ฐ ํต์ฌ์ด๋ค. ๋จผ์ , ๋๋ ์ด ์ดํํฐ๊ฐ ํ๋ ์ผ์ ๋ํด์ ๋ค์ ํ๋ฒ ์ดํด๋ณด์.
์ ๋ ฅ -> ์ง์ฐ -> ๊ฐ์๋ ์ ํธ ์ถ๋ ฅ -> ์ ๋ ฅ -> ์ง์ฐ -> ๊ฐ์๋ ์ ํธ ์ถ๋ ฅโฆ
๋๋ ์ด ์ดํํฐ๊ฐ ํ๋ ์ผ์ ์ด๊ฒ ์ ๋ถ๋ค. ์ ํธ๋ฅผ ์กฐ๊ธ์ฉ ์ง์ฐ์ํค๊ณ ๊ฐ์๋ ์ ํธ๋ฅผ ๋ค์ ์ถ๋ ฅํ๋ ์ผ์ ๋ฐ๋ณตํ๋ค. ๊ทธ๋์ ํ์๋ delayNode
์ feedbackNode
๋ฅผ ์๋ก ์ฐ๊ฒฐํด์ฃผ๋ ๋ฐฉ๋ฒ์ผ๋ก ์ด ์ดํํฐ๋ฅผ ๊ตฌํํ๋ ค๊ณ ํ๋ค.
์ด๋ ๊ฒ ๋
ธ๋๋ค์ ์ฐ๊ฒฐํ๊ฒ๋๋ฉด DelayNode
๋ฅผ ํตํด ์
๋ ฅ๋ ์ค๋์ค ์ ํธ๊ฐ ์ง์ฐ๋ ํ FeedbackNode
์ OutputNode
๋ก ์ถ๋ ฅ๋๊ณ , FeedbackNode
๋ฅผ ํตํด์ ๊ฒ์ธ์ด ๊ฐ์๋ ์๋ฆฌ๋ ๋ค์ DelayNode
๋ก ์
๋ ฅ๋์ด ์ง์ฐ๋ ํ OutputNode
๋ก ์ถ๋ ฅ๋ ๊ฒ์ด๋ค. ๊ทธ๋ผ ์ ๊ทธ๋ฆผ๋๋ก ํ๋ฒ ๋
ธ๋๋ค์ ์ฐ๊ฒฐํด๋ณด๋๋ก ํ์.
sourceNode.connect(inputNode);
// Dry ์์ค ๋
ธ๋ ์ฐ๊ฒฐ
inputNode.connect(dryGainNode);
dryGainNode.connect(outputNode);
dryGainNode.gain.value = 1 - mix;
// Delay ๋ฃจํ ์์ฑ
delayNode.connect(feedbackNode);
feedbackNode.connect(delayNode);
// Wet ์์ค ๋
ธ๋ ์ฐ๊ฒฐ
inputNode.connect(delayNode);
delayNode.connect(wetGainNode);
wetGainNode.connect(outputNode);
wetGainNode.gain.vaule = mix;
outputNode.connect(audioContext.destination);
์ด์ ์์ค ๋ ธ๋๋ฅผ ์ฌ์ํด๋ณด๋ฉด ๋๋ ์ด ์ดํํฐ๋ฅผ ํตํด ๋ฉ์๋ฆฌ๊ฐ ์น๋ ๋ฏํ ํจ๊ณผ๊ฐ ์ ์ฉ๋ ์๋ฆฌ๋ฅผ ๋ค์ด๋ณผ ์ ์๋ค.
Filter
ํํฐ(Filter)
๋ ๋ฌด์ธ๊ฐ๋ฅผ ๊ฑธ๋ฌ๋ด๋ ๋๊ตฌ ํน์ ๊ฐ๋
์ ์๋ฏธํ๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฏธ ํํฐ๋ผ๋ ๊ฐ๋
์ ํ์์ ๋ง์ด ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ์ดํดํ๊ธฐ ์ด๋ ค์ด ๊ฐ๋
์ ์๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ค๋์ค ์ดํํฐ์์์ ํํฐ๋ ๋ฐ๋ก ์ฃผํ์
๋ฅผ ๊ฑธ๋ฌ๋ด๋ ์ญํ ์ ํ๋ค.
์ฝ๊ฒ ๋งํ๋ฉด ํํฐ๋ ์ค๋์ค์ ์์ญ๋ ์ค ํน์ ํ ์์ญ๋๋ง ์ฝ ์ง์ด๋ด์ด ์์ ๋ฒ๋ฆด ์ ์๋ ์ดํํฐ์ธ ๊ฒ์ด๋ค. ๊ทธ๋์ ํํฐ๋ ์ฃผ๋ก ์๋ฆฌ์ ์์ฌ์๋ ๋ ธ์ด์ฆ๋ฅผ ๊ฑธ๋ฌ๋ด๊ฑฐ๋ ๋๋ฌด ๋ฎ๊ฑฐ๋ ๋๋ฌด ๋์์ ์ธ๋ฐ์๋ ์ธ๋ฆผ์ ์์ฑํ๋ ์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ด๋๋ฐ ๋ง์ด ์ฌ์ฉ๋๋ค.
์ด๋ฌํ ํํฐ์ ํน์ฑ์ ์ ์ฌ์ฉํ๋ฉด ์๋นํ ์ฌ๋ฏธ์๋ ์ง์ ๋ง์ด ํ ์ ์๋๋ฐ ๋ํ์ ์ธ ์๋ฅผ ๋๊ฐ ์ ๋ ๋ค์๋ฉด, ๋ฐ๋ก ์ ํ๊ธฐ์์ ๋์ค๋ ๋ชฉ์๋ฆฌ๋ฅผ ๋ง๋ค๊ฑฐ๋ ํด๋ฝ์์ ๋๋ ์์ ์๋ฆฌ์ ๊ฐ์ ์๋ฆฌ๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
๋จผ์ , ์ ํ๊ธฐ์์ ๋์ค๋ ๋ชฉ์๋ฆฌ๋ ์ ์ฒด ์ฃผํ์ ์ค์์ ํน์ ํ ๋์ญ์ ์ฃผํ์๋ง ํต๊ณผ์ํค๋ Bandpass
ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋ค์ด ๋ผ ์ ์๋ค. ์ ํ๊ธฐ๊ฐ ์ ์กํ ์ ์๋ ์ฃผํ์ ๋์ญ์ ํ๊ณ๊ฐ ์๋ค๋ ๊ฒ์ ์ด์ฉํ์ฌ ์ธ๊ฐ์ ๋ชฉ์๋ฆฌ ๋์ญ์ธ 100 ~ 250hz
์ ์ฃผํ์๋ฅผ ์ ์ธํ ๋๋จธ์ง ์ฃผํ์๋ฅผ ๋ชจ๋ ์๋ผ๋ด๋ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์ฌ๋์ ๋ชฉ์๋ฆฌ ์์ค์ ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ 100 ~ 250hz
๋์ญ์ ์ ์ธํ๊ณ ๋๋จธ์ง ์ฃผํ์๋ฅผ ๋ชจ๋ ๋ ๋ ค๋ฒ๋ฆฌ๊ฒ๋๋ฉด ์ฐ๋ฆฌ๊ฐ ์ผ๋ฐ์ ์ผ๋ก ์ ํ๋ฅผ ํ ๋ ๋ค๋ฆฌ๋ ๋ชฉ์๋ฆฌ๋ก ๋ง๋ค์ด๋ผ ์ ์๋ ๊ฒ์ด๋ค.
ํด๋ฝ์์ ๋๋ ์์
์๋ฆฌ๋ ๋น์ทํ ์๋ฆฌ๋ก ๋ง๋ค์ด๋ด๋ ๊ฒ์ด๋ค. ํด๋ฝ์ ํน์ฑ ์ ๋ณดํต ์งํ์ ์์นํ๊ณ ์ข์ ์
๊ตฌ๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ๊ทธ๋ฐ ์ํฉ์์ ํด๋ฝ์์ ๋
ธ๋๋ฅผ ํ๊ฒ๋๋ฉด ์๋ฆฌ๊ฐ ๋ฐ์ผ๋ก ๋น ์ ธ๋์ฌ ์ ์๋ ํต๋ก๊ฐ ๊ฑฐ์ ์๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ์ง์์์ ํด๋ฝ์์ ํ๊ณ ์๋ ๋
ธ๋๋ฅผ ๋ค์ด๋ณด๋ฉด ๊ต์ฅํ ๋ฌต์งํ ๋ถ~ ๋ถ~
ํ๋ ์๋ฆฌ๊ฐ ๋ค๋ฆฌ๊ฒ ๋๋ค.
ํด๋ฝ ์์ ์ ํน์ฑ ์ ๊ฐํ ๋๋ผ๊ณผ ๋ฒ ์ด์ค๋ก ์ธํด ์ ์์ด ๋ถ๊ฐ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ณ , ๊ณ ์๋ณด๋ค๋ ์ ์์ ๋ฌผ์ฒด ํฌ๊ณผ์จ์ด ๋๊ธฐ ๋๋ฌธ์ ํด๋ฝ ์ธ๋ถ์์๋ ์๋์ ์ผ๋ก ๊ณ ์์ ๋นํด ๋ง์ด ํฌ๊ณผ๋ ์ ์์ ์์ฃผ๋ก ๋ฃ๊ฒ ๋๋ ๊ฒ์ด๋ค. ์ด๋ฌํ ํ๋์ ํน์ฑ์ ์๋ฆฌ์ ํ์ ๋๋ ๊ฒ์ ์๋๊ณ ๋น๊ณผ ๊ฐ์ ๋ค๋ฅธ ํ๋๋ํ ๊ณ ์ฃผํ์ ์๋์ง ์์ค๋ฅ ์ด ์ ์ฃผํ๋ณด๋ค ๋๋ค.
์ด๋ ๋ฏ ์ฌ์ด๋ ์์ง๋์ด๋ค์ ํน์ ์ํฉ์ ์๋ฆฌ๊ฐ ์ด๋ป๊ฒ ๋ค๋ฆฌ๋์ง ๋ถ์ํ๊ณ ํํฐ๋ฅผ ํฌํจํ ์ฌ๋ฌ๊ฐ์ง ์ดํํฐ๋ค์ ์ฌ์ฉํ์ฌ ๊ทธ ์ํฉ์ ํ์ฅ๊ฐ์ ๋ถ์ฌํ๊ธฐ๋ ํ๋ค.
๋คํํ๋ HTML5 Audio API๋ ์ด๋ฐ ํํฐ๋ฅผ ๋ง๋ค ์ ์๋ BiquadFilterNode
๋ฅผ ์ ๊ณตํด์ฃผ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ์ง์ ์ค๋์ค ๋ฒํผ๋ฅผ ๊น์ ์ฃผํ์๋ฅผ ๋ถ์ํด์ผํ๋ ์ฌํ ์ํฉ์ ํผํ ์ ์๋ค. ์ฐ๋ฆฌ๋ ์ด ๋
ธ๋๊ฐ ์ ๊ณตํ๋ ๊ฐ๋ค์ด ์ด๋ค ๊ฒ์ ์๋ฏธํ๋์ง๋ง ์๊ณ ์์ผ๋ฉด ๋๋ค.
๊ทธ๋ผ BiquadFilterNode
๊ฐ ์ ๊ณตํ๋ ์์ฑ๋ค์ด ๋ฌด์์ ์๋ฏธํ๋์ง ํ๋ํ๋ ์ดํด๋ณด๋๋ก ํ์.
Frequency
Frequency
๋ ์ด๋ค ๋์ญ์ ์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ผ ๊ฒ์ธ์ง๋ฅผ ์ ํ๋ ๊ฐ์ด๋ค. ๋จ์๋ hz(ํค๋ฅด์ธ )
๋ฅผ ์ฌ์ฉํ๋ฉฐ, 10hz
๋ถํฐ ์ค๋์ค์ ์ํ๋ ์ดํธ์ ์ ๋ฐ๊น์ง์ ๊ฐ์ ํ ๋นํ ์ ์๋ค. ๋ง์ฝ ์ค๋์ค ์์ค์ ์ํ๋ ์ดํธ๊ฐ 44,100hz
๋ผ๋ฉด 22,050
๊น์ง๋ฅผ ํ ๋นํ ์ ์๋ค๋ ์๋ฏธ์ด๋ค.
Q
์ ํธ๋ฅผ ๊ฑธ๋ฌ๋ธ๋ค๋ ๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์นผ์ฒ๋ผ ๋ฑ! ์๋ฅผ ์ ์๋ ๊ฒ์ด ์๋๋ค. ์๋ฆฌ ์์ฒด๋ ์๋ ๋ก๊ทธ ์ ํธ์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ชจ ๋ฐ๋ฏํ๊ฒ ์๋ผ๋ผ ์ ์๊ณ ์ด๋ ์ ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๊ฐ์ง๊ณ ๊ฑธ๋ฌ๋ผ ์๋ฐ์ ์๋๋ฐ, ์ด๋ Q
๋ ํน์ ์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ผ ๋ ์ผ๋ง๋ ์๋ฏผํ๊ฒ ๊ฑธ๋ฌ๋ผ ์ ์๋ ์ง๋ฅผ ์๋ฏธํ๋ค.
Q
์๋ 0.0001 ~ 1000
์ฌ์ด์ ๊ฐ์ ํ ๋นํ ์ ์์ผ๋ฉฐ, Q์ ๊ฐ์ด ๋์ ์๋ก ์ก์๋ธ ์ฃผํ์๋ฅผ ๋ ์๋ฏผํ๊ฒ ๊ฑธ๋ฌ๋ผ ์ ์๋ค. ๊ทธ๋ฌ๋ ์ค๋์ค ์ ํธ๋ฅผ ํํฐ๋ง ํ ๋ Q๊ฐ ๋๋ฌด ๋๋ค๋ฉด ์์ฐ์ค๋ฝ๊ฒ ๋ค๋ฆฌ์ง ์๊ณ ์ธ์์ ์ผ๋ก ๋ค๋ฆด ์ ์๊ธฐ ๋๋ฌธ์ ์ ๋นํ ๊ฐ์ ์ฐพ๋ ๊ฒ์ด ์ค์ํ๋ค.
Type
BiquadFilterNode
๋ก๋ ์ฌ๋ฌ๊ฐ์ง ํ์
์ ํํฐ๋ฅผ ๋ง๋ค์ด ๋ผ ์ ์๋๋ฐ, ํฌ๊ฒ๋ ์ฃผํ์๋ฅผ ์์ ๊ฑธ๋ฌ๋ด๋ฒ๋ฆฌ๋ ํ์
๊ณผ, ํน์ ์ฃผํ์๋ฅผ ์ฆํญ์ํค๊ฑฐ๋ ๊ฐ์์ํฌ ์ ์๋ ํ์
์ผ๋ก ๋๋ ์ง๋ค.
์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ด๋ ํ์
lowpass(highcut)
: ์ง์ ํ ์ฃผํ์๋ณด๋ค ๋์ ์ฃผํ์๋ฅผ ๋ชจ๋ ๊ฑธ๋ฌ๋ธ๋ค.highpass(lowcut)
: ์ง์ ํ ์ฃผํ์๋ณด๋ค ๋ฎ์ ์ฃผํ์๋ฅผ ๋ชจ๋ ๊ฑธ๋ฌ๋ธ๋ค.bandpass
: ์ง์ ํ ์ฃผํ์๋ฅผ ์ ์ธํ ๋ชจ๋ ์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ธ๋ค.notch
: ์ง์ ํ ์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ธ๋ค.
์ฃผํ์๋ฅผ ์ฆํญ/๊ฐ์ํ๋ ํ์
lowshelf
: ์ง์ ํ ์ฃผํ์๋ณด๋ค ๋ฎ์ ์ฃผํ์๋ฅผ ์ฆํญ/๊ฐ์ ์ํจ๋ค.highshelf
: ์ง์ ํ ์ฃผํ์๋ณด๋ค ๋์ ์ฃผํ์๋ฅผ ์ฆํญ/๊ฐ์ ์ํจ๋ค.peaking
: ์ง์ ํ ์ฃผํ์๋ฅผ ์ฆํญ/๊ฐ์ ์ํจ๋ค.
์ด ์ค ์ฃผํ์๋ฅผ ์ฆํญ/๊ฐ์์ํค๋ ํ์
์ ๋ฐ์์ ํ์ ํ EQ(Equalizer)
์์๋ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ฒ์๋ ๋จ์ํ ์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ด๋ ํํฐ๋ฅผ ๋ง๋ค ์์ ์ด๋ฏ๋ก ํ์๋ ์ฃผํ์๋ฅผ ๊ฑธ๋ฌ๋ด๋ ํ์
๋ง์ ์ฌ์ฉํ์ฌ ํํฐ๋ฅผ ๊ตฌํํ ๊ฒ์ด๋ค.
ํ์๋ ํน์ ์ฃผํ์๋ณด๋ค ๋์ ์ฃผํ์๋ฅผ ๋ชจ๋ ๊ฑธ๋ฌ๋ด๋ Lowpass ํํฐ
์ ํน์ ์ฃผํ์๋ณด๋ค ๋ฎ์ ์ฃผํ์๋ฅผ ๋ชจ๋ ๊ฑธ๋ฌ๋ด๋ Highpass ํํฐ
๋ฅผ ๊ตฌํํ ๊ฒ์ด๋ค. ๊ทธ๋ผ ํ๋ฒ ๊ฐ๋จํ๊ฒ ํํฐ๋ฅผ ๊ตฌํํด๋ณด๋๋ก ํ์.
Filter ๊ตฌํํด๋ณด๊ธฐ
์ฐ์ AudioContext ๊ฐ์ฒด์ createBiquadFilter
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ BiquadFilterNode
๋ฅผ ์์ฑํ๋ค. ํ์๊ฐ ๊ฐ์ง๊ณ ์๋ ์ค๋์ค ์ํ์ 44,100hz
์ ์ํ๋ ์ดํธ๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก Lowpass ํํฐ์ ์ฃผํ์๋ 1,000hz
๋ก Highpass ํํฐ์ ์ฃผํ์๋ 20,000hz
๋ก ์ค์ ํ๊ฒ ๋ค.
const lowpassFilterNode = audioContext.createBiquadFilter();
lowpassFilterNode.type = 'lowpass';
lowpassFilterNode.frequency.setValueAtTime(1000, audioContext.currentTime);
const highpassFilterNode = audioContext.createBiquadFilter();
highpassFilterNode.type = 'highpass';
highpassFilterNode.frequency.setValueAtTime(20000, audioContext.currentTime);
Q๊ฐ์ ๋ฐ๋ก ์ค์ ํด์ฃผ์ง ์์๋๋ฐ, ๊ทธ๋๋ ์ฌ์ค ์๊ด์๋ค. BiquadFilterNode
์ Q๋ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก 350์ ๊ฐ์ง๊ณ ์๊ณ ์ด ๊ฐ์ ๋๋ฌด ๊ณผํ์ง๋ ๋ถ์กฑํ์ง๋ ์์ ์ ๋นํ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ๊ธฐ๋ณธ ๊ฐ์ ์ฌ์ฉํ ๊ฒ์ด๋ค.(์กฐ๊ธ ๊ท์ฐฎ๊ธฐ๋ ํ๋ค.)
์ด์ ์์ฑํ ํํฐ ๋
ธ๋๋ค์ ์ค๋์ค ์์ค์ ์ฐ๊ฒฐํด์ฃผ๋ฉด 1,000hz
๋ณด๋ค ๋ฎ๊ณ 20,000hz
๋ณด๋ค ๋์ ์ฃผํ์๊ฐ ์ ๊ฑฐ๋ ์ค๋์ค ์ํ์ ๋ค์ด๋ณผ ์ ์๋ค.
sourceNode.connect(lowpassFilterNode);
lowpassFilterNode.connect(highpassFilterNode);
highpassFilterNode.connect(audioContext.destination);
์ฌ๊ธฐ๊น์ง ์ฝ์ผ์ ๋ถ๋ค์ ์ฌ์ฌ ๋๋ผ๊ธฐ ์์ํ๊ฒ ์ง๋ง ์ฌ์ค HTML5 Audio API๊ฐ ์๋ ์ ๋ง๋ค์ด์ ธ์์ด์ ๊ฐ๋ฐ์๊ฐ ๋ง์ ธ์ผํ ๋ถ๋ถ์ด ๊ฑฐ์ ์๋ค. ํ์๋ BiquadFilterNode
์ ์กด์ฌ๋ฅผ ์๊ธฐ ์ ์๋ โ์ ์ด๊ฑฐ ํํฐ๋ ์ด๋ป๊ฒ ๋ง๋ค์งโฆ?โ๋ผ๊ณ ๊ณ ๋ฏผํ์๋๋ฐ ์ฌ์ค ์ ์ผ ๊ณ ๋ฏผํ ํ์๊ฐ ์๋ ๋์ด์๋ค. (๊ทธ๋์ ์ฝ๊ฐ ํ๋ฌดํ๊ธฐ๋ ํ๋ค.)
EQ
Equalizer(EQ, ์ดํ๋ผ์ด์ )
๋ ์ด๋ฆ์์๋ ์ ์ ์๋ฏ์ด ์ผ์ข
์ ์ฃผํ์ ํํํ ์์
(Frequancy Equalizing)
์ ํ๋ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ๋ ์ดํํฐ์ด๋ค. EQ๋ ์ปดํ๋ ์์ ํจ๊ป ์ค๋์ค ๋ฏน์ฑ์ ๊ธฐ๋ณธ์ผ๋ก ๊น๊ณ ๋ค์ด๊ฐ๋ ์ดํํฐ์ธ๋ฐ, ์๋ณธ ์์ค์์ ์ธ๋ฐ์๋ ์๋ฆฌ๋ฅผ ์์ ๊ณ ๋ค๋ฅธ ์๋ฆฌ๋ค๊ณผ์ ์กฐํ๋ฅผ ์ด๋ฃจ๋๋ก ํ๋ ์ฉ๋๋ก ์ฃผ๋ก ์ฌ์ฉํ๋ค. EQ๋ ๊ฒฐ๊ตญ ์ฃผํ์๋ฅผ ์ปจํธ๋กคํ๋ ์ดํํฐ์ด๋ฏ๋ก ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ๋๋ฐ, ์ด๋ฏธ ์ฐ๋ฆฌ๋ ํํฐ๋ฅผ ํ๋ฒ ๋ง๋ค์ด๋ดค๊ธฐ ๋๋ฌธ์ EQ ์ ๋๋ ๋๋ฑ ๋ง๋ค ์ ์๋ค.
EQ๋ ํฌ๊ฒ ํ๋ผ๋ฉํธ๋ฆญ ์ดํ๋ผ์ด์ (Parametric EQ)
์ ๊ทธ๋ํฝ ์ดํ๋ผ์ด์ (Graphic EQ)
๋ ๊ฐ์ง ์ข
๋ฅ๋ก ๋๋์ด์ง๋๋ฐ, ํ์๋ ์ด ์ค ๊ทธ๋ํฝ ์ดํ๋ผ์ด์ ๋ฅผ ๊ตฌํํ ์์ ์ด๋ค. ์ฐธ๊ณ ๋ก ์๋จ์ ๊ทธ๋ฆผ์ ํ๋ผ๋ฉํธ๋ฆญ EQ์ธ๋ฐ, ๊ทธ๋ฅ ์ด๋ฏธ์ง๊ฐ ๋ ๋ฉ์์ด์ ๋ฃ์๋ค. ์ฐธ๊ณ ๋ก ๊ทธ๋ํฝ EQ๋ ์ด๋ ๊ฒ ์๊ฒผ๋ค.
๋ ๊ฐ์ EQ ๋ชจ๋ ์ฅ๋จ์ ์ด ์กด์ฌํ๋๋ฐ, ์ผ๋จ ๊ทธ๋ํฝ EQ์ ์ฅ์ ์ ํ๋ผ๋ฉํธ๋ฆญ EQ์ ๋นํด ์กฐ์ ํ ์ ์๋ ์ฃผํ์ ๋์ญ์ ์๊ฐ ๋ง๊ณ ์ง๊ด์ ์ธ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ ๊ฒ์ด๋ค. ์ฌ๋ฌ๋ถ์ ์ด ๋จ๋ฝ์ ๋งจ ์์ ์ฒจ๋ถ๋ ํ๋ผ๋ฉํธ๋ฆญ EQ ์ด๋ฏธ์ง๋ฅผ ๋ณด๊ณ โ์ฅ? ํ๋ผ๋ฉํธ๋ฆญ๋ ๋๋ฆ ์ง๊ด์ ์ธ๋ฐ?โ๋ผ๊ณ ํ์ค ์ ์๋๋ฐ, ์๋ ํ๋์จ์ด ํ๋ผ๋ฉํธ๋ฆญ EQ๋ ์ด๋ ๊ฒ ์๊ฒผ๋ค.
๊ทธ๋์ ๊ทธ๋ํฝ EQ๋ ๋ณดํต ๋น ๋ฅธ ๋์์ด ํ์ํ ๊ณต์ฐ์ฅ๊ฐ์ ๊ณณ์์ ๋ง์ด ์ฌ์ฉ๋๊ณ ์์ผ๋ฉฐ, ์งฌ์ด ๋ง์ด ์์ธ ์๋์ด ์ฌ์ด๋ ์์ง๋์ด๋ค์ ๊ณต์ฐ์ฅ์์ ํ์ธ๋ง(๋ ธ๋๋ฐฉ์์ ์- ํ๋ฉฐ ๊ฐ๋ ๋๋ ๋ ์นด๋ก์ด ์๋ฆฌ)์ด ๋ฐ์ํ๋ฉด ๋ฐ๋ก ํด๋น ์ฃผํ์๋ฅผ ์บ์นํด์ ๊ทธ๋ํฝ EQ๋ก ์ฃฝ์ฌ๋ฒ๋ฆฌ๋ ๋ฌด์์ด ์คํฌ์ ๊ฐ์ง๊ณ ์๋ค.
๊ทธ๋ํฝ EQ์ ๋จ์ ์ ์กฐ์ ํ ์ ์๋ ์ฃผํ์ ๋์ญ์ด ์ ํด์ ธ ์๋ค๋ ๊ฒ๊ณผ ์ฃผํ์์ ์ธ๋ฐํ ์กฐ์ ์ด ํ๋ค๋ค๋ ๊ฒ์ด๋ค. ๋ฐ๋ฉด ํ๋ผ๋ฉํธ๋ฆญ EQ๋ ๊ทธ๋ํฝ EQ์ ๋ค๋ฅด๊ฒ ์กฐ์ ํ ์ ์๋ ์ฃผํ์ ๋์ญ๊น์ง ๋ชจ๋ ์ ํด์ค ์ ์๋ค.
๊ทธ๋ฌ๋ ํ๋ฒ์ ์กฐ์ ํ ์ ์๋ ์ฃผํ์์ ๊ฐ์๋ ๊ทธ๋ํฝ EQ์ ๋นํด ํฌ๊ฒ ๋ถ์กฑํ๋ค. ์ผ๋ฐ์ ์ธ ํ๋ผ๋ฉํธ๋ฆญ EQ๊ฐ 3~5
๊ฐ์ ์ฃผํ์ ๋์ญ์ ์กฐ์ ํ ์ ์๋ ๋ฐ๋ฉด์ ๊ทธ๋ํฝ EQ๋ ํ๋ฒ์ ์กฐ์ ๊ฐ๋ฅํ ์ฃผํ์๊ฐ 40
๊ฐ๊ฐ ๋์ด๊ฐ๋ ๊ต์๋ ์กด์ฌํ๋ค.
ํ์ ์๊ฐ์ ํ๋์จ์ด ํ๋ผ๋ฉํธ๋ฆญ EQ์ ์ต๋ ๋จ์ ์ ๋ฐ๋ก ์ง๊ด์ ์ด์ง ์์ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ ๊ฒ์ธ๋ฐ, ์ด ๋จ์ ์ ์ํํธ์จ์ด๋ก ๊ตฌํํ๋ฉด UI๋ก ์ปค๋ฒํ ์ ์๋ ์์ญ์ด๊ธฐ๋ ํ๊ณ ๋๋ถ๋ถ์ ๋ น์์ค์์๋ ์ฆ๊ฐ์ ์ธ ๋์๋ณด๋ค๋ ๊ณ์ ์๋ฆฌ๋ฅผ ๋ค์ด๋ณด๋ฉด์ ์ดํ๋ผ์ด์ง์ ํ ์ ์๋ ์ํฉ์ด ๋๋ถ๋ถ์ด๊ธฐ ๋๋ฌธ์ ๋ง์ ์ํํธ์จ์ด EQ๊ฐ ์ฃผํ์ ๋์ญ ์กฐ์ ์ ์์ ๋๊ฐ ๋์ ํ๋ผ๋ฉํธ๋ฆญ EQ๋ก ๊ตฌํ๋๋ค.
ํ์ง๋ง ํ์๊ฐ ๋ง๋๋ ๋ฐ๋ชจ์ฒ๋ผ ๊ฐ๋จํ ๊ตฌํํด๋ณด๋ ์ํฉ์์๋ ์ ์์ ํ๋์จ์ด ํ๋ผ๋ฉํธ๋ฆญ EQ์ ๋น์ทํ UI๋ก ๊ตฌํ๋ ๊ฒ์ด ๋ปํ๋ฏ๋ก ํ์๋ ์๋์ ์ผ๋ก UI ๋ง๋ค๊ธฐ๊ฐ ์ฌ์ด ๊ทธ๋ํฝ EQ๋ฅผ ์ ํํ๋ค.(์ด ๋ง์ด ์ ์ดํด๊ฐ ์๋๋ค๋ฉด EQ ์ฑํฐ์ ๊ฐ์ฅ ์์ ์ฒจ๋ถํ ํ๋ผ๋ฉํธ๋ฆญ EQ๋ฅผ ํ๋ฒ ๋ณด๊ณ ์ค์)
์์์ ํ๋ฒ ์ด์ผ๊ธฐํ๋ฏ์ด EQ๋ ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ๋ฏ๋ก ๊ทธ๋ ๊ฒ ๋ณต์กํ์ง ์๋ค. ๊ทธ๋ผ ์ด์ ํ๋ฒ ๊ฐ๋จํ๊ฒ ๋๋ฑ ๋ง๋ค์ด๋ณด๋๋ก ํ์.
๊ทธ๋ํฝ EQ ๊ตฌํํ๊ธฐ
์์์ ๊ทธ๋ํฝ EQ ์ด๋ฏธ์ง๋ฅผ ๋ดค๋ค๋ฉด ์๊ฒ ์ง๋ง ์ด ์น๊ตฌ๋ ์กฐ์ ํ ์ ์๋ ์ฃผํ์ ๋์ญ์ ๊ฐ์๊ฐ ์ ํด์ ธ ์๋ ์ฅ๋น์ด๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ์๋ ์กฐ์ ํ ์ ์๋ ์ฃผํ์๊ฐ ๋ค์ด์๋ ๋ฐฐ์ด์ ํ๋ ์ ์ธํ๊ณ ์ด ๋ฐฐ์ด์ ์ดํฐ๋ ์ด์ ํ๋ฉด์ ํํฐ๋ค์ ์์ฑํ ๊ฒ์ด๋ค.
const frequencies = [
25, 31, 40, 50, 63, 80, 100, 125, 160, 200,
250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000,
2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500, 16000, 20000
];
์ด๋ ์ฃผ์ํด์ผํ ์ ์ด ์๋ค. EQ๋ ์ฌ๋ฌ ๊ฐ์ ํํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ฐ ํํฐ๋ฅผ ์๋ก ์ฒด์ด๋ํด์ ์ฐ๊ฒฐํด์ฃผ์ด์ผํ๋ค. ์ด๋ ํํฐ์ ๊ฒ์ธ์ด 1๋ณด๋ค ์กฐ๊ธ์ด๋ผ๋ ๋๋ค๋ฉด ํ๋ฒ ํํฐ๋ฅผ ํต๊ณผํ ๋๋ง๋ค ์๋ฆฌ๊ฐ ์กฐ๊ธ์ฉ ์ฆํญ๋์ด ์ฌ๋ฌ๋ถ์ ๊ท์ ๋ค์ด์ฌ ๋ ์ฏค์ด๋ฉด ์์ฒญ ํฐ ์๋ฆฌ๊ฐ ๋์ด ์ฌ๋ฌ๋ถ์ ๊ณ ๋ง์ ์์ํ ์ด๋ณ์ํฌ ์๋ ์๋ค.
๐จ ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ํํฐ๋ค์ ๊ฒ์ธ์
0
์ดํ๋ก ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
const inputNode = audioContext.createGain();
sourceNode.connect(inputNode);
const filters = frequencies.map((frequency, index, array) => {
const filterNode = audioContext.createBiquadFilter();
filterNode.gain.value = 0;
filterNode.frequency.setValueAtTime(frequency, audioContext.currentTime);
if (index === 0) {
filterNode.type = 'lowshelf';
}
else if (index === array.length - 1) {
filterNode.type = 'highshelf';
}
else {
filterNode.type = 'peaking';
}
return filterNode;
});
filters.reduce((prev, current) => {
prev.connect(currentNode);
return currentNode;
}, inputNode);
const outputNode = audioContext.createGain();
filters[filters.length - 1].connect(outputNode);
outputNode.connect(audioContext.destination);
map
๋ฉ์๋ ๋ด๋ถ์ if
๋ฌธ์ ๋ณด๋ฉด ํด๋น ์ฒซ๋ฒ์งธ ํํฐ์ ๋ง์ง๋ง ํํฐ์ ํ์
๋ง ๋ค๋ฅด๊ฒ ์ฃผ๊ณ ์๋ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ, ์ด๋ Shelf
ํ์
์ ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฒซ๋ฒ์งธ ํํฐ์ ์ฃผํ์๋ณด๋ค ๋ฎ์ ์ฃผํ์์ ๋ง์ง๋ง ํํฐ์ ์ฃผํ์๋ณด๋ค ๋์ ์ฃผํ์๊น์ง ๋ชจ๋ ์ปค๋ฒํ๊ธฐ ์ํด์์ด๋ค.(ํํฐ ํ์
์ด ์ ๊ธฐ์ต๋์ง ์๋๋ค๋ฉด Filter ๋ถ๋ถ์ ๋ค์ ๋ณด๊ณ ์ค์)
๊ทธ ํ ์์ฑ๋ ํํฐ๋ฅผ reduce
๋ฉ์๋๋ฅผ ํตํด ๋ชจ๋ ์ฒด์ด๋ํด์ฃผ๊ณ outputNode
์๋ ์ฐ๊ฒฐํด์ฃผ์๋ค. ์ฌ๊ธฐ๊น์ง ์์ฑํ ํ sourceNode
๋ฅผ ์ฌ์์์ผ๋ณด๋ฉด ์๋ฌด ๋ณํ๋ ์๋ ๊ฒ์ ์ ์ ์๋ค.
๋น์ฐํ ๋ชจ๋ ํํฐ์ ๊ฒ์ธ์ด 0
์ด๊ธฐ ๋๋ฌธ์ ์๋ฌด๋ฐ ๋ณํ๊ฐ ์๋ ๊ฒ์ด๋ค. ์ด๋ ์ ํํฐ๋ค์ ๊ฐ์ -1 ~ 1
์ฌ์ด์ ๋๋คํ ๋์๋ก ํ ๋นํ๋ฉด ์๋ฆฌ๊ฐ ์กฐ๊ธ์ฉ ๋ณํ๋ ๊ฒ์ ๋ค์ด๋ณผ ์๋ ์๋ค. ํ์๋ ๊ฐ์ธ์ ์ผ๋ก input[type="range"]
์๋ฆฌ๋จผํธ์ ์ฐ๋ํ์ฌ ํํฐ๋ค์ ๊ฒ์ธ์ ์กฐ์ ํ ์ ์๋๋ก ๋ง๋ค๊ณ ์ง์ ์ด๊ฒ์ ๊ฒ ๋ง์ ธ๋ณด๋ ๊ฒ์ ์ถ์ฒํ๋ค.
๋ํ ๊ฐ์ฅ ๋ฎ์ ์ฃผํ์์ ๋์ ์ฃผํ์์ ํํฐ๋ฅผ Shelf
ํ์
์ผ๋ก ์ค์ ํ๊ธฐ ๋๋ฌธ์ ์ด ํํฐ๋ค์ ๊ฒ์ธ์ ๋ฎ์ถ๋ฉด Lowpass ํํฐ
๋ Highpass ํํฐ
์ ๊ฐ์ ํจ๊ณผ๋ ๋ผ ์ ์๋ค.
๋ง์น๋ฉฐ
์, ์ฌ๊ธฐ๊น์ง ๋ํ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉํ๋ ์ดํํฐ๋ค์ธ ์ปดํ๋ ์, ๋ฆฌ๋ฒ๋ธ, ๋๋ ์ด, ํํฐ, EQ๋ฅผ ๋ง๋ค์ด๋ณด์๋ค. ์ฌ์ค ์ด 5๊ฐ ์ธ์๋ ์ฌ๋ฐ๋ ์ฌ๋ฌ๊ฐ์ง ์ดํํฐ๊ฐ ์์ง๋ง ๋ถ๋์กฐ์ ๋์คํจ๋ก ์ธํด ์ฌ๊ธฐ๊น์ง๋ง ๋ ธ๋ ๊ฒ์ผ๋ก ํ๊ฒ ๋ค.
ํํฐ๋ฅผ ๋ง๋ค ๋ ํ๋ฒ ์ด์ผ๊ธฐ ํ๋ฏ์ด HTML5 Audio API๋ ๊ต์ฅํ ๋์ ์์ค์ ์ถ์ํ๋ ๋ ธ๋๋ฅผ ์ ๊ณตํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ฌ์ค ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ตฌํํ ๊ฒ๋ค์ด ๋ณ๋ก ์๋ค. ์ด๋ ๋ค๋ฅด๊ฒ ๋งํ๋ฉด ์ธ๋ฐํ ์์ค์ ๊ตฌํ์ด ํ๋ค๋ค๋ ๋ป์ด๊ธฐ๋ ํ์ง๋ง ํ์๊ฐ ๋ฌด์จ ์ค๋์ค ์ดํํฐ ํ์ฌ๋ฅผ ์ฐจ๋ฆด ๊ฒ๋ ์๋๊ธฐ ๋๋ฌธ์ ๋จ์ ์ฌ๋ฏธ๋ก ๋ง๋ค์ด๋ณด๊ธฐ์๋ ์ถฉ๋ถํ ๊ฒ ๊ฐ๋ค.
์ด๋ ๊ฒ ์ฌ๋ฌ๊ฐ์ง ์ดํํฐ๋ฅผ ๊ตฌํํด๋ณด๋ฉฐ ํ์๋ ์์ ์ ์ฌ์ด๋ ์์ง๋์ด๋ก ์ผํ ๋์ ์ถ์ต์ด ์๋ก์๋ก ๋ ์ค๋ฅด๊ธฐ๋ ํ๊ณ ๋ ์ดํํฐ์ ๋ํด์ ์๋กญ๊ฒ ์๊ฒ๋ ๋ด์ฉ๋ ์์ด์ ๊ต์ฅํ ์ฌ๋ฐ๊ฒ ์์ ์ ํ๋ค. ํ์๋ ํฌ์คํ ์ ์์ฑํ ์ดํํฐ ์ธ์๋ ์ฌ๋ฌ๊ฐ์ง ์ดํํฐ๋ฅผ ๊ณ์ ๊ตฌํํด๋ณผ ์์ ์ด๋ฏ๋ก ๊ด์ฌ์๋ ๋ถ๋ค์ ํ์์ ๊นํ๋ธ์์ ํ๋ฒ ์ฑ ๋๋ฌ๋ณด๊ณ PR์ ๋ ๋ ค๋ ๋๋ค.(์ข์ ๊ฑด ๋๋๋ฉด ๋ฐฐ๊ฐ ๋๋ ๋ฒ์ด๋ค.)
์ด์์ผ๋ก JavaScript๋ก ์ค๋์ค ์ดํํฐ๋ฅผ ๋ง๋ค์ด๋ณด์ - ๋๋ง์ ์๋ฆฌ ๋ง๋ค๊ธฐ ํฌ์คํ ์ ๋ง์น๋ค.
- JavaScript
- ์๋ฐ์คํฌ๋ฆฝํธ
- Audio
- ์ค๋์ค ์ดํํฐ
- JavaScript Audio API
- Logic Pro X
- ๋ก์งํ๋ก
- Protools
- ํ๋กํด์ฆ
- Cubase
- ํ๋ฒ ์ด์ค
- Audio Plugin
- Compressor
- Delay
- Reverb
- EQ
๊ด๋ จ ํฌ์คํ ๋ณด๋ฌ๊ฐ๊ธฐ
[JavaScript ์ค๋์ค ์ดํํฐ ๋ง๋ค๊ธฐ] ์๋ฆฌ์ ํ๋ฆ์ ํ์ ํ์
์ปดํจํฐ๋ ์ด๋ป๊ฒ ์๋ฆฌ๋ฅผ ๋ค์๊น?
[JS ํ๋กํ ํ์ ] ํ๋กํ ํ์ ์ ์ฌ์ฉํ์ฌ ์์ํ๊ธฐ
[JS ํ๋กํ ํ์ ] ์๋ฐ์คํฌ๋ฆฝํธ์ ํ๋กํ ํ์ ํ์ด๋ณด๊ธฐ
์ต์ ๊ฐ๊ณผ ์ต๋ ๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์๊ฒ ๋์์ฃผ๋ ํ(Heap)