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.AudioTimestamp;
19 import android.util.Log;
20 
21 public class OboePlayer extends Player {
22     @SuppressWarnings("unused")
23     private static final String TAG = OboePlayer.class.getSimpleName();
24     @SuppressWarnings("unused")
25     private static final boolean LOG = true;
26 
27     private int mPlayerSubtype;
28 
29     private long mNativePlayer;
30 
OboePlayer(PlayerBuilder builder, AudioSourceProvider sourceProvider, int playerSubtype)31     public OboePlayer(PlayerBuilder builder, AudioSourceProvider sourceProvider,
32                       int playerSubtype) {
33         super(sourceProvider);
34 
35         mPlayerSubtype = playerSubtype;
36         mAudioSource = mSourceProvider.getNativeSource();
37         if (mAudioSource != null) {
38             mNativePlayer = allocNativePlayer(
39                     ((NativeAudioSource) mAudioSource).getNativeObject(), mPlayerSubtype);
40         } else {
41             // No native source provided, so wrap a Java source in a native provider wrapper
42             mAudioSource = mSourceProvider.getJavaSource();
43             mNativePlayer = allocNativePlayer(
44                     JavaSourceProxy.allocNativeSource(mAudioSource), mPlayerSubtype);
45         }
46 
47         setupStream(builder);
48     }
49 
getNumBufferFrames()50     public int getNumBufferFrames() {
51         return getBufferFrameCountN(mNativePlayer);
52     }
53 
54     @Override
getRoutedDeviceId()55     public int getRoutedDeviceId() {
56         return getRoutedDeviceIdN(mNativePlayer);
57     }
58 
59     @Override
getSharingMode()60     public int getSharingMode() {
61         return getSharingModeN(mNativePlayer);
62     }
63 
64     @Override
getChannelCount()65     public int getChannelCount() {
66         return getChannelCountN(mNativePlayer);
67     }
68 
69     @Override
isMMap()70     public boolean isMMap() {
71         return isMMapN(mNativePlayer);
72     }
73 
setupStream(PlayerBuilder builder)74     private int setupStream(PlayerBuilder builder) {
75         mChannelCount = builder.getChannelCount();
76         mChannelMask = builder.getChannelMask();
77         mSampleRate = builder.getSampleRate();
78         mNumExchangeFrames = builder.getNumExchangeFrames();
79         mPerformanceMode = builder.getPerformanceMode();
80         mSharingMode = builder.getSharingMode();
81         int routeDeviceId = builder.getRouteDeviceId();
82         if (LOG) {
83             Log.d(TAG, "setupStream()");
84             Log.d(TAG, "  chans:" + mChannelCount);
85             Log.d(TAG, "  mask:0x" + Integer.toHexString(mChannelMask));
86             Log.d(TAG, "  rate: " + mSampleRate);
87             Log.d(TAG, "  frames: " + mNumExchangeFrames);
88             Log.d(TAG, "  perf mode: " + mPerformanceMode);
89             Log.d(TAG, "  route device: " + routeDeviceId);
90             Log.d(TAG, "  sharing mode: " + mSharingMode);
91         }
92         return setupStreamN(
93                 mNativePlayer, mChannelCount, mChannelMask, mSampleRate,
94                 mPerformanceMode, mSharingMode,
95                 routeDeviceId);
96     }
97 
98     @Override
teardownStream()99     public int teardownStream() {
100         int errCode = teardownStreamN(mNativePlayer);
101 
102         mChannelCount = 0;
103         mSampleRate = 0;
104 
105         return errCode;
106     }
107 
108     @Override
startStream()109     public int startStream() {
110         int retVal = startStreamN(mNativePlayer, mPlayerSubtype);
111         // TODO - Need Java constants defined for the C++ StreamBase.Result enum
112         mPlaying = retVal == 0;
113         return retVal;
114     }
115 
116     @Override
stopStream()117     public int stopStream() {
118         mPlaying = false;
119 
120         return stopN(mNativePlayer);
121     }
122 
123     /**
124      * Gets a timestamp from the audio stream
125      *
126      * @param timestamp
127      * @return
128      */
getTimestamp(AudioTimestamp timestamp)129     public boolean getTimestamp(AudioTimestamp timestamp) {
130         return getTimestampN(mNativePlayer, timestamp);
131     }
132 
getStreamState()133     public int getStreamState() {
134         return getStreamStateN(mNativePlayer);
135     }
136 
getLastErrorCallbackResult()137     public int getLastErrorCallbackResult() {
138         return getLastErrorCallbackResultN(mNativePlayer);
139     }
140 
allocNativePlayer(long nativeSource, int playerSubtype)141     private native long allocNativePlayer(long nativeSource, int playerSubtype);
142 
setupStreamN(long nativePlayer, int channelCount, int channelMask, int sampleRate, int performanceMode, int sharingMode, int routeDeviceId)143     private native int setupStreamN(long nativePlayer, int channelCount, int channelMask,
144                                     int sampleRate, int performanceMode, int sharingMode,
145                                     int routeDeviceId);
146 
teardownStreamN(long nativePlayer)147     private native int teardownStreamN(long nativePlayer);
148 
startStreamN(long nativePlayer, int playerSubtype)149     private native int startStreamN(long nativePlayer, int playerSubtype);
150 
stopN(long nativePlayer)151     private native int stopN(long nativePlayer);
152 
getBufferFrameCountN(long mNativePlayer)153     private native int getBufferFrameCountN(long mNativePlayer);
154 
getRoutedDeviceIdN(long nativePlayer)155     private native int getRoutedDeviceIdN(long nativePlayer);
156 
getSharingModeN(long nativePlayer)157     private native int getSharingModeN(long nativePlayer);
158 
getChannelCountN(long nativePlayer)159     private native int getChannelCountN(long nativePlayer);
160 
isMMapN(long nativePlayer)161     private native boolean isMMapN(long nativePlayer);
162 
getTimestampN(long nativePlayer, AudioTimestamp timestamp)163     private native boolean getTimestampN(long nativePlayer, AudioTimestamp timestamp);
164 
getStreamStateN(long nativePlayer)165     private native int getStreamStateN(long nativePlayer);
166 
getLastErrorCallbackResultN(long nativePlayer)167     private native int getLastErrorCallbackResultN(long nativePlayer);
168 }
169