1 /* 2 * Copyright 2019 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 #ifndef OBOETESTER_FULL_DUPLEX_STREAM_H 18 #define OBOETESTER_FULL_DUPLEX_STREAM_H 19 20 #include <unistd.h> 21 #include <sys/types.h> 22 23 #include "oboe/Oboe.h" 24 25 class FullDuplexStream : public oboe::AudioStreamCallback { 26 public: FullDuplexStream()27 FullDuplexStream() {} 28 virtual ~FullDuplexStream() = default; 29 setInputStream(oboe::AudioStream * stream)30 void setInputStream(oboe::AudioStream *stream) { 31 mInputStream = stream; 32 } 33 getInputStream()34 oboe::AudioStream *getInputStream() { 35 return mInputStream; 36 } 37 setOutputStream(oboe::AudioStream * stream)38 void setOutputStream(oboe::AudioStream *stream) { 39 mOutputStream = stream; 40 } getOutputStream()41 oboe::AudioStream *getOutputStream() { 42 return mOutputStream; 43 } 44 45 virtual oboe::Result start(); 46 47 virtual oboe::Result stop(); 48 49 /** 50 * Called when data is available on both streams. 51 * Caller should override this method. 52 */ 53 virtual oboe::DataCallbackResult onBothStreamsReady( 54 const void *inputData, 55 int numInputFrames, 56 void *outputData, 57 int numOutputFrames 58 ) = 0; 59 60 /** 61 * Called by Oboe when the stream is ready to process audio. 62 */ 63 oboe::DataCallbackResult onAudioReady( 64 oboe::AudioStream *audioStream, 65 void *audioData, 66 int numFrames) override; 67 68 int32_t getMNumInputBurstsCushion() const; 69 70 /** 71 * Number of bursts to leave in the input buffer as a cushion. 72 * Typically 0 for latency measurements 73 * or 1 for glitch tests. 74 * 75 * @param mNumInputBurstsCushion 76 */ 77 void setMNumInputBurstsCushion(int32_t mNumInputBurstsCushion); 78 setMinimumFramesBeforeRead(int32_t numFrames)79 void setMinimumFramesBeforeRead(int32_t numFrames) { 80 mMinimumFramesBeforeRead = numFrames; 81 } 82 getMinimumFramesBeforeRead()83 int32_t getMinimumFramesBeforeRead() const { 84 return mMinimumFramesBeforeRead; 85 } 86 87 private: 88 89 // TODO add getters and setters 90 static constexpr int32_t kNumCallbacksToDrain = 20; 91 static constexpr int32_t kNumCallbacksToDiscard = 30; 92 93 // let input fill back up, usually 0 or 1 94 int32_t mNumInputBurstsCushion = 0; 95 int32_t mMinimumFramesBeforeRead = 0; 96 97 // We want to reach a state where the input buffer is empty and 98 // the output buffer is full. 99 // These are used in order. 100 // Drain several callback so that input is empty. 101 int32_t mCountCallbacksToDrain = kNumCallbacksToDrain; 102 // Let the input fill back up slightly so we don't run dry. 103 int32_t mCountInputBurstsCushion = mNumInputBurstsCushion; 104 // Discard some callbacks so the input and output reach equilibrium. 105 int32_t mCountCallbacksToDiscard = kNumCallbacksToDiscard; 106 107 oboe::AudioStream *mInputStream = nullptr; 108 oboe::AudioStream *mOutputStream = nullptr; 109 110 int32_t mBufferSize = 0; 111 std::unique_ptr<float[]> mInputBuffer; 112 }; 113 114 115 #endif //OBOETESTER_FULL_DUPLEX_STREAM_H 116