안드로이드 녹음기 만드는 중

Posted by ITPangPang
2016.12.09 00:28 안드로이드 삽질메모/삽질중


(삽 질 중)

녹음기를 만들자



녹음, 일시중지, 정지, 재생 기능이 있는 녹음기를

    만들어 보자


ㆍ 녹음 부분을 제대로 파본적은 없으나 기본서에 나온

    MediaRecorder와 MediaPlayer 이 두가지를 사용하면

    아주 간단하게 만들것이라 예상했다.


ㆍ 첫번째 난관 : 아주 당연하게 존재할 것이라 생각하는 녹음중에 일지중지를 시키는 메서드가 존재하지 않았다.


ㆍ 첫번째 난관 해결방법

    1) 녹음 버튼을 눌러서 녹음을 시작하고, 일시중지 버튼을 누른 순간 파일이 완성된다.

    2) 일시중지 눌러서 완성된 파일을 리스트에 담는다.

    3) 일시중지가 아닌 녹음완료 버튼을 누르면 만들어진 파일을 합친다.

    4) 만약 일시정지로 인해 파일이 1개 이상 리스트에 담겼는데, 이 상태에서 중간에 녹음을 취소할때는

       리스트에 있는 파일 전체를 삭제한다.

    5) 파일을 합치기 위해서 mp4parser이라는 라이브러리를 사용했다

        (mp4parser를 사용해서 오디오파일을 합쳐보자!)


ㆍ 파일도 합치고 녹음, 일시중지, 정지, 재생기능등 모든걸 만드는데 성공했다.


ㆍ 그런데 여기서 목소리 높이에 따라(데시벨?, 진폭?) 파형 같은걸 만들어보고 싶어졌다.


ㆍ 그래서 찾아보니 Visualizer라는 것이 있었다.


ㆍ 인터넷에 예제도 굉장히 많았고, 그냥 완성된 파일과 Visualizer을 연결하니 자동으로 파형을 예쁘게 그려준다.


ㆍ 두번째 난관 : 녹음된 파일을 재생할때는 Visualizer로 아주 쉽게 해결했는데, 실시간 녹음할때는 감이 안온다.


ㆍ 녹음을 하는 도중 실시간 목소리 높낮이에 따라 변하는 값으로 파형을 그려줘야 할 것 같았다.


ㆍ 그래서 MediaRecorder를 뒤져보았더니 getMaxAmplitude()라는 메서드가 있었다.


ㆍ 실시간으로 진폭값을 내뱉어주는 메서드였다. 


ㆍ 실시간 진폭값으로 캔버스를 이용하든 뭘 하든 파형을 만들 수 있을거란 확신이 생겼다.


ㆍ 그래서 캔버스에도 그려보고 예제도 찾아보고 해봤다.. 그런데 뭔가 만들어지긴 하는데 위에서 사용해본

     Visualizer와 비교해보니 굉장히.. 내 눈에는 허졉해보였다.. 


ㆍ 결국 Visualizer를 이용해서 실시간으로 나타낼 수 있는 방법이 없을까? 생각해보고 찾아보았다.


ㆍ 두번째 난관 해결방법

    1) 심플하게 사용할 수 있지만 정보가 적은 MediaRecorder보다는 좀 더 분석이 용이한 AudioRecorder를

       쓰기로 했다.

    2) AudioRecorder로 바꾸고 나니 PCM 데이터와 WAV 파일을 뽑아낼 수 있었다.

    3) 기존에 .mp4 파일을 받을때에는 mp4parser을 사용해서 파일을 합쳤었는데 .wav 파일로 받다보니 여기도

        좀 문제가 생겼다.

    4) 하지만 wav파일끼리 병합하는 방법을 찾아보니, 어렵지 않게 찾을 수 있었다.

    5) 이제 실시간으로 파형을 나타내기 위해서 Visualizer와 AudioRecorder를 합쳐보기로 했다.

    6) 기존에 MediaPlayer와 Visualizer를 연결해서 사용할 때에는 mediaPlayer.getAudioSessionId() 이런식으로

        연결해버리면 됬었는데, audioRecorder.getAudioSessionId()를 해보니 에러가 발생했다.

     7) 찾아보니 AudioTrack을 사용하면 된다고 한다.

    8) AudioTrack을 사용해서 audioTrack.getAudioSessionId()를 해보니까 실시간으로 파형이 나온다.

    9) 녹음을 하는 도중 높낮이에 따라 파형이 휘리릭 휘리릭 바뀌는것을 확인 했다.



ㆍ 두번째 난관을 해결한것 같았으나, 뭔가 좀 이상하다..


ㆍ AudioTrack을 사용해서 파형을 나타내는데, AudioTrack은 data값을 스피커로 그대로 내보내 주는 것 같다.


ㆍ 그 소리를 다시 Visualizer가 파형으로 변환해주는 것 같다.


ㆍ 그렇다 보니 녹음을 하는도중 메아리라 해야되나?(echo) 같은 것들이 울리는 것이다..


ㆍ 그래서 AudioTrack을 뒤져보면서 볼륨 set을 0으로 맞춰봤다. 그랬더니 파형이 안그려진다.


ㆍ 여기서 어떻게 해야할까..? 삽질중이다..




ㆍ 동시에 삽질중인 부분은 wav파일은 크기가 너무 크다.

ㆍ .wav -> mp3로 바꿔야 한다.

ㆍ 간단한 변환이니 쉬울거라 생각했는데 오산이었다.

ㆍ 아직 집중해서 서치해보진 않았지만, 잠깐 알아본 바로는 FFMPEG 라이브러리를 사용해야 되는 것 같다.

ㆍ FFMPEG를 사용하려면 NDK를 써야 하는 것 같다.. 일단 이 부분은 머리 아프니 위에 부터 해결해야겠다.






저작자 표시 비영리 변경 금지
신고

'안드로이드 삽질메모 > 삽질중' 카테고리의 다른 글

안드로이드 녹음기 만드는 중  (2) 2016.12.09
이 댓글을 비밀 댓글로
    • 2017.01.16 15:42
    비밀댓글입니다
    • ㅠㅠ 저도 이부분은 현재 스킵해놓은 상태입니다.. 프로젝트에서 거의 쓰이지 않는 부분이라.. 나중에 하려고 합니다..

      나중에 해결방법 다시 검색해보고 안되면
      이미지로 진폭에 따라 바꿔줄까 생각 합니다.

      지금은 빈공간으로 놓긴 그래서 캔버스로 그려놓긴했습니다..

      플젝이 좀 크다보니 여러 코드들이 합쳐져 있어서 공유는 못해드리지만..

      getMaxAmplitude() 여기서 나온값을
      데시벨로 변환해서 어거지로 해놨습니다..

      풀코드는 아니지만 대충 이런 느낌으로..
      double displayWaveForm = decibel - 25;
      int displayWaveArray[] = new int[500];
      Random random = new Random();
      path = new Path();
      if(displayWaveForm > 1)
      {
      for (int i = 0; i < displayWaveArray.length; i++)
      {
      if(i%3==0)
      {
      displayWaveArray[i] = 2 * (random.nextInt((int) displayWaveForm));
      }
      else
      {
      displayWaveArray[i] = 2 * ((int) (displayWaveForm / 2) + random.nextInt((int) displayWaveForm));
      }
      if (i == 0)
      {
      path.moveTo(i * 4, (getHeight() * 2 / 3) - displayWaveArray[0]);
      }
      path.lineTo(i * 4, (getHeight() * 2 / 3) - displayWaveArray[i]);
      }
      }
      canvas.drawPath(path,mForePaint);


      데시벨 최소값이 25정도 나와서
      (데시벨-25) 한 후에 여기 나온값을 랜덤함수로 500개로 쪼갠 후에 y값으로 쓰고 x값은 4픽셀씩 이동시켜서 그려놨습니다..

      0.1초당 500개씩 점을 찍어서 연결해주는 식으로..

      도움은 안되시겠지만.. 저는 일단 이런식으로 채워놨습니다..