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