matlab을 이용한 기본적인 음성인식 프로그램(정말기초!)
주의! 정말 기초밖에 모르는 ! 학생이 공부해과는 과정입니다 ㅋㅋ
실패에서 배우는 과정..뭐이런것도 있고해서..
괜히 소스 가져다 쓰시면 교수님한테 욕먹어요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
이번 텀 프로젝트로 음성인식을 맡게 되었습니다.
사실 음성인식에 대해서 배운적도없고... 무작정 찾아봤습니다...
먼저 저희 조원들의 목소리를 녹음했습니다.
아래 그램과같이 같은 단어인데도 불구하고 파형 및 길이가 다 다르게 나왔습니다.
이점에 착안해서 특정 수렴값들만 뽑아내자! 라는 아이디어를 냈습니다.
어떻게하면 저 수많은 값들중에 대표값을 따올수있을까.. 하다가 round를 시켜서 1값만 따오자 하는 생각이 났습니다.
그래서 아래와같은 식을 하나 만들어서 0도아닌,-1도아닌 오직 반올림후 1이되는 값의 갯수만 받아왔습니다.
(이미 ry라는 변수는 round시킨 데이터입니다)
(nnz는 0이아닌 데이터의 갯수만 출력해주는 함수입니다)
이 방법이 통하긴 하더군요! 사람마다 같은단어도 말하는 시간이 다르고 특성도 다르고 해서..
하지만 단점이 많았습니다. 마이크의 위치에따라 값이 너무나 크게 변하였고 주위의 잡음에도 쉽게 데이터가 변하였습니다.
그래서 이틀 밤낮을 고민고민하며 머리를 굴렸습니다.(구글링보다는 왠만하면 혼자해보자 이런생각이어서..)
그래서 생각해낸 방식이 주파수 찾기였습니다.
왠지 사람마다 고유의 주파수가 있을것 같다! 라는생각이 들어서 바로 함수검색에 돌입..
specgram이라는 함수를 찾아내었습니다. help를 통해서 내용을 보니깐 요놈은 점차 사라질 함수라고 spectogram을 쓰라고 하던군요
그런데 spectogram은 변수?입력이 너무 많아서 일단 보류 ㅠㅠ...
녹음된 파형을 specgram에 뿌렸습니다.
같은 음성을 다섯번 집어넣어서 아래와 같은 그래프가 나왔습니다.
요놈을 temp라는 변수에 집어넣었더니 자동으로 오른쪽과같이 grayscale의 그림이 나오더군요.
그래서 abs와 round를 시켜준후 sum으로 총값을 구해서 5로 나눴습니다!
이방법은 처음 시도한 1개수 찾기보다는 좀 더 정확한(비교적) 데이터가 나왔지만, 역시나 주파수를 직접적으로 분리해낸 방식이 아닌
0과 1의 데이터갯수에만 의존해서 오차가..음..ㅠ....
그래서 또 짱구를 굴렸습니다...
안되더군요.
구글링 들어갔습니다 ㅋㅋ
선형대수 시간에 잠깐 지나갔던 퓨리에 변환이라는 함수를 쓰면 주파수를 뽑아낼수 있다는 글을 보았습니다.
물론 구글링에서도 정확히 사용법을 알려주는 정보는 없었습니다. ㅠㅠ
그래서 직접 하나 하나 데이터를 집어넣어보면서 어떤놈이 주파수일까..어떻게하면 구할까..를 여러번 시도해봤습니다.
아래의 그래프는 원래의 데이터입니다.
시간과 음성데이터에 관한 그래프입니다.
이 그래프의 데이터를(즉, x축인 시간값이 아닌 y축인 음성값을)
퓨리에트렌스폼 함수에 집어넣으면!!!!!!
짜잔~
중간과정은 과감히생략..
한 아래와같은 그래프가 나옵니다. 원래는 length의 2/N지점에서 대칭비스무리한 모습이 나오는데
목소리의 주파수를 체킹해야 하기때문에 과감히 날렸습니다.
아래와같이 뽀족하게 솟은 부분이 음성데이터의 주파수부분입니다.
퓨리에트렌스폼을 거치게되면
시간에 대한 음성의 값이
주파수와 크기에관한 그래프로 바뀌게됩니다.
함수는 fft()를 썼습니다.
그렇게 해서 아래와같은 결과물을 만들었습니다!
사진은 자체검열 ㅋㅋ
레코드를 누르면 미리 저장된 조원 4명의 데이터와 현제 입력받은 음성의 주파수를 분석해서 사용자가 누구인지 찾아줍니다.
피아노는 입력받은 노래or음을 체킹하여 피아노 건반을 체킹하는 프로그램이구요
마리오는 간단하게 음성입력으로 전진후진점프를 하는 게임입니다.(정말 간단 몹도없고 아이템하나있음)
체인지는 Fs를 조절해서 음성변조를 하였습니다!
정말 배울것도 많고 재밌었던 프로젝트였습니다!