์ปดํจํฐ๋ ์ด๋ป๊ฒ ์๋ฆฌ๋ฅผ ๋ค์๊น?
์ด๋ฒ ํฌ์คํ
์์๋ ํ์์ ์์ ์ง์
์ด์๋ ์ฌ์ด๋ ์์ง๋์ด
์ ์ถ์ต์ ์ด๋ ค์ ํ๋ฒ ์ค๋์ค์ ๋ํ ์ด๋ก ์ ์ค๋ช
ํด๋ณผ๊น ํ๋ค. ํ์ง๋ง ์ด๋ก ์ค๋ช
๋ง ํ๋ฉด ๋
ธ์ผ์ด๋๊น ์ค๋์ค ์ด๋ก ์ ๊ธฐ์ด๋ก ์๋ฐ์คํฌ๋ฆฝํธ์ Web Audio API
๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ ์ค๋์ค ํํ๊น์ง ๊ทธ๋ ค๋ณด๋ ค๊ณ ํ๋ค.
๋ฐ๋ก ์ฝ๋ฉ์ ๋ค์ด๊ฐ๊ณ ์ถ์ง๋ง ์ค๋์ค์ ๊ดํ ๊ธฐ๋ณธ์ ์ธ ์ง์์ด ์์ด์ผ ์ค๋์ค ํํ์ ๊ทธ๋ฆด ๋์ ๊ณผ์ ์ ์ดํดํ ์ ์์ผ๋ฏ๋ก ์ด๋ก ์ ์ต๋ํ ์ง๋ฃจํ์ง ์๊ฒ ์ค๋ช ํ๋ ค๊ณ ํ๋ค. ์ด๋ก ์ด ์ฝ๋ฉ๋ณด๋ค ์ฌ๋ฏธ์๋ ๊ฑด ๋ง์ง๋ง ์ค๋์ค ํํ์ ๊ทธ๋ฆฌ๋ ค๋ฉด ์ต์ํ ๊ธฐ๋ณธ์ ์ผ๋ก ์๊ณ ์์ด์ผ ํ๋ ๊ฒ๋ค์ด๋๊น ํ๋ฒ ์ฑ ํ์ด๋ณด์.
์๋ฆฌ๋ ๋ฌด์์ผ๊น?
์ ์ผ ๋จผ์ ์๋ฆฌ๊ฐ ๋ฌด์์ธ์ง๋ถํฐ ์์๋ณด์! ์๋ฆฌ๋ฅผ ๋ฑ ํ๋ง๋๋ก ํํํ์๋ฉด ๋ฐ๋ก ์ง๋
์ด๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์๋ฆฌ๋ฅผ ๋ฃ๋๋ค๋ ๊ฒ์ ์ด๋ฐ ์์๋ก ์ผ์ด๋๋ค.
- ์ด๋ค ๋ฌผ์ฒด๊ฐ ๋ถ๋ฅด๋ฅด ์ง๋์ ํ๋ค. ์ด๋ ์ง๋ ์ฃผํ์๋ ๋ญ ๋์ถฉ
440hz
๋ผ๊ณ ์น์. - ๊ทธ ๋ฌผ์ฒด ์ฃผ๋ณ์ ์๋ ๋งค์ง์ด
440hz
์ ์ง๋์ ์ ๋ฌํ๋ค.(์ผ๋ฐ์ ์ธ ์ํฉ์์๋ ์ฃผ๋ก ๊ณต๊ธฐ) - ๋งค์ง์ด ์ง๋์ ์ ๋ฌํ๋ฉด ์ฐ๋ฆฌ์ ๊ณ ๋ง๋
440hz
๋ก ์ง๋ํ๋ค. - ๊ทธ ์ง๋ ์ ํธ๋ฅผ ๋ฌํฝ์ด๊ด์ด ์ ๊ธฐ ์ ํธ๋ก ๋ฐ๊ฟ์ ์ฒญ์ ๊ฒฝ์ ์ ๋ฌํ๋ค.
- ๋๊ฐ ์ ํธ๋ฅผ ๋ฐ์์ ํด์ํ๋ค.
440hz
์ ์์๋ฃ!
์ด๋ 1๋ฒ
์์์์ ๋ฌผ์ฒด๊ฐ 1์ด์ ๋ช ๋ฒ์ด๋ ๋จ๋ ธ๋์ง ํํํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ํค๋ฅด์ธ (herz, hz)
๋จ์๋ฅผ ์ฌ์ฉํ๋ค. 10hz
๋ 1์ด์ 10๋ฒ ์ง๋์ ํ๋ค๋ ์๋ฏธ์ด๊ณ 1khz
๋ 1์ด์ 1000๋ฒ ์ง๋์ ํ๋ค๋ ๊ฒ์ด๋ค. ์ฐธ๊ณ ๋ก ์์์ 440hz
๋ ๋๋ ๋ฏธํ์๋ผ์๋ํ ๋ ๋ผ
์์ด๋ค. ์ฐ๋ฆฌ๊ฐ ์์
์ ๋ค์ ๋๋ ํ์
๊ธฐ๋ฉด ํ์ ์ง๋
, ๊ด์
๊ธฐ๋ฉด ์
์ ์ด๋ ๋ฆฌ๋์ ์ง๋์ด ์ฆํญ๋ ๊ฒ
, ๋
ธ๋๋ผ๋ฉด ์ฑ๋์ ์ง๋
์ ๋ฃ๊ฒ ๋๋ ๊ฒ์ด๋ค. ์๋ฌด๋ฆฌ ๊ฐ์ฑํฐ์ง๋ ์์
๋ ๊ณต๋์ด ์์ ๊ฑธ๋ฆฌ๋ฉด ์ด๋ ๊ฒ ๋ถํด๋ ์ ์๋ค.
์ด๋ ์ด ์ง๋์ ์์ฐ๊ณ์์ ๋ฐ์ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์๋ ๋ก๊ทธ(Analog)
์ ํํ๋ก ๋ํ๋๋ค. ์ฌ์ค ์์ฐ๊ณ์์ ๋ฐ์ํ๋ ๋๋ถ๋ถ์ ๊ฑฐ์์ ์ธ ์ ํธ๋ ์๋ ๋ก๊ทธ ํํ๋ฅผ ๊ฐ์ง๋๋ฐ, ์๋ฅผ ๋ค๋ฉด ๋น์ ๋ฐ๊ธฐ๊ฐ ๋ณํ๋ค๊ฑฐ๋ ๋ฐ๋์ ์ธ๊ธฐ๊ฐ ๋ณํ๋ค๊ฑฐ๋ ์๋ฆฌ์ ํฌ๊ธฐ๊ฐ ๋ณํ๋ ๋ฑ์ ์ ํธ๋ฅผ ๋งํ๋ค.
์๋ฆฌ๋ ์๋ ๋ก๊ทธ ์ ํธ๋ค
์๋ ๋ก๊ทธ
๋ ์ ํธ๋ ์๋ฃ๋ฅผ ์ฐ์์ ์ธ ๋ฌผ๋ฆฌ๋
์ผ๋ก ๋ํ๋ธ ๊ฒ์ด๋ค. ์ด๊ฒ ์ฐ์์ ์ธ ๋ฌผ๋ฆฌ๋
์ด๋ผ๊ณ ํ๋ฉด ๋ญ๊ฐ ์ ๋ฌธ์ ์ด๊ณ ์ด๋ ค์๋ณด์ด๋๋ฐ ํ์ด๋ณด๋ฉด ์ฌ์ค ๋ณ ๊ฑฐ ์๋ค. ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๊ฐ ์ง์คํด์ผํ ๋จ์ด๋ ๋ฌผ๋ฆฌ๋์ด ์๋ ์ฐ์์
์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฐ์์ ์ด๋ผ๋ ๊ฑด ๋ฌด์จ ๋ง์ผ๊น?
์ฐ์์ฑ์ ๋ํ์ ์ธ ์๋ ๋ฐ๋ก ์
์ด๋ค. ์ ์ฐ๋ฆฌ๊ฐ ์ด์ 1
๋ถํฐ 2
๊น์ง ๊ฑธ์ด๊ฐ๋ค๊ณ ์๊ฐํด๋ณด์. ์ฐ๋ฆฌ๋ 1
์์ 2
๊น์ง ๊ฑธ์ด๊ฐ๋ ๋์ ๋ช๊ฐ์ ์๋ฅผ ๋ง๋ ์ ์์๊น?
์ฐ์ ์ ๋ฐ์ด ๋๋ ์์น์ ์๋ 1.5
๊ฐ ์์ ๊ฒ์ด๋ค. ๊ทธ ์ ๋ฐ์ธ 1.25
๋ ์์ ๊ฒ์ด๋ฉฐ ๋ ๊ทธ๊ฒ์ ์ ๋ฐ์ธ 1.125
๋ ์์ ๊ฒ์ด๋ค. ์ด๋ฐ ์์ผ๋ก ๊ณ์ ์๋ฅผ ์ชผ๊ฐ๋ค ๋ณด๋ฉด ์ฐ๋ฆฌ๋ ๊ฒฐ๊ตญ ์ด๊ฒ ์๋ฏธ์๋ ์ฝ์ง์ด๋ผ๋ ๊ฒ์ ๊นจ๋ซ๊ฒ ๋๋ค. n/2
๋ฅผ ๊ณ์ ํ๋ค ๋์ด ์์๋ฆฌ๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ง์ฝ ๋จ์๊น์ง ์ชผ๊ฐ ๋ค ํด๋ ์ฐ๋ฆฌ๋ ๊ทธ ์๋ฅผ ๊ณ์ ํด์ ๋ฌดํํ ์ชผ๊ฐค ์ ์๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฐ ์ฑ์ง์ ์ฐ์
์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์ด์ ์ฐ์์ ์ด๋ผ๋ ๋ง์ด ์กฐ๊ธ ์ดํด๊ฐ ๋์๊ธธ ๋ฐ๋๋ค.
์ปดํจํฐ๊ฐ ์๋ฆฌ๋ฅผ ๋ฃ๋ ๋ฐฉ๋ฒ
๊ทผ๋ฐ ์ฌ๋ฌ๋ถ๋ ์๋ค์ํผ ์ปดํจํฐ๋ 0
๊ณผ 1
๋ฐ์ ์ดํดํ์ง ๋ชปํ๋ ๋ฐ๋ณด๋ค. ์ด ๋ฐฉ์์ ์ฐ๋ฆฌ๋ ๋์งํธ(Digital)
์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ๊ทธ๋์ 0
๊ณผ 1
๋ฐ์ ๋ชจ๋ฅด๋ ์ปดํจํฐ๋ ์ฐ์์ฑ
์ ๊ฐ์ง ์๋ ๋ก๊ทธ ์ ํธ๋ฅผ ์ดํดํ ์๊ฐ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฐ๋ฆฌ๊ฐ ์์ฐ์์ ๋ฐ์ํ ์๋ ๋ก๊ทธ ํํ์ธ ์๋ฆฌ๋ฅผ ์ปดํจํฐ๊ฐ ๋ฃ๊ฒ ํด์ฃผ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น?
๊ฐ๋จํ๋ค. ์๋ ๋ก๊ทธ๋ฅผ ๋์งํธ๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค. ์๋ ๋ก๊ทธ ์ ํธ์ธ ์๋ฆฌ๋ฅผ ์ปดํจํฐ๊ฐ ์์ ๋ค์ ์ ์๊ฒ ๋ณ๊ฒฝํ๋ ๊ณผ์ ์ ์๊ณ ๋๋ฉด Web Audio API
๊ฐ ์ฐ๋ฆฌ์๊ฒ ์ฃผ๋ ์ ๋ณด๋ค์ด ๋ญ ์๋ฏธํ๋ ์ง ์ ์ ์๋ค. ๊ทธ๋ผ ์ง๊ธ๋ถํฐ ์๋ ๋ก๊ทธ๋ฅผ ๋์งํธ๋ก ๋ณ๊ฒฝํ๋ ๊ณผ์ ์ ์์๋ณด์.
์๋ ๋ก๊ทธ๋ฅผ ๋์งํธ๋ก ๋ณ๊ฒฝํ๊ธฐ ์ํด์๋ ๋ช๊ฐ์ง ์์๋ฅผ ๊ฑฐ์ณ์ผ ํ๋ค. ์ด ์์์์ ์ด๋ค ๊ฐ๋ค์ ์ฌ์ฉํ๋์ ๋ฐ๋ผ์ ๋์งํธ๋ก ๋ณ๊ฒฝ๋ ์๋ฆฌ์ ํด์๋, ์ฆ ์์ง์ด ๊ฒฐ์ ๋๋ค.
์ด๋ ๋์ค๋ ๋จ์ด๊ฐ ๋ฐ๋ก ์ํ ๋ ์ดํธ(Sample Rate)
์ ๋นํธ ๋ ์ดํธ(Bit Rate)
์ด๋ค.
๋จ์ด๋ ์ด๋ ค์ ๋ณด์ด์ง๋ง ์ฌ์ค ๊ฐ๋จํ๋ค. ๊ฒฐ๊ตญ ์๋ฆฌ๋ ๊ฐ๋ก ์ถ์ ์๊ฐ(Time)
, ์ธ๋ก ์ถ์ ์งํญ(Amplitude)
์ผ๋ก ์ ์๋ ๊ณต๊ฐ์ ๊ทธ๋ ค์ง 2์ฐจ์์ ์ง๋ ์ฃผํ์ ๋ฐ์ดํฐ์ด๋ค. ์ด๋ ์ํ ๋ ์ดํธ
๋ ๊ฐ๋ก ์ถ์ ํด์๋, ๋นํธ ๋ ์ดํธ
๋ ์ธ๋ก ์ถ์ ํด์๋๋ฅผ ์๋ฏธํ๋ ๊ฒ์ด๋ค. ์ด ๊ฐ๋ค์ ์๋ ๋ก๊ทธ๋ฅผ ๋์งํธ๋ก ๋ณ๊ฒฝํ๋ ์ฒซ๋ฒ์งธ ๋จ๊ณ์ธ ์ํ๋ง(Sampling)
์์ ํ์ฉ๋๋ค.
์ํ๋ง(Sampling)
์ํ๋ง
์ ์๋ ๋ก๊ทธ ์ ํธ๋ฅผ ๋์งํธ ์ ํธ๋ก ๋ฐ๊พธ๊ธฐ ์ํ ์ฒซ๋ฒ์งธ ๋จ๊ณ์ด๋ค. ์์์ ์ค๋ช
ํ ๊ฒ์ฒ๋ผ ์๋ ๋ก๊ทธ ์ ํธ์ธ ์๋ฆฌ๋ ์ฐ์์ ์ธ ์ ํธ์ด๊ธฐ ๋๋ฌธ์ ์ปดํจํฐ๊ฐ ์ด ์ ํธ๋ฅผ ๊ทธ๋๋ก ์ดํดํ ์๊ฐ ์๋ค. ์ฐ๋ฆฌ๊ฐ ๋ง์ดํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฆฌ๋ฅผ ๋
น์ํ ๋, ์ด ์๋ ๋ก๊ทธ ์ ํธ๋ ๊ฒฐ๊ตญ ์ ๊ธฐ ์ ํธ๋ก ๋ณํ๋์ด ์ปดํจํฐ์๊ฒ ์ฃผ์ด์ง๋ค. ์๋ฆฌ์ ์ง๋์ด ๋ง์ดํฌ ์์ ์๋ ์ฅ์น์ ์ ๋ฌ๋๋ฉด ์ด ์ฅ์น๊ฐ ์ ์์ ์ฌ๋ ธ๋ค ๋ด๋ ธ๋ค ํ๋ฉด์ ๋ณํํ๋ ์๋ฆฌ์ด๋ค.
ํ์ง๋ง ์ฐ๋ฆฌ์ ๋ฐ๋ณด ์ปดํจํฐ๋ ์ด๋ ๊ฒ ๊น์ง ํด์ค๋ ์ด ์ ๊ธฐ ์ ํธ๋ฅผ ์ดํดํ ์ ์๋ค.
๊ทธ๋์ ์ปดํจํฐ๋ ์ฐ์์ ์ธ ์ ๊ธฐ ์ ํธ๋ฅผ ์ธก์ ํ๊ธฐ ์ํด ํน์ ํ์ด๋ฐ์ ์ ํด์ ์ด ํ์ด๋ฐ๋ง๋ค ๋ด๊ฐ ์ ์์ ์ธก์ ํ ๊ฒ!
๋ผ๋ ๊ผผ์๋ฅผ ์ฌ์ฉํ๋ค. ์ปดํจํฐ๊ฐ ๊ผผ์๋ฅผ ์ฐ๋ ์ด ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ด๋ณด๋ฉด ์ด๋ฐ ๋๋์ด๋ค.
์ ๊ทธ๋ฆผ์ ๋ํ๋ ๋นจ๊ฐ ์ ์ด ์ปดํจํฐ๊ฐ ์ ์์ ์ธก์ ํ ํ์ด๋ฐ์ด๋ค. ์ปดํจํฐ๋ ํน์ ํ์ด๋ฐ์ ์ ๊ธฐ ์ ํธ๋ฅผ ์ธก์ ํ๊ณ ๊ทธ ๊ฐ์ ์ ์ฅํ๋ค. ๋นจ๊ฐ ์ ์ ์์น๋ฅผ ๋ณด๋ฉด ์ ์ ํธ๋ [10, 20, 30, 27, 19, 8...]
๋ญ ์ด๋ฐ ์์ผ๋ก ์ธก์ ์ด ๋์์ ๊ฒ์ด๋ค.
์ด๋ ์ ๋นจ๊ฐ ์ ์ ๋ ์ธ๋ฐํ๊ฒ, ์ฆ ์ปดํจํฐ๊ฐ ์ํ ์ธก์ ์ ํ๋ ๊ฐ๊ฒฉ์ด ์งง์ ์๋ก ์ฐ๋ฆฌ๋ ์๋ ์ ํธ์ ๊ฐ๊น์ด ๊ฐ์ ์ธก์ ํ ์ ์๋ค.
์ด๋ ์ด ์ ํธ๋ฅผ ์ธก์ ํ๋ ๊ฐ๊ฒฉ์ ์ํ ๋ ์ดํธ(Sample Rate)
๋ผ๊ณ ํ๊ณ ์ ํธ๋ฅผ ์ธก์ ํ๋ ๊ณผ์ ์์ฒด๋ฅผ ์ํ๋ง(Sampling)
์ด๋ผ๊ณ ํ๋ค. ๋น์ฐํ ์ํ ๋ ์ดํธ๊ฐ ๋์ ์๋ก ์๋ฆฌ์ ํด์๋, ์ฆ ์์ง์ด ๋ ์ข์ ์ ๋ฐ์ ์๋ค. ํนํ ๋์ ์ฃผํ์๋ฅผ ๊ฐ์ง ์๋ฆฌ, ์ฆ ๊ณ ์์ ํด์๋๊ฐ ํ์ฐํ๊ฒ ์ข์์ง๋ค.
๋ณดํต CD์ ์์ง์ด 44.1kHz
, TV๋ ๋ผ๋์ค ๋ฐฉ์ก์ด 48kHz
์ ์ํ ๋ ์ดํธ๋ฅผ ๊ฐ์ง๋๋ฐ, ์ด๋ ์ฝ 1์ด์ 44,100
๋ฒ, 48,000
๋ฒ ์ํ์ ์ธก์ ํ๋ค๋ ๊ฒ์ด๋ค. ์ ์ํ ๋ ์ดํธ๋ ์ด๋ค ๊ธฐ์ค์ผ๋ก ์ ํ๋ ๊ฑธ๊น?
์ํ ๋ ์ดํธ(Sample Rate)๋ฅผ ์ข ๋ ์์ธํ ์์๋ณด์
๋ฐฉ๊ธ ์ค๋ช
ํ๋ฏ์ด CD์ ๊ฒฝ์ฐ ์ํ ๋ ์ดํธ๊ฐ 44.1kHz
์ด๋ค. ๊ทธ ๋ง์ธ ์ฆ์จ CD์ ๋ค์ด๊ฐ๋ ์ค๋์ค๋ ์ปดํจํฐ๊ฐ ์๋ ๋ก๊ทธ ์ ํธ๋ฅผ 1์ด์ 44,100
๋ฒ ์ธก์ ํ ๊ฒฐ๊ณผ๋ฌผ์ธ ๊ฒ์ด๋ผ๋ ๊ฒ์ด๋ค.
ํ์ง๋ง ์ธ๊ฐ์ด ๋ค์ ์ ์๋ ์์ญ์ธ ๊ฐ์ฒญ์ฃผํ์๋ 20hz ~ 20kHz
๋ฐ์ ๋์ง ์๋๋ค. ๊ทผ๋ฐ ์ ์ํ ๋ ์ดํธ๋ 44.1kHz
, 48kHz
์ฒ๋ผ ํจ์ฌ ํฌ๊ฒ ์ก๋ ๊ฒ์ผ๊น?
์ด์ฐจํผ ์ธ๊ฐ์ 1์ด์
20,000
๋ฒ ์ง๋ํ๋ ์๋ฆฌ๊น์ง๋ฐ์ ๋ค์ ์ ์์ด์44,100
๋ฒ ์ง๋ํ๋ ์๋ฆฌ๋ฅผ ๋ น์ํด๋ ์ด์ฐจํผ ๋ค์ ์ ์๋๋ฐ?
์ด ์ง๋ฌธ์ ๋ํ ๋ต์ ์๋ฆฌ์ ์ง๋ ์ฌ์ดํด์ด ์ด๋ป๊ฒ ์๊ฒผ๋์ง๋ฅผ ๋ณด๋ฉด ์ดํด๊ฐ ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ค๋์ค ์ฃผํ์๋ ์ด๋ ๊ฒ ํ๋์ ์ฌ์ดํด ๋จ์๋ก ๋๋์ด ์ง๋๋ฐ, ์ด๋ ์๋ก ์ฌ๋ผ๊ฐ๋ +
๋ถ๋ถ์ด ๊ณต๊ธฐ๊ฐ ์์ถ๋๋ ๋ถ๋ถ์ด๊ณ ์๋๋ก ๋ด๋ ค๊ฐ๋ -
๋ถ๋ถ์ด ๋ค์ ๊ณต๊ธฐ๊ฐ ํฝ์ฐฝํ๋ ๋ถ๋ถ์ด๋ค.
์์์ ๊ณ์ ์ค๋ช
ํ๋ ๋๋ก ์๋ฆฌ๋ ๊ณง ์ง๋์ด๊ณ , ์ฐ๋ฆฌ๊ฐ ๋๋ผ๋ ๊ฒ์ ๊ทธ ์ง๋์ผ๋ก ์ธํ ๊ณต๊ธฐ์ ๋จ๋ฆผ
์ด๋ฏ๋ก ์์ถ -> ํฝ์ฐฝ -> ์์ถ
๊น์ง ๋ชจ๋ ๋ค์ด์ผ ๋จ๋ ธ๋ค!
๋ผ๊ณ ๋๋ ์ ์๋ค๋ ๊ฒ์ด๋ค. ์ฆ, ์ฐ๋ฆฌ๊ฐ ๋ค์ ์ ์๋ 20,000
๋ฒ์ ์ง๋์ ์ด ์ฌ์ดํด์ด 1์ด์ 20,000
๋ฒ ๋ฐ๋ณต๋๋ ์๋ฆฌ๋ผ๋ ๊ฒ์ด๋ค.
์์ถ์ด๋ ํฝ์ฐฝ ์ค์ ํ๋๋ง ์ฃผ๊ตฌ์ฅ์ฐฝ ๋๋๋ค๊ณ ํด์ ์ด๊ฒ ์ง๋์ด๊ตฌ๋
๋ผ๊ณ ๋๋ ์๋ ์์ ๊ฒ์ด๋ค.
๊ทธ๋์ ์ค๋์ค ์ ํธ์ ํ ์ฌ์ดํด์ ์ ๋๋ก ์ธก์ ํ๋ ค๋ฉด + ๋ฐฉํฅ์ ๋งจ ์์ ๊ผญ์ง์ ํ๋
์ - ๋ฐฉํฅ์ ๋งจ ๋ฐ์ ๊ผญ์ง์ ํ๋
๋ฅผ ๋ชจ๋ ์ธก์ ํด์ผํ๊ธฐ ๋๋ฌธ์ ์ต์ 2๋ฒ
์ ์ธก์ ์ ํด์ผํ๋ค. ๊ทธ๋์ ์ธ๊ฐ์ด ๋ค์ ์ ์๋ ๊ฐ์ฅ ๋์ ์๋ฆฌ์ธ ์ด๋น 20,000๋ฒ์ ๋จ๋ฆผ
์ธ 20kHz
์ ์ ๋๋ก ์ธก์ ํ๋ ค๋ฉด ์ปดํจํฐ๋ ์ต์ํ 1์ด์ 20,000 * 2 = 40,000๋ฒ
์ธก์ ์ ํด์ผ ํ๋ ๊ฒ์ด๋ค.
์ด๊ฒ ๋ฐ๋ก CD๊ฐ ์ 44.1kHz
์ ์ํ ๋ ์ดํธ๋ฅผ ๊ฐ์ง๊ณ ์๋์ง์ ๋ํ ์ด์ ๋ค. ์ด๊ฑธ ๋์ดํด์คํธ ์ด๋ก (Nyquist Theorem)
์ด๋ผ๊ณ ํ๋ค. ์ฆ, ๋์ดํด์คํธ ์ด๋ก ์ ํ๋ง๋๋ก ์ ๋ฆฌํ์๋ฉด
์ธก์ ํ๊ณ ์ถ์ ์ค๋์ค ์ฃผํ์์์ง? ์ค๋์ค ์ ํธ ์ ๋๋ก ๋ค ์ด๋ฆฌ๊ณ ์ถ์ผ๋ฉด ์ต์ํ ๊ทธ ์ฃผํ์๋ณด๋ค ๋๋ฐฐ๋ ๋ ๋น ๋ฅด๊ฒ ์ธก์ ํด์ผ๋๋ค.
๊ทธ๋ฌ๋๊น ์ต์ํ ์ธก์ ํ๊ณ ์ถ์ ์ค๋์ค ์ฃผํ์์ ๋๋ฐฐ ์ฌ์ด์ฆ์ ์ํ ๋ ์ดํธ๋ฅผ ์ค๋นํ๋ ด.
์ธ ๊ฒ์ด๋ค. ๊ทผ๋ฐ ์ฌ๊ธฐ์ ๋ ์๋ฌธ์ด ์๊ธด๋ค. ์ ์ด๋ก ์ ๋ฐ๋ฅด๋ฉด ์ธ๊ฐ์ ๊ฐ์ฒญ์ฃผํ์๋ 20,000hz
๋๊น ๋ฑ 40,000
๋ฒ๋ง ์ธก์ ํ๋ฉด ์ธ๊ฐ์ด ๋ค์ ์ ์๋ ์๋ฆฌ๋ ๋ค ๋
น์ํ ์ ์๋๋ฐ ์ 44,100
๋ฒ์ด๋ 48,000
๋ฒ๊น์ง ์ธก์ ํ๋ ๊ฑธ๊น?
์์ฐ์๋ ์ธ๊ฐ๋ง ์๋ ๊ฒ์ด ์๋๋ผ ์ด๋ฐ ์น๊ตฌ๋ค๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ฌ์ค ์์ฐ์๋ ์ฐ๋ฆฌ๊ฐ ๋ฃ์ง ๋ชปํ๋ ํจ์ฌ ๋์ ์๋ฆฌ๋ค๋ ์กด์ฌํ๋ค. ๋จ์ง ์ฐ๋ฆฌ๊ฐ 20kHz
๊น์ง๋ฐ์ ๋ชป ๋ค์ ๋ฟ์ด๋ค. ๋ญ ๋ฐ์ฅ๋ ๋๊ณ ๋ ๊ฐ์ ์น๊ตฌ๋ค์ ํจ์ฌ ๊ณ ์์ญ๋์ ์๋ฆฌ๋ฅผ ๋ด์ง ์๋๊ฐ?
๊ทผ๋ฐ ์ด ์๋ฆฌ๊ฐ 40kHz
์ ์ํ ๋ ์ดํธ๋ฅผ ์ค๋นํ ๊ทธ๋ฆ์ ๋ค์ด์ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น? ์ปดํจํฐ๋ 1์ด์ 20,000
๋ฒ์ ์ฌ์ดํด์ ๋๋ ์๋ฆฌ๋ฅผ ์ ๋๋ก ์ธก์ ํ๋ ค๊ณ 1์ด์ 40,000
๋ฒ ์ ์์ ์ธก์ ํ๋ ค๊ณ ํ๋๋ฐ ๋ง์ฝ 1์ด์ 30,000
๋ฒ์ ์ฌ์ดํด์ ๋๋ ํจ์ฌ ๋ ๋์ ์ฃผํ์์ ์๋ฆฌ๊ฐ ๋ค์ด์๋ฒ๋ฆฐ๋ค๋ฉด?
์ ๋ต. ์ ์ ์ด์ํ๋ฐ๋ค๊ฐ ์ฐ๋๋ค.
๊ทธ๋ฆผ์ ๋ณด๋ฉด ์ปดํจํฐ๊ฐ ์ ์ ์ฐ๋ ๊ฐ๊ฒฉ, ์ฆ ์ ์์ ์ธก์ ํ๋ ๊ฐ๊ฒฉ๋ณด๋ค ๋ค์ด์จ ์ ํธ์ ์ฌ์ดํด์ด ๋ ์งง๋ค. ๊ทธ๋์ ์ปดํจํฐ๊ฐ ์ฐ์ ์ ์ ๋ณด๋ฉด ์ ํธ์ ๊ผญ์ง์ ์ด ์๋ ์ด์ค๊ฐํ ์ด๋๊ฐ์ ์ฐํ ๊ฒ์ ๋ณผ ์ ์๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ๋์ดํด์คํธ ์ด๋ก
์ ๊ฐ์ง๊ณ ์๋ ํจ์ ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ด์ค๊ฐํ๋ฐ ์ฐํ ์ ๋ค์ ์ด์ด๋ณธ ํ๋์ ์ ์ ๋ณด๋ฉด ๊ฒฐ๊ตญ ๋ฎ์ ์ฃผํ์๊ฐ ๋ ๊ฒ์ ์ ์ ์๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
์ฐ๋ฆฌ ๊ท์ ์์ฃผ ์ ๋ค๋ฆฐ๋ค. ์ฐธ ์๋ฆ๋๋ ์๊ฐ์ด๋ค! ๋
น์ํ ๋๋ ๋ถ๋ช
ํ ์๋ฌด๊ฒ๋ ์๋ค๋ ธ๋๋ฐ ๋
น์ํ ๊ฑธ ๋ค์ด๋ณด๋ ์ด์ํ ์๋ฆฌ๊ฐ ๋
น์๋์ด์์ผ๋ ๋ง์ด๋ค. ๊ทธ๋์ ์ด ํ์์ ๊ณ ์คํธ ์ฃผํ์(Ghost Frequency)
๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์๋ ๊ทธ๋ฌ๋ฉด ์ํ ๋ ์ดํธ๋ฅผ ํํ ์ฌ๋ฆฌ๋ฉด ๋์์! ๋์ ์๋ฆฌ๋ ์ ๋๋ก ๋ น์๋๋ฉด ๋ฌธ์ ํด๊ฒฐ ์๋๊ฐ?
ํ์ง๋ง ์ด ๋์งํธ ์ค๋์ค ๊ธฐ์ ์ด ์ฒ์ ์ฌ์ฉ๋๊ธฐ ์์ํ๊ฒ 1970๋
๋
์ด๊ธฐ ๋๋ฌธ์ ๋ฌด์์ ์ํ ๋ ์ดํธ๋ฅผ ์ฌ๋ฆฌ๊ธฐ์๋ ํ๋์จ์ด ์ฉ๋์ด ๋ชป ๋ฐ๋ผ๊ฐ์๋ค.
๊ทธ๋์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ์ฉํ ๋ฐฉ๋ฒ์ด ๋ฐ๋ก LPF(Low Pass Filter)
์ด๋ค. ์ด ํํฐ๋ ์ ๊ธฐ ์ชฝ ๊ณต๋ถํ์ ๋ถ๋ค์ ๋งค์ฐ ์ต์ํ ํ
๋ฐ, ๋ง ๊ทธ๋๋ก ๋ฎ์(Low) ์ฃผํ์๋ง ํต๊ณผ(Pass)์ํค๋ ํํฐ์ด๋ค. ์ค๋์ค ๋
น์์ ํ ๋ LPF
๋ฅผ ์ฌ์ฉํด์ ์ธ๊ฐ์ ๊ฐ์ฒญ์ฃผํ์๋ณด๋ค ๋์ ์๋ฆฌ๋ ๋ค ์๋ผ๋ฒ๋ฆฌ๊ณ ์ธ๊ฐ์ ๊ฐ์ฒญ์ฃผํ์ ์์ญ์ ์๋ฆฌ๋ง ํต๊ณผ์ํค๋ฉด ๋ฐฉ๊ธ ์๊ธฐํ ๊ณ ์คํธ ์ฃผํ์๊ฐ ์๊ธธ ์ผ๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทผ๋ฐ ๋ ์๋ ๋ก๊ทธ ์ ํธ๋ผ๋ ๊ฒ ๊ทธ๋ ๊ฒ ๋ฌด ์๋ฅด๋ฏ์ด ์น๋! ์๋ฆฌ๋ ๊ฒ ์๋๋ค.
LPF
๋ฅผ ์จ๋ ๊ฒฐ๊ตญ ์๋ฆฐ ๋ถ๋ถ์ด ์ ๋ ๊ฒ ๋น์ค๋ฌํ๊ฒ ๊บพ์ด๋ฉด์ ์ฝ๊ฐ ์์ฌ์ด ๋ถ๋ถ์ด ๋จ๊ฒ๋๋ค. ์ด๋ ๊ทธ๋ฆผ์ ํ์๋ ํ์ฉ ๋ฒ์์ธ -3db
๋ฐ์ผ๋ก ๋จ์ด์ง๊ธฐ ์์ํ๋ ๊ณณ์ Cut Off
๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์ ๊ธฐ์์๋ถํฐ ์ ํธ๊ฐ ์๋ ธ๋ค๊ณ ์น๊ฒ ๋ค๋ ๊ฒ์ด๋ค. ๊ทธ๋ผ Cut Off
๋๋ ๋ถ๋ถ์ 20kHz
๋ณด๋ค ์กฐ๊ธ ๋ ๋ฐ์ผ๋ก ๋ด๋ฆฌ๋ฉด 20kHz
์ธ์ ๋ฆฌ์์ ์ ํธ๊ฐ ์ฌ๋ผ์ง๊ฒ ๋ง๋ค ์ ์์ง ์์๊น? ๋ผ๋ ์๊ฐ๋ ๋ค์ง๋ง ๊ทธ ๋ฌธ์ ๋๋ฌธ์ 20kHz
์ ์ฃผํ์ ์์ญ์ ์ ๋ถ ํ์ฉํ์ง ๋ชปํ๋ ๊ฑด ๋๋ฌด ์๊น๋ค๊ณ ํ๋จ์ด ๋ค์๋๋ณด๋ค.
๊ทธ๋์ Cut Off
๋ฅผ ๋ฑ 20kHz
์ ๋ง์ถ๊ณ ๋จ๋ ๋ถ๋ถ์ ๊ทธ๋ฅ ๊ฐ์ํ์๊ณ ํฉ์๊ฐ ๋ ๊ฒ์ด๋ค. ๋น์ ๊ธฐ์ ๋ก ์ ๋จ๋ ๋ถ๋ถ์ ์ค์ด๊ณ ์ค์ฌ์ ๋ง์ถ๊ฒ ๋ฑ 2,050hz
์๋ค.
๊ทธ๋ผ ์ด์ ๋จ๋ ๋ถ๋ถ๊ณผ ๊ฐ์ฒญ์ฃผํ์๋ฅผ ํฉ์ณ๋ณด๋ฉด 22,050hz
๊ฐ ๋๋ค. ๋์ดํด์คํธ ์ด๋ก ์ ๋ฐ๋ฅด๋ฉด ์ฐ๋ฆฌ๋ ์ต์ํ 2๋ฐฐ์ ์ํ ๋ ์ดํธ๋ฅผ ์ค๋นํด์ผ ์ด ์ ํธ๋ฅผ ์ ๋๋ก ์ธก์ ํ ์ ์์ผ๋ฏ๋ก ๊ฒฐ๊ตญ CD์ ํ์ค ์ํ ๋ ์ดํธ๊ฐ 44,100hz = 44.1kHz
๊ฐ ๋ ๊ฒ์ด๋ค.
๋ญ ๊ทธ ์ธ์๋ ๋น์ ๊ธฐ์ ์ ํ๊ณ ์ธ์๋ ๊ธฐ์
๋ค๋ผ๋ฆฌ ์ธ์ฐ๊ธฐ๋ ํ๊ณ ์ด๋ฅธ์ ์ฌ์ ๋ ์๋ ๋ฑ ๊ตญ์ ํ์ค์ ์ ํ ๋ ๋ ๋ฐ์ํ๋ ์ฌ๋ฌ๊ฐ์ง ์ด์๊ฐ ์์์ง๋ง ๋ํ์ ์ธ ๊ธฐ์ ์ ์ธ ์ด์๋ ์ด ์ด์ ์๋ค.
๊ทธ ํ 48kHz
, 96kHz
, 192kHz
๋ฑ์ ๋์ ์ํ ๋ ์ดํธ๋ ๊ทธ๋ฅ ๋๋ฐ์ด์ค๊ฐ ๋ฐ์ ํ๋ฉด์ ๊ธฐ์ ์ ์ธ ์ ํ์ด ์์ด์ก์ผ๋๊น โ์ํ ๋ ์ดํธ๋ ํด์๋ก ์ข์ง! ๋ฟ๋ฟโํ๋ฉด์ ๋๋ฆฐ ๊ฒ์ด๋ค.
๋นํธ ๋ ์ดํธ(Bit Rate)
๋นํธ ๋ ์ดํธ
๋ ์ํ๋ง์ ๋นํ๋ฉด ์ด ๊ฐ๋จํ๋ค. ํนํ ์ฐ๋ฆฌ ๊ฐ์ ๊ฐ๋ฐ๋ญ์ด๋ค์๊ฒ ์ต์ํ ์ด๋ฆ์ธ Bit
๊ฐ ๋ถ์ด์์ง ์์๊ฐ? ์ํ ๋ ์ดํธ๊ฐ ์๋ฆฌ์ ๊ฐ๋ก ํด์๋ ์ญํ ์ ํ๋ค๋ฉด ๋นํธ ๋ ์ดํธ
๋ ์ธ๋ก ํด์๋ ์ญํ ์ ํ๋ค.
์ํ ๋ ์ดํธ์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋นํธ ๋ ์ดํธ๋ CD๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ช ํ๋ ๊ฒ ๋ณดํธ์ ์ด๊ธฐ ๋๋ฌธ์ ๋ค์ CD๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ช ํ๊ฒ ๋ค.
CD์ ๋นํธ ๋ ์ดํธ๋ 16bit
์ธ๋ฐ ์ด๊ฑด ๋ง ๊ทธ๋๋ก ์ธ๋ก๋ก 16bit
๋งํผ์ ํด๋นํ๋ ๊ฐ์ ํํํ ์ ์๋ค๋ ์๊ธฐ์ด๋ค. ์๊น ์์์ ์ค๋ช
ํ ์ํ๋ง์ ์งํํ ๋ ์ ์์ ์ธก์ ํ์๋ค. ์ด๋ ์ปดํจํฐ๊ฐ ์ธก์ ํ ์ด ์ ์์ ๊ฐ์ ์ผ๋ง๋ ์ฌ์ธํ๊ฒ ํํํ ์ ์๋๋๋ฅผ ๋นํธ ๋ ์ดํธ๊ฐ ๊ฒฐ์ ํ๋ ๊ฒ์ด๋ค. 16bit
๋ฉด 16์๋ฆฌ์ ์ด์ง๋ฒ์ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ด๊ณ ์ด๋๊น 0~65536
๊น์ง ์ด 65537
๊ฐ์ ๊ฐ์ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด๋ค.
+와 -를 합쳐서 비트를 세는 `signed`이기 때문에 그림에는 50% 씩만 표현되어있는 것이다.
๋ฌผ๋ก ์๋ ๋ก๊ทธ์ธ ์๋ฆฌ ์ ํธ๊ฐ ๋ณํ๋ ์ ์ ๊ฐ์ด 123
๊ฐ์ด ๋ฑ ๋จ์ด์ง๋ ์ ์์ผ๋ฆฌ๊ฐ ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ์ ์๋ 0~65536
์ค ๊ทผ์ฌ์น๋ฅผ ์ฐพ์์ ๋ฐ๊ฟ์ฃผ๋๋ฐ ์ด ๊ณผ์ ์ ์์ํ(Quantizing)
์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. (์์์ญํ์์ ๋์ค๋ ๊ทธ ์์๋ ๊ฐ์ ์๋ฏธ ๋ง๋ค.)
์ดํ 0~65536
์ ๊ฐ์ผ๋ก ๋ณ๊ฒฝ๋ ์ ์์ ์ปดํจํฐ๊ฐ ์ดํดํ ์ ์๋ ์ด์ง์(Binary)
๋ก ๋ณ๊ฒฝํ๋ ๊ณผ์ ์ ๋ถํธํ(Coding)
๋ผ๊ณ ํ๋ค.
์ด๋ฐ ๊ฒ๋ค์ ์ฐ๋ฆฌ๊ฐ์ ๊ฐ๋ฐ๋ญ์ด๋ค์ ์๋ ์ต์ํ ๋ฌธ์ ์ด๊ธฐ ๋๋ฌธ์ ์ด ์ ๋๋ง ์ค๋ช ํ๊ณ ๋์ด๊ฐ๊ฒ ๋ค.
Web Audio API๋ก ํํ ๊ทธ๋ ค๋ณด๊ธฐ
์, ๋๋์ด ๊ธธ๊ณ ๊ธธ์๋ ์๋ฆฌ ์ด๋ก ์ด ๋๋ฌ๋ค. ํ์๋ ๋์งํธ๋ก ๋ณํ๋ ์ค๋์ค๋ฅผ ๊ฐ์ง๊ณ ํํ์ ๊ทธ๋ ค๋ณด๋ ๊ฒ์ด ๋ชฉ์ ์ด๊ธฐ ๋๋ฌธ์ Analog to Digital
๋ง ๋ค๋ค๊ณ Digital to Analog
๋ ์ด ํฌ์คํ
์์ ๋ค๋ฃจ์ง ์๊ฒ ๋ค. ๊ทผ๋ฐ ์ด๊ฒ๋ ๋๋ฆ ์ฌ๋ฐ์ผ๋ฏ๋ก ๋ฐ๋ก ์ฐพ์๋ณด๊ธธ ๊ฐ์ถํ๋ค. ํ์๋ ์ค๋์ค ํ์ผ์ ์
๋ก๋ํด์ ํด๋น ์ค๋์ค ํ์ผ์ Web Audio API
๋ก ๋ถ์ํ์ฌ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฝ์๋ด๊ณ svg
๋ฅผ ์ฌ์ฉํ์ฌ ํํ์ ๊ทธ๋ฆด ๊ฒ์ด๋ค.
์ฐธ๊ณ ๋ก ํ๋ก์ ํธ๋ webpack4
์ babel7
์ ์ฌ์ฉํ์ฌ ์ด๊ฐ๋จํ๊ฒ ๊ตฌ์ฑํ๋ค. ์์ธํ ์ฝ๋๋ ๊นํ๋ธ ๋ ํ์งํ ๋ฆฌ์์ ํ์ธ ํด๋ณผ ์ ์๋ค.
๊ธฐ๋ณธ ํ ์ก๊ธฐ
๊ทธ๋ผ ๋จผ์ HTML์ ๊ฐ๋จํ๊ฒ ์์ฑํ์.
<body>
<input id="audio-uploader" type="file">
<svg id="waveform" preserveAspectRatio="none">
<g id="waveform-path-group"></g>
</svg>
</body>
HTML์ ์ด๊ฒ ๋์ด๋ค. ์ค๋์ค ํ์ผ์ ์
๋ก๋ํ input
์๋ฆฌ๋จผํธ ํ๋์ ํํ์ ๊ทธ๋ฆด svg
์๋ฆฌ๋จผํธ ํ๋๋ง ์์ผ๋ฉด ๋๋ค. ์ด์ฐจํผ ํ
์คํธ ์ฉ๋๋ผ์ UI๊ฐ ์ค์ํ๊ฒ ์๋๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ฅ ๊ตฌํ์ ์ถฉ์คํ๋ค.(๋ผ๊ณ ํฌ์ฅ์ ํด๋ด
๋๋ค)
์ด์ ํ์ผ์ด ์ ๋ก๋๋๋ฉด ์คํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์์ฑํ์.
// index.js
(function () {
const inputDOM = document.getElementById('audio-uploader');
inputDOM.onchange = e => {
const file = e.currentTarget.files[0];
if (file) {
const reader = new FileReader();
reader.onload = e => console.log(e.target.result);
reader.readAsArrayBuffer(file);
}
}
})();
FileReader.prototype.readAsArrayBuffer
๋ฉ์๋๋ ๋ฐ์ด๋๋ฆฌ ํํ์ธ ํ์ผ์ ํ๋ฒ์ ๋ฐํํ๋ ๊ฒ์ด ์๋๋ผ ์ผ์ ๋จ์์ ์ฒญํฌ(Chunk)
๋ก ๋ฐํํ๋ ๋ฉ์๋์ด๋ค. ๋ณดํต ๋ญ ์๋ฒ๋ก ํ์ผ ์
๋ก๋ ํ๋ค๊ฑฐ๋ ํ ๋ ๋ง์ด ์ฌ์ฉํ๋ค. ์๋๋ ์ด ArrayBuffer
๋ฅผ ์ฒ๋ฆฌํด์ฃผ๊ธฐ ์ํ ๋ณ๋์ ๋ก์ง์ ์์ฑํด์ผํ์ง๋ง ์ด๋ฒ์ ์ฌ์ฉํ Web Audio API
๊ฐ ๋ด๋ถ์ ์ผ๋ก ArrayBuffer
๋ฅผ ์์์ ์ฒ๋ฆฌํด์ฃผ๊ธฐ ๋๋ฌธ์ ๊ฑฑ์ ํ์ง ์์๋ ๋๋ค.
AudioAnalyzer ํด๋์ค ์์ฑ
์ด์ ๋ณธ๊ฒฉ์ ์ธ Web Audio API
๋ฅผ ์ฌ์ฉํด๋ณผ ์ฐจ๋ก์ด๋ค. ํ์๋ ๋ณ๋๋ก AudioAnalyzer
๋ผ๋ ์ฑ๊ธํค ํด๋์ค๋ฅผ ๋ง๋ค์๋ค.
// lib/AudioAnalyzer.js
class AudioAnalyzer {
constructor () {
if (!window.AudioContext) {
const errorMsg = 'Web Audio API ์ง์ ์๋ผ์ ใ
ใ
';
alert(errorMsg);
throw new Error(errorMsg);
}
this.audioContext = new (AudioContext || webkitAudioContext)();
this.audioBuffer = null;
this.sampleRate = 0;
this.peaks = [];
this.waveFormBox = document.getElementById('waveform');
this.waveFormPathGroup = document.getElementById('waveform-path-group');
}
reset () {
this.audioContext = new (AudioContext || webkitAudioContext)();
this.audioBuffer = null;
this.sampleRate = 0;
this.peaks = [];
}
}
export default new AudioAnalyzer();
SVG ๋ทฐ๋ฐ์ค๋ฅผ ์ค์ ํ์
์ด๋ ๊ฒ ๋์ถฉ ๊ธฐ๋ณธ ํ์ ์ก์์ฃผ๊ณ ๋์ ์ค๋์ค ํํ์ ๊ทธ๋ฆด svg
์๋ฆฌ๋จผํธ์ ๋ทฐ๋ฐ์ค๋ฅผ ์ค์ ํ ์ ์๋ ๋ฉ์๋๋ฅผ ํ๋ ์ ์ธํ ๊ฒ์ด๋ค. ์๋ฆฌ ์ ํธ๋ ์ํ ๋ ์ดํธ์ ๋ฐ๋ผ์ ๋ค์ด์จ ๋ฐ์ดํฐ์ ๊ธธ์ด๊ฐ ์ฒ์ฐจ๋ง๋ณ์ด๊ธฐ ๋๋ฌธ์ ๋ทฐ๋ฐ์ค์ width
๋ฅผ ์ค๋์ค ๋ฐ์ดํฐ์ ํฌ๊ธฐ์ ๋ง๊ฒ ๋์ ์ผ๋ก ๋ณ๊ฒฝํด์ค์ผ์ง ๋ชจ๋ ์ ํธ๋ฅผ ๋ทฐ๋ฐ์ค์ ๋ฑ ๋ง๊ฒ ๊ทธ๋ฆด ์ ์๋ค.
updateViewboxSize () {
this.waveFormBox.setAttribute('viewBox', `0 -1 ${this.sampleRate} 2`);
}
svg
์๋ฆฌ๋จผํธ์ viewBox
์์ฑ์ ์์์๋ถํฐ min-x
, min-y
, width
, height
๋ฅผ ์๋ฏธํ๋ค. ๋นํธ ๋ ์ดํธ๋ฅผ ์ค๋ช
ํ ๋ ์๊ธฐ ํ๋ฏ์ด ์ค๋์ค ์ ํธ๋ ๋ถํธ๋ฅผ ๊ฐ์ง๋ signed
์ด๊ธฐ ๋๋ฌธ์ 0, 0
์ด ์๋ 0, -1
์์ ๋ทฐ๋ฐ์ค๋ฅผ ์ค์ ํด์ผํ๋ค. ๊ทธ๋ฆฌ๊ณ width
๋ ์ค๋์ค์ ์ํ ๋ ์ดํธ๋ก ์ก์์ค์ ์ค๋์ค ์ ํธ๊ฐ ๋ทฐ๋ฐ์ค์ ์ฒ์๋ถํฐ ๋๊น์ง ๊ฝ ์ฐจ๋๋ก ์ค์ ํ๊ณ height
๋ -1 ~ 1
๊น์ง ์ก์์ค์ผํ๋๊น 2
๋ก ์ค์ ํ๋ค.
์ด๋ ๊ฒ ์ ์ธํ updateViewboxSize
๋ฉ์๋๋ ์ดํ๋ฆฌ์ผ์ด์
์ด ์ด๊ธฐํ๋ ๋ ๋ทฐ๋ฐ์ค ์ฌ์ด์ฆ๋ ํจ๊ป ์ด๊ธฐํ๋๋๋ก constructor
์ reset
๋ฉ์๋์ ์ ๋นํ ์ถ๊ฐํด์ฃผ์๋ค.
์ ๋ก๋๋ AudioBuffer ํ์ธํ๊ธฐ
์ด์ input
์๋ฆฌ๋จผํธ๋ฅผ ํตํด ์
๋ก๋๋ ์ค๋์ค ํ์ผ์ ๋์ฝ๋ฉํ๋ ๊ท์ฌ์ด setter๋ฅผ ํ๋ ์ ์ธํ๋ฉด ๋๋ค.
setAudio (audioFile) {
this.audioContext.decodeAudioData(audioFile).then(buffer => {
console.log(buffer);
});
}
AudioContext.prototype.decodeAudioData
๋ฉ์๋๋ ArrayBuffer
๋ฅผ ๋ฐ์์ AudioBuffer
๋ก ๋ณํํ๋ ๋ฉ์๋์ด๋ค. ์๊น ์์์ ์ค๋ช
ํ๋ ๋๋ก readAsArrayBuffer
๋ฉ์๋๊ฐ ๋ฐํํ ArrayBuffer
๋ ํ๋ฒ์ ๋ชจ๋ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ๊ฒ์ด ์๋๋ผ ์ฒญํฌ ๋จ์๋ก ๋ถ๋ฌ์ค๊ธฐ ๋๋ฌธ์ decodeAudioData
๋ ๋ณํ์ ๋๊ธฐ์ ์ผ๋ก ํด์ฃผ์ง๋ ์๋๋ค. ๊ทธ๋์ ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๋๋ ์ฝ๋ฐฑํจ์๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ Promise
๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
์ด์ ์ค์ ๋ก ์ค๋์ค ํ์ผ์ด ์ด๋ป๊ฒ ๋ณํ๋๋์ง ๋ณด๊ธฐ ์ํด ํ์ผ์ ์
๋ก๋ํ๋ฉด AudioAnalyzer
์๊ฒ ์ค๋์ค ํ์ผ์ ๋๊ธฐ๋๋ก ๋ณ๊ฒฝํด์ฃผ์.
// index.js
import AudioAnalyzer from './lib/AudioAnalyzer';
(function () {
const inputDOM = document.getElementById('audio-uploader');
inputDOM.onchange = e => {
const file = e.currentTarget.files[0];
if (file) {
// AudioAnalyzer ์ด๊ธฐํ
AudioAnalyzer.reset();
const reader = new FileReader();
// AudioAnalyzer์๊ฒ ํ์ผ ํ ์ค
reader.onload = e => AudioAnalyzer.setAudio(e.target.result);
reader.readAsArrayBuffer(file);
}
}
})();
์ด ์ฏค ํ์ผ๋ฉด ์ด์ ๋ฉ์ธ ํจ์์๋ ๋ ์ด์ ๋ญ ์์ฑํ ํ์๊ฐ ์์ ๊ฒ ๊ฐ๋ค. ์ด์ AudioAnalyzer
๋ง ๊ฐ์ง๊ณ ๋๋ฉด ๋๋ค. ๋ฐ์ดํฐ๊ฐ ์ด๋ป๊ฒ ๋์ค๋ ์ง ํ์ธํ๊ธฐ ์ํด ํ์๊ฐ ์ข์ํ๋ ๊ฐ์์ธ ๊ฑฐ๋ฏธ์ ๊ทธ๋ ๋์์ค๋ฉด.mp3
ํ์ผ์ ์
๋ก๋ ํด๋ณด์๋ค.
AudioBuffer {
length: 12225071,
duration: 277.2124943310658,
sampleRate: 44100,
numberOfChannels: 2
}
๊ทธ๋ฌ๋ฉด AudioAnalyzer
์ setAudio
๋ฉ์๋ ๋ด๋ถ์์ ์คํ๋ decodeAudioData
๊ฐ ArrayBuffer
๋ฅผ ๋ฐ์์ AudioBuffer
๋ก ๋ณํํ ๋ค ๋ฐํํด์ค๋ค. ์ด๊ฑธ ๋ฏ์ด๋ณด๋ฉด ์ ์ฉํ ์ ๋ณด๋ค์ด ๋ค์ด์๋ค.
sampleRate
: ๋น์ฐํ ์ํ ๋ ์ดํธ๋ฅผ ์๋ฏธํ๊ณ ์ด ๊ณก์ ์ํ ๋ ์ดํธ๋44,100hz
์ด๋ค.numberOfChannels
: ์ด ์ค๋์ค๊ฐ ๋ช๊ฐ์ ์ฑ๋์ ๊ฐ์ง๊ณ ์๋์ง๋ฅผ ๋ํ๋ด๋๋ฐ ์ด ํ์ผ์ ๋ ๊ฐ์ ์ฑ๋์ด ์๋ ์คํ ๋ ์ค ์ฑ๋ ์ค๋์ค ํ์ผ์ด๋ค.length
:ํผํฌ(Peak)
๋ค์ ๊ฐ์๋ฅผ ์๋ฏธํ๋ค. ํผํฌ๋ ์ปดํจํฐ๊ฐ ์ํ๋ง์ ์งํํ ๋ ์ ์์ ์ธก์ ํ ๊ฐ์ ์๋ฏธํ๋ค.duration
: ์ด ์ค๋์ค ํ์ผ์ ์ฌ์ ๊ธธ์ด๋ฅผ์ด
๋จ์๋ก ํ์ํด์ค๋ค.๊ทธ๋ ๋์์ค๋ฉด
์ ์ฝ277์ด
๋์ ์ฌ์๋๋๋ณด๋ค.
์ ์ฌ๊ธฐ์ ํ๊ฐ์ง ๊ฒฐ์ ํด์ผํ ๊ฒ์ด ์๊ฒผ๋ค. ์ฑ๋์ด ๊ฐ์ธ ์ค๋์ค ๋ฐ์ดํฐ๊ฐ ๋ค์ด์์ ๋ ๊ทธ ๊ฐ์ ์ฑ๋์ ์ค๋์ค ํํ์ ๋ชจ๋ ํํํด์ฃผ๊ฑฐ๋ ์ฑ๋์ ํ๋๋ก ํฉ์ณ์ ํํ์ ํํํด์ฃผ์ด์ผํ๋ค. ํ์๋ ๊ฐ์ ์ฑ๋์ ๊ฐ์ง ์ค๋์ค ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ค๋๋ผ๋ ๊ทธ ์ฑ๋์ ๋ชจ๋ ํ๊ฐ์ ์ฑ๋๋ก ๋จธ์งํด์ ํํ์ ๊ทธ๋ฆด ์์ ์ด๋ค.
ํ์ง๋ง ์ด ํฌ์คํ ์์ ์ฑ๋์ ๋จธ์งํ๋ ๊ฒ๊น์ง ๋ชจ๋ ์ด์ผ๊ธฐํ๋ฉด ๋๋ฌด ๋ณต์กํด์ง๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ํ๋์ ์ฑ๋๋ง ์ฌ์ฉํ์ฌ ์งํํ๋๋ก ํ๊ฒ ๋ค.
์ค๋์ค ๋ฐ์ดํฐ ๋ถ์ํ๊ณ ์ ์ ํ๊ธฐ
์ด์ ํ์๋ ๊ธฐ๋ณธ์ ์ธ ์ค๋์ค ๋ฐ์ดํฐ์ธ AudioBuffer
๋ฅผ ์ป์๋ค. ์ด์ ์ด ๋ฐ์ดํฐ๋ง ์์ด๋ ์ค๋์ค ํํ์ ๊ทธ๋ฆด ์ ์๋ค.
์ด์ AudioBuffer
์์ ํ์ํ ๋ฐ์ดํฐ๋ง ๋ฝ์์ ํด๋์ค์ ๋ฉค๋ฒ๋ณ์๋ค์ ํ ๋นํด์ฃผ์.
setAudio (audioFile) {
this.audioContext.decodeAudioData(audioFile).then(buffer => {
// AudioBuffer ๊ฐ์ฒด๋ฅผ ๋ฉค๋ฒ๋ณ์์ ํ ๋น
this.audioBuffer = buffer;
// ์
๋ก๋๋ ์ค๋์ค์ ์ํ ๋ ์ดํธ๋ฅผ ๋ฉค๋ฒ๋ณ์์ ํ ๋น
this.sampleRate = buffer.sampleRate;
// ์ํ ๋ ์ดํธ์ ๋ง์ถฐ์ svg ์๋ฆฌ๋จผํธ ํฌ๊ธฐ ์กฐ์
this.updateViewboxSize();
});
}
ํ, ์ฌ๊ธฐ๊น์ง ์์ผ๋ฉด ํํ์ ๊ทธ๋ฆด ์ค๋น๊ฐ ๋ชจ๋ ๋๋ฌ๋ค. ์ฐ์ AudioBuffer
์์ ์ค๋์ค ์ ํธ๋ฅผ ํ๋ํ๋ ๋ฝ์๋ณด์.
๋จผ์ ์ค๋์ค ์ ํธ๊ฐ ๋ค์ด์๋ ๋ฐฐ์ด๋ถํฐ ํ๋ฒ ์ดํด๋ณด์. ์๊น ํ์๊ฐ AudioBuffer
์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋ตํ๊ฒ ๋ดค์ ๋ numberOfChannels
๋ผ๋ ํ๋กํผํฐ๊ฐ ์์๊ณ ์ด ๊ฐ์ด 2
์ธ ์คํ
๋ ์ค
์ฑ๋์ด์๋ค. ์ด ์ฑ๋ ๋ฐ์ดํฐ๋ AudioBuffer.getChannelData
๋ฉ์๋๋ฅผ ํตํด์ ๊ฐ์ ธ์ฌ ์ ์๋ค.
for (let i = 0; i < this.audioBuffer.numberOfChannels; i++) {
console.log(this.audioBuffer.getChannelData(i));
}
// Float32Array(12225071) [0, 0, 0, โฆ]
// Float32Array(12225071) [0, 0, 0, โฆ]
์๋ ์ด๋ง๋ฌด์ํ ๊ธธ์ด์ Float32Array
๊ฐ ๋์๋ค. ์ง๊ธ ํ์์๊ฒ ๋ณด์ด๋ ๊ฐ์ ์ ๋ถ 0
์ด์ง๋ง ๋ณดํต ์์
์ด ์์ํ์๋ง์ ์ฟ ๊ณผ๊ณผ๊ด! ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฐ๊ฑฐ์ง ๋ค์ชฝ ์ธ๋ฑ์ค์ ์๋ฆฌ๋จผํธ์๋ ๊ฐ์ด ์ ๋๋ก ๋ค์ด๊ฐ ์๋ค. ๊ทธ๋ ๋ค๊ณ ์ด ๊ฐ๋ค์ ๊ทธ๋๋ก ์ฌ์ฉํ๊ธด ์กฐ๊ธ ํ๋ค๊ณ ์กฐ๊ธ ์์ง์ ํด์ค์ผ ํ๋ค.
์ฐ์ ์ ๋ฐฐ์ด์ ๋ค์ด์๋ ์์์ ์ ์ฒด๊ฐ ๋ญ์ง๋ถํฐ ์๊ฐํด๋ณด์. ๋ฐฐ์ด์ ๊ธธ์ด์ธ 12225071
๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ์น๊ตฌ์ ์ ์ฒด๋ฅผ ํ์
ํ ์ ์๋ค. ์๊น ์ฐ๋ฆฌ๊ฐ AudioBuffer
๋ฅผ ํตํด ์ด ๊ณก์ ์ฌ์๊ธธ์ด(Duration)
๋ฅผ ๋ดค์ ๋ ์ฝ 277์ด
์๋ค. ์ด ๊ณก์ ์ํ ๋ ์ดํธ
์ ์ฌ์๊ธธ์ด
๋ฅผ ๊ณฑํด๋ณด๋ฉด 12225071
์ด ๋์จ๋ค. ์ฆ, ์ ์์๋ค์ ์ปดํจํฐ๊ฐ ์ํ ๋ ์ดํธ์ ๋ฐ๋ผ ์ธก์ ํ ์ ์์ธ ํผํฌ์ด๋ค.
์ผ๋จ ์ ์์์ ์ ์ฒด๊ฐ ํผํฌ๋ผ๋ ๊ฒ์ ์์์ผ๋ ์ด ์น๊ตฌ๋ค์ ์กฐ๊ธ ์ ์ ํด๋ณด์. ์ ์ด๊ฑธ ์ ์ ํ๋๋?
12,225,071๊ฐ์ ํผํฌ๋ฅผ ์ ๋ถ ๋ ๋ํ๋ค๋ ๊ฒ ๊ณผ์ฐ ํจ์จ์ ์ธ ์๊ฐํ์ธ๊ฐโฆ?
๋ผ๋ ํฉ๋ฆฌ์ ์์ฌ ๋๋ฌธ์ด๋ค. ์์งํ ํผํฌ๊ฐ ์ฒ๋ง
๊ฐ๊ฐ ์ฐํ๋ ์ค๋ฐฑ๋ง
๊ฐ๊ฐ ์ฐํ๋ ์ด์ฐจํผ ์ฐ๋ฆฌ๋ ์กฐ๊ทธ๋ง ๋ชจ๋ํฐ๋ก ๋ณผ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ์ด๊ฑธ ํ๋ํ๋ ๋ค ํํํด์ค๋ค๋ ๊ฒ ์์ฒด๊ฐ ํฐ ์๋ฏธ๋ ์๋ค.
๊ทธ๋์ ํ์๋ ํผํฌ๋ค์ ์ ๋นํ ์์ถํ ๊ฒ์ด๋ค. ๋ชจ๋ ํผํฌ๋ฅผ ์์งํ๋ ๊ฒ์ด ์๋๋ผ ์ ๋นํ ๊ธธ์ด์ ์ํ์ ๋ง๋ค๊ณ ํด๋น ์ํ ์์ ์ต๋๊ฐ
๊ณผ ์ต์๊ฐ
๋ง ์์งํ ๊ฒ์ด๋ค.
์์์ ์ค๋ช
ํ๋ฏ์ด ๋์ดํด์คํธ ์ด๋ก
์ ๋ฐ๋ฅด๋ฉด ์ด์ฐจํผ ํ๋์ ์ฌ์ดํด์ ํํํ ๋ ์ต๋๊ฐ ํ๊ฐ
์ ์ต์๊ฐ ํ๊ฐ
๋ง ์๋ฉด ์๋ฌด ๋ฌธ์ ๊ฐ ์๋ค. ํํ์ ํด์๋๋ ์กฐ๊ธ ๋จ์ด์ง๊ฒ ์ง๋ง ์ด๊ฑด ๋ญ ์์ฉ ํด๋ ์๋๊ธฐ ๋๋ฌธ์ ํฐ ์๋ฏธ๋ ์๋ค.
const sampleSize = peaks.length / this.sampleRate;
const sampleStep = Math.floor(sampleSize / 10);
// ์์๋ก 0๋ฒ ์ฑ๋๋ง ๊ฐ์ ธ์ด
const peaks = this.audioBuffer.getChannelData(0);
const resultsPeaks = [];
// ๋ฑ ์ํ ๋ ์ดํธ ๊ธธ์ด์ธ 44100๊ฐ์ ํผํฌ๋ง ์์งํ ๊ฒ์ด๋ค.
Array(this.sampleRate).fill().forEach((v, newPeakIndex) => {
const start = Math.floor(newPeakIndex * sampleSize);
const end = Math.floor(newPeakIndex + sampleSize);
let min = peaks[0];
let max = peaks[0];
for (let sampleIndex = start; sampleIndex < end; sampleIndex += sampleStep) {
const v = peaks[sampleIndex];
if (v > max) {
max = v;
}
else if (v < min) {
min = v;
}
}
resultPeaks[2 * newPeakIndex] = max;
resultPeaks[2 * newPeakIndex + 1] = min;
});
์ข ๋ณต์กํด๋ณด์ด์ง๋ง ์ด ์ฝ๋๋ฅผ ํ๋ง๋๋ก ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- ์ํ๋ ์ดํธ ๋งํผ ์ดํฐ๋ ์ด์ ์ ๋๋ค.
- ํน์ ๊ธธ์ด์ 2์ฐจ ์ํ ๊ตฌ๊ฐ์ ์ ํ๊ณ ๊ทธ ๊ตฌ๊ฐ ๋ด์์ ์ต๋๊ฐ๊ณผ ์ต์๊ฐ์ ์ฐพ๋๋ค.
- resultPeaks ๋ฐฐ์ด์ ์ง์ ์ธ๋ฑ์ค์ ์ต๋๊ฐ์, ํ์ ์ธ๋ฑ์ค์๋ ์ต์๊ฐ์ ์ฝ์ ํ๋ค.
resultsPeaks
๋ฐฐ์ด์ ๊ฐ์ ์ ์ฅํ ๋ 2 * newPeakIndex
์ ๊ฐ์ด ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ 2๋ฐฐ๋ก ํด์ฃผ๋ ์ด์ ๋ ํผํฌ๋ฅผ ํ๋ฒ ์ดํฐ๋ ์ด์
๋ ๋ max
์ min
์ต๋ 2๊ฐ์ ๊ฐ์ ์ ์ฅํด์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ ๊ฒ ํด์ ํ์๋ ์ ๋นํ ์์ถ๋ 88200
๊ธธ์ด์ ํผํฌ ๋ฐฐ์ด ํ๋๋ฅผ ์ป๊ฒ ๋์๋ค.
์ด์ ์ง์ง ๊ทธ๋ ค๋ณด์!
๊ทธ๋ฆฌ๋ ๋ฐฉ๋ฒ์ ์๊ฐ๋ณด๋ค ๋จ์ํ๋ค. ์์์ ๋ฝ์์จ ํผํฌ ๋ฐฐ์ด์ ์ํ๋๋ฉด์ ๊ทธ๋ ค์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
SVG
์ path
์๋ฆฌ๋จผํธ๋ d
์์ฑ์ ๋ด๊ธด ๋ฌธ์์ด์ ๋ถ์ํ์ฌ ์ ์ ๊ทธ๋ ค์ค๋ค. ์ด๋ M
์ Move
, ๊ทธ๋ฆผ์ ๊ทธ๋ฆด ํฌ์ธํฐ๋ฅผ ์ฎ๊ธฐ๋ ๋ช
๋ น์ด์ด๊ณ L
์ Line
, ์ง์ ํ ๊ณณ๊น์ง ์ ์ ๊ธ๋ ๋ช
๋ น์ด์ด๋ค.
์ฆ, ์ฐ๋ฆฌ๋ ํฌ์ธํฐ๋ฅผ ์ฎ๊ธฐ๊ณ ์ ์ ๊ธ๊ณ
๋ฅผ ๋ฐ๋ณตํ๋ฉด ๋๋ ๊ฒ์ด๋ค. ์๊น ํ์๊ฐ ์ง์ ์ธ๋ฑ์ค์๋ ์ต๋ ๊ฐ์ ๋ด๊ณ ํ์ ์ธ๋ฑ์ค์๋ ์ต์๊ฐ์ ๋ด์์ค ์ด์ ๊ฐ ๋ฐ๋ก ์ฌ๊ธฐ์ ์๋ค. ์ดํฐ๋ ์ด์
์ ๋๋ฉด์ ์ง์ ์ธ๋ฑ์ค ์ผ๋๋ M
๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ํฌ์ธํฐ๋ฅผ ์ฎ๊ธฐ๊ณ ํ์ ์ธ๋ฑ์ค ์ผ๋๋ L
๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ ๊ทธ๋ฆฌ๋ ค๊ณ ํ ๊ฒ์ด๋ค.
draw () {
if (this.audioBuffer) {
const peaks = this.peaks;
const totalPeaks = peaks.length;
let d = '';
for(let peakIndex = 0; peakIndex < totalPeaks; peakIndex++) {
if (peakNumber % 2 === 0) {
d += ` M${Math.floor(peakNumber / 2)}, ${peaks.shift()}`;
}
else {
d += ` L${Math.floor(peakNumber / 2)}, ${peaks.shift()}`;
}
}
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttributeNS(null, 'd', d);
this.waveFormPathGroup.appendChild(path);
}
}
Math.floor(peakNumber / 2)
๋ ์ถ, peaks.shift()
๋ ์ถ์ ์๋ฏธํ๋ค. ์ด ์ฝ๋๋ ๋๋ต ์ด๋ฐ ์์ผ๋ก ์๋ํ ๊ฒ์ด๋ค. ์์ ๋ถ์ ์ซ์๋ ํผํฌ์ ์ธ๋ฑ์ค๋ผ๊ณ ์๊ฐํ์.
- (0, 100)์ผ๋ก ํฌ์ธํฐ ์ด๋
- (0, -25)์ผ๋ก ์ ์ ๊ธ๋๋ค.
- (1, 300)์ผ๋ก ํฌ์ธํฐ ์ด๋
- (1, -450)์ผ๋ก ์ ์ ๊ธ๋๋ค.
- ์ญ์ญ ๋ฐ๋ณต
์ฐ๋ฆฌ๊ฐ ๊ทธ๋ฆฌ๋ ค๋ ์ค๋์ค ํํ์ ๋์งํธ ์ ํธ๋ฅผ ํํํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์์์ ์ฐ๋ฆฌ๊ฐ ๋ดค๋ ์ค๋์ค ์ ํธ์ ์์์ฒ๋ผ ์ฐ์์ ์ธ ์๋ ๋ก๊ทธ๋ก๋ ํํ์ด ๋ถ๊ฐ๋ฅ ํ๋ค. ๊ทธ๋์ ์ด๋ ๊ฒ ์๋๊ธฐ๋ฅผ ์ญ์ญ ๊ทธ์ด๊ฐ๋ฉด์ ํํํด์ผํ๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ๋ณด๋ฉด ์๋นํ ํ์ ํ ๊ทธ๋ฆผ์ด ๋์ฌ ๊ฒ ๊ฐ์ง๋ง, ์ ์ ์ด 88,200
๊ฐ๊ฐ ๊ฒน์ณ์์ผ๋ฉด ๊ฝค ๊ทธ๋ด์ธํด๋ณด์ธ๋ค.
์, ์ด๋ ๊ฒ ์ค๋์ค ํํ์ ์ฌํํ๊ฒ ๊ทธ๋ ค๋ณด์๋ค. ์ฌ๊ธฐ๊น์ง ํด๋๊ณ ํ๋ ๋ง์ธ๋ฐโฆ ์ฌ์ค WaveSurfer๋ผ๊ณ ์ด๊ฑฐ ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค. ๊ธฐ๋ฅ๋ ๋ ๋ง๋ค.
๊ทธ๋ฅ ๋ด ์์ผ๋ก ํ๋ฒ ์ง์ ๊ทธ๋ ค๋ณด๊ณ ์ถ์๋ค.
์์ ์ฃผ์ธ์ DJ
ํํ๋ง ๊ทธ๋ฆฌ๊ธฐ๋ ์ข ์์ฌ์ฐ๋ ๋ง๊ฐ์ ์ด์ฉํด์ ๋ฉ์๋ ํ๋๋ง ๋ ๋ง๋ค์ด๋ณด์. ๋ฐ๋ก ์ด ์์
์ ์ฌ์ํ๋ ๊ธฐ๋ฅ์ด๋ค.
์๋ ์ด ๋ฉ์๋๋ฅผ ๋ง๋ค ๋ ํ์์ ์๋๋ ์์
์ด๋ผ๋ ์ข ๋ค์ผ๋ฉด์ ๋ง๋ค์
์๋๋ฐ ์ด๊ฑฐ ๋ง๋ค๋ฉด์ ๊ทธ๋ ๋์์ค๋ฉด
์ ๋๋ฌด ๋ง์ด ๋ค์ด์ ์กฐ๊ธ ์ง๋ ค๋ฒ๋ ธ๋ค.(๊ฑฐ๋ฏธ ๋๋ ๋ฏธ์โฆ)
play (buffer) {
const sourceBuffer = this.audioContext.createBufferSource();
sourceBuffer.buffer = buffer;
sourceBuffer.connect(this.audioContext.destination);
sourceBuffer.start();
}
AudioContext.prototype.createBufferSource
๋ฉ์๋๋ AudioNode
์ค ํ๋์ธ AudioBufferSourceNode
๋ผ๋ ์น๊ตฌ๋ฅผ ์์ฑํ๋ ๋ฉ์๋์ธ๋ฐ, ์ด AudioNode
์๊ฒ ์ฐ๋ฆฌ๊ฐ ์ง๊ธ๊น์ง ๊ฐ์ง๊ณ ๋์๋ AudioBuffer
๋ฅผ ๋๊ฒจ์ฃผ๋ฉด ์ง์ง ์ค๋์ค์ ์ธ ์ปจํธ๋กค์ ํ ์๊ฐ ์๊ฒ ๋์์ฃผ๋ ์โฆ๊ป๋ฐ๊ธฐ ๊ฐ์ ๋๋์ด๋ค.
Web Audio API
๋ ์ด๋ฐ AudioNode
๋ค์ ์๋ก ์ฐ๊ฒฐํด์ ์๋ฆฌ๋ฅผ ๋ณ์กฐํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ์ด๊ฑธ ์ฌ์ฉํด์ ์ปดํ๋ ์๋ ๋ฆฌ๋ฒ๋ธ ๊ฐ์ ์ค๋์ค ์ดํํฐ๋ ๋ง๋ค ์ ์๋ค. ๋ค์์๋ ํ๋ฒ ์ค๋์ค ์ดํํฐ๋ฅผ ๋ง๋ค์ด๋ณด๋ ๊ฒ์ ๋ชฉํ๋ก ํด์ผ๊ฒ ๋ค.
์์ฑ๋ ์ํ์ ์์ค๋ ํ์์ ๊นํ๋ธ ๋ ํ์งํ ๋ฆฌ์์, ๋ผ์ด๋ธ ๋ฐ๋ชจ๋ ์ฌ๊ธฐ์ ํ์ธํ ์ ์๋ค.
์ด์์ผ๋ก ์ปดํจํฐ๋ ์ด๋ป๊ฒ ์๋ฆฌ๋ฅผ ๋ค์๊น? ํฌ์คํ ์ ๋ง์น๋ค.
- Sound Engineering
- ์ฌ์ด๋ ์์ง๋์ด
- ๋์ดํด์คํธ
- Logic Pro X
- ๋ก์งํ๋ก
- Cubase
- ํ๋ฒ ์ด์ค
- Analog to Digital
- AD Covert
- Digital to Analog
- DA Covert
- ์ํ๋ง
- Sampling
- Sample Rate
- AudioContext
- Bit Rate
- ์๋ฐ์คํฌ๋ฆฝํธ
- JavaScript Audio API
๊ด๋ จ ํฌ์คํ ๋ณด๋ฌ๊ฐ๊ธฐ
[JavaScript ์ค๋์ค ์ดํํฐ ๋ง๋ค๊ธฐ] ์ค๋์ค ์ดํํฐ๋ก ๋๋ง์ ์๋ฆฌ ๋ง๋ค๊ธฐ
[JavaScript ์ค๋์ค ์ดํํฐ ๋ง๋ค๊ธฐ] ์๋ฆฌ์ ํ๋ฆ์ ํ์ ํ์
[JS ํ๋กํ ํ์ ] ํ๋กํ ํ์ ์ ์ฌ์ฉํ์ฌ ์์ํ๊ธฐ
[JS ํ๋กํ ํ์ ] ์๋ฐ์คํฌ๋ฆฝํธ์ ํ๋กํ ํ์ ํ์ด๋ณด๊ธฐ
์ต์ ๊ฐ๊ณผ ์ต๋ ๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์๊ฒ ๋์์ฃผ๋ ํ(Heap)