2014-01-17 5 views
2

소리를 생성하는 앱을 만들고 있습니다 (현재는 실험적입니다). Android 폰에서 재생합니다.OpenSL로 생성 사운드 재생

지금은 간단한 사인파 사운드 (440Hz)를 재생하려고 시도하고 있으며 처음에는 Audiotrack을 시도했지만 버퍼 언더런이 발생했습니다. 그래서 OpenSL을 살펴보기로했습니다.

이제 이것에 대한 튜토리얼과 블로그 게시물을 많이 읽었으며, 결국 Android Simple Buffer Queue가있는 OpenSL Engine을 사용하여 직접 구현했습니다.

이제 버퍼 콜백에서 새 버퍼 데이터를 생성하여 대기열에 추가하지만 대기 시간은 오디오 트랙보다 훨씬 나쁩니다 (각 버퍼 간의 간격이 들릴 수 있음).

제 질문은 OpenSL에서 생성 된 사운드에 가장 적합한 방법/아키텍처는 무엇입니까? 대체 스레드에서 버퍼를 채워야합니까? (버퍼 콜백으로 동기화 프로세스가 필요합니까?)

OpenSL ES에서 생성 된 사운드에 대한 자습서를 찾지 못했습니다. 대부분 오디오 파일을 재생하거나 오디오 입력을 오디오 출력으로 리디렉션합니다.

+0

_ "대기 시간은 오디오 트랙보다 훨씬 나쁩니다. (각 버퍼 사이의 간격을들을 수 있습니다)"_. 버퍼 언더런 (버퍼가 완전히 채워지지 않고 대기열에 들어갑니다)을 설명하는 것처럼 나에게 들립니다. 각 버퍼 사이에서 플레이어 개체를 중지했다가 다시 시작하지 않는 한 버퍼 사이에 대기 시간이 없어야합니다. 처음으로 플레이어 개체를 시작할 때 처음 것만. 귀하의 질문에 관해서는; 버퍼 큐 콜백을 사용하여 다음 버퍼를 큐에 넣기 만하면되지만 다른 버퍼 크기를 시도한 후에 작동합니다. – Michael

답변

3

대기 시간 : 올바른 샘플링 속도와 버퍼 크기를 선택하는 것이 중요합니다. 당신은 안드로이드 SDK의 AudioManager을 (PROPERTY_OUTPUT_SAMPLE_RATEPROPERTY_OUTPUT_FRAMES_PER_BUFFER는 API 레벨 17에서 구할 수 있습니다)를 사용하여 권장 값에 대한 장치를 조회하고 NDK 응용 프로그램에 값을 전달할 수 있습니다

// getting the samplerate and buffer size 
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) 
{ 
    AudioManager am = (AudioManager) aContext.getSystemService(Context.AUDIO_SERVICE); 
    int sampleRate = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); 
    int bufferSize = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); 
} 

샘플 속도를 얻기의 중요성 맞습니다. 장치 선호 샘플 속도 (일부는 48kHz, 다른 것은 44.1kHz)와 다른 경우 하드웨어가 출력하기 전에 시스템 리샘플러를지나 오디오가 라우팅되어 전반적인 대기 시간이 늘어납니다. 또한 올바른 버퍼 크기를 얻는 중요성은 몇 가지 버퍼 콜백 후에 샘플/프레임이 떨어지는 것을 방지하기 때문에 콜백간에 갭/글리치가 발생하는 문제를 설명 할 수 있습니다. 배수 (2의 거듭 제곱)를 사용하여보다 안정적인 엔진 (높은 버퍼 크기)과 빠른 응답 (낮은 버퍼 크기)을 실험하기 위해 버퍼 크기를 줄이거 나 늘릴 수 있습니다.

정확히이 작업을 수행하는 간단한 Android 앱을 만들었으므로 위의 권장 사항을 음악 관련 애플리케이션 용 기본 시퀀스 엔진을 구성하는 방법과 함께 약간 자세히 설명하는 작은 글을 작성했지만 그냥 기본 아키텍처 개요, 그리고 당신의 필요에 따라 완전히 쓸모가 없을 수도 있습니다>Android audio engine in OpenSL