• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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 package org.hyphonate.megaaudio.player;
17 
18 import android.media.AudioFormat;
19 import android.media.AudioTimestamp;
20 import android.media.AudioTrack;
21 
22 import org.hyphonate.megaaudio.common.StreamBase;
23 
24 import java.util.ArrayList;
25 
26 /**
27  * An abstract class defining the common operations and attributes for all
28  * player (concrete) sub-classes.
29  */
30 public abstract class Player extends StreamBase {
31     private ArrayList<BufferCallback> mCallbacks = new ArrayList<BufferCallback>();
32 
Player(AudioSourceProvider sourceProvider)33     public Player(AudioSourceProvider sourceProvider) {
34         mSourceProvider = sourceProvider;
35     }
36 
37     /*
38      * Audio Source
39      */
40     protected AudioSourceProvider mSourceProvider;
41 
42     //
43     // Attributes
44     //
45     // This needs to be static because it is called before creating the Recorder subclass
calcMinBufferFrames(int channelCount, int sampleRate)46     public static int calcMinBufferFrames(int channelCount, int sampleRate) {
47         int channelMask = Player.channelCountToChannelMask(channelCount);
48         int bufferSizeInBytes =
49                 AudioTrack.getMinBufferSize (sampleRate,
50                         channelMask,
51                         AudioFormat.ENCODING_PCM_FLOAT);
52         return bufferSizeInBytes / sampleSizeInBytes(AudioFormat.ENCODING_PCM_FLOAT);
53     }
54 
55     /**
56      * @return The AudioSouce object associated with this player
57      */
getAudioSource()58     public abstract AudioSource getAudioSource();
59 
60     //
61     // Status
62     //
isPlaying()63     public abstract boolean isPlaying();
64 
65     /*
66      * Channel utils
67      */
68     // TODO Consider moving these to a "Utility" library.
69     /**
70      * @param channelCount  The number of channels for which to generate an output position mask.
71      * @return An output channel-position mask corresponding to the supplied number of channels.
72      */
channelCountToChannelMask(int channelCount)73     public static int channelCountToChannelMask(int channelCount) {
74         switch (channelCount) {
75             case 1:
76                 return AudioFormat.CHANNEL_OUT_MONO;
77 
78             case 2:
79                 return AudioFormat.CHANNEL_OUT_STEREO;
80 
81             case 3:
82                 return AudioFormat.CHANNEL_OUT_STEREO | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
83 
84             case 4:
85                 return AudioFormat.CHANNEL_OUT_QUAD;
86 
87             case 5: // 5.0
88                 return AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
89 
90             case 6: // 5.1
91                 return AudioFormat.CHANNEL_OUT_5POINT1;
92 
93             case 7: // 6.1
94                 return AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
95 
96             case 8:
97                 return AudioFormat.CHANNEL_OUT_7POINT1;
98 
99             default:
100                 return AudioTrack.ERROR_BAD_VALUE;
101         }
102     }
103 
104     //
105     // TimeStamp
106     //
107     /**
108      * Gets a timestamp from the audio stream
109      * @param timestamp
110      * @return
111      */
getTimestamp(AudioTimestamp timestamp)112     public abstract boolean getTimestamp(AudioTimestamp timestamp);
113 
114     //
115     // BufferCallback Stuff
116     //
117 
118     /**
119      * Defines an interface for buffer callback objects
120      */
121     public interface BufferCallback {
122         /**
123          * Called when player executes a pull() on the associated AudioSource
124          */
onPull()125         void onPull();
126     }
127 
128     /**
129      * Adds a callback object
130      * @param callback
131      */
addBufferCallback(BufferCallback callback)132     public void addBufferCallback(BufferCallback callback) {
133         mCallbacks.add(callback);
134     }
135 
136     /**
137      * Removes a previously added callback object
138      * @param callback
139      */
removeBufferCallback(BufferCallback callback)140     public void removeBufferCallback(BufferCallback callback) {
141         mCallbacks.remove(callback);
142     }
143 
144     /**
145      * Iterates through callback objects and calls their onPull() method.
146      */
onPull()147     public void onPull() {
148         for (BufferCallback callback : mCallbacks) {
149             callback.onPull();
150         }
151     }
152 }
153