AudioInput.java 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. vvphone is a SIP app for android.
  3. vvsip is a SIP library for softphone (SIP -rfc3261-)
  4. Copyright (C) 2003-2010 Bluegoby - <bluegoby@163.com>
  5. */
  6. package com.vvsip.ansip;
  7. import android.media.AudioFormat;
  8. import android.media.AudioRecord;
  9. import android.media.MediaRecorder;
  10. //import android.media.audiofx.AcousticEchoCanceler;
  11. //import android.media.audiofx.AutomaticGainControl;
  12. import android.os.Build;
  13. import android.util.Log;
  14. /*
  15. * 语音输入类,功能:采集语音
  16. */
  17. public class AudioInput {
  18. public static boolean beready=false;
  19. public static boolean restart = false;
  20. public static int mAudiomanager_audio_source = MediaRecorder.AudioSource.MIC;
  21. public static boolean muted = false;
  22. AudioRecord record;
  23. // AutomaticGainControl agc;
  24. // AcousticEchoCanceler aec;
  25. boolean running = false;
  26. int offset = 0;
  27. int mRate = 8000;//20160617.8000->16000
  28. AudioInput(int rate) {
  29. // rate = 8000;//20160617.add line.
  30. mRate = rate;
  31. if (beready==false)
  32. return;
  33. int bufsize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
  34. if (bufsize < 2048)
  35. bufsize = 2048;
  36. bufsize = AudioCompatibility.getAudioRecord_getMinBufferSize(bufsize);
  37. Log.i("AudioInput", "AudioRecord will use buffer = " + bufsize);
  38. Log.i("AudioInput", "AudioRecord will use rate = " + rate);
  39. android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
  40. record = new AudioRecord(mAudiomanager_audio_source, rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufsize);
  41. if (record != null) {
  42. // if (Build.VERSION.SDK_INT>=16)
  43. // {
  44. // try {
  45. //
  46. // if (AutomaticGainControl.isAvailable()) {
  47. // int session_id = record.getAudioSessionId();
  48. // agc = AutomaticGainControl.create(session_id);
  49. // Log.w("AudioInput",
  50. // "AudioRecord with AGC created / session id = " + session_id);
  51. // if (agc.getEnabled()==false) {
  52. // Log.w("AudioInput", "AudioRecord with AGC not yet enabled");
  53. // agc.setEnabled(true);
  54. // }
  55. // if (agc.getEnabled()==true) {
  56. // Log.w("AudioInput", "AudioRecord with AGC enabled");
  57. // }
  58. // }
  59. // } catch (Exception e) {
  60. // }
  61. // try {
  62. // if (AcousticEchoCanceler.isAvailable()) {
  63. // int session_id = record.getAudioSessionId();
  64. // aec = AcousticEchoCanceler.create(session_id);
  65. // Log.w("AudioInput",
  66. // "AudioRecord with AEC created / session id = " + session_id);
  67. // if (aec!=null) {
  68. // if (aec.getEnabled()==false) {
  69. // Log.w("AudioInput", "AudioRecord with AEC not yet enabled");
  70. // aec.setEnabled(true);
  71. // }
  72. // if (aec.getEnabled()==true) {
  73. // Log.w("AudioInput",
  74. // "AudioRecord with AEC enabled and hasControl = " +
  75. // aec.hasControl());
  76. // }
  77. // }
  78. // }
  79. // } catch (Exception e) {
  80. // }
  81. // }
  82. if (mAudiomanager_audio_source != record.getAudioSource()) {
  83. Log.w("AudioInput", "AudioRecord is using " + record.getAudioSource() + " audio source instead of "
  84. + mAudiomanager_audio_source);
  85. }
  86. }
  87. if (record == null) {
  88. /* ressource not yet available? */
  89. Log.w("AudioInput", "AudioRecord not yet available, retry later");
  90. running = false;
  91. } else {
  92. running = true;
  93. try {
  94. record.startRecording();
  95. } catch (Exception e) {
  96. try {
  97. record.stop();
  98. } catch (Exception e1) {
  99. }
  100. record.release();
  101. record = null;
  102. // if (Build.VERSION.SDK_INT>=16) {
  103. // if (agc!=null)
  104. // agc.release();
  105. // agc=null;
  106. // if (aec!=null)
  107. // aec.release();
  108. // aec=null;
  109. // }
  110. running = false;
  111. }
  112. }
  113. }
  114. /** Stops running */
  115. public int stop() {
  116. if (record != null) {
  117. running = false;
  118. record.stop();
  119. record.release();
  120. record = null;
  121. // if (Build.VERSION.SDK_INT>=16) {
  122. // if (agc!=null)
  123. // agc.release();
  124. // agc=null;
  125. // if (aec!=null)
  126. // aec.release();
  127. // aec=null;
  128. // }
  129. }
  130. return 0;
  131. }
  132. int read_bytes(byte[] data, int len) {
  133. if (beready==false) {
  134. if (record != null) {
  135. Log.i("AudioInput", "AudioRecord is now unused: stop");
  136. running = false;
  137. record.stop();
  138. record.release();
  139. record = null;
  140. restart = false;
  141. // if (Build.VERSION.SDK_INT>=16) {
  142. // if (agc!=null)
  143. // agc.release();
  144. // agc=null;
  145. // if (aec!=null)
  146. // aec.release();
  147. // aec=null;
  148. // }
  149. }
  150. //Log.i("AudioInput", "AudioRecord is now unused: stopped");
  151. return 0;
  152. }
  153. if (restart == true && Build.VERSION.SDK_INT >= 14) {
  154. // let's consider restart is not required anymore for 4.0 and above.
  155. restart = false;
  156. }
  157. if (record == null || restart == true) {
  158. if (record != null) {
  159. running = false;
  160. record.stop();
  161. record.release();
  162. record = null;
  163. // if (Build.VERSION.SDK_INT>=16) {
  164. // if (agc!=null)
  165. // agc.release();
  166. // agc=null;
  167. // if (aec!=null)
  168. // aec.release();
  169. // aec=null;
  170. // }
  171. }
  172. int bufsize = AudioRecord.getMinBufferSize(mRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
  173. if (bufsize < 2048)
  174. bufsize = 2048;
  175. bufsize = AudioCompatibility.getAudioRecord_getMinBufferSize(bufsize);
  176. Log.i("AudioInput", "AudioRecord will use buffer = " + bufsize);
  177. record = new AudioRecord(mAudiomanager_audio_source, mRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
  178. bufsize);
  179. if (record != null) {
  180. restart = false;
  181. // if (Build.VERSION.SDK_INT>=16)
  182. // {
  183. // try {
  184. // if (AutomaticGainControl.isAvailable()) {
  185. // int session_id = record.getAudioSessionId();
  186. // agc = AutomaticGainControl.create(session_id);
  187. // if (agc!=null) {
  188. // Log.w("AudioInput",
  189. // "AudioRecord with AGC created / session id = " + session_id);
  190. // if (agc.getEnabled()==false) {
  191. // Log.w("AudioInput", "AudioRecord with AGC not yet enabled");
  192. // agc.setEnabled(true);
  193. // }
  194. // if (agc.getEnabled()==true) {
  195. // Log.w("AudioInput", "AudioRecord with AGC enabled");
  196. // }
  197. // }
  198. // }
  199. // } catch (Exception e) {
  200. // }
  201. // try {
  202. // if (AcousticEchoCanceler.isAvailable()) {
  203. // int session_id = record.getAudioSessionId();
  204. // aec = AcousticEchoCanceler.create(session_id);
  205. // Log.w("AudioInput",
  206. // "AudioRecord with AEC created / session id = " + session_id);
  207. // if (aec!=null) {
  208. // if (aec.getEnabled()==false) {
  209. // Log.w("AudioInput", "AudioRecord with AEC not yet enabled");
  210. // aec.setEnabled(true);
  211. // }
  212. // if (aec.getEnabled()==true) {
  213. // Log.w("AudioInput",
  214. // "AudioRecord with AEC enabled and hasControl = " +
  215. // aec.hasControl());
  216. // }
  217. // }
  218. // }
  219. // } catch (Exception e) {
  220. // }
  221. // }
  222. if (mAudiomanager_audio_source != record.getAudioSource()) {
  223. Log.w("AudioInput", "AudioRecord is using " + record.getAudioSource() + " audio source instead of "
  224. + mAudiomanager_audio_source);
  225. }
  226. }
  227. if (record == null) {
  228. /* resource not yet available? */
  229. running = false;
  230. } else {
  231. Log.w("AudioInput", "AudioRecord finally available!");
  232. running = true;
  233. try {
  234. record.startRecording();
  235. } catch (Exception e) {
  236. try {
  237. record.stop();
  238. } catch (Exception e1) {
  239. }
  240. record.release();
  241. record = null;
  242. // if (Build.VERSION.SDK_INT>=16) {
  243. // if (agc!=null)
  244. // agc.release();
  245. // agc=null;
  246. // if (aec!=null)
  247. // aec.release();
  248. // aec=null;
  249. // }
  250. running = false;
  251. }
  252. }
  253. }
  254. if (record != null) {
  255. int num = record.read(data, 0, len);
  256. if (num==android.media.AudioRecord.ERROR_INVALID_OPERATION) {
  257. try {
  258. record.stop();
  259. } catch (Exception e1) {
  260. }
  261. record.release();
  262. record = null;
  263. running = false;
  264. }
  265. if (muted == true) {
  266. for (int k = 0; k < len; k++) {
  267. data[k] = 0;
  268. }
  269. }
  270. offset += num;
  271. if (num < len) {
  272. Log.w("AudioInput", "AudioRecord return smaller data than expected!" + num + " asked:" + len);
  273. }
  274. return num;
  275. }
  276. return 0;
  277. }
  278. }