am 63183ff2: Merge "Update native-audio example app"

* commit '63183ff22733a4bc8cb8aa52730c862481038554':
  Update native-audio example app
This commit is contained in:
David Turner
2011-10-20 04:04:55 -07:00
committed by Android Git Automerger
4 changed files with 444 additions and 21 deletions

View File

@@ -30,7 +30,7 @@
// for native audio
#include <SLES/OpenSLES.h>
#include "SLES/OpenSLES_Android.h"
#include <SLES/OpenSLES_Android.h>
// for native asset manager
#include <sys/types.h>
@@ -60,6 +60,8 @@ static SLObjectItf bqPlayerObject = NULL;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLEffectSendItf bqPlayerEffectSend;
static SLMuteSoloItf bqPlayerMuteSolo;
static SLVolumeItf bqPlayerVolume;
// aux effect on the output mix, used by the buffer queue player
static const SLEnvironmentalReverbSettings reverbSettings =
@@ -69,11 +71,15 @@ static const SLEnvironmentalReverbSettings reverbSettings =
static SLObjectItf uriPlayerObject = NULL;
static SLPlayItf uriPlayerPlay;
static SLSeekItf uriPlayerSeek;
static SLMuteSoloItf uriPlayerMuteSolo;
static SLVolumeItf uriPlayerVolume;
// file descriptor player interfaces
static SLObjectItf fdPlayerObject = NULL;
static SLPlayItf fdPlayerPlay;
static SLSeekItf fdPlayerSeek;
static SLMuteSoloItf fdPlayerMuteSolo;
static SLVolumeItf fdPlayerVolume;
// recorder interfaces
static SLObjectItf recorderObject = NULL;
@@ -199,10 +205,12 @@ void Java_com_example_nativeaudio_NativeAudio_createBufferQueueAudioPlayer(JNIEn
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND};
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND,
/*SL_IID_MUTESOLO,*/ SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
/*SL_BOOLEAN_TRUE,*/ SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
2, ids, req);
3, ids, req);
assert(SL_RESULT_SUCCESS == result);
// realize the player
@@ -227,6 +235,16 @@ void Java_com_example_nativeaudio_NativeAudio_createBufferQueueAudioPlayer(JNIEn
&bqPlayerEffectSend);
assert(SL_RESULT_SUCCESS == result);
#if 0 // mute/solo is not supported for sources that are known to be mono, as this is
// get the mute/solo interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
#endif
// get the volume interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
// set the player's state to playing
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
@@ -255,10 +273,10 @@ jboolean Java_com_example_nativeaudio_NativeAudio_createUriAudioPlayer(JNIEnv* e
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[1] = {SL_IID_SEEK};
const SLboolean req[1] = {SL_BOOLEAN_TRUE};
const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &uriPlayerObject, &audioSrc,
&audioSnk, 1, ids, req);
&audioSnk, 3, ids, req);
// note that an invalid URI is not detected here, but during prepare/prefetch on Android,
// or possibly during Realize on other platforms
assert(SL_RESULT_SUCCESS == result);
@@ -283,8 +301,12 @@ jboolean Java_com_example_nativeaudio_NativeAudio_createUriAudioPlayer(JNIEnv* e
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_SEEK, &uriPlayerSeek);
assert(SL_RESULT_SUCCESS == result);
// enable whole file looping
result = (*uriPlayerSeek)->SetLoop(uriPlayerSeek, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN);
// get the mute/solo interface
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_MUTESOLO, &uriPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
// get the volume interface
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_VOLUME, &uriPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
return JNI_TRUE;
@@ -292,6 +314,7 @@ jboolean Java_com_example_nativeaudio_NativeAudio_createUriAudioPlayer(JNIEnv* e
// set the playing state for the URI audio player
// to PLAYING (true) or PAUSED (false)
void Java_com_example_nativeaudio_NativeAudio_setPlayingUriAudioPlayer(JNIEnv* env,
jclass clazz, jboolean isPlaying)
{
@@ -310,6 +333,134 @@ void Java_com_example_nativeaudio_NativeAudio_setPlayingUriAudioPlayer(JNIEnv* e
}
// set the whole file looping state for the URI audio player
void Java_com_example_nativeaudio_NativeAudio_setLoopingUriAudioPlayer(JNIEnv* env,
jclass clazz, jboolean isLooping)
{
SLresult result;
// make sure the URI audio player was created
if (NULL != uriPlayerSeek) {
// set the looping state
result = (*uriPlayerSeek)->SetLoop(uriPlayerSeek, (SLboolean) isLooping, 0,
SL_TIME_UNKNOWN);
assert(SL_RESULT_SUCCESS == result);
}
}
// expose the mute/solo APIs to Java for one of the 3 players
static SLMuteSoloItf getMuteSolo()
{
if (uriPlayerMuteSolo != NULL)
return uriPlayerMuteSolo;
else if (fdPlayerMuteSolo != NULL)
return fdPlayerMuteSolo;
else
return bqPlayerMuteSolo;
}
void Java_com_example_nativeaudio_NativeAudio_setChannelMuteUriAudioPlayer(JNIEnv* env,
jclass clazz, jint chan, jboolean mute)
{
SLresult result;
SLMuteSoloItf muteSoloItf = getMuteSolo();
if (NULL != muteSoloItf) {
result = (*muteSoloItf)->SetChannelMute(muteSoloItf, chan, mute);
assert(SL_RESULT_SUCCESS == result);
}
}
void Java_com_example_nativeaudio_NativeAudio_setChannelSoloUriAudioPlayer(JNIEnv* env,
jclass clazz, jint chan, jboolean solo)
{
SLresult result;
SLMuteSoloItf muteSoloItf = getMuteSolo();
if (NULL != muteSoloItf) {
result = (*muteSoloItf)->SetChannelSolo(muteSoloItf, chan, solo);
assert(SL_RESULT_SUCCESS == result);
}
}
int Java_com_example_nativeaudio_NativeAudio_getNumChannelsUriAudioPlayer(JNIEnv* env, jclass clazz)
{
SLuint8 numChannels;
SLresult result;
SLMuteSoloItf muteSoloItf = getMuteSolo();
if (NULL != muteSoloItf) {
result = (*muteSoloItf)->GetNumChannels(muteSoloItf, &numChannels);
if (SL_RESULT_PRECONDITIONS_VIOLATED == result) {
// channel count is not yet known
numChannels = 0;
} else {
assert(SL_RESULT_SUCCESS == result);
}
} else {
numChannels = 0;
}
return numChannels;
}
// expose the volume APIs to Java for one of the 3 players
static SLVolumeItf getVolume()
{
if (uriPlayerVolume != NULL)
return uriPlayerVolume;
else if (fdPlayerVolume != NULL)
return fdPlayerVolume;
else
return bqPlayerVolume;
}
void Java_com_example_nativeaudio_NativeAudio_setVolumeUriAudioPlayer(JNIEnv* env, jclass clazz,
jint millibel)
{
SLresult result;
SLVolumeItf volumeItf = getVolume();
if (NULL != volumeItf) {
result = (*volumeItf)->SetVolumeLevel(volumeItf, millibel);
assert(SL_RESULT_SUCCESS == result);
}
}
void Java_com_example_nativeaudio_NativeAudio_setMuteUriAudioPlayer(JNIEnv* env, jclass clazz,
jboolean mute)
{
SLresult result;
SLVolumeItf volumeItf = getVolume();
if (NULL != volumeItf) {
result = (*volumeItf)->SetMute(volumeItf, mute);
assert(SL_RESULT_SUCCESS == result);
}
}
void Java_com_example_nativeaudio_NativeAudio_enableStereoPositionUriAudioPlayer(JNIEnv* env,
jclass clazz, jboolean enable)
{
SLresult result;
SLVolumeItf volumeItf = getVolume();
if (NULL != volumeItf) {
result = (*volumeItf)->EnableStereoPosition(volumeItf, enable);
assert(SL_RESULT_SUCCESS == result);
}
}
void Java_com_example_nativeaudio_NativeAudio_setStereoPositionUriAudioPlayer(JNIEnv* env,
jclass clazz, jint permille)
{
SLresult result;
SLVolumeItf volumeItf = getVolume();
if (NULL != volumeItf) {
result = (*volumeItf)->SetStereoPosition(volumeItf, permille);
assert(SL_RESULT_SUCCESS == result);
}
}
// enable reverb on the buffer queue player
jboolean Java_com_example_nativeaudio_NativeAudio_enableReverb(JNIEnv* env, jclass clazz,
jboolean enabled)
@@ -426,10 +577,10 @@ jboolean Java_com_example_nativeaudio_NativeAudio_createAssetAudioPlayer(JNIEnv*
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
const SLInterfaceID ids[1] = {SL_IID_SEEK};
const SLboolean req[1] = {SL_BOOLEAN_TRUE};
const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &fdPlayerObject, &audioSrc, &audioSnk,
1, ids, req);
3, ids, req);
assert(SL_RESULT_SUCCESS == result);
// realize the player
@@ -444,6 +595,14 @@ jboolean Java_com_example_nativeaudio_NativeAudio_createAssetAudioPlayer(JNIEnv*
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_SEEK, &fdPlayerSeek);
assert(SL_RESULT_SUCCESS == result);
// get the mute/solo interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_MUTESOLO, &fdPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
// get the volume interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_VOLUME, &fdPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
// enable whole file looping
result = (*fdPlayerSeek)->SetLoop(fdPlayerSeek, SL_BOOLEAN_TRUE, 0, SL_TIME_UNKNOWN);
assert(SL_RESULT_SUCCESS == result);
@@ -562,6 +721,8 @@ void Java_com_example_nativeaudio_NativeAudio_shutdown(JNIEnv* env, jclass clazz
bqPlayerPlay = NULL;
bqPlayerBufferQueue = NULL;
bqPlayerEffectSend = NULL;
bqPlayerMuteSolo = NULL;
bqPlayerVolume = NULL;
}
// destroy file descriptor audio player object, and invalidate all associated interfaces
@@ -570,6 +731,8 @@ void Java_com_example_nativeaudio_NativeAudio_shutdown(JNIEnv* env, jclass clazz
fdPlayerObject = NULL;
fdPlayerPlay = NULL;
fdPlayerSeek = NULL;
fdPlayerMuteSolo = NULL;
fdPlayerVolume = NULL;
}
// destroy URI audio player object, and invalidate all associated interfaces
@@ -578,6 +741,8 @@ void Java_com_example_nativeaudio_NativeAudio_shutdown(JNIEnv* env, jclass clazz
uriPlayerObject = NULL;
uriPlayerPlay = NULL;
uriPlayerSeek = NULL;
uriPlayerMuteSolo = NULL;
uriPlayerVolume = NULL;
}
// destroy audio recorder object, and invalidate all associated interfaces

View File

@@ -26,6 +26,11 @@
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/hello"
android:text="Hello"
@@ -44,6 +49,18 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/embedded_soundtrack"
android:text="Embedded\nsoundtrack"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/reverb"
android:text="Reverb"
@@ -51,14 +68,105 @@
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/embedded_soundtrack"
android:text="Embedded soundtrack"
android:id="@+id/mute_uri"
android:text="Mute"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/enable_stereo_position_uri"
android:text="Enable SP"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<Spinner
android:id="@+id/uri_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="URI spinner"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/uri_soundtrack"
android:text="URI soundtrack"
android:text="URI\nsoundtrack"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/pause_uri"
android:text="Pause\nURI"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/play_uri"
android:text="Play\nURI"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/loop_uri"
android:text="Loop\nURI"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<Button
android:id="@+id/mute_left_uri"
android:text="mute left"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/mute_right_uri"
android:text="mute right"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/solo_left_uri"
android:text="solo left"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/solo_right_uri"
android:text="solo right"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<Button
android:id="@+id/channels_uri"
android:text="Get channels"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<SeekBar
android:id="@+id/volume_uri"
android:text="Volume"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<SeekBar
android:id="@+id/pan_uri"
android:text="Pan"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

View File

@@ -19,4 +19,10 @@
<resources>
<string name="hello">Hello, Android using native audio!</string>
<string name="app_name">NativeAudio</string>
<string-array name="uri_spinner_array">
<item>http://upload.wikimedia.org/wikipedia/commons/6/6d/Banana.ogg</item>
<item>http://www.freesound.org/data/previews/18/18765_18799-lq.mp3</item>
</string-array>
</resources>

View File

@@ -19,24 +19,35 @@ package com.example.nativeaudio;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
//import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.Toast;
public class NativeAudio extends Activity {
//static final String TAG = "NativeAudio";
static final int CLIP_NONE = 0;
static final int CLIP_HELLO = 1;
static final int CLIP_ANDROID = 2;
static final int CLIP_SAWTOOTH = 3;
static final int CLIP_PLAYBACK = 4;
static final String URI = "http://upload.wikimedia.org/wikipedia/commons/6/6d/Banana.ogg";
static String URI;
static AssetManager assetManager;
static boolean isPlayingAsset = false;
static boolean isPlayingUri = false;
static int numChannelsUri = 0;
/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle icicle) {
@@ -50,6 +61,24 @@ public class NativeAudio extends Activity {
createEngine();
createBufferQueueAudioPlayer();
// initialize URI spinner
Spinner uriSpinner = (Spinner) findViewById(R.id.uri_spinner);
ArrayAdapter<CharSequence> uriAdapter = ArrayAdapter.createFromResource(
this, R.array.uri_spinner_array, android.R.layout.simple_spinner_item);
uriAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
uriSpinner.setAdapter(uriAdapter);
uriSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
URI = parent.getItemAtPosition(pos).toString();
}
public void onNothingSelected(AdapterView parent) {
URI = null;
}
});
// initialize button click handlers
((Button) findViewById(R.id.hello)).setOnClickListener(new OnClickListener() {
@@ -99,16 +128,122 @@ public class NativeAudio extends Activity {
((Button) findViewById(R.id.uri_soundtrack)).setOnClickListener(new OnClickListener() {
boolean created = false;
public void onClick(View view) {
if (!created) {
if (!created && URI != null) {
created = createUriAudioPlayer(URI);
}
if (created) {
isPlayingUri = !isPlayingUri;
setPlayingUriAudioPlayer(isPlayingUri);
}
}
});
((Button) findViewById(R.id.pause_uri)).setOnClickListener(new OnClickListener() {
public void onClick(View view) {
setPlayingUriAudioPlayer(false);
}
});
((Button) findViewById(R.id.play_uri)).setOnClickListener(new OnClickListener() {
public void onClick(View view) {
setPlayingUriAudioPlayer(true);
}
});
((Button) findViewById(R.id.loop_uri)).setOnClickListener(new OnClickListener() {
boolean isLooping = false;
public void onClick(View view) {
isLooping = !isLooping;
setLoopingUriAudioPlayer(isLooping);
}
});
((Button) findViewById(R.id.mute_left_uri)).setOnClickListener(new OnClickListener() {
boolean muted = false;
public void onClick(View view) {
muted = !muted;
setChannelMuteUriAudioPlayer(0, muted);
}
});
((Button) findViewById(R.id.mute_right_uri)).setOnClickListener(new OnClickListener() {
boolean muted = false;
public void onClick(View view) {
muted = !muted;
setChannelMuteUriAudioPlayer(1, muted);
}
});
((Button) findViewById(R.id.solo_left_uri)).setOnClickListener(new OnClickListener() {
boolean soloed = false;
public void onClick(View view) {
soloed = !soloed;
setChannelSoloUriAudioPlayer(0, soloed);
}
});
((Button) findViewById(R.id.solo_right_uri)).setOnClickListener(new OnClickListener() {
boolean soloed = false;
public void onClick(View view) {
soloed = !soloed;
setChannelSoloUriAudioPlayer(1, soloed);
}
});
((Button) findViewById(R.id.mute_uri)).setOnClickListener(new OnClickListener() {
boolean muted = false;
public void onClick(View view) {
muted = !muted;
setMuteUriAudioPlayer(muted);
}
});
((Button) findViewById(R.id.enable_stereo_position_uri)).setOnClickListener(
new OnClickListener() {
boolean enabled = false;
public void onClick(View view) {
enabled = !enabled;
enableStereoPositionUriAudioPlayer(enabled);
}
});
((Button) findViewById(R.id.channels_uri)).setOnClickListener(new OnClickListener() {
public void onClick(View view) {
if (numChannelsUri == 0) {
numChannelsUri = getNumChannelsUriAudioPlayer();
}
Toast.makeText(NativeAudio.this, "Channels: " + numChannelsUri,
Toast.LENGTH_SHORT).show();
}
});
((SeekBar) findViewById(R.id.volume_uri)).setOnSeekBarChangeListener(
new OnSeekBarChangeListener() {
int lastProgress = 100;
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
assert progress >= 0 && progress <= 100;
lastProgress = progress;
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
int attenuation = 100 - lastProgress;
int millibel = attenuation * -50;
setVolumeUriAudioPlayer(millibel);
}
});
((SeekBar) findViewById(R.id.pan_uri)).setOnSeekBarChangeListener(
new OnSeekBarChangeListener() {
int lastProgress = 100;
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
assert progress >= 0 && progress <= 100;
lastProgress = progress;
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
int permille = (lastProgress - 50) * 20;
setStereoPositionUriAudioPlayer(permille);
}
});
((Button) findViewById(R.id.record)).setOnClickListener(new OnClickListener() {
boolean created = false;
public void onClick(View view) {
@@ -155,9 +290,18 @@ public class NativeAudio extends Activity {
public static native void createEngine();
public static native void createBufferQueueAudioPlayer();
public static native boolean createAssetAudioPlayer(AssetManager assetManager, String filename);
// true == PLAYING, false == PAUSED
public static native void setPlayingAssetAudioPlayer(boolean isPlaying);
public static native boolean createUriAudioPlayer(String uri);
public static native void setPlayingUriAudioPlayer(boolean isPlaying);
public static native void setLoopingUriAudioPlayer(boolean isLooping);
public static native void setChannelMuteUriAudioPlayer(int chan, boolean mute);
public static native void setChannelSoloUriAudioPlayer(int chan, boolean solo);
public static native int getNumChannelsUriAudioPlayer();
public static native void setVolumeUriAudioPlayer(int millibel);
public static native void setMuteUriAudioPlayer(boolean mute);
public static native void enableStereoPositionUriAudioPlayer(boolean enable);
public static native void setStereoPositionUriAudioPlayer(int permille);
public static native boolean selectClip(int which, int count);
public static native boolean enableReverb(boolean enabled);
public static native boolean createAudioRecorder();