1 /* 2 * Copyright (C) 2015 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.android.common.midi.synth; 18 19 import android.media.AudioFormat; 20 import android.media.AudioManager; 21 import android.media.AudioTrack; 22 import android.util.Log; 23 24 /** 25 * Simple base class for implementing audio output for examples. 26 * This can be sub-classed for experimentation or to redirect audio output. 27 */ 28 public class SimpleAudioOutput { 29 30 private static final String TAG = "AudioOutputTrack"; 31 public static final int SAMPLES_PER_FRAME = 2; 32 public static final int BYTES_PER_SAMPLE = 4; // float 33 public static final int BYTES_PER_FRAME = SAMPLES_PER_FRAME * BYTES_PER_SAMPLE; 34 private AudioTrack mAudioTrack; 35 private int mFrameRate; 36 37 /** 38 * 39 */ SimpleAudioOutput()40 public SimpleAudioOutput() { 41 super(); 42 } 43 44 /** 45 * Create an audio track then call play(). 46 * 47 * @param frameRate 48 */ start(int frameRate)49 public void start(int frameRate) { 50 stop(); 51 mFrameRate = frameRate; 52 mAudioTrack = createAudioTrack(frameRate); 53 // AudioTrack will wait until it has enough data before starting. 54 mAudioTrack.play(); 55 } 56 createAudioTrack(int frameRate)57 public AudioTrack createAudioTrack(int frameRate) { 58 int minBufferSizeBytes = AudioTrack.getMinBufferSize(frameRate, 59 AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_FLOAT); 60 Log.i(TAG, "AudioTrack.minBufferSize = " + minBufferSizeBytes 61 + " bytes = " + (minBufferSizeBytes / BYTES_PER_FRAME) 62 + " frames"); 63 int bufferSize = 8 * minBufferSizeBytes / 8; 64 int outputBufferSizeFrames = bufferSize / BYTES_PER_FRAME; 65 Log.i(TAG, "actual bufferSize = " + bufferSize + " bytes = " 66 + outputBufferSizeFrames + " frames"); 67 68 AudioTrack player = new AudioTrack(AudioManager.STREAM_MUSIC, 69 mFrameRate, AudioFormat.CHANNEL_OUT_STEREO, 70 AudioFormat.ENCODING_PCM_FLOAT, bufferSize, 71 AudioTrack.MODE_STREAM); 72 Log.i(TAG, "created AudioTrack"); 73 return player; 74 } 75 write(float[] buffer, int offset, int length)76 public int write(float[] buffer, int offset, int length) { 77 return mAudioTrack.write(buffer, offset, length, 78 AudioTrack.WRITE_BLOCKING); 79 } 80 stop()81 public void stop() { 82 if (mAudioTrack != null) { 83 mAudioTrack.stop(); 84 mAudioTrack = null; 85 } 86 } 87 getFrameRate()88 public int getFrameRate() { 89 return mFrameRate; 90 } 91 getAudioTrack()92 public AudioTrack getAudioTrack() { 93 return mAudioTrack; 94 } 95 } 96