• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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.mobileer.oboetester;
18 
19 import java.io.IOException;
20 
21 /**
22  * Base class for any audio input or output.
23  */
24 public abstract class AudioStreamBase {
25 
26     private StreamConfiguration mRequestedStreamConfiguration;
27     private StreamConfiguration mActualStreamConfiguration;
28     AudioStreamBase.DoubleStatistics mLatencyStatistics;
29 
30     private int mBufferSizeInFrames;
31 
getStreamStatus()32     public StreamStatus getStreamStatus() {
33         StreamStatus status = new StreamStatus();
34         status.bufferSize = getBufferSizeInFrames();
35         status.xRunCount = getXRunCount();
36         status.framesRead = getFramesRead();
37         status.framesWritten = getFramesWritten();
38         status.callbackCount = getCallbackCount();
39         status.latency = getLatency();
40         mLatencyStatistics.add(status.latency);
41         status.callbackTimeStr = getCallbackTimeStr();
42         status.cpuLoad = getCpuLoad();
43         status.state = getState();
44         return status;
45     }
46 
getLatencyStatistics()47     public DoubleStatistics getLatencyStatistics() {
48         return mLatencyStatistics;
49     }
50 
51     public static class DoubleStatistics {
52         private double sum;
53         private int count;
54         private double minimum = Double.MAX_VALUE;
55         private double maximum = Double.MIN_VALUE;
56 
add(double statistic)57         void add(double statistic) {
58             if (statistic <= 0.0) return;
59             sum += statistic;
60             count++;
61             minimum = Math.min(statistic, minimum);
62             maximum = Math.max(statistic, maximum);
63         }
64 
getAverage()65         double getAverage() {
66             return sum / count;
67         }
68 
dump()69         public String dump() {
70             if (count == 0) return "?";
71             return String.format("%3.1f/%3.1f/%3.1f ms", minimum, getAverage(), maximum);
72         }
73     }
74 
75     /**
76      * Changes dynamic at run-time.
77      */
78     public static class StreamStatus {
79         public int bufferSize;
80         public int xRunCount;
81         public long framesWritten;
82         public long framesRead;
83         public double latency; // msec
84         public int state;
85         public long callbackCount;
86         public int framesPerCallback;
87         public double cpuLoad;
88         public String callbackTimeStr;
89 
90         // These are constantly changing.
dump(int framesPerBurst)91         String dump(int framesPerBurst) {
92             if (bufferSize < 0 || framesWritten < 0) {
93                 return "idle";
94             }
95             StringBuffer buffer = new StringBuffer();
96 
97             buffer.append("time between callbacks = " + callbackTimeStr + "\n");
98 
99             buffer.append("written "
100                     + String.format("0x%08X", framesWritten)
101                     + " - read " + String.format("0x%08X", framesRead)
102                     + " = " + (framesWritten - framesRead) + " frames\n");
103 
104             String cpuLoadText = String.format("%2d%c", (int)(cpuLoad * 100), '%');
105             buffer.append(
106                     convertStateToString(state)
107                     + ", #cb=" + callbackCount
108                     + ", f/cb=" + String.format("%3d", framesPerCallback)
109                     + ", " + cpuLoadText + " cpu"
110                     + "\n");
111 
112             buffer.append("buffer size = ");
113             if (bufferSize < 0) {
114                 buffer.append("?");
115             } else {
116                 int numBuffers = bufferSize / framesPerBurst;
117                 int remainder = bufferSize - (numBuffers * framesPerBurst);
118                 buffer.append(bufferSize + " = (" + numBuffers + " * " + framesPerBurst + ") + " + remainder);
119             }
120             buffer.append(",   xRun# = " + ((xRunCount < 0) ? "?" : xRunCount));
121 
122             return buffer.toString();
123         }
124         /**
125          * Converts ints from Oboe index to human-readable stream state
126          */
convertStateToString(int stateId)127         private String convertStateToString(int stateId) {
128             final String[] STATE_ARRAY = {"Uninit.", "Unknown", "Open", "Starting", "Started",
129                     "Pausing", "Paused", "Flushing", "Flushed",
130                     "Stopping", "Stopped", "Closing", "Closed", "Disconn."};
131             if (stateId < 0 || stateId >= STATE_ARRAY.length) {
132                 return "Invalid - " + stateId;
133             }
134             return STATE_ARRAY[stateId];
135         }
136     }
137 
138     /**
139      *
140      * @param requestedConfiguration
141      * @param actualConfiguration
142      * @param bufferSizeInFrames
143      * @throws IOException
144      */
open(StreamConfiguration requestedConfiguration, StreamConfiguration actualConfiguration, int bufferSizeInFrames)145     public void open(StreamConfiguration requestedConfiguration,
146                      StreamConfiguration actualConfiguration,
147                      int bufferSizeInFrames) throws IOException {
148         mRequestedStreamConfiguration = requestedConfiguration;
149         mActualStreamConfiguration = actualConfiguration;
150         mBufferSizeInFrames = bufferSizeInFrames;
151         mLatencyStatistics = new AudioStreamBase.DoubleStatistics();
152     }
153 
isInput()154     public abstract boolean isInput();
155 
startPlayback()156     public void startPlayback() throws IOException {}
157 
stopPlayback()158     public void stopPlayback() throws IOException {}
159 
write(float[] buffer, int offset, int length)160     public abstract int write(float[] buffer, int offset, int length);
161 
close()162     public abstract void close();
163 
getChannelCount()164     public int getChannelCount() {
165         return mActualStreamConfiguration.getChannelCount();
166     }
167 
getSampleRate()168     public int getSampleRate() {
169         return mActualStreamConfiguration.getSampleRate();
170     }
171 
getFramesPerBurst()172     public int getFramesPerBurst() {
173         return mActualStreamConfiguration.getFramesPerBurst();
174     }
175 
getBufferCapacityInFrames()176     public int getBufferCapacityInFrames() {
177         return mBufferSizeInFrames;
178     }
179 
getBufferSizeInFrames()180     public int getBufferSizeInFrames() {
181         return mBufferSizeInFrames;
182     }
183 
setBufferSizeInFrames(int bufferSize)184     public int setBufferSizeInFrames(int bufferSize) {
185         throw new UnsupportedOperationException("bufferSize cannot be changed");
186     }
187 
getCallbackCount()188     public long getCallbackCount() { return -1; }
189 
getLastErrorCallbackResult()190     public int getLastErrorCallbackResult() { return 0; }
191 
getFramesWritten()192     public long getFramesWritten() { return -1; }
193 
getFramesRead()194     public long getFramesRead() { return -1; }
195 
getLatency()196     public double getLatency() { return -1.0; }
197 
getCpuLoad()198     public double getCpuLoad() { return 0.0; }
199 
getCallbackTimeStr()200     public String getCallbackTimeStr() { return "?"; };
201 
getState()202     public int getState() { return -1; }
203 
isThresholdSupported()204     public boolean isThresholdSupported() {
205         return false;
206     }
207 
setWorkload(double workload)208     public void setWorkload(double workload) {}
209 
getXRunCount()210     public abstract int getXRunCount();
211 
212 }
213