1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 2470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 39d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license that can be found 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the LICENSE file in the root of the source tree. An additional 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * intellectual property rights grant can be found in the file PATENTS. All 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * contributing project authors may be found in the AUTHORS file in the root of 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * VoiceEngine Android test application. It starts either auto test or acts like 13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * a GUI test. 14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.compackage org.webrtc.voiceengine.test; 17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport java.io.File; 19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport java.io.FileInputStream; 20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport java.io.FileNotFoundException; 21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport java.io.FileOutputStream; 22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport java.io.FileReader; 23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport java.io.IOException; 24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.app.Activity; 26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.content.Context; 27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.media.AudioFormat; 28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.media.AudioManager; 29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.media.AudioRecord; 30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.media.AudioTrack; 31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.media.MediaRecorder; 32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.os.Bundle; 33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.util.Log; 34470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.view.View; 35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.widget.AdapterView; 36470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.widget.ArrayAdapter; 37470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.widget.Button; 38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.widget.EditText; 39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.widget.Spinner; 40470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comimport android.widget.TextView; 41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.compublic class AndroidTest extends Activity { 43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private byte[] _playBuffer = null; 44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private short[] _circBuffer = new short[8000]; // can hold 50 frames 45470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _recIndex = 0; 47470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _playIndex = 0; 48470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // private int _streamVolume = 4; 49470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _maxVolume = 0; // Android max level (commonly 5) 50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // VoE level (0-255), corresponds to level 4 out of 5 51470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _volumeLevel = 204; 52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private Thread _playThread; 54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private Thread _recThread; 55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private Thread _autotestThread; 56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private static AudioTrack _at; 58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private static AudioRecord _ar; 59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private File _fr = null; 61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private FileInputStream _in = null; 62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private boolean _isRunningPlay = false; 64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private boolean _isRunningRec = false; 65470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private boolean _settingSet = true; 66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private boolean _isCallActive = false; 67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private boolean _runAutotest = false; // ENABLE AUTOTEST HERE! 68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _channel = -1; 70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _codecIndex = 0; 71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _ecIndex = 0; 72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _nsIndex = 0; 73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _agcIndex = 0; 74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _vadIndex = 0; 75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _audioIndex = 3; 76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _settingMenu = 0; 77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _receivePort = 1234; 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private int _destinationPort = 1234; 79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private String _destinationIP = "127.0.0.1"; 80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // "Build" settings 82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private final boolean _playFromFile = false; 83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Set to true to send data to native code and back 84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private final boolean _runThroughNativeLayer = true; 85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private final boolean enableSend = true; 86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private final boolean enableReceive = true; 87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private final boolean useNativeThread = false; 88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /** Called when the activity is first created. */ 90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onCreate(Bundle savedInstanceState) { 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com super.onCreate(savedInstanceState); 92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com setContentView(R.layout.main); 93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com TextView tv = (TextView) findViewById(R.id.TextView01); 95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tv.setText(""); 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final EditText ed = (EditText) findViewById(R.id.EditText01); 98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ed.setWidth(200); 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ed.setText(_destinationIP); 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final Button buttonStart = (Button) findViewById(R.id.Button01); 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStart.setWidth(200); 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_runAutotest) { 104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStart.setText("Run test"); 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStart.setText("Start Call"); 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // button.layout(50, 50, 100, 40); 109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStart.setOnClickListener(new View.OnClickListener() { 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onClick(View v) { 111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_runAutotest) { 113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startAutoTest(); 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_isCallActive) { 116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (stopCall() != -1) { 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isCallActive = false; 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStart.setText("Start Call"); 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _destinationIP = ed.getText().toString(); 124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (startCall() != -1) { 125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isCallActive = true; 126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStart.setText("Stop Call"); 127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // displayTextFromFile(); 132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // recordAudioToFile(); 133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // if(!_playFromFile) 134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // { 135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // recAudioInThread(); 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // playAudioInThread(); 138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }); 140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final Button buttonStop = (Button) findViewById(R.id.Button02); 142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStop.setWidth(200); 143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStop.setText("Close app"); 144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com buttonStop.setOnClickListener(new View.OnClickListener() { 145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onClick(View v) { 146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_runAutotest) { 148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ShutdownVoE(); 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This call terminates and should close the activity 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com finish(); 153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // playAudioFromFile(); 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // if(!_playFromFile) 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // { 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stopRecAudio(); 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stopPlayAudio(); 160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }); 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String ap1[] = {"EC off", "AECM"}; 165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final ArrayAdapter<String> adapterAp1 = new ArrayAdapter<String>( 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com this, 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.R.layout.simple_spinner_dropdown_item, 168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ap1); 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String ap2[] = 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com {"NS off", "NS low", "NS moderate", "NS high", 171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "NS very high"}; 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final ArrayAdapter<String> adapterAp2 = new ArrayAdapter<String>( 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com this, 174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.R.layout.simple_spinner_dropdown_item, 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ap2); 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String ap3[] = {"AGC off", "AGC adaptive", "AGC fixed"}; 177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final ArrayAdapter<String> adapterAp3 = new ArrayAdapter<String>( 178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com this, 179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.R.layout.simple_spinner_dropdown_item, 180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ap3); 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String ap4[] = 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com {"VAD off", "VAD conventional", "VAD high rate", 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "VAD mid rate", "VAD low rate"}; 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final ArrayAdapter<String> adapterAp4 = new ArrayAdapter<String>( 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com this, 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.R.layout.simple_spinner_dropdown_item, 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ap4); 1889d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com String codecs[] = {"iSAC", "PCMU", "PCMA", "iLBC"}; 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final ArrayAdapter<String> adapterCodecs = new ArrayAdapter<String>( 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com this, 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.R.layout.simple_spinner_dropdown_item, 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecs); 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final Spinner spinnerSettings1 = (Spinner) findViewById(R.id.Spinner01); 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final Spinner spinnerSettings2 = (Spinner) findViewById(R.id.Spinner02); 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings1.setMinimumWidth(200); 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String settings[] = 1989d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com {"Codec", "Echo Control", "Noise Suppression", 1999d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com "Automatic Gain Control", 2009d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com "Voice Activity Detection"}; 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ArrayAdapter<String> adapterSettings1 = new ArrayAdapter<String>( 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com this, 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.R.layout.simple_spinner_dropdown_item, 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com settings); 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings1.setAdapter(adapterSettings1); 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings1.setOnItemSelectedListener( 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new AdapterView.OnItemSelectedListener() { 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onItemSelected(AdapterView adapterView, View view, 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int position, long id) { 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _settingMenu = position; 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _settingSet = false; 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (position == 0) { 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setAdapter(adapterCodecs); 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setSelection(_codecIndex); 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2179d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com if (position == 1) { 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setAdapter(adapterAp1); 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setSelection(_ecIndex); 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2219d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com if (position == 2) { 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setAdapter(adapterAp2); 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setSelection(_nsIndex); 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2259d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com if (position == 3) { 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setAdapter(adapterAp3); 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setSelection(_agcIndex); 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2299d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com if (position == 4) { 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setAdapter(adapterAp4); 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setSelection(_vadIndex); 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onNothingSelected(AdapterView adapterView) { 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("No setting1 selected"); 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }); 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setMinimumWidth(200); 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ArrayAdapter<String> adapterSettings2 = new ArrayAdapter<String>( 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com this, 243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.R.layout.simple_spinner_dropdown_item, 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecs); 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setAdapter(adapterSettings2); 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setOnItemSelectedListener( 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new AdapterView.OnItemSelectedListener() { 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onItemSelected(AdapterView adapterView, View view, 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int position, long id) { 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // avoid unintentional setting 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_settingSet == false) { 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _settingSet = true; 254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Change volume 258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_settingMenu == 0) { 259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Selected audio " + position); 260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com setAudioProperties(position); 261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com spinnerSettings2.setSelection(_audioIndex); 262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Change codec 265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_settingMenu == 1) { 266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _codecIndex = position; 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Selected codec " + position); 268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetSendCodec(_channel, _codecIndex)) { 269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set send codec failed"); 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Change EC 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_settingMenu == 2) { 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com boolean enable = true; 276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int ECmode = 5; // AECM 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int AESmode = 0; 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _ecIndex = position; 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Selected EC " + position); 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (position == 0) { 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enable = false; 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (position > 1) { 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ECmode = 4; // AES 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AESmode = position - 1; 288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetECStatus(enable, ECmode)) { 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set EC status failed"); 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Change NS 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_settingMenu == 3) { 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com boolean enable = true; 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _nsIndex = position; 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Selected NS " + position); 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (position == 0) { 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enable = false; 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetNSStatus(enable, position + 2)) { 306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set NS status failed"); 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Change AGC 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_settingMenu == 4) { 312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com boolean enable = true; 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _agcIndex = position; 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Selected AGC " + position); 316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (position == 0) { 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enable = false; 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com position = 1; // default 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetAGCStatus(enable, position + 2)) { 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set AGC status failed"); 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Change VAD 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_settingMenu == 5) { 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com boolean enable = true; 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _vadIndex = position; 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Selected VAD " + position); 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (position == 0) { 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enable = false; 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com position++; 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetVADStatus(_channel, enable, position - 1)) { 338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set VAD status failed"); 339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onNothingSelected(AdapterView adapterView) { 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }); 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Setup VoiceEngine 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_runAutotest && !useNativeThread) SetupVoE(); 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Suggest to use the voice call audio stream for hardware volume 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // controls 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get max Android volume and adjust default volume to map exactly to an 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Android level 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioManager am = 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (AudioManager) getSystemService(Context.AUDIO_SERVICE); 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); 359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_maxVolume <= 0) { 360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Could not get max volume!"); 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int androidVolumeLevel = (_volumeLevel * _maxVolume) / 255; 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _volumeLevel = (androidVolumeLevel * 255) / _maxVolume; 364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Started Webrtc Android Test"); 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Will be called when activity is shutdown. 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // NOTE: Activity may be killed without this function being called, 371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // but then we should not need to clean up. 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com protected void onDestroy() { 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com super.onDestroy(); 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ShutdownVoE(); 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private void SetupVoE() { 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create VoiceEngine 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Create(); // Error logging is done in native API wrapper 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Initialize 3829d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com if (0 != Init(false, false)) { 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE init failed"); 384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create channel 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channel = CreateChannel(); 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != _channel) { 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE create channel failed"); 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private void ShutdownVoE() { 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Delete channel 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != DeleteChannel(_channel)) { 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE delete channel failed"); 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Terminate 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != Terminate()) { 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE terminate failed"); 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Delete VoiceEngine 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Delete(); // Error logging is done in native API wrapper 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int startCall() { 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (useNativeThread == true) { 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Create(); 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enableReceive == true) { 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Set local receiver 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetLocalReceiver(_channel, _receivePort)) { 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set local receiver failed"); 421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != StartListen(_channel)) { 424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE start listen failed"); 425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Route audio to earpiece 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetLoudspeakerStatus(false)) { 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set louspeaker status failed"); 431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebrtcLog("VoE start record now"); if (0 != 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * StartRecordingPlayout(_channel, "/sdcard/singleUserDemoOut.pcm", 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * false)) { WebrtcLog("VoE Recording Playout failed"); } 438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebrtcLog("VoE start Recording Playout end"); 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Start playout 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != StartPlayout(_channel)) { 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE start playout failed"); 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Start playout file 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // if (0 != StartPlayingFileLocally(_channel, 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // "/sdcard/singleUserDemo.pcm", true)) { 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("VoE start playout file failed"); 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // return -1; 451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enableSend == true) { 455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetSendDestination(_channel, _destinationPort, 456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _destinationIP)) { 457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set send destination failed"); 458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetSendCodec(_channel, _codecIndex)) { 462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set send codec failed"); 463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * if (0 != StartPlayingFileAsMicrophone(_channel, 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * "/sdcard/singleUserDemo.pcm", true)) { 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebrtcLog("VoE start playing file as microphone failed"); } 470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != StartSend(_channel)) { 472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE start send failed"); 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // if (0 != StartPlayingFileAsMicrophone(_channel, 477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // "/sdcard/singleUserDemo.pcm", true)) { 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("VoE start playing file as microphone failed"); 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // return -1; 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int stopCall() { 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (useNativeThread == true) { 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Delete(); 491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enableSend == true) { 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Stop playing file as microphone 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * if (0 != StopPlayingFileAsMicrophone(_channel)) { 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebrtcLog("VoE stop playing file as microphone failed"); return 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * -1; } 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Stop send 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != StopSend(_channel)) { 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE stop send failed"); 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enableReceive == true) { 509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // if (0 != StopRecordingPlayout(_channel)) { 510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("VoE stop Recording Playout failed"); 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("VoE stop Recording Playout ended"); 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Stop listen 515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != StopListen(_channel)) { 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE stop listen failed"); 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Stop playout file 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // if (0 != StopPlayingFileLocally(_channel)) { 522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("VoE stop playout file failed"); 523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // return -1; 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Stop playout 527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != StopPlayout(_channel)) { 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE stop playout failed"); 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Route audio to loudspeaker 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetLoudspeakerStatus(true)) { 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set louspeaker status failed"); 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int startAutoTest() { 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _autotestThread = new Thread(_autotestProc); 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _autotestThread.start(); 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private Runnable _autotestProc = new Runnable() { 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void run() { 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // TODO(xians): choose test from GUI 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 1 = standard, not used 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 2 = extended, 2 = base 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RunAutoTest(1, 2); 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }; 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int setAudioProperties(int val) { 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // AudioManager am = (AudioManager) 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // getSystemService(Context.AUDIO_SERVICE); 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (val == 0) { 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // _streamVolume = 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // am.getStreamVolume(AudioManager.STREAM_VOICE_CALL); 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // am.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (_streamVolume+1), 0); 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int androidVolumeLevel = (_volumeLevel * _maxVolume) / 255; 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (androidVolumeLevel < _maxVolume) { 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _volumeLevel = ((androidVolumeLevel + 1) * 255) / _maxVolume; 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetSpeakerVolume(_volumeLevel)) { 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set speaker volume failed"); 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (val == 1) { 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // _streamVolume = 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // am.getStreamVolume(AudioManager.STREAM_VOICE_CALL); 580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // am.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (_streamVolume-1), 0); 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int androidVolumeLevel = (_volumeLevel * _maxVolume) / 255; 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (androidVolumeLevel > 0) { 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _volumeLevel = ((androidVolumeLevel - 1) * 255) / _maxVolume; 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetSpeakerVolume(_volumeLevel)) { 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set speaker volume failed"); 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (val == 2) { 591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // route audio to back speaker 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetLoudspeakerStatus(true)) { 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set loudspeaker status failed"); 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioIndex = 2; 596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else if (val == 3) { 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // route audio to earpiece 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (0 != SetLoudspeakerStatus(false)) { 599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("VoE set loudspeaker status failed"); 600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioIndex = 3; 602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int displayTextFromFile() { 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com TextView tv = (TextView) findViewById(R.id.TextView01); 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileReader fr = null; 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com char[] fileBuffer = new char[64]; 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fr = new FileReader("/sdcard/test.txt"); 615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (FileNotFoundException e) { 616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tv.setText("File not found!"); 618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fr.read(fileBuffer); 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IOException e) { 623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String readString = new String(fileBuffer); 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com tv.setText(readString); 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // setContentView(tv); 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int recordAudioToFile() { 634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com File fr = null; 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // final to be reachable within onPeriodicNotification 636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com byte[] recBuffer = new byte[320]; 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int recBufSize = 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioRecord.getMinBufferSize(16000, 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT); 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioRecord rec = 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new AudioRecord(MediaRecorder.AudioSource.MIC, 16000, 644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT, 646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com recBufSize); 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fr = new File("/sdcard/record.pcm"); 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileOutputStream out = null; 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com out = new FileOutputStream(fr); 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (FileNotFoundException e1) { 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e1.printStackTrace(); 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // start recording 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rec.startRecording(); 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int i = 0; i < 550; i++) { 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // note, there is a short version of write as well! 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int wrBytes = rec.read(recBuffer, 0, 320); 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com out.write(recBuffer); 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IOException e) { 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stop playout 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rec.stop(); 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int playAudioFromFile() { 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com File fr = null; 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // final to be reachable within onPeriodicNotification 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // final byte[] playBuffer = new byte [320000]; 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // final to be reachable within onPeriodicNotification 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final byte[] playBuffer = new byte[320]; 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final int playBufSize = 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioTrack.getMinBufferSize(16000, 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT); 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // final int playBufSize = 1920; // 100 ms buffer 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // byte[] playBuffer = new byte [playBufSize]; 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final AudioTrack play = 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new AudioTrack(AudioManager.STREAM_VOICE_CALL, 16000, 700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT, 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playBufSize, AudioTrack.MODE_STREAM); 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // implementation of the playpos callback functions 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com play.setPlaybackPositionUpdateListener( 706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new AudioTrack.OnPlaybackPositionUpdateListener() { 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int count = 0; 709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onPeriodicNotification(AudioTrack track) { 711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int wrBytes = play.write(playBuffer, count, 320); 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com count += 320; 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void onMarkerReached(AudioTrack track) { 716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }); 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // set the notification period = 160 samples 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int ret = play.setPositionNotificationPeriod(160); 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fr = new File("/sdcard/record.pcm"); 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileInputStream in = null; 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in = new FileInputStream(fr); 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (FileNotFoundException e1) { 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e1.printStackTrace(); 729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // try { 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // in.read(playBuffer); 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } catch (IOException e) { 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // e.printStackTrace(); 735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // play all at once 738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int wrBytes = play.write(playBuffer, 0, 320000); 739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // start playout 742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com play.play(); 744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // returns the number of samples that has been written 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int headPos = play.getPlaybackHeadPosition(); 750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // play with multiple writes 752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int i = 0; i < 500; i++) { 753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com in.read(playBuffer); 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IOException e) { 756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // note, there is a short version of write as well! 761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int wrBytes = play.write(playBuffer, 0, 320); 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Log.d("testWrite", "wrote"); 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stop playout 767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com play.stop(); 769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int playAudioInThread() { 777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_isRunningPlay) { 779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // File fr = null; 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // final byte[] playBuffer = new byte[320]; 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playFromFile) { 785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playBuffer = new byte[320]; 786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // reset index 788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playIndex = 0; 789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // within 791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // onPeriodicNotification 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Log some info (static) 794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Creating AudioTrack object"); 795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final int minPlayBufSize = 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioTrack.getMinBufferSize(16000, 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT); 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Min play buf size = " + minPlayBufSize); 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Min volume = " + AudioTrack.getMinVolume()); 801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Max volume = " + AudioTrack.getMaxVolume()); 802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Native sample rate = " 803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com + AudioTrack.getNativeOutputSampleRate( 804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioManager.STREAM_VOICE_CALL)); 805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final int playBufSize = minPlayBufSize; // 3200; // 100 ms buffer 807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // byte[] playBuffer = new byte [playBufSize]; 808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _at = new AudioTrack( 810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioManager.STREAM_VOICE_CALL, 811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16000, 812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT, 814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playBufSize, AudioTrack.MODE_STREAM); 815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (Exception e) { 816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog(e.getMessage()); 817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Log some info (non-static) 820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Notification marker pos = " 821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com + _at.getNotificationMarkerPosition()); 822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Play head pos = " + _at.getPlaybackHeadPosition()); 823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Pos notification dt = " 824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com + _at.getPositionNotificationPeriod()); 825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Playback rate = " + _at.getPlaybackRate()); 826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Sample rate = " + _at.getSampleRate()); 827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // implementation of the playpos callback functions 829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // _at.setPlaybackPositionUpdateListener( 830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // new AudioTrack.OnPlaybackPositionUpdateListener() { 831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int count = 3200; 833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // public void onPeriodicNotification(AudioTrack track) { 835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // // int wrBytes = play.write(playBuffer, count, 320); 836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // count += 320; 837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // public void onMarkerReached(AudioTrack track) { 840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // }); 842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // set the notification period = 160 samples 844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int ret = _at.setPositionNotificationPeriod(160); 845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playFromFile) { 847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _fr = new File("/sdcard/singleUserDemo.pcm"); 848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _in = new FileInputStream(_fr); 850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (FileNotFoundException e1) { 851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e1.printStackTrace(); 852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // try { 856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // in.read(playBuffer); 857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } catch (IOException e) { 858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // e.printStackTrace(); 859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isRunningPlay = true; 862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // buffer = new byte[3200]; 864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playThread = new Thread(_playProc); 865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ar.startRecording(); 866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // bytesRead = 3200; 867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // recording = true; 868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playThread.start(); 869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int stopPlayAudio() { 874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_isRunningPlay) { 875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isRunningPlay = false; 879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private Runnable _playProc = new Runnable() { 884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void run() { 885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // set high thread priority 887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.os.Process.setThreadPriority( 888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // play all at once 891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int wrBytes = play.write(playBuffer, 0, 320000); 892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // fill the buffer 894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // play.write(playBuffer, 0, 3200); 895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // play.flush(); 897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // start playout 899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _at.play(); 901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // play with multiple writes 906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int i = 0; 907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (; i < 3000 && _isRunningPlay; i++) { 908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playFromFile) { 910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _in.read(_playBuffer); 912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IOException e) { 913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int wrBytes = _at.write(_playBuffer, 0 /* i * 320 */, 320); 917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int wrSamples = 919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _at.write(_circBuffer, _playIndex * 160, 920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 160); 921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Played 10 ms from buffer, _playIndex = " + 923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // _playIndex); 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Diff = " + (_recIndex - _playIndex)); 925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playIndex == 49) { 927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playIndex = 0; 928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playIndex += 1; 930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Wrote 10 ms to buffer, head = " 934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // + _at.getPlaybackHeadPosition()); 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stop playout 938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _at.stop(); 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // returns the number of samples that has been written 945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Test stopped, i = " + i + ", head = " 946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com + _at.getPlaybackHeadPosition()); 947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int headPos = _at.getPlaybackHeadPosition(); 948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // flush the buffers 950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _at.flush(); 951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // release the object 953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _at.release(); 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _at = null; 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // try { 957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Thread.sleep() must be within a try - catch block 958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Thread.sleep(3000); 959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // }catch (Exception e){ 960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // System.out.println(e.getMessage()); 961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isRunningPlay = false; 964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }; 967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int recAudioInThread() { 969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_isRunningRec) { 971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // within 975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // onPeriodicNotification 976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // reset index 978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recIndex = 20; 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Log some info (static) 981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Creating AudioRecord object"); 982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final int minRecBufSize = AudioRecord.getMinBufferSize(16000, 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT); 985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Min rec buf size = " + minRecBufSize); 986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Min volume = " + AudioTrack.getMinVolume()); 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Max volume = " + AudioTrack.getMaxVolume()); 988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Native sample rate = " 989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // + AudioRecord 990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // .getNativeInputSampleRate(AudioManager.STREAM_VOICE_CALL)); 991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com final int recBufSize = minRecBufSize; // 3200; // 100 ms buffer 993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _ar = new AudioRecord( 995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MediaRecorder.AudioSource.MIC, 996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16000, 997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.CHANNEL_CONFIGURATION_MONO, 998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFormat.ENCODING_PCM_16BIT, 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com recBufSize); 1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (Exception e) { 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog(e.getMessage()); 1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Log some info (non-static) 1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Notification marker pos = " 1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com + _ar.getNotificationMarkerPosition()); 1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Play head pos = " + _ar.getRecordHeadPosition()); 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Pos notification dt rec= " 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com + _ar.getPositionNotificationPeriod()); 1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Playback rate = " + _ar.getRecordRate()); 1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Playback rate = " + _ar.getPlaybackRate()); 1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebrtcLog("Sample rate = " + _ar.getSampleRate()); 1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Playback rate = " + _ar.getPlaybackRate()); 1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Playback rate = " + _ar.getPlaybackRate()); 1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isRunningRec = true; 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recThread = new Thread(_recProc); 1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recThread.start(); 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int stopRecAudio() { 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_isRunningRec) { 1027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isRunningRec = false; 1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private Runnable _recProc = new Runnable() { 1036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com public void run() { 1037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // set high thread priority 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.os.Process.setThreadPriority( 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // start recording 1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _ar.startRecording(); 1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // keep recording to circular buffer 1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // for a while 1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int i = 0; 1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int rdSamples = 0; 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com short[] tempBuffer = new short[160]; // Only used for native case 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (; i < 3000 && _isRunningRec; i++) { 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_runThroughNativeLayer) { 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rdSamples = _ar.read(tempBuffer, 0, 160); 1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // audioLoop(tempBuffer, 160); // Insert into native layer 1059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rdSamples = _ar.read(_circBuffer, _recIndex * 160, 160); 1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Recorded 10 ms to buffer, _recIndex = " + 1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // _recIndex); 1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("rdSamples = " + rdSamples); 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_recIndex == 49) { 1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recIndex = 0; 1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recIndex += 1; 1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stop recording 1075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com try { 1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _ar.stop(); 1077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } catch (IllegalStateException e) { 1078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com e.printStackTrace(); 1079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // release the object 1082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _ar.release(); 1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _ar = null; 1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // try { 1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Thread.sleep() must be within a try - catch block 1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Thread.sleep(3000); 1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // }catch (Exception e){ 1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // System.out.println(e.getMessage()); 1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // } 1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _isRunningRec = false; 1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // returns the number of samples that has been written 1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebrtcLog("Test stopped, i = " + i + ", head = " 1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // + _at.getPlaybackHeadPosition()); 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // int headPos = _at.getPlaybackHeadPosition(); 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com }; 1100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private void WebrtcLog(String msg) { 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Log.d("*Webrtc*", msg); 1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // //////////////// Native function prototypes //////////////////// 1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native static boolean NativeInit(); 1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int RunAutoTest(int testType, int extendedSel); 1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native boolean Create(); 1112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native boolean Delete(); 1114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1115412889a2a97ec72ebc72ee17184e84fe396efcfcleozwang@google.com private native int Init(boolean enableTrace, boolean useExtTrans); 1116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int Terminate(); 1118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int CreateChannel(); 1120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int DeleteChannel(int channel); 1122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetLocalReceiver(int channel, int port); 1124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetSendDestination(int channel, int port, 1126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String ipaddr); 1127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StartListen(int channel); 1129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StartPlayout(int channel); 1131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StartSend(int channel); 1133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StopListen(int channel); 1135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StopPlayout(int channel); 1137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StopSend(int channel); 1139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StartPlayingFileLocally(int channel, String fileName, 1141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com boolean loop); 1142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StopPlayingFileLocally(int channel); 1144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StartRecordingPlayout(int channel, String fileName, 1146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com boolean loop); 1147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StopRecordingPlayout(int channel); 1149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StartPlayingFileAsMicrophone(int channel, 1151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com String fileName, boolean loop); 1152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int StopPlayingFileAsMicrophone(int channel); 1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int NumOfCodecs(); 1156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetSendCodec(int channel, int index); 1158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetVADStatus(int channel, boolean enable, int mode); 1160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetNSStatus(boolean enable, int mode); 1162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetAGCStatus(boolean enable, int mode); 1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetECStatus(boolean enable, int mode); 1166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetSpeakerVolume(int volume); 1168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com private native int SetLoudspeakerStatus(boolean enable); 1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com /* 11729d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com * this is used to load the 'webrtc-voice-demo-jni' 11739d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com * library on application startup. 1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * The library has already been unpacked into 11759d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com * /data/data/webrtc.android.AndroidTest/lib/libwebrtc-voice-demo-jni.so 11769d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com * at installation time by the package manager. 1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com static { 11799d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com Log.d("*Webrtc*", "Loading webrtc-voice-demo-jni..."); 11809d23ba096d809e51fec7e259ea2d026cf9113919leozwang@google.com System.loadLibrary("webrtc-voice-demo-jni"); 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Log.d("*Webrtc*", "Calling native init..."); 1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!NativeInit()) { 1184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Log.e("*Webrtc*", "Native init failed"); 1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com throw new RuntimeException("Native init failed"); 1186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else { 1187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com Log.d("*Webrtc*", "Native init successful"); 1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1191