Advertisement
saurabhmesh17

Android

Sep 22nd, 2014
390
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.78 KB | None | 0 0
  1. package com.example.audiorecplayfinalaug14;
  2.  
  3.  
  4. /* This Program is used to Record and Play back Some audio
  5. * The Recorded Audio is written to a file, and same file is used during Play back
  6. * */
  7.  
  8. import java.io.DataInputStream;
  9. import java.util.Arrays;
  10. import java.io.File;
  11. import java.io.FileInputStream;
  12. import java.io.FileNotFoundException;
  13. import java.io.FileOutputStream;
  14. import java.io.IOException;
  15. import java.sql.Date;
  16. import java.text.SimpleDateFormat;
  17. import java.util.Calendar;
  18.  
  19. import android.support.v7.app.ActionBarActivity;
  20. import android.support.v7.app.ActionBar;
  21. import android.support.v4.app.Fragment;
  22. import android.media.AudioFormat;
  23. import android.media.AudioManager;
  24. import android.media.AudioRecord;
  25. import android.media.AudioTrack;
  26. import android.media.MediaCodecInfo.CodecCapabilities;
  27. import android.media.MediaRecorder.AudioEncoder;
  28. import android.media.MediaRecorder.AudioSource;
  29. import android.net.rtp.AudioCodec;
  30. import android.os.Bundle;
  31. import android.os.Environment;
  32. import android.util.Log;
  33. import android.view.LayoutInflater;
  34. import android.view.Menu;
  35. import android.view.MenuItem;
  36. import android.view.View;
  37. import android.view.ViewGroup;
  38. import android.widget.Button;
  39. import android.os.Build;
  40.  
  41. public class Main extends ActionBarActivity {
  42.  
  43. private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
  44.  
  45. private String TAG = "AUDIO_RECORD_PLAYBACK_SAURABH";
  46. private static final int RECORDER_BPP = 16;
  47. private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
  48. private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
  49. private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
  50. private static final int RECORDER_SAMPLERATE = 8000;
  51. private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
  52. private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
  53.  
  54. private AudioRecord recorder = null;
  55. private AudioCodec codec = AudioCodec.getCodec(100, "AMR/8000", "mode-set=1");
  56.  
  57. private int bufferSize = 0;
  58.  
  59. /* Threads for Recording/Playing */
  60. private Thread recordingThread = null;
  61. //private Thread playingThread = null;
  62.  
  63. /* Flags for Recording/Playing */
  64. private boolean isRecording = false;
  65. //private boolean isPlaying = false;
  66.  
  67.  
  68. @Override
  69. protected void onCreate(Bundle savedInstanceState) {
  70. Log.d(TAG, "\n\n\n\n======================= Starting Application now =======================");
  71. super.onCreate(savedInstanceState);
  72. setContentView(R.layout.activity_main);
  73.  
  74. setButtonHandlers();
  75.  
  76. enableButton(R.id.btnStartRec,true);
  77. enableButton(R.id.btnStopRec,false);
  78.  
  79. enableButton(R.id.btnStartPlay,false);
  80. enableButton(R.id.btnStopPlay,false);
  81.  
  82. bufferSize = AudioRecord.getMinBufferSize(8000,
  83. AudioFormat.CHANNEL_IN_DEFAULT,
  84. AudioFormat.ENCODING_PCM_16BIT); /* Return 640 */
  85.  
  86. /** Overriding bufferSize value of 640 with 320**/
  87. bufferSize = 320;
  88. Log.d(TAG, "AudioRecord==> Size of 'BufferSize' :" +bufferSize);
  89.  
  90. /**AudioCodec arr[] = codec.getCodecs();
  91. Log.d(TAG, "Supported Codecs :" +Arrays.toString(arr) +"\n");
  92. **/
  93.  
  94. /*if (savedInstanceState == null) {
  95. getSupportFragmentManager().beginTransaction()
  96. .add(R.id.container, new PlaceholderFragment()).commit();
  97. }*/
  98. }
  99.  
  100. private void startRecording()
  101. {
  102. recorder = findAudioRecord();
  103. int i = recorder.getState();
  104. if(i==1)
  105. recorder.startRecording();
  106.  
  107. isRecording = true;
  108. recordingThread = new Thread(new Runnable() {
  109. @Override
  110. public void run() {
  111. writeAudioDataToFile();
  112. }
  113. },"AudioRecorder Thread");
  114. recordingThread.start();
  115. }
  116.  
  117. private void stopRecording(){
  118. if(null != recorder){
  119. isRecording = false;
  120.  
  121. int i = recorder.getState();
  122. if(i==1)
  123. recorder.stop();
  124. recorder.release();
  125. Log.d(TAG, "===== Recording Audio Completed ===== ");
  126.  
  127. recorder = null;
  128. recordingThread = null;
  129. }
  130.  
  131. //copyWaveFile(getTempFilename(), getFilename());
  132. //deleteTempFile();
  133. }
  134.  
  135. public void StartPlaying()
  136. {
  137. int minBufferSize = AudioTrack.getMinBufferSize(8000,
  138. AudioFormat.CHANNEL_OUT_MONO,
  139. AudioFormat.ENCODING_PCM_16BIT); /* Return 640 */
  140.  
  141. /** Overriding bufferSize value of 640 with 320**/
  142. minBufferSize = 320;
  143.  
  144. Log.d(TAG, "===== StartPlaying ==> Value of minBufferSize : ["+minBufferSize+"] ===== ");
  145. int bufferSize = minBufferSize;
  146. AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO,
  147. //AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
  148. AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);
  149.  
  150. int i = 0;
  151. byte[] temp = new byte[bufferSize];
  152. try {
  153. //FileInputStream fin = new FileInputStream("/sdcard/AudioRecorder/audiofile.wav");
  154. //Log.d(TAG, "===== opening file : /sdcard/AudioRecorder/audiofile.wav ===== ");
  155.  
  156. FileInputStream fin = new FileInputStream(raw_filename);
  157. Log.d(TAG, "===== Opening file : "+raw_filename+" ===== ");
  158.  
  159. DataInputStream dis = new DataInputStream(fin);
  160.  
  161. SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
  162. Calendar cal = Calendar.getInstance();
  163. String strDate = s.format(cal.getTime());
  164.  
  165. at.play();
  166. while((i = dis.read(temp, 0, bufferSize)) > -1)
  167. {
  168. cal = Calendar.getInstance();
  169. strDate = s.format(cal.getTime());
  170. //Log.e(TAG, "================== Buffer before Playing ===================="+Arrays.toString(temp));
  171. at.write(temp, 0, i);
  172. //Log.e(TAG, "================== Buffer after Playing ===================="+Arrays.toString(temp));
  173. //Log.d(TAG, "===== Playing Audio ===== Time :"+strDate);
  174. }
  175.  
  176. Log.d(TAG, "===== Playing Audio Completed ===== ");
  177. at.stop();
  178. at.release();
  179. dis.close();
  180. fin.close();
  181.  
  182. } catch (FileNotFoundException e) {
  183. // TODO
  184. e.printStackTrace();
  185. } catch (IOException e) {
  186. // TODO
  187. e.printStackTrace();
  188. }
  189. }
  190.  
  191. private void writeAudioDataToFile()
  192. {
  193. byte data[] = new byte[bufferSize];
  194. String filename = getTempFilename();
  195. FileOutputStream os = null;
  196.  
  197. try {
  198. os = new FileOutputStream(filename);
  199. } catch (FileNotFoundException e) {
  200. // TODO Auto-generated catch block
  201. e.printStackTrace();
  202. }
  203.  
  204. int read = 0;
  205.  
  206. SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
  207. Calendar cal = Calendar.getInstance();
  208. String strDate = s.format(cal.getTime());
  209.  
  210. if(null != os){
  211. while(isRecording){
  212.  
  213. /* Printing Time Stamp */
  214. //Log.e(TAG, "================== Buffer Before Reading ===================="+Arrays.toString(data));
  215. read = recorder.read(data, 0, bufferSize);
  216. //Log.e(TAG, "================== Buffer After Reading ===================="+Arrays.toString(data));
  217.  
  218. cal = Calendar.getInstance();
  219. strDate = s.format(cal.getTime());
  220. //Log.d(TAG, "===== Recording Audio ===== Time :"+strDate);
  221.  
  222. if(AudioRecord.ERROR_INVALID_OPERATION != read){
  223. try {
  224. os.write(data);
  225. } catch (IOException e) {
  226. e.printStackTrace();
  227. }
  228. }
  229. }
  230.  
  231. try {
  232. os.close();
  233. } catch (IOException e) {
  234. e.printStackTrace();
  235. }
  236. }
  237. }
  238.  
  239. private String getFilename(){
  240. String filepath = Environment.getExternalStorageDirectory().getPath();
  241. File file = new File(filepath,AUDIO_RECORDER_FOLDER);
  242.  
  243. if(!file.exists()){
  244. file.mkdirs();
  245. }
  246. return (file.getAbsolutePath() + "/" + "audiofile" + AUDIO_RECORDER_FILE_EXT_WAV);
  247. }
  248.  
  249. private String raw_filename = null;
  250.  
  251. private String getTempFilename(){
  252. String filepath = Environment.getExternalStorageDirectory().getPath();
  253. File file = new File(filepath,AUDIO_RECORDER_FOLDER);
  254.  
  255. if(!file.exists()){
  256. file.mkdirs();
  257. }
  258.  
  259. File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);
  260.  
  261. //if(tempFile.exists())
  262. // tempFile.delete();
  263.  
  264. raw_filename = file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE;
  265. Log.d(TAG, "================= Temp File Name : "+file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE+"=================");
  266. return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
  267. }
  268.  
  269. private void copyWaveFile(String inFilename,String outFilename){
  270. FileInputStream in = null;
  271. FileOutputStream out = null;
  272. long totalAudioLen = 0;
  273. long totalDataLen = totalAudioLen + 36;
  274. long longSampleRate = RECORDER_SAMPLERATE;
  275. int channels = 1;
  276. long byteRate = (RECORDER_BPP/8) * RECORDER_SAMPLERATE * channels;
  277.  
  278. byte[] data = new byte[bufferSize];
  279.  
  280. try {
  281. in = new FileInputStream(inFilename);
  282. out = new FileOutputStream(outFilename);
  283. totalAudioLen = in.getChannel().size();
  284. totalDataLen = totalAudioLen + 36;
  285.  
  286. Log.d(TAG, "File size: " + totalDataLen);
  287.  
  288. WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
  289. longSampleRate, channels, byteRate);
  290.  
  291. while(in.read(data) != -1){
  292. out.write(data);
  293. }
  294. in.close();
  295. out.close();
  296. } catch (FileNotFoundException e) {
  297. e.printStackTrace();
  298. } catch (IOException e) {
  299. e.printStackTrace();
  300. }
  301. }
  302.  
  303. private void WriteWaveFileHeader(
  304. FileOutputStream out, long totalAudioLen,
  305. long totalDataLen, long longSampleRate, int channels,
  306. long byteRate) throws IOException {
  307.  
  308. byte[] header = new byte[44];
  309.  
  310. header[0] = 'R'; // RIFF/WAVE header
  311. header[1] = 'I';
  312. header[2] = 'F';
  313. header[3] = 'F';
  314. header[4] = (byte) (totalDataLen & 0xff);
  315. header[5] = (byte) ((totalDataLen >> 8) & 0xff);
  316. header[6] = (byte) ((totalDataLen >> 16) & 0xff);
  317. header[7] = (byte) ((totalDataLen >> 24) & 0xff);
  318. header[8] = 'W';
  319. header[9] = 'A';
  320. header[10] = 'V';
  321. header[11] = 'E';
  322. header[12] = 'f'; // 'fmt ' chunk
  323. header[13] = 'm';
  324. header[14] = 't';
  325. header[15] = ' ';
  326. header[16] = 16; // 4 bytes: size of 'fmt ' chunk
  327. header[17] = 0;
  328. header[18] = 0;
  329. header[19] = 0;
  330. header[20] = 1; // format = 1
  331. header[21] = 0;
  332. header[22] = (byte) channels;
  333. header[23] = 0;
  334. header[24] = (byte) (longSampleRate & 0xff);
  335. header[25] = (byte) ((longSampleRate >> 8) & 0xff);
  336. header[26] = (byte) ((longSampleRate >> 16) & 0xff);
  337. header[27] = (byte) ((longSampleRate >> 24) & 0xff);
  338. header[28] = (byte) (byteRate & 0xff);
  339. header[29] = (byte) ((byteRate >> 8) & 0xff);
  340. header[30] = (byte) ((byteRate >> 16) & 0xff);
  341. header[31] = (byte) ((byteRate >> 24) & 0xff);
  342. header[32] = (byte) (2 * 16 / 8); // block align
  343. header[33] = 0;
  344. header[34] = RECORDER_BPP; // bits per sample
  345. header[35] = 0;
  346. header[36] = 'd';
  347. header[37] = 'a';
  348. header[38] = 't';
  349. header[39] = 'a';
  350. header[40] = (byte) (totalAudioLen & 0xff);
  351. header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
  352. header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
  353. header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
  354.  
  355. out.write(header, 0, 44);
  356. }
  357.  
  358. /* Method will attempt to find correct combination of Audio Configuration, by attempting
  359. * different combinations of Sampling rate, channel configuration and encoding_types */
  360. public AudioRecord findAudioRecord()
  361. {
  362. for (int rate : mSampleRates) {
  363. for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) {
  364. for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
  365. try {
  366. Log.d(TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
  367. + channelConfig);
  368. int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
  369.  
  370. if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
  371. // check if we can instantiate and have a success
  372. AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
  373.  
  374. if (recorder.getState() == AudioRecord.STATE_INITIALIZED) {
  375. Log.d(TAG, "================== Final Values: rate " + rate + "Hz, audioFormat: " + audioFormat + ", channel: "
  376. + channelConfig+" ==================");
  377. return recorder;
  378. }
  379. }
  380. } catch (Exception e) {
  381. Log.e(TAG, rate + "Exception, keep trying.",e);
  382. }
  383. }
  384. }
  385. }
  386. return null;
  387. }
  388.  
  389. private void deleteTempFile() {
  390. File file = new File(getTempFilename());
  391. file.delete();
  392. }
  393.  
  394. private View.OnClickListener btnClick = new View.OnClickListener() {
  395. @Override
  396. public void onClick(View v) {
  397. switch(v.getId()){
  398. case R.id.btnStartRec:{
  399. Log.d(TAG, "Start Recording");
  400. enableButton(R.id.btnStartRec,false);
  401. enableButton(R.id.btnStopRec,true);
  402. startRecording();
  403. enableButton(R.id.btnStopPlay,false);
  404. break;
  405. }
  406. case R.id.btnStopRec:{
  407. Log.d(TAG, "Stop Recording");
  408. enableButton(R.id.btnStartRec,true);
  409. enableButton(R.id.btnStopRec,false);
  410. stopRecording();
  411. enableButton(R.id.btnStartPlay,true);
  412. break;
  413. }
  414. case R.id.btnStartPlay:{
  415. Log.d(TAG, "Play Recording");
  416. enableButton(R.id.btnStartRec,false);
  417. enableButton(R.id.btnStopRec,false);
  418. StartPlaying();
  419. enableButton(R.id.btnStartPlay,false);
  420. enableButton(R.id.btnStopPlay,true);
  421. break;
  422. }
  423.  
  424. case R.id.btnStopPlay:{
  425. Log.d(TAG, "Stop Playing");
  426. //StopPlaying();
  427. enableButton(R.id.btnStartPlay,true);
  428. enableButton(R.id.btnStopPlay,false);
  429. enableButton(R.id.btnStartRec,true);
  430. break;
  431. }
  432. }
  433. }
  434. };
  435.  
  436. /* Assign OnClickListener to Buttons */
  437. private void setButtonHandlers() {
  438. ((Button)findViewById(R.id.btnStartRec)).setOnClickListener(btnClick);
  439. ((Button)findViewById(R.id.btnStopRec)).setOnClickListener(btnClick);
  440. ((Button)findViewById(R.id.btnStartPlay)).setOnClickListener(btnClick);
  441. ((Button)findViewById(R.id.btnStopPlay)).setOnClickListener(btnClick);
  442. }
  443.  
  444. /* Function to Enable/Disable Buttons */
  445. private void enableButton(int id,boolean isEnable){
  446. ((Button)findViewById(id)).setEnabled(isEnable);
  447. }
  448.  
  449. @Override
  450. public boolean onCreateOptionsMenu(Menu menu) {
  451. // Inflate the menu; this adds items to the action bar if it is present.
  452. getMenuInflater().inflate(R.menu.main, menu);
  453. return true;
  454. }
  455.  
  456. @Override
  457. public boolean onOptionsItemSelected(MenuItem item) {
  458. // Handle action bar item clicks here. The action bar will
  459. // automatically handle clicks on the Home/Up button, so long
  460. // as you specify a parent activity in AndroidManifest.xml.
  461. int id = item.getItemId();
  462. if (id == R.id.action_settings) {
  463. return true;
  464. }
  465. return super.onOptionsItemSelected(item);
  466. }
  467.  
  468. /**
  469. * A placeholder fragment containing a simple view.
  470. */
  471. public static class PlaceholderFragment extends Fragment {
  472.  
  473. public PlaceholderFragment() {
  474. }
  475.  
  476. @Override
  477. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  478. Bundle savedInstanceState) {
  479. View rootView = inflater.inflate(R.layout.fragment_main, container,
  480. false);
  481. return rootView;
  482. }
  483. }
  484.  
  485. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement