1*05767d91SRobert Wu[Home](README.md) 2*05767d91SRobert Wu 3*05767d91SRobert Wu# Automated Testing 4*05767d91SRobert Wu 5*05767d91SRobert WuOboeTester can be used to measure the round trip latency and glitches. 6*05767d91SRobert WuIt can be launched from a shell script by using an Android Intent. 7*05767d91SRobert Wu 8*05767d91SRobert WuBefore running the app from an Intent, it should be launched manually and a Round Trip Latency test run. Then you can give permission for using the microphone to record the looped back sound, and give permission to write to external storage for saving the test result. 9*05767d91SRobert Wu 10*05767d91SRobert Wu## Requirements 11*05767d91SRobert Wu 12*05767d91SRobert WuAll tests require: 13*05767d91SRobert Wu 14*05767d91SRobert Wu* host computer 15*05767d91SRobert Wu* ADB installed 16*05767d91SRobert Wu* ADB USB cable 17*05767d91SRobert Wu 18*05767d91SRobert WuThe latency, glitch and data_paths tests also need: 19*05767d91SRobert Wu 20*05767d91SRobert Wu* [loopback adapter](https://source.android.com/devices/audio/latency/loopback) 21*05767d91SRobert Wu* a 3.5 mm jack on the phone* 22*05767d91SRobert Wu 23*05767d91SRobert Wu\* If you don't have a 3.5 mm jack then you can use a USB-C to 3.5mm adapter. 24*05767d91SRobert WuIn order to use ADB at the same time you will also need a USB switching device 25*05767d91SRobert Wuor use ADB/Wifi. 26*05767d91SRobert Wu 27*05767d91SRobert Wu## Start App from Intent 28*05767d91SRobert Wu 29*05767d91SRobert WuThe app can be started by sending a Start comment to the OboeTester class. 30*05767d91SRobert WuThe app will run and the results will be written to a file. 31*05767d91SRobert Wu 32*05767d91SRobert Wu adb shell am start -n com.mobileer.oboetester/.MainActivity {parameters} 33*05767d91SRobert Wu 34*05767d91SRobert WuString parameters are sent using: 35*05767d91SRobert Wu 36*05767d91SRobert Wu --es {parameterName} {parameterValue} 37*05767d91SRobert Wu 38*05767d91SRobert WuFor example: 39*05767d91SRobert Wu 40*05767d91SRobert Wu --es test latency 41*05767d91SRobert Wu 42*05767d91SRobert WuInteger parameters are sent using: 43*05767d91SRobert Wu 44*05767d91SRobert Wu --ei {parameterName} {parameterValue} 45*05767d91SRobert Wu 46*05767d91SRobert WuFor example: 47*05767d91SRobert Wu 48*05767d91SRobert Wu --ei buffer_bursts 8 49*05767d91SRobert Wu 50*05767d91SRobert WuBoolean parameters are sent using: 51*05767d91SRobert Wu 52*05767d91SRobert Wu --ez {parameterName} {parameterValue} 53*05767d91SRobert Wu 54*05767d91SRobert WuFor example: 55*05767d91SRobert Wu 56*05767d91SRobert Wu --ez use_input_presets false 57*05767d91SRobert Wu 58*05767d91SRobert Wu## Parameters 59*05767d91SRobert Wu 60*05767d91SRobert WuThere are two required parameters for all tests: 61*05767d91SRobert Wu 62*05767d91SRobert Wu --es test {latency, glitch, data_paths, input, output} 63*05767d91SRobert Wu The "latency" test will perform a Round Trip Latency test. 64*05767d91SRobert Wu It will request EXCLUSIVE mode for minimal latency. 65*05767d91SRobert Wu The "glitch" test will perform a single Glitch test. 66*05767d91SRobert Wu The "data_paths" test will verify input and output streams in many possible configurations. 67*05767d91SRobert Wu The "input" test will open and start an input stream. 68*05767d91SRobert Wu The "output" test will open and start an output stream. 69*05767d91SRobert Wu 70*05767d91SRobert Wu --es file {name of resulting file} 71*05767d91SRobert Wu 72*05767d91SRobert WuThe file will be stored in a directory that can be written by OboeTester without any special permissions. 73*05767d91SRobert WuThis is typically "/storage/emulated/0/Android/data/com.mobileer.oboetester/files/". 74*05767d91SRobert Wu 75*05767d91SRobert WuThere are some optional parameter in common for all tests: 76*05767d91SRobert Wu 77*05767d91SRobert Wu --ef volume {volume} // normalized volume in the range of 0.0 to 1.0 78*05767d91SRobert Wu --es volume_type {"accessibility", "alarm", "dtmf", "music", "notification", "ring", "system", "voice_call"} 79*05767d91SRobert Wu Stream type for the setStreamVolume() call. Default is "music". 80*05767d91SRobert Wu --ez background {"true", 1, "false", 0} // if true then Oboetester will continue to run in the background 81*05767d91SRobert Wu 82*05767d91SRobert WuThere are several optional parameters in common for glitch, latency, input, and output tests: 83*05767d91SRobert Wu 84*05767d91SRobert Wu --ei buffer_bursts {bursts} // number of bursts in the buffer, 2 for "double buffered" 85*05767d91SRobert Wu --es in_api {"unspecified", "opensles", "aaudio"} // native input API, default is "unspecified" 86*05767d91SRobert Wu --es out_api {"unspecified", "opensles", "aaudio"} // native output API, default is "unspecified" 87*05767d91SRobert Wu --es in_channel_mask {"mono", "stereo", "2.1", "tri", "triBack", "3.1", "2.0.2", "2.1.2", "3.0.2", "3.1.2", "quad", "quadSide", "surround", "penta", "5.1", "5.1Side", "6.1", "7.1", "5.1.2", "5.1.4", "7.1.2", "7.1.4", "9.1.4", "9.1.6", "frontBack"} 88*05767d91SRobert Wu --es out_channel_mask {"mono", "stereo", "2.1", "tri", "triBack", "3.1", "2.0.2", "2.1.2", "3.0.2", "3.1.2", "quad", "quadSide", "surround", "penta", "5.1", "5.1Side", "6.1", "7.1", "5.1.2", "5.1.4", "7.1.2", "7.1.4", "9.1.4", "9.1.6", "frontBack"} 89*05767d91SRobert Wu --ei in_channels {samples} // number of input channels, default is 2. This is ignored if in_channel_mask is set. 90*05767d91SRobert Wu --ei out_channels {samples} // number of output channels, default is 2. This is ignored if out_channel_mask is set. 91*05767d91SRobert Wu --ei sample_rate {hertz} 92*05767d91SRobert Wu --es in_perf {"none", "lowlat", "powersave"} // input performance mode, default is "lowlat" 93*05767d91SRobert Wu --es out_perf {"none", "lowlat", "powersave"} // output performance mode, default is "lowlat" 94*05767d91SRobert Wu --es out_usage {"media", "voice_communication", "alarm", "notification", "game"} // default is media 95*05767d91SRobert Wu --es in_sharing {"shared", "exclusive"} // input sharing mode, default is "exclusive" 96*05767d91SRobert Wu --es out_sharing {"shared", "exclusive"} // output sharing mode, default is "exclusive" 97*05767d91SRobert Wu --ez in_use_mmap {"true", 1, "false", 0} // if true then MMAP is allowed, if false then MMAP will be disabled 98*05767d91SRobert Wu --ez out_use_mmap {"true", 1, "false", 0} // if true then MMAP is allowed, if false then MMAP will be disabled 99*05767d91SRobert Wu 100*05767d91SRobert WuThere are some optional parameters in common for glitch, input, and output tests: 101*05767d91SRobert Wu 102*05767d91SRobert Wu --ei duration {seconds} // glitch test duration, default is 10 seconds 103*05767d91SRobert Wu 104*05767d91SRobert WuThere are several optional parameters for just the "glitch" test: 105*05767d91SRobert Wu 106*05767d91SRobert Wu --ef tolerance {tolerance} // amount of deviation from expected that is considered a glitch 107*05767d91SRobert Wu // Range of tolerance is 0.0 to 1.0. Default is 0.1. Note use of "-ef". 108*05767d91SRobert Wu // input preset, default is "voicerec" 109*05767d91SRobert Wu --es in_preset ("generic", "camcorder", "voicerec", "voicecomm", "unprocessed", "performance"} 110*05767d91SRobert Wu 111*05767d91SRobert WuThere are several optional parameters for just the "data_paths" test. Note the Note the use of "-ez" for the boolean parameters. 112*05767d91SRobert Wu 113*05767d91SRobert Wu --ez use_input_presets {"true", 1, "false", 0} // Whether to test various input presets. 114*05767d91SRobert Wu --ez use_all_sample_rates {"true", 1, "false", 0} // Whether to test all sample rates. Note use of "-ez". Default is false 115*05767d91SRobert Wu --ei single_test_index {testId} // Index for testing one specific test 116*05767d91SRobert Wu 117*05767d91SRobert WuThese parameters are used with the "data_paths" test starting with v2.5.11. 118*05767d91SRobert Wu 119*05767d91SRobert Wu --ez use_input_channel_masks {"true", 1, "false", 0} // Whether to test the reported input channel MASKS. Default is false. 120*05767d91SRobert Wu --ez use_all_channel_counts {"true", 1, "false", 0} // Whether to test all the supported channel COUNTS. Default is true. 121*05767d91SRobert Wu --ei output_channel_masks_level {0, 1, 2} // Whether to test NONE=0, SOME=1, or ALL=2 channel masks. Default is false. 122*05767d91SRobert Wu 123*05767d91SRobert WuThese parameters were used with the "data_paths" test prior to v2.5.11. 124*05767d91SRobert Wu 125*05767d91SRobert Wu --ez use_input_devices {"true", 1, "false", 0} // Whether to test various input devices. 126*05767d91SRobert Wu --ez use_output_devices {"true", 1, "false", 0} // Whether to test various output devices. 127*05767d91SRobert Wu --ez use_all_output_channel_masks {"true", 1, "false", 0} // Whether to test all output channel masks. Default is false 128*05767d91SRobert Wu 129*05767d91SRobert WuThere are some optional parameters for just the "output" test: 130*05767d91SRobert Wu 131*05767d91SRobert Wu --es signal_type {sine, sawtooth, freq_sweep, pitch_sweep, white_noise} // type of sound to play, default is sine 132*05767d91SRobert Wu 133*05767d91SRobert WuFor example, a complete command for a "latency" test might be: 134*05767d91SRobert Wu 135*05767d91SRobert Wu adb shell am start -n com.mobileer.oboetester/.MainActivity \ 136*05767d91SRobert Wu --es test latency \ 137*05767d91SRobert Wu --ei buffer_bursts 2 \ 138*05767d91SRobert Wu --ef volume 0.8 \ 139*05767d91SRobert Wu --es volume_type music \ 140*05767d91SRobert Wu --ei buffer_bursts 2 \ 141*05767d91SRobert Wu --ei out_channels 1 \ 142*05767d91SRobert Wu --es out_usage game \ 143*05767d91SRobert Wu --es file latency20230608.txt 144*05767d91SRobert Wu 145*05767d91SRobert Wuor for a "glitch" test: 146*05767d91SRobert Wu 147*05767d91SRobert Wu adb shell am start -n com.mobileer.oboetester/.MainActivity \ 148*05767d91SRobert Wu --es test glitch \ 149*05767d91SRobert Wu --es in_perf lowlat \ 150*05767d91SRobert Wu --es out_perf lowlat \ 151*05767d91SRobert Wu --es in_sharing exclusive \ 152*05767d91SRobert Wu --es out_sharing exclusive \ 153*05767d91SRobert Wu --ei buffer_bursts 2 \ 154*05767d91SRobert Wu --ei sample_rate 48000 \ 155*05767d91SRobert Wu --ef tolerance 0.123 \ 156*05767d91SRobert Wu --ei in_channels 2 \ 157*05767d91SRobert Wu --es file glitch20230608.txt 158*05767d91SRobert Wu 159*05767d91SRobert Wuor for a "data_paths" test: 160*05767d91SRobert Wu 161*05767d91SRobert Wu adb shell am start -n com.mobileer.oboetester/.MainActivity \ 162*05767d91SRobert Wu --es test data_paths \ 163*05767d91SRobert Wu --ez use_input_presets true \ 164*05767d91SRobert Wu --ez use_input_devices false \ 165*05767d91SRobert Wu --ez use_output_devices true \ 166*05767d91SRobert Wu --es file datapaths20230608.txt 167*05767d91SRobert Wu 168*05767d91SRobert Wu## Interpreting Test Results 169*05767d91SRobert Wu 170*05767d91SRobert WuTest results are simple files with "name = value" pairs. 171*05767d91SRobert WuAfter running the test you can determine where the results file was written by entering: 172*05767d91SRobert Wu 173*05767d91SRobert Wu adb logcat | grep EXTFILE 174*05767d91SRobert Wu 175*05767d91SRobert WuThe test results can be obtained using adb pull. For example: 176*05767d91SRobert Wu 177*05767d91SRobert Wu adb pull /storage/emulated/0/Android/data/com.mobileer.oboetester/files/glitch20230608.txt . 178*05767d91SRobert Wu 179*05767d91SRobert WuThe beginning of the report is common to latency and glitch tests: 180*05767d91SRobert Wu 181*05767d91SRobert Wu``` 182*05767d91SRobert Wubuild.fingerprint = google/cheetah/cheetah:14/MASTER/eng.philbu.20230518.172104:userdebug/dev-keys 183*05767d91SRobert Wutest.version = 2.5.1 184*05767d91SRobert Wutest.version.code = 72 185*05767d91SRobert Wutime.millis = 1686156503523 186*05767d91SRobert Wuin.channels = 2 187*05767d91SRobert Wuin.perf = ll 188*05767d91SRobert Wuin.preset = voicerec 189*05767d91SRobert Wuin.sharing = ex 190*05767d91SRobert Wuin.api = aaudio 191*05767d91SRobert Wuin.rate = 48000 192*05767d91SRobert Wuin.device = 22 193*05767d91SRobert Wuin.mmap = yes 194*05767d91SRobert Wuin.rate.conversion.quality = 0 195*05767d91SRobert Wuin.hardware.channels = 2 196*05767d91SRobert Wuin.hardware.sampleRate = 48000 197*05767d91SRobert Wuin.hardware.format = i32 198*05767d91SRobert Wuin.burst.frames = 96 199*05767d91SRobert Wuin.xruns = 0 200*05767d91SRobert Wuout.channels = 1 201*05767d91SRobert Wuout.perf = ll 202*05767d91SRobert Wuout.usage = game 203*05767d91SRobert Wuout.contentType = music 204*05767d91SRobert Wuout.sharing = ex 205*05767d91SRobert Wuout.api = aaudio 206*05767d91SRobert Wuout.rate = 48000 207*05767d91SRobert Wuout.device = 3 208*05767d91SRobert Wuout.mmap = yes 209*05767d91SRobert Wuout.rate.conversion.quality = 0 210*05767d91SRobert Wuout.hardware.channels = 2 211*05767d91SRobert Wuout.hardware.sampleRate = 48000 212*05767d91SRobert Wuout.hardware.format = float 213*05767d91SRobert Wuout.burst.frames = 96 214*05767d91SRobert Wuout.buffer.size.frames = 192 215*05767d91SRobert Wuout.buffer.capacity.frames = 1920 216*05767d91SRobert Wuout.xruns = 0 217*05767d91SRobert Wu``` 218*05767d91SRobert Wu 219*05767d91SRobert Wu### Latency Report 220*05767d91SRobert Wu 221*05767d91SRobert WuEach test also adds specific value. For "latency". If the test fails then some values will be unavailable. 222*05767d91SRobert Wu 223*05767d91SRobert WuHere is a report from a good test. The '#' comments were added for this document and are not in the report. 224*05767d91SRobert Wu 225*05767d91SRobert Wu``` 226*05767d91SRobert Wuconfidence = 0.892 # quality of the latency result between 0.0 and 1.0, higher is better 227*05767d91SRobert Wuresult.text = OK # text equivalent of the result 228*05767d91SRobert Wulatency.msec = 23.27 # round trip latency in milliseconds 229*05767d91SRobert Wulatency.frames = 1117 # round trip latency in frames 230*05767d91SRobert Wulatency.empty.msec = 19.27 # round trip latency if the top output buffer was empty 231*05767d91SRobert Wulatency.empty.frames = 925 # same but translated to frames 232*05767d91SRobert Wurms.signal = 0.03142 # Root Mean Square of the signal, if it can be detected 233*05767d91SRobert Wurms.noise = 0.00262 # Root Mean Square of the background noise before the signal is detected 234*05767d91SRobert Wucorrelation = 0.975 # raw normalized cross-correlation peak 235*05767d91SRobert Wutimestamp.latency.msec = 10.35 # latency based on timestamps 236*05767d91SRobert Wutimestamp.latency.mad = 0.05 # Mean absolute deviation 237*05767d91SRobert Wutimestamp.latency.count = 12 # number of measurements 238*05767d91SRobert Wureset.count = 1 # number of times the full duplex stream input underflowed and had to resynchronize 239*05767d91SRobert Wuresult = 0 # 0 or a negative error 240*05767d91SRobert Wu``` 241*05767d91SRobert Wu 242*05767d91SRobert WuHere is a report from a test that failed because the output was muted. Note the latency.msec is 243*05767d91SRobert Wumissing because it could not be measured. 244*05767d91SRobert Wu 245*05767d91SRobert Wu rms.signal = 0.00000 246*05767d91SRobert Wu rms.noise = 0.00048 247*05767d91SRobert Wu reset.count = 3 248*05767d91SRobert Wu result = -96 249*05767d91SRobert Wu result.text = ERROR_CONFIDENCE 250*05767d91SRobert Wu confidence = 0.009 251*05767d91SRobert Wu 252*05767d91SRobert Wu### Glitch Report 253*05767d91SRobert Wu 254*05767d91SRobert WuHere is a report from a good test. The '#' comments were added for this document and are not in the report. 255*05767d91SRobert Wu 256*05767d91SRobert Wu tolerance = 0.123 257*05767d91SRobert Wu state = LOCKED 258*05767d91SRobert Wu unlocked.frames = 2528 # frames spent trying to lock onto the signal 259*05767d91SRobert Wu locked.frames = 384084 # frames spent locked onto a good signal with no glitches 260*05767d91SRobert Wu glitch.frames = 0 # frames spent glitching or recovering from a glitch 261*05767d91SRobert Wu reset.count = 208 # number of times the full duplex stream input underflowed and had to resynchronize 262*05767d91SRobert Wu peak.amplitude = 0.057714 # peak amplitude of the input signal, between 0.0 and 1.0 263*05767d91SRobert Wu signal.noise.ratio.db = 96.3 264*05767d91SRobert Wu time.total = 9.96 seconds # close to your specified duration 265*05767d91SRobert Wu time.no.glitches = 9.96 # time we have been running with no glitches 266*05767d91SRobert Wu max.time.no.glitches = 9.96 # max time with no glitches 267*05767d91SRobert Wu glitch.count = 0 # number of glitch events, actual number may be higher if close together 268*05767d91SRobert Wu 269*05767d91SRobert WuHere is a report from a test that failed because the output was muted. Note the glitch.count is 270*05767d91SRobert Wumissing because it could not be measured. 271*05767d91SRobert Wu 272*05767d91SRobert Wu state = WAITING_FOR_SIGNAL 273*05767d91SRobert Wu unlocked.frames = 0 274*05767d91SRobert Wu locked.frames = 0 275*05767d91SRobert Wu glitch.frames = 0 276*05767d91SRobert Wu reset.count = 1 277*05767d91SRobert Wu time.total = 9.95 seconds 278*05767d91SRobert Wu 279*05767d91SRobert Wu### Data Paths Report 280*05767d91SRobert Wu 281*05767d91SRobert WuThe report first goes through the info about the specific device before going through input preset tests, 282*05767d91SRobert Wuinput devices tests, and output tests. 283*05767d91SRobert WuEach will show the specific configuration of a test before showing whether it passed or failed. 284*05767d91SRobert WuAt the end of the report, an analysis of the failed tests will be given 285*05767d91SRobert Wufollowed by the number of passed, failed, and skipped tests. 286