package com.example.recorder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class AudioRecorder extends Activity {
private int audioSource = MediaRecorder.AudioSource.MIC;
/ / Set audio sample rate, 44100 is the current standard, but some devices still support 22050,16000,11025
private static int sampleRateInHz = 44100;
Channel CHANNEL_IN_STEREO / / set the audio recording of two channels, CHANNEL_CONFIGURATION_MONO mono
private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
/ / Audio data formats: PCM 16 bits of each sample. Ensure that the device supports. PCM 8 bits for each sample. May not be able to get the device supports.
private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private int bufferSizeInBytes = 0;
private Button btnRecord;
/ / Private Button Stop;
private AudioRecord audioRecord;
private boolean isRecord = false ;/ / set the state of being recorded
/ / AudioName bare audio data file
private static final String AudioName = "/ sdcard / love.raw";
/ / NewAudioName playable audio file
private static final String NewAudioName = "/ sdcard / new.wav";
@ Override
protected void onCreate (Bundle savedInstanceState) {
/ / TODO Auto-generated method stub
super.onCreate (savedInstanceState);
setContentView (R.layout.record);
initUI ();
initData ();
btnRecord.setOnClickListener (new OnClickListener () {
@ Override
public void onClick (View v) {
/ / TODO Auto-generated method stub
if (isRecord) {
btnRecord.setText ("start recording");
stop ();
} Else {
btnRecord.setText ("being recorded ...");
startRecord ();
}
}
});
}
public void initUI () {
btnRecord = (Button) findViewById (R.id.btnRecord);
}
public void initData () {
creatAudioRecord ();
}
private void creatAudioRecord () {
Buffer size in bytes
/ / get
bufferSizeInBytes = AudioRecord.getMinBufferSize (sampleRateInHz,
channelConfig, audioFormat);
/ / Create AudioRecord object
audioRecord = new AudioRecord (audioSource, sampleRateInHz,
channelConfig, audioFormat, bufferSizeInBytes);
}
private void startRecord () {
audioRecord.startRecording ();
/ / Let the recording state true
isRecord = true;
/ / Open the audio file write thread
new Thread (new AudioRecordThread ()) start ();.
}
private void stop () {
if (audioRecord! = null) {
System.out.println ("stopRecord");
isRecord = false ;/ / stop file write
audioRecord.stop ();
}
}
class AudioRecordThread implements Runnable {
@ Override
public void run () {
writeDateTOFile () ;/ / write data to the file bare
copyWaveFile (AudioName, NewAudioName) ;/ / data plus header files to the bare
}
}
/ **
*
* This data is written to the file, but does not play, is obtained as the original audio AudioRecord bare audio,
*
* If you want to play you must add some format or encoding header information. But this advantage is that you can bare the audio data processing, for example, you want to be a talkative TOM
*
* Cat in here for audio processing, and then re-packaged so that this was easier to do some audio audio processing.
* /
private void writeDateTOFile () {
/ / New a byte array to save some bytes of data, the size of the buffer size
byte [] audiodata = new byte [bufferSizeInBytes];
FileOutputStream fos = null;
int readsize = 0;
try {
File file = new File (AudioName);
if (file.exists ()) {
file.delete ();
}
fos = new FileOutputStream (file) ;/ / create documents
an accessible byte
} Catch (Exception e) {
e.printStackTrace ();
}
while (isRecord == true) {
readsize = audioRecord.read (audiodata, 0, bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION! = readsize) {
try {
System.out.println ("writeDateTOFile ...." + readsize);
/ / Fos.write (audiodata);
fos.write (audiodata, 0, readsize);
} Catch (IOException e) {
e.printStackTrace ();
}
}
}
try {
fos.close () ;/ / close the write stream
} Catch (IOException e) {
e.printStackTrace ();
}
}
/ / Get here can play audio files
private void copyWaveFile (String inFilename, String outFilename) {
FileInputStream in = null;
FileOutputStream out = null;
long totalAudioLen = 0;
long totalDataLen = totalAudioLen + 36;
long longSampleRate = sampleRateInHz;
int channels = 2;
long byteRate = 16 * sampleRateInHz * channels / 8;
byte [] data = new byte [bufferSizeInBytes];
try {
in = new FileInputStream (inFilename);
out = new FileOutputStream (outFilename);
totalAudioLen = in.getChannel () size ();.
totalDataLen = totalAudioLen + 36;
WriteWaveFileHeader (out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
int size = 0;
while ((size = in.read (data))! = -1) {
System.out.println ("copyWaveFile ...." + size);
out.write (data, 0, size);
}
in.close ();
out.close ();
} Catch (FileNotFoundException e) {
e.printStackTrace ();
} Catch (IOException e) {
e.printStackTrace ();
}
}
/ **
*
* Here a header. This information can be inserted into the file can be played.
*
* Insert me why this 44 bytes, this really did not in-depth study, but you just open a wav
*
* Audio files can be found in front of the header files can say basically the same, oh. Each file format has
*
* Own unique header files.
* /
private void WriteWaveFileHeader (FileOutputStream out, long totalAudioLen,
long totalDataLen, long longSampleRate, int channels, long byteRate)
throws IOException {
byte [] header = new byte [44];
header [0] = 'R'; / / RIFF / WAVE header
header [1] = 'I';
header [2] = 'F';
header [3] = 'F';
header [4] = (byte) (totalDataLen & 0xff);
header [5] = (byte) ((totalDataLen >> 8) & 0xff);
header [6] = (byte) ((totalDataLen >> 16) & 0xff);
header [7] = (byte) ((totalDataLen >> 24) & 0xff);
header [8] = 'W';
header [9] = 'A';
header [10] = 'V';
header [11] = 'E';
header [12] = 'f'; / / 'fmt' chunk
header [13] = 'm';
header [14] = 't';
header [15] = '';
header [16] = 16; / / 4 bytes: size of 'fmt' chunk
header [17] = 0;
header [18] = 0;
header [19] = 0;
header [20] = 1; / / format = 1
header [21] = 0;
header [22] = (byte) channels;
header [23] = 0;
header [24] = (byte) (longSampleRate & 0xff);
header [25] = (byte) ((longSampleRate >> 8) & 0xff);
header [26] = (byte) ((longSampleRate >> 16) & 0xff);
header [27] = (byte) ((longSampleRate >> 24) & 0xff);
header [28] = (byte) (byteRate & 0xff);
header [29] = (byte) ((byteRate >> 8) & 0xff);
header [30] = (byte) ((byteRate >> 16) & 0xff);
header [31] = (byte) ((byteRate >> 24) & 0xff);
header [32] = (byte) (2 * 16/8); / / block align
header [33] = 0;
header [34] = 16; / / bits per sample
header [35] = 0;
header [36] = 'd';
header [37] = 'a';
header [38] = 't';
header [39] = 'a';
header [40] = (byte) (totalAudioLen & 0xff);
header [41] = (byte) ((totalAudioLen >> 8) & 0xff);
header [42] = (byte) ((totalAudioLen >> 16) & 0xff);
header [43] = (byte) ((totalAudioLen >> 24) & 0xff);
out.write (header, 0, 44);
}
@ Override
protected void onDestroy () {
stop ();
audioRecord.release () ;/ / release resources
audioRecord = null;
super.onDestroy ();
}
}
I copy the above code from the Internet, to achieve AudioRecord recording, and generate WAV file to SDCard.
The problem is that the generated files, playback is completely wrong, a lot faster than the original, the code plus
And a simple layout file to run, the effect can try it yourself. . . .
Hope to have the cause of the problem appears elaborate under similar experience and solutions, be grateful!<-! Main posts under Banner (D4) -><-! Posts under the main text (D5) ->
Reply:
Ladies and gentlemen, to the point of it!
Reply:
In addition to the playback speed, the other is that right? What camera do the test? What system version?
Reply:
You can normally play pcm data, google nuxe s android4.0
Reply:
Reply:
Will the landlord to solve it?
Reply:
The landlord, ask you a question: I just want to collect the bare audio, do not intend to play out, save path is located on the sd card ah (/ sdcard / love.raw), but why they finished recording the sound to find this document? I hope the great God to explain it!
Reply:
Resolved, the landlord, the original configuration file is missing a piece of two lines of code, thanks to three lines of code that you see listed below, or really tangled for a long time ah!
Reply:
That is faster encoding wrong, it should be eight, using 16 of the
Reply:
The landlord did not solve?
No comments:
Post a Comment