• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.google.sample.oboe.manualtest;
18 
19 import android.content.Intent;
20 import android.os.Bundle;
21 import android.os.Handler;
22 import android.os.Looper;
23 import android.util.Log;
24 import android.widget.SeekBar;
25 import android.widget.TextView;
26 
27 import java.io.IOException;
28 
29 public class ManualGlitchActivity extends GlitchActivity {
30 
31     public static final String KEY_IN_PERF = "in_perf";
32     public static final String KEY_OUT_PERF = "out_perf";
33     public static final String VALUE_PERF_LOW_LATENCY = "lowlat";
34     public static final String VALUE_PERF_POWERSAVE = "powersave";
35     public static final String VALUE_PERF_NONE = "none";
36 
37     public static final String KEY_IN_SHARING = "in_sharing";
38     public static final String KEY_OUT_SHARING = "out_sharing";
39     public static final String VALUE_SHARING_EXCLUSIVE = "exclusive";
40     public static final String VALUE_SHARING_SHARED = "shared";
41 
42     public static final String KEY_SAMPLE_RATE = "sample_rate";
43     public static final int VALUE_DEFAULT_SAMPLE_RATE = 48000;
44 
45     public static final String KEY_IN_PRESET = "in_preset";
46 
47     public static final String KEY_IN_CHANNELS = "in_channels";
48     public static final String KEY_OUT_CHANNELS = "out_channels";
49     public static final int VALUE_DEFAULT_CHANNELS = 2;
50 
51     public static final String KEY_DURATION = "duration";
52     public static final int VALUE_DEFAULT_DURATION = 10;
53 
54     public static final String KEY_BUFFER_BURSTS = "buffer_bursts";
55     public static final int VALUE_DEFAULT_BUFFER_BURSTS = 2;
56 
57     public static final String KEY_TOLERANCE = "tolerance";
58     private static final float DEFAULT_TOLERANCE = 0.1f;
59 
60     private TextView mTextTolerance;
61     private SeekBar mFaderTolerance;
62     protected ExponentialTaper mTaperTolerance;
63     private WaveformView mWaveformView;
64     private float[] mWaveform = new float[256];
65     private boolean mTestRunningByIntent;
66     private Bundle mBundleFromIntent;
67 
68     private float   mTolerance = DEFAULT_TOLERANCE;
69 
70     private SeekBar.OnSeekBarChangeListener mToleranceListener = new SeekBar.OnSeekBarChangeListener() {
71         @Override
72         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
73             setToleranceProgress(progress);
74         }
75 
76         @Override
77         public void onStartTrackingTouch(SeekBar seekBar) {
78         }
79 
80         @Override
81         public void onStopTrackingTouch(SeekBar seekBar) {
82         }
83     };
84 
setToleranceProgress(int progress)85     protected void setToleranceProgress(int progress) {
86         float tolerance = (float) mTaperTolerance.linearToExponential(
87                 ((double)progress) / FADER_PROGRESS_MAX);
88         setTolerance(tolerance);
89         mTextTolerance.setText("Tolerance = " + String.format("%5.3f", tolerance));
90     }
91 
92     @Override
onCreate(Bundle savedInstanceState)93     protected void onCreate(Bundle savedInstanceState) {
94         super.onCreate(savedInstanceState);
95         mBundleFromIntent = getIntent().getExtras();
96 
97         mTextTolerance = (TextView) findViewById(R.id.textTolerance);
98         mFaderTolerance = (SeekBar) findViewById(R.id.faderTolerance);
99         mTaperTolerance = new ExponentialTaper(0.0, 0.5, 100.0);
100         mFaderTolerance.setOnSeekBarChangeListener(mToleranceListener);
101         setToleranceFader(DEFAULT_TOLERANCE);
102 
103         mWaveformView = (WaveformView) findViewById(R.id.waveview_audio);
104     }
105 
setToleranceFader(float tolerance)106     private void setToleranceFader(float tolerance) {
107         int progress = (int) Math.round((mTaperTolerance.exponentialToLinear(
108                 tolerance) * FADER_PROGRESS_MAX));
109         mFaderTolerance.setProgress(progress);
110     }
111 
112     @Override
inflateActivity()113     protected void inflateActivity() {
114         setContentView(R.layout.activity_manual_glitches);
115     }
116 
117     @Override
onResume()118     public void onResume(){
119         super.onResume();
120         processBundleFromIntent();
121     }
122 
123     @Override
onNewIntent(Intent intent)124     public void onNewIntent(Intent intent) {
125         mBundleFromIntent = intent.getExtras();
126     }
127 
processBundleFromIntent()128     private void processBundleFromIntent() {
129         if (mBundleFromIntent == null) {
130             return;
131         }
132         if (mTestRunningByIntent) {
133             return;
134         }
135 
136         mResultFileName = null;
137         if (mBundleFromIntent.containsKey(KEY_FILE_NAME)) {
138             mTestRunningByIntent = true;
139             mResultFileName = mBundleFromIntent.getString(KEY_FILE_NAME);
140 
141             // Delay the test start to avoid race conditions.
142             Handler handler = new Handler(Looper.getMainLooper()); // UI thread
143             handler.postDelayed(new Runnable() {
144                 @Override
145                 public void run() {
146                     startAutomaticTest();
147                 }
148             }, 500); // TODO where is the race, close->open?
149 
150         }
151     }
152 
getPerfFromText(String text)153     private int getPerfFromText(String text) {
154         if (VALUE_PERF_NONE.equals(text)) {
155             return StreamConfiguration.PERFORMANCE_MODE_NONE;
156         } else if (VALUE_PERF_POWERSAVE.equals(text)) {
157             return StreamConfiguration.PERFORMANCE_MODE_POWER_SAVING;
158         } else {
159             return StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY;
160         }
161     }
162 
getSharingFromText(String text)163     private int getSharingFromText(String text) {
164         if (VALUE_SHARING_SHARED.equals(text)) {
165             return StreamConfiguration.SHARING_MODE_SHARED;
166         } else {
167             return StreamConfiguration.SHARING_MODE_EXCLUSIVE;
168         }
169     }
170 
configureStreamsFromBundle(Bundle bundle)171     void configureStreamsFromBundle(Bundle bundle) {
172 
173         // Configure settings
174         StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
175         StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
176 
177         requestedInConfig.reset();
178         requestedOutConfig.reset();
179 
180         configureStreamsFromBundleForApi(bundle);
181 
182         // Extract parameters from the bundle.
183         String text = bundle.getString(KEY_IN_PERF, VALUE_PERF_LOW_LATENCY);
184         int perfMode = getPerfFromText(text);
185         requestedInConfig.setPerformanceMode(perfMode);
186 
187         text = bundle.getString(KEY_OUT_PERF, VALUE_PERF_LOW_LATENCY);
188         perfMode = getPerfFromText(text);
189         requestedOutConfig.setPerformanceMode(perfMode);
190 
191         text = bundle.getString(KEY_IN_SHARING, VALUE_SHARING_EXCLUSIVE);
192         int sharingMode = getSharingFromText(text);
193         requestedInConfig.setSharingMode(sharingMode);
194         text = bundle.getString(KEY_OUT_SHARING, VALUE_SHARING_EXCLUSIVE);
195         sharingMode = getSharingFromText(text);
196         requestedOutConfig.setSharingMode(sharingMode);
197 
198         int sampleRate = bundle.getInt(KEY_SAMPLE_RATE, VALUE_DEFAULT_SAMPLE_RATE);
199         requestedInConfig.setSampleRate(sampleRate);
200         requestedOutConfig.setSampleRate(sampleRate);
201 
202         float tolerance = bundle.getFloat(KEY_TOLERANCE, DEFAULT_TOLERANCE);
203         setToleranceFader(tolerance);
204         setTolerance(tolerance);
205         mTolerance = tolerance;
206 
207         int inChannels = bundle.getInt(KEY_IN_CHANNELS, VALUE_DEFAULT_CHANNELS);
208         requestedInConfig.setChannelCount(inChannels);
209         int outChannels = bundle.getInt(KEY_OUT_CHANNELS, VALUE_DEFAULT_CHANNELS);
210         requestedOutConfig.setChannelCount(outChannels);
211 
212         String defaultText = StreamConfiguration.convertInputPresetToText(
213                 StreamConfiguration.INPUT_PRESET_VOICE_RECOGNITION);
214         text = bundle.getString(KEY_IN_PRESET, defaultText);
215         int inputPreset = StreamConfiguration.convertTextToInputPreset(text);
216         requestedInConfig.setInputPreset(inputPreset);
217     }
218 
startAudioTest()219     public void startAudioTest() throws IOException {
220         super.startAudioTest();
221         setToleranceProgress(mFaderTolerance.getProgress());
222     }
223 
startAutomaticTest()224     void startAutomaticTest() {
225         configureStreamsFromBundle(mBundleFromIntent);
226 
227         int durationSeconds = mBundleFromIntent.getInt(KEY_DURATION, VALUE_DEFAULT_DURATION);
228         int numBursts = mBundleFromIntent.getInt(KEY_BUFFER_BURSTS, VALUE_DEFAULT_BUFFER_BURSTS);
229         mBundleFromIntent = null;
230 
231         try {
232             onStartAudioTest(null);
233             int sizeFrames = mAudioOutTester.getCurrentAudioStream().getFramesPerBurst() * numBursts;
234             mAudioOutTester.getCurrentAudioStream().setBufferSizeInFrames(sizeFrames);
235 
236             // Schedule the end of the test.
237             Handler handler = new Handler(Looper.getMainLooper()); // UI thread
238             handler.postDelayed(new Runnable() {
239                 @Override
240                 public void run() {
241                     stopAutomaticTest();
242                 }
243             }, durationSeconds * 1000);
244         } catch (IOException e) {
245             String report = "Open failed: " + e.getMessage();
246             maybeWriteTestResult(report);
247             mTestRunningByIntent = false;
248         }
249 
250     }
251 
stopAutomaticTest()252     void stopAutomaticTest() {
253         String report = getCommonTestReport()
254                 + String.format("tolerance = %5.3f\n", mTolerance)
255                 + mLastGlitchReport;
256         onStopAudioTest(null);
257         maybeWriteTestResult(report);
258         mTestRunningByIntent = false;
259     }
260 
261     // Only call from UI thread.
262     @Override
onTestFinished()263     public void onTestFinished() {
264         super.onTestFinished();
265     }
266     // Only call from UI thread.
267     @Override
onTestBegan()268     public void onTestBegan() {
269         mWaveformView.clearSampleData();
270         mWaveformView.postInvalidate();
271         super.onTestBegan();
272     }
273 
274     // Called on UI thread
275     @Override
onGlitchDetected()276     protected void onGlitchDetected() {
277         int numSamples = getGlitch(mWaveform);
278         mWaveformView.setSampleData(mWaveform, 0, numSamples);
279         mWaveformView.postInvalidate();
280     }
281 
getGlitchWaveform()282     private float[] getGlitchWaveform() {
283         return mWaveform;
284     }
285 
getGlitch(float[] mWaveform)286     private native int getGlitch(float[] mWaveform);
287 
288 }
289