갑자기 심심해져서 한건데 생각보다 괜춘하네요.
소리에서 특징이 되는 주파수를 뽑아내는걸 해봤습니다.
여기서 특징 주파수만 봐도 몇가지를 알수 있는데,
* 대게 일직선으로 나타나는 소리는 악기 소리입니다. 배음이 몇개 잡힌 것도 있지만 그걸 제외해도 적어도 2~3 화음이 나타나는 걸 알수 있죠.
* 위아래로 굴곡이 심한 소리는 사람 목소리입니다. 강한 주파수만 뽑아내서 포만트를 볼 수는 없지만, 주파수를 바탕으로 포만트도 얻어올수 있다면 어떤 모음인지도 알아낼 수 있을겁니다.
구현 원리는 간단합니다.
1. 가버 변환을 수행한다.
2. 해당 구간의 평균적인 진폭의 크기를 구한다.
3. 진폭의 크기에 비례해서 그보다 강한 주파수 영역을 선택해낸다.
가버 변환은 예전에 간단하게 설명한 글이 있었으니 패스하고 (푸리에변환의 업그레이드 버전이라고 생각하시면됩니다.)
해당 구간의 평균적인 진폭의 크기를 구하는거, 뭐 사람이 그냥 소리를 듣는거면 시끄러우면 시끄럽다 작으면 작다 쉽게 판별 가능하겠지만, 음파 데이터는 그냥 [-1,1] 범위의 숫자 몇 천개가 나열되어있는 것이니 소리의 크기를 파악해내는게 간단하지만은 않더라구요.
구간 내에서 최댓값과 최솟값을 찾아 그 차이를 최대 진폭이라고 할수도 있겠지만 그건 해당 구간의 전반적인 소리 크기를 반영하지 못한다고 판단하여, 평균 진폭을 계산했습니다.
이렇게 계산했어요. 표준편차 구하는 공식이랑 거의 유사하죠. f(i)는 각 지점에서의 진폭이고, n은 구간의 길이입니다. 가버 변환에 윈도우 함수인 가우스 분포함수 곱하는것마냥 f(i) 계산할때도 그렇게 했습니다. (재탕했다는 말이죠ㅋ)
주파수 영역 선택하는건 생각보다 단순한 일이 아니더라구요. 왜냐면 사인/코사인 파를 제외한 모든 소리를 배음을 포함하고 있어서, 100Hz음이라고 해도 200Hz, 300Hz, 400Hz 등등의 소리를 다 포함하고 있기 때문이죠. 따라서 대충 골라내면 100, 200, 300, 400Hz의 소리가 다 각각 잡혀버릴수도 있는 문제가 있습니다.
그래서 100Hz 주파수인 음의 세기는 100*n Hz 주파수의 음을 모두 합쳐서 계산하기로 했습니다.
단, 고주파의 음까지도 같은 비율로 계산되는건 아닌거 같아서 1/n 배를 했습니다.
주파수별 세기인 I(f)는 가버변환된 결과 F(i)에 가우스분포함수를 곱하여 계산했습니다. 원래는 F(f)만 뽑아 쓰려고 했는데, 애초에 변환결과라는게 100Hz면 딱 100Hz 부분에만 나타나는게 아니라 100+-10Hz 처럼 두루뭉술하게 나타나는 거기에 주변부분의 세기도 함께 잡고자 가우스 분포함수를 계수로 곱해줘서 주변부분의 세기도 함께 잡았습니다.
이렇게 구한 Intensity가 평균 진폭의 10% 이상인 부분만 뽑아낸것이 위의 나타난 최종 결과물인거죠.
[그냥 옛날 이야기 2] 스타크래프트와 드래프트 (0) | 2014.04.08 |
---|---|
[그냥 옛날 이야기 1] 홈페이지 붐과 초3 (1) | 2014.04.05 |
[적분스페셜] 문화재를 왜 보호해야하죠? (7) | 2014.01.08 |
앞으로 하고 싶은 일! (2) | 2013.11.07 |
문법트리 그려주는 좋은 웹앱! (0) | 2013.10.12 |
축 10만 조회 돌파 (0) | 2013.06.05 |
댓글 영역