1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.nativeaudio; 18 19 import android.app.Activity; 20 import android.content.res.AssetManager; 21 import android.os.Bundle; 22 //import android.util.Log; 23 import android.view.View; 24 import android.view.View.OnClickListener; 25 import android.widget.AdapterView; 26 import android.widget.ArrayAdapter; 27 import android.widget.Button; 28 import android.widget.SeekBar; 29 import android.widget.SeekBar.OnSeekBarChangeListener; 30 import android.widget.Spinner; 31 import android.widget.Toast; 32 33 public class NativeAudio extends Activity { 34 35 //static final String TAG = "NativeAudio"; 36 37 static final int CLIP_NONE = 0; 38 static final int CLIP_HELLO = 1; 39 static final int CLIP_ANDROID = 2; 40 static final int CLIP_SAWTOOTH = 3; 41 static final int CLIP_PLAYBACK = 4; 42 43 static String URI; 44 static AssetManager assetManager; 45 46 static boolean isPlayingAsset = false; 47 static boolean isPlayingUri = false; 48 49 static int numChannelsUri = 0; 50 51 /** Called when the activity is first created. */ 52 @Override 53 protected void onCreate(Bundle icicle) { 54 super.onCreate(icicle); 55 setContentView(R.layout.main); 56 57 assetManager = getAssets(); 58 59 // initialize native audio system 60 61 createEngine(); 62 createBufferQueueAudioPlayer(); 63 64 // initialize URI spinner 65 Spinner uriSpinner = (Spinner) findViewById(R.id.uri_spinner); 66 ArrayAdapter<CharSequence> uriAdapter = ArrayAdapter.createFromResource( 67 this, R.array.uri_spinner_array, android.R.layout.simple_spinner_item); 68 uriAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 69 uriSpinner.setAdapter(uriAdapter); 70 uriSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 71 72 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 73 URI = parent.getItemAtPosition(pos).toString(); 74 } 75 76 public void onNothingSelected(AdapterView parent) { 77 URI = null; 78 } 79 80 }); 81 82 // initialize button click handlers 83 84 ((Button) findViewById(R.id.hello)).setOnClickListener(new OnClickListener() { 85 public void onClick(View view) { 86 // ignore the return value 87 selectClip(CLIP_HELLO, 5); 88 } 89 }); 90 91 ((Button) findViewById(R.id.android)).setOnClickListener(new OnClickListener() { 92 public void onClick(View view) { 93 // ignore the return value 94 selectClip(CLIP_ANDROID, 7); 95 } 96 }); 97 98 ((Button) findViewById(R.id.sawtooth)).setOnClickListener(new OnClickListener() { 99 public void onClick(View view) { 100 // ignore the return value 101 selectClip(CLIP_SAWTOOTH, 1); 102 } 103 }); 104 105 ((Button) findViewById(R.id.reverb)).setOnClickListener(new OnClickListener() { 106 boolean enabled = false; 107 public void onClick(View view) { 108 enabled = !enabled; 109 if (!enableReverb(enabled)) { 110 enabled = !enabled; 111 } 112 } 113 }); 114 115 ((Button) findViewById(R.id.embedded_soundtrack)).setOnClickListener(new OnClickListener() { 116 boolean created = false; 117 public void onClick(View view) { 118 if (!created) { 119 created = createAssetAudioPlayer(assetManager, "background.mp3"); 120 } 121 if (created) { 122 isPlayingAsset = !isPlayingAsset; 123 setPlayingAssetAudioPlayer(isPlayingAsset); 124 } 125 } 126 }); 127 128 ((Button) findViewById(R.id.uri_soundtrack)).setOnClickListener(new OnClickListener() { 129 boolean created = false; 130 public void onClick(View view) { 131 if (!created && URI != null) { 132 created = createUriAudioPlayer(URI); 133 } 134 } 135 }); 136 137 ((Button) findViewById(R.id.pause_uri)).setOnClickListener(new OnClickListener() { 138 public void onClick(View view) { 139 setPlayingUriAudioPlayer(false); 140 } 141 }); 142 143 ((Button) findViewById(R.id.play_uri)).setOnClickListener(new OnClickListener() { 144 public void onClick(View view) { 145 setPlayingUriAudioPlayer(true); 146 } 147 }); 148 149 ((Button) findViewById(R.id.loop_uri)).setOnClickListener(new OnClickListener() { 150 boolean isLooping = false; 151 public void onClick(View view) { 152 isLooping = !isLooping; 153 setLoopingUriAudioPlayer(isLooping); 154 } 155 }); 156 157 ((Button) findViewById(R.id.mute_left_uri)).setOnClickListener(new OnClickListener() { 158 boolean muted = false; 159 public void onClick(View view) { 160 muted = !muted; 161 setChannelMuteUriAudioPlayer(0, muted); 162 } 163 }); 164 165 ((Button) findViewById(R.id.mute_right_uri)).setOnClickListener(new OnClickListener() { 166 boolean muted = false; 167 public void onClick(View view) { 168 muted = !muted; 169 setChannelMuteUriAudioPlayer(1, muted); 170 } 171 }); 172 173 ((Button) findViewById(R.id.solo_left_uri)).setOnClickListener(new OnClickListener() { 174 boolean soloed = false; 175 public void onClick(View view) { 176 soloed = !soloed; 177 setChannelSoloUriAudioPlayer(0, soloed); 178 } 179 }); 180 181 ((Button) findViewById(R.id.solo_right_uri)).setOnClickListener(new OnClickListener() { 182 boolean soloed = false; 183 public void onClick(View view) { 184 soloed = !soloed; 185 setChannelSoloUriAudioPlayer(1, soloed); 186 } 187 }); 188 189 ((Button) findViewById(R.id.mute_uri)).setOnClickListener(new OnClickListener() { 190 boolean muted = false; 191 public void onClick(View view) { 192 muted = !muted; 193 setMuteUriAudioPlayer(muted); 194 } 195 }); 196 197 ((Button) findViewById(R.id.enable_stereo_position_uri)).setOnClickListener( 198 new OnClickListener() { 199 boolean enabled = false; 200 public void onClick(View view) { 201 enabled = !enabled; 202 enableStereoPositionUriAudioPlayer(enabled); 203 } 204 }); 205 206 ((Button) findViewById(R.id.channels_uri)).setOnClickListener(new OnClickListener() { 207 public void onClick(View view) { 208 if (numChannelsUri == 0) { 209 numChannelsUri = getNumChannelsUriAudioPlayer(); 210 } 211 Toast.makeText(NativeAudio.this, "Channels: " + numChannelsUri, 212 Toast.LENGTH_SHORT).show(); 213 } 214 }); 215 216 ((SeekBar) findViewById(R.id.volume_uri)).setOnSeekBarChangeListener( 217 new OnSeekBarChangeListener() { 218 int lastProgress = 100; 219 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 220 assert progress >= 0 && progress <= 100; 221 lastProgress = progress; 222 } 223 public void onStartTrackingTouch(SeekBar seekBar) { 224 } 225 public void onStopTrackingTouch(SeekBar seekBar) { 226 int attenuation = 100 - lastProgress; 227 int millibel = attenuation * -50; 228 setVolumeUriAudioPlayer(millibel); 229 } 230 }); 231 232 ((SeekBar) findViewById(R.id.pan_uri)).setOnSeekBarChangeListener( 233 new OnSeekBarChangeListener() { 234 int lastProgress = 100; 235 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 236 assert progress >= 0 && progress <= 100; 237 lastProgress = progress; 238 } 239 public void onStartTrackingTouch(SeekBar seekBar) { 240 } 241 public void onStopTrackingTouch(SeekBar seekBar) { 242 int permille = (lastProgress - 50) * 20; 243 setStereoPositionUriAudioPlayer(permille); 244 } 245 }); 246 247 ((Button) findViewById(R.id.record)).setOnClickListener(new OnClickListener() { 248 boolean created = false; 249 public void onClick(View view) { 250 if (!created) { 251 created = createAudioRecorder(); 252 } 253 if (created) { 254 startRecording(); 255 } 256 } 257 }); 258 259 ((Button) findViewById(R.id.playback)).setOnClickListener(new OnClickListener() { 260 public void onClick(View view) { 261 // ignore the return value 262 selectClip(CLIP_PLAYBACK, 3); 263 } 264 }); 265 266 } 267 268 /** Called when the activity is about to be destroyed. */ 269 @Override 270 protected void onPause() 271 { 272 // turn off all audio 273 selectClip(CLIP_NONE, 0); 274 isPlayingAsset = false; 275 setPlayingAssetAudioPlayer(false); 276 isPlayingUri = false; 277 setPlayingUriAudioPlayer(false); 278 super.onPause(); 279 } 280 281 /** Called when the activity is about to be destroyed. */ 282 @Override 283 protected void onDestroy() 284 { 285 shutdown(); 286 super.onDestroy(); 287 } 288 289 /** Native methods, implemented in jni folder */ 290 public static native void createEngine(); 291 public static native void createBufferQueueAudioPlayer(); 292 public static native boolean createAssetAudioPlayer(AssetManager assetManager, String filename); 293 // true == PLAYING, false == PAUSED 294 public static native void setPlayingAssetAudioPlayer(boolean isPlaying); 295 public static native boolean createUriAudioPlayer(String uri); 296 public static native void setPlayingUriAudioPlayer(boolean isPlaying); 297 public static native void setLoopingUriAudioPlayer(boolean isLooping); 298 public static native void setChannelMuteUriAudioPlayer(int chan, boolean mute); 299 public static native void setChannelSoloUriAudioPlayer(int chan, boolean solo); 300 public static native int getNumChannelsUriAudioPlayer(); 301 public static native void setVolumeUriAudioPlayer(int millibel); 302 public static native void setMuteUriAudioPlayer(boolean mute); 303 public static native void enableStereoPositionUriAudioPlayer(boolean enable); 304 public static native void setStereoPositionUriAudioPlayer(int permille); 305 public static native boolean selectClip(int which, int count); 306 public static native boolean enableReverb(boolean enabled); 307 public static native boolean createAudioRecorder(); 308 public static native void startRecording(); 309 public static native void shutdown(); 310 311 /** Load jni .so on initialization */ 312 static { 313 System.loadLibrary("native-audio-jni"); 314 } 315 316 } 317