Sonic 라이브러리를 사용하여 오디오 재생 속도를 제어하는 방법을 일전에 살펴보았었다. 이번에는 SoundTouch라는 또다른 유명한 라이브러리를 이용하여 재생 속도를 제어하는 방법을 살펴보려고 한다.

SoundTouch여기에서 보는 바와 같이 수많은 어플리케이션에서 사용하고 있다.

Sonic 라이브러리는 소스파일이 단촐하게 단 하나의 메인 소스로 구성되어있는 반면 SoundTouch 소스코드는 이보다 더 많고, 여러가지 추가적인 기능 (WAV 파일 다루기 및 필터 등등으로 구성)이 같이 포함되어 있다.

SoundTouch를 안드로이드용 NDK 라이브러리로 컴파일하는 방법 및 JNI 소스는 https://github.com/svenoaks/SoundTouch-Android 사이트를 통해서 그 정보를 얻을 수 있었으며, 일전에 소개했던 Sonic 라이브러리용 테스트 앱을 살짝 변형시켜서 SoundTouch 라이브러리를 사용한 간단한 재생 속도 조절 앱을 만들 수 있었다. 소스는 https://github.com/wkpark/soundtouch-ndk를 통해서 받을 수 있다. soundtouch는 별도의 레포지터리 https://github.com/wkpark/soundtouch에 최신 soundtouch 소스코드를 올려두었으니 참고하시기 바란다.

Sonic 홈페이지에 설명되어있는 것처럼, Sonic 라이브러리는 PICOLA 알고리즘을 사용하여 음성 속도 제어에 유리한 반면, SoundTouch 라이브러리는 WSOLA 알고리즘을 사용하여서 음성 속도 제어보다는 일반적인 음악의 속도 제어에 유리하다고 한다.

다음은 SoundTouch JNI의 간단한 사용법 예제이다.

.... if (soundFile != null) { soundtouch.setSpeed(speed); soundtouch.setPitch(pitch); soundtouch.setRate(rate); do { try { bytesRead = soundFile.read(samples, 0, samples.length); // WAV 파일을 읽음 } catch (IOException e) { e.printStackTrace(); return; } if (bytesRead > 0) { soundtouch.putBytes(samples, bytesRead); // soundtouch 라이브러리 통해 프로세싱 } else { soundtouch.finish(); // 프로세싱이 완료되면 finish()를 호출 soundtouch.flush(); // 남아있는 버퍼를 지움 } int available = (int) soundtouch.availableBytes(); if (available > 0) { if (modifiedSamples.length < available) { modifiedSamples = new byte[available*2]; // 버퍼 크기가 부족하면 늘려준다. } soundtouch.getBytes(modifiedSamples, available); // 프로세싱된 결과를 가져옴 device.writeSamples(modifiedSamples, available); // AudioTrack에 쓴다. } } while(bytesRead > 0); device.flush(); // 오디오 트랙 끝. ...

Sonic 라이브러리와 함께 SoundTouch는 링드로이드클론 학습기에 기능이 포함되었으며 최신 링드로이드 클론에서 사용해볼 수도 있다.

by dumpcookie 2014. 11. 28. 01:54