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 
17 #ifndef CTS_NATIVE_AUDIO_ANALYZER_H
18 #define CTS_NATIVE_AUDIO_ANALYZER_H
19 
20 #define LOG_TAG "NativeAudioAnalyzer"
21 #include <android/log.h>
22 
23 #ifndef MODULE_NAME
24 #define MODULE_NAME  "NativeAudioAnalyzer"
25 #endif
26 
27 #define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__)
28 #define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__)
29 #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__)
30 #define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, MODULE_NAME, __VA_ARGS__)
31 #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, MODULE_NAME, __VA_ARGS__)
32 #define ALOGF(...) __android_log_print(ANDROID_LOG_FATAL, MODULE_NAME, __VA_ARGS__)
33 
34 #include <aaudio/AAudio.h>
35 
36 #include "analyzer/LatencyAnalyzer.h"
37 
38 class NativeAudioAnalyzer {
39 public:
40 
41     /**
42      * Open the audio input and output streams.
43      * @return AAUDIO_OK or negative error
44      */
45     aaudio_result_t openAudio(int inputDeviceId, int outputDeviceId);
46 
47     /**
48      * Start the audio input and output streams.
49      * @return AAUDIO_OK or negative error
50      */
51     aaudio_result_t startAudio();
52 
53     /**
54      * Stop the audio input and output streams.
55      * @return AAUDIO_OK or negative error
56      */
57     aaudio_result_t stopAudio();
58 
59     /**
60      * Close the audio input and output streams.
61      * @return AAUDIO_OK or negative error
62      */
63     aaudio_result_t closeAudio();
64 
65     /**
66      * @return true if enough audio input has been recorded
67      */
68     bool isRecordingComplete();
69 
70     /**
71      * Analyze the input and measure the latency between output and input.
72      * @return AAUDIO_OK or negative error
73      */
74     int analyze();
75 
76     /**
77      * @return the measured latency in milliseconds
78      */
79     double getLatencyMillis();
80 
81     /**
82      * @return the sample rate (in Hz) used for the measurement signal
83      */
84     int getSampleRate();
85 
86     /**
87      * The confidence is based on a normalized correlation.
88      * It ranges from 0.0 to 1.0. Higher is better.
89      *
90      * @return the confidence in the latency result
91      */
92     double getConfidence();
93 
94     /**
95      * Returns true if the stream was successfully opened in low-latency mode.
96      */
97     bool isLowLatencyStream();
98 
99     /**
100      * Returns true if the hardware supports 24 bit audio.
101      */
102     bool has24BitHardwareSupport();
103 
104     /**
105      * Gets the hardware format.
106      */
107     int getHardwareFormat();
108 
getError()109     aaudio_result_t getError() {
110         return mInputError ? mInputError : mOutputError;
111     }
112 
113     double measureTimestampLatencyMillis();
114 
115     AAudioStream      *mInputStream = nullptr;
116     AAudioStream      *mOutputStream = nullptr;
117     aaudio_format_t    mActualInputFormat = AAUDIO_FORMAT_INVALID;
118     int16_t           *mInputShortData = nullptr;
119     float             *mInputFloatData = nullptr;
120     int32_t            mOutputSampleRate = 0;
121 
122     aaudio_result_t    mInputError = AAUDIO_OK;
123     aaudio_result_t    mOutputError = AAUDIO_OK;
124 
125 aaudio_data_callback_result_t dataCallbackProc(
126         void *audioData,
127         int32_t numFrames);
128 
129 private:
130 
131     int32_t readFormattedData(int32_t numFrames);
132 
133     bool has24BitSupport(aaudio_format_t format);
134 
135     WhiteNoiseLatencyAnalyzer mWhiteNoiseLatencyAnalyzer;
136     LoopbackProcessor   *mLoopbackProcessor;
137 
138     int32_t            mInputFramesMaximum = 0;
139     int32_t            mActualInputChannelCount = 0;
140     int32_t            mActualOutputChannelCount = 0;
141     int32_t            mNumCallbacksToDrain = kNumCallbacksToDrain;
142     int32_t            mNumCallbacksToNotRead = kNumCallbacksToNotRead;
143     int32_t            mNumCallbacksToDiscard = kNumCallbacksToDiscard;
144     int32_t            mMinNumFrames = INT32_MAX;
145     int32_t            mMaxNumFrames = 0;
146     int32_t            mInsufficientReadCount = 0;
147     int32_t            mInsufficientReadFrames = 0;
148     int32_t            mFramesReadTotal = 0;
149     int32_t            mFramesWrittenTotal = 0;
150     bool               mIsDone = false;
151     bool               mIsLowLatencyStream = false;
152     bool               mHas24BitHardwareSupport = false;
153     int32_t            mHardwareFormat = 0;
154 
155     int32_t            mOutputDeviceId = 0;
156     int32_t            mInputDeviceId = 0;
157 
158     std::atomic<bool> mWriteReadDeltaValid{false};
159     std::atomic<int64_t> mWriteReadDelta{0};
160 
161     static constexpr int kLogPeriodMillis         = 1000;
162     static constexpr int kNumInputChannels        = 1;
163     static constexpr int kNumCallbacksToDrain     = 20;
164     static constexpr int kNumCallbacksToNotRead   = 0; // let input fill back up
165     static constexpr int kNumCallbacksToDiscard   = 20;
166     static constexpr int kDefaultHangTimeMillis   = 50;
167     static constexpr int kMaxGlitchEventsToSave   = 32;
168     static constexpr int kDefaultOutputSizeBursts = 2;
169 };
170 
171 #endif // CTS_NATIVE_AUDIO_ANALYZER_H
172