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.google.sample.oboe.manualtest; 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 29 private int mBufferSizeInFrames; 30 getStreamStatus()31 public StreamStatus getStreamStatus() { 32 StreamStatus status = new StreamStatus(); 33 status.bufferSize = getBufferSizeInFrames(); 34 status.xRunCount = getXRunCount(); 35 status.framesRead = getFramesRead(); 36 status.framesWritten = getFramesWritten(); 37 status.callbackCount = getCallbackCount(); 38 status.latency = getLatency(); 39 status.cpuLoad = getCpuLoad(); 40 status.state = getState(); 41 return status; 42 } 43 44 /** 45 * Changes dynamic at run-time. 46 */ 47 public static class StreamStatus { 48 public int bufferSize; 49 public int xRunCount; 50 public long framesWritten; 51 public long framesRead; 52 public double latency; // msec 53 public int state; 54 public long callbackCount; 55 public int framesPerCallback; 56 public double cpuLoad; 57 58 // These are constantly changing. dump(int framesPerBurst)59 String dump(int framesPerBurst) { 60 if (bufferSize < 0 || framesWritten < 0) { 61 return "idle"; 62 } 63 StringBuffer buffer = new StringBuffer(); 64 65 buffer.append("frames written " + framesWritten + " - read " + framesRead 66 + " = " + (framesWritten - framesRead) + "\n"); 67 68 String latencyText = (latency < 0.0) 69 ? "?" 70 : String.format("%6.1f ms", latency); 71 String cpuLoadText = String.format("%2d%c", (int)(cpuLoad * 100), '%'); 72 buffer.append( 73 convertStateToString(state) 74 + ", #cb=" + callbackCount 75 + ", f/cb=" + String.format("%3d", framesPerCallback) 76 + ", latnc = " + latencyText 77 + ", " + cpuLoadText + " cpu" 78 + "\n"); 79 80 buffer.append("buffer size = "); 81 if (bufferSize < 0) { 82 buffer.append("?"); 83 } else { 84 int numBuffers = bufferSize / framesPerBurst; 85 int remainder = bufferSize - (numBuffers * framesPerBurst); 86 buffer.append(bufferSize + " = (" + numBuffers + " * " + framesPerBurst + ") + " + remainder); 87 } 88 buffer.append(", xRun# = " + ((xRunCount < 0) ? "?" : xRunCount) + "\n"); 89 90 return buffer.toString(); 91 } 92 /** 93 * Converts ints from Oboe index to human-readable stream state 94 */ convertStateToString(int stateId)95 private String convertStateToString(int stateId) { 96 final String[] STATE_ARRAY = {"Uninit.", "Unknown", "Open", "Starting", "Started", 97 "Pausing", "Paused", "Flushing", "Flushed", 98 "Stopping", "Stopped", "Closing", "Closed", "Disconn."}; 99 if (stateId < 0 || stateId >= STATE_ARRAY.length) { 100 return "Invalid - " + stateId; 101 } 102 return STATE_ARRAY[stateId]; 103 } 104 } 105 106 /** 107 * 108 * @param requestedConfiguration 109 * @param actualConfiguration 110 * @param bufferSizeInFrames 111 * @throws IOException 112 */ open(StreamConfiguration requestedConfiguration, StreamConfiguration actualConfiguration, int bufferSizeInFrames)113 public void open(StreamConfiguration requestedConfiguration, 114 StreamConfiguration actualConfiguration, 115 int bufferSizeInFrames) throws IOException { 116 mRequestedStreamConfiguration = requestedConfiguration; 117 mActualStreamConfiguration = actualConfiguration; 118 mBufferSizeInFrames = bufferSizeInFrames; 119 } 120 isInput()121 public abstract boolean isInput(); 122 startPlayback()123 public void startPlayback() throws IOException {} 124 stopPlayback()125 public void stopPlayback() throws IOException {} 126 write(float[] buffer, int offset, int length)127 public abstract int write(float[] buffer, int offset, int length); 128 close()129 public abstract void close(); 130 getChannelCount()131 public int getChannelCount() { 132 return mActualStreamConfiguration.getChannelCount(); 133 } 134 getSampleRate()135 public int getSampleRate() { 136 return mActualStreamConfiguration.getSampleRate(); 137 } 138 getFramesPerBurst()139 public int getFramesPerBurst() { 140 return mActualStreamConfiguration.getFramesPerBurst(); 141 } 142 getBufferCapacityInFrames()143 public int getBufferCapacityInFrames() { 144 return mBufferSizeInFrames; 145 } 146 getBufferSizeInFrames()147 public int getBufferSizeInFrames() { 148 return mBufferSizeInFrames; 149 } 150 setBufferSizeInFrames(int bufferSize)151 public int setBufferSizeInFrames(int bufferSize) { 152 throw new UnsupportedOperationException("bufferSize cannot be changed"); 153 } 154 getCallbackCount()155 public long getCallbackCount() { return -1; } 156 getFramesWritten()157 public long getFramesWritten() { return -1; } 158 getFramesRead()159 public long getFramesRead() { return -1; } 160 getLatency()161 public double getLatency() { return -1.0; } 162 getCpuLoad()163 public double getCpuLoad() { return 0.0; } 164 getState()165 public int getState() { return -1; } 166 isThresholdSupported()167 public boolean isThresholdSupported() { 168 return false; 169 } 170 setWorkload(double workload)171 public void setWorkload(double workload) {} 172 getXRunCount()173 public abstract int getXRunCount(); 174 175 176 } 177