Android audio processing through Audiorecord to save PCM files for recording, playback, stop, delete function _android

Source: Internet
Author: User
Tags throwable

Audio this aspect is very profound, I certainly can not speak what advanced things, at most also just some basic knowledge, first, we want to introduce Android he provided the recording class, in fact, he has two, one is Mediarecorder, There is another one that we are going to use today, what is the difference between them? Audiorecord

I. Distinction

Mediarecorder and Audiorecord can record audio, the difference is Mediarecorder recorded audio files are compressed, you need to set the encoder. And the recorded audio file can be played with the music player with the system itself.

And Audiorecord recorded in PCM format audio files, need to play with Audiotrack, audiotrack closer to the bottom.

PCM may be more understandable as a source file for audio

Two. Advantages and disadvantages

Audiorecord

The main is to achieve edge recording and audio real-time processing, this feature makes him more suitable for the voice of the advantage

Advantages: Real-time speech processing, you can use code to achieve a variety of audio encapsulation

Disadvantage: Output is a PCM format file, if saved as audio files, is not able to be played by the player, so must first write code to achieve data coding and compression

Mediarecorder

has integrated recording, coding, compression, and so on, support a small number of recording audio format, probably, AAC,AMR,3GP, etc.

Advantages: integration, directly invoke the relevant interface can be small code

Disadvantage: Unable to process audio in real time; output has not much audio format, for example, no output MP3 format file

Three. Preparatory work

What we want to achieve is a real-time to recording, playback, stop and other functions of the test case, then we must prepare something, for example, I create a project here first--pcmsample

and write a layout.

Layout_main.xml

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/"
Android "Android:layout_width=" Match_parent "android:layout_height=" match_parent "android:orientation=" vertical " android:padding= "10DP" > <button android:id= "@+id/startaudio" android:layout_width= "Match_parent" Android: layout_height= "Wrap_content" android:background= "@drawable/button_bg" android:text= "Start recording" android:textcolor= "@ Android:color/white "/> <button android:id= @+id/stopaudio" android:layout_width= "Match_parent" Android: layout_height= "Wrap_content" android:layout_marginbottom= "10DP" android:layout_margintop= "5DP" Android:background
= "@drawable/button_bg" android:enabled= "false" android:text= "Stop Recording" android:textcolor= "@android: Color/white"/>
<button android:id= "@+id/playaudio" android:layout_width= "match_parent" android:layout_height= "Wrap_content" android:background= "@drawable/button_bg" android:enabled= "false" android:text= "Play Audio" android:textcolor= "@aNdroid:color/white "/> <button android:id= @+id/deleteaudio" android:layout_width= "Match_parent" Android: layout_height= "Wrap_content" android:layout_margintop= "5DP" android:background= "@drawable/button_bg" Android:text = "Delete pcm" android:textcolor= "@android: Color/white"/> <scrollview android:id= "@+id/mscrollview" android:layout
_width= "Match_parent" android:layout_height= "0DP" android:layout_margintop= "5DP" android:layout_weight= "1" > <textview android:id= "@+id/tv_audio_succeess" android:layout_width= wrap_content "android:layout_height=" Wrap_ Content "android:text=" initialization complete .... "android:textcolor=" @color/coloraccent "/> </ScrollView> </ Linearlayout>

You can preview

Here I added a flat effect to the button, actually writing an XML, very simple

Button_bg.xml

<?xml version= "1.0" encoding= "Utf-8"?> <selector xmlns:android=
"http://schemas.android.com/apk/res/" Android ">
<item android:state_pressed=" true ">
<shape>
<corners android:radius=" 30DP "/>
<solid android:color=" @color/colorprimary "/>
</shape>
</item>
< Item android:state_pressed= "false" >
<shape>
<corners android:radius= "30DP"/>
< Solid android:color= "@color/colorprimarydark"/>
</shape>
</item>
</selector >

OK, back to the point, we have four buttons here, respectively, to start. Stop, play, and delete, we just want to implement these four features, before that, we also need to do is add permissions, because we want to record and write memory card files, all need these two permissions can

<!--recording-->
<uses-permission android:name= "Android.permission.RECORD_AUDIO"/>
<!--read SD card >
<uses-permission android:name= "Android.permission.WRITE_EXTERNAL_STORAGE"/>

We're going to go straight to the point where it's initialized.

Four. Start recording

To start recording, here, we define a variable isrecording to control, so it's better to end, and note that the recording is not on the UI thread, you know, so we can write a way to start recording.

Start recording public void Startrecord () {log.i (TAG, "Start recording");//16k acquisition rate int frequency = 16000;//format int channelconfiguration = Aud
Ioformat.channel_configuration_mono;
16Bit int audioencoding = audioformat.encoding_pcm_16bit;
Generating PCM file = new file (Environment.getexternalstoragedirectory (). GetAbsolutePath () + "/REVERSEME.PCM");
LOG.I (TAG, "Generate file");
If present, delete and then create if (File.exists ()) File.delete ();
LOG.I (TAG, "delete file");
try {file.createnewfile ();
LOG.I (TAG, "Create file"); catch (IOException e) {log.i (TAG, failed to create); throw new IllegalStateException ("Failed to create" + file.tostring ());} try {//output stream OUTP
Utstream OS = new FileOutputStream (file);
Bufferedoutputstream BOS = new Bufferedoutputstream (OS);
DataOutputStream dos = new DataOutputStream (BOS);
int buffersize = audiorecord.getminbuffersize (Frequency, channelconfiguration, audioencoding); Audiorecord Audiorecord = new Audiorecord (MediaRecorder.AudioSource.MIC, frequency, channelconfiguration,
Audioencoding, buffersize);
short[] buffer = new Short[buffersize];Audiorecord.startrecording ();
LOG.I (TAG, "Start recording");
IsRecording = true; while (isrecording) {int bufferreadresult = audiorecord.read (buffer, 0, buffersize); for (int i = 0; i < bufferreadres Ult
i++) {dos.writeshort (buffer[i]);}
Audiorecord.stop ();
Dos.close (); catch (Throwable t) {log.e (TAG, "Recording failed");}

First of all, here we understand the sampling rate, coding, audio streaming and other basic concepts, the rest is mostly read-write stream operation, we create a audiorecord to write PCM file, define a while loop, with the isrecording we have just defined, so, Our Click events are

Case R.id.startaudio:
thread thread = new Thread (new Runnable () {
@Override public
void Run () {
Startrecord ();
LOG.E (TAG, "start");
}
);
Thread.Start ();
Printlog ("Start recording");
Buttonenabled (False, True, false);
Break

Here you should pay attention to the Thread.Start (), open the thread, and print out the log, the specific code is as follows

Print log
private void Printlog (final String resultstring) {
tv_audio_succeess.post (new Runnable () {
@ Override public
Void Run () {
tv_audio_succeess.append (resultstring + "\ n");
Mscrollview.fullscroll (Scrollview.focus_down);
}
);

Here, I control the focus of the button to prevent ANR.

Get/Lose focus
private void Buttonenabled (Boolean start, Boolean stop, Boolean play) {
startaudio.setenabled (start) ;
Stopaudio.setenabled (stop);
Playaudio.setenabled (play);
}

Okay, let's run it.

It doesn't seem to change, but you'll find a PCM file in your memory card.

Of course, you just click on the start recording is not generated by this PCM file, you need to click Stop Stop Recording the button

Five. Stop recording

It's easy to stop recording, we control it by changing the write stream.

Case R.id.stopaudio:
isrecording = false;
Buttonenabled (True, false, true);
Printlog ("Stop Recording");
Break

This will generate PCM.

Six play audio

Now with the PCM we can try to play it, write a playback method

Play file public
void PlayRecord () {
if (file = = null) {return
;
}
Read the file
int musiclength = (int) (File.length ()/2);
Short[] music = new Short[musiclength];
try {
InputStream is = new FileInputStream (file);
Bufferedinputstream bis = new Bufferedinputstream (is);
DataInputStream dis = new DataInputStream (bis);
int i = 0;
while (dis.available () > 0) {
music[i] = Dis.readshort ();
i++;
}
Dis.close ();
Audiotrack audiotrack = new Audiotrack (Audiomanager.stream_music,
16000, Audioformat.channel_configuration_ MONO,
audioformat.encoding_pcm_16bit,
musiclength * 2,
audiotrack.mode_stream);
Audiotrack.play ();
Audiotrack.write (music, 0, musiclength);
Audiotrack.stop ();
} catch (Throwable t) {
log.e (TAG, "Play failed");
}

As mentioned above, we need to use Audiotrack for playback, call his play method and set some parameters to

Seven. Remove Audio

Remove audio only need to delete this PCM file on the line

Delete file
private void Delefile () {
if (file = = null) {return
;
}
File.delete ();
Printlog ("File deletion succeeded");
}

This is the general recording logic, although it seems very simple, but this is the most basic part of voice and audio, especially voice, if you are engaged in voice work, I believe you will thank me!

OK, finally put the complete code:

Mainactivity

Package com.liuguilin.pcmsample;
Import Android.media.AudioFormat;
Import Android.media.AudioManager;
Import Android.media.AudioRecord;
Import Android.media.AudioTrack;
Import Android.media.MediaRecorder;
Import Android.os.Bundle;
Import android.os.Environment;
Import android.support.v7.app.AppCompatActivity;
Import Android.util.Log;
Import Android.view.View;
Import Android.widget.Button;
Import Android.widget.ScrollView;
Import Android.widget.TextView;
Import Java.io.BufferedInputStream;
Import Java.io.BufferedOutputStream;
Import Java.io.DataInputStream;
Import Java.io.DataOutputStream;
Import Java.io.File;
Import Java.io.FileInputStream;
Import Java.io.FileOutputStream;
Import java.io.IOException;
Import Java.io.InputStream;
Import Java.io.OutputStream; public class Mainactivity extends appcompatactivity implements View.onclicklistener {public static final String TAG = PC
Msample ";
Whether to record private Boolean isrecording = false;
Start recording private Button Startaudio; End Recording Private Button Stopaudio;
Play the recording private Button Playaudio;
Delete file private Button Deleteaudio;
Private ScrollView Mscrollview;
Private TextView tv_audio_succeess;
PCM files private file file; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (
R.layout.activity_main);
Initview (); }//Initialize view private void Initview () {Mscrollview = (ScrollView) Findviewbyid (r.id.mscrollview); tv_audio_succeess = (Text
View) Findviewbyid (r.id.tv_audio_succeess);
Printlog ("initialization succeeded");
Startaudio = (Button) Findviewbyid (R.id.startaudio);
Startaudio.setonclicklistener (this);
Stopaudio = (Button) Findviewbyid (R.id.stopaudio);
Stopaudio.setonclicklistener (this);
Playaudio = (Button) Findviewbyid (R.id.playaudio);
Playaudio.setonclicklistener (this);
Deleteaudio = (Button) Findviewbyid (R.id.deleteaudio);
Deleteaudio.setonclicklistener (this);  //Click event @Override public void OnClick (View v) {switch (V.getid ()) {case R.id.startaudio:thread thread = new Thread (new Runnable ({@Override public void run () {Startrecord ();
LOG.E (TAG, "start");
}
});
Thread.Start ();
Printlog ("Start recording");
Buttonenabled (False, True, false);
Break
Case r.id.stopaudio:isrecording = false;
Buttonenabled (True, false, true);
Printlog ("Stop Recording");
Break
Case R.id.playaudio:playrecord ();
Buttonenabled (True, false, false);
Printlog ("Play recording");
Break
Case R.id.deleteaudio:delefile ();
Break }//print log private void Printlog (final String resultstring) {tv_audio_succeess.post (new Runnable () {@Override public vo
ID run () {tv_audio_succeess.append (resultstring + "\ n"); Mscrollview.fullscroll (Scrollview.focus_down);}); //Get/Lose Focus private void buttonenabled (Boolean start, Boolean stop, Boolean play) {startaudio.setenabled (start); Stopaudi
O.setenabled (stop);
Playaudio.setenabled (play); //Start recording public void Startrecord () {log.i (TAG, "Start recording");//16k acquisition rate int frequency = 16000;//format int channelconfiguration = Au
Dioformat.channel_configuration_mono; 16Bit int audioencoding = audioformat.encoding_pcm_16bit;
Generating PCM file = new file (Environment.getexternalstoragedirectory (). GetAbsolutePath () + "/REVERSEME.PCM");
LOG.I (TAG, "Generate file");
If present, delete and then create if (File.exists ()) File.delete ();
LOG.I (TAG, "delete file");
try {file.createnewfile ();
LOG.I (TAG, "Create file"); catch (IOException e) {log.i (TAG, failed to create); throw new IllegalStateException ("Failed to create" + file.tostring ());} try {//output stream OUTP
Utstream OS = new FileOutputStream (file);
Bufferedoutputstream BOS = new Bufferedoutputstream (OS);
DataOutputStream dos = new DataOutputStream (BOS);
int buffersize = audiorecord.getminbuffersize (Frequency, channelconfiguration, audioencoding); Audiorecord Audiorecord = new Audiorecord (MediaRecorder.AudioSource.MIC, frequency, channelconfiguration,
Audioencoding, buffersize);
short[] buffer = new Short[buffersize];
Audiorecord.startrecording ();
LOG.I (TAG, "Start recording");
IsRecording = true; while (isrecording) {int bufferreadresult = audiorecord.read (buffer, 0, buffersize); for (int i = 0; i < bufferreadres Ult i++) {DOS. Writeshort (Buffer[i]);
} audiorecord.stop ();
Dos.close ();
catch (Throwable t) {log.e (TAG, "Recording failed");} Play file public void PlayRecord () {if (file = = null) {return;//read file int musiclength = (int) (File.length ()/2); short[]
Music = new Short[musiclength];
try {InputStream is = new FileInputStream (file);
Bufferedinputstream bis = new Bufferedinputstream (IS);
DataInputStream dis = new DataInputStream (bis);
int i = 0;
while (dis.available () > 0) {music[i] = Dis.readshort (); i++;} dis.close ();
Audiotrack audiotrack = new Audiotrack (Audiomanager.stream_music, 16000, Audioformat.channel_configuration_mono,
Audioformat.encoding_pcm_16bit, Musiclength * 2, Audiotrack.mode_stream);
Audiotrack.play ();
Audiotrack.write (music, 0, musiclength);
Audiotrack.stop ();
catch (Throwable t) {log.e (TAG, "Play Failed");} Delete file private void Delefile () {if (file = = null) {return;} file.delete (); Printlog ("file delete succeeded");}

If you want to debug these PCM files to do audio testing, I recommend using audacity this software, you can see, I directly click on the upper left corner of the file-import-source files, and then set 16K

So you can debug it.

Finally, put a complete screenshot

The above is a small series to introduce the Android audio processing through Audiorecord to save PCM files for recording, playback, stop, delete function, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.