package com.zzk.a1507audiorecord;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
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.view.MotionEvent;
import android.view.View;
import android.widget.*;
import java.io.*;
public class MainActivity extends AppCompatActivity {
File soundFile; // 存放录音的文件
boolean isRecording;
int frequency = 11025;
int inChannelConfig = AudioFormat.CHANNEL_IN_MONO;
int outChannelConfig = AudioFormat.CHANNEL_OUT_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
setContentView(ll);
// 录制到文件:Android/data/<package-name>/files/audioRecord.pcm
soundFile = new File(getExternalFilesDir(null), "audioRecord.pcm");
Button btnRecord = new Button(this);
btnRecord.setText("Record");
ll.addView(btnRecord);
btnRecord.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Thread t = new Thread() {
public void run() {
try {
record();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
}
});
Button btnStop = new Button(this);
btnStop.setText("Stop");
ll.addView(btnStop);
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
isRecording = false;
}
});
Button btnPlay = new Button(this);
btnPlay.setText("Play");
ll.addView(btnPlay);
btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (soundFile.exists()) {
try {
play(frequency);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
Button btnPlayFast = new Button(this);
btnPlayFast.setText("Play Fast");
ll.addView(btnPlayFast);
btnPlayFast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (soundFile.exists()) {
try {
play(frequency * 4 / 3);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
Button btnPlaySlow = new Button(this);
btnPlaySlow.setText("Play Slow");
ll.addView(btnPlaySlow);
btnPlaySlow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (soundFile.exists()) {
try {
play(frequency * 3 / 4);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
Button btnSpeak = new Button(this);
btnSpeak.setText("Press to Speak");
ll.addView(btnSpeak);
btnSpeak.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN:
Thread t = new Thread() {
public void run() {
try {
record();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
break;
case MotionEvent.ACTION_UP:
isRecording = false;
break;
}
return false;
}
});
}
void record() throws IOException {
// 动态权限申请
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
return;
}
if (soundFile.exists()) soundFile.delete();
soundFile.createNewFile();
FileOutputStream fos = new FileOutputStream(soundFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream dos = new DataOutputStream(bos);
int bufferSize = AudioRecord.getMinBufferSize(frequency, inChannelConfig, audioFormat);
short[] buffer = new short[bufferSize];
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, inChannelConfig, audioFormat, bufferSize);
audioRecord.startRecording();
isRecording = true;
while(isRecording){
int bufferRead = audioRecord.read(buffer, 0, bufferSize);
for(int i=0; i<bufferRead; i++){
dos.writeShort(buffer[i]);
}
}
audioRecord.stop();
audioRecord.release();
dos.close();
bos.close();
fos.close();
}
void play(int frq) throws IOException{
int length = (int)soundFile.length()/2;
if(!soundFile.exists() || length==0) {
Toast.makeText(getBaseContext(), "音频文件不存在或为空", Toast.LENGTH_SHORT).show();
return;
}
short[] data = new short[length];
FileInputStream fis = new FileInputStream(soundFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
int i=0;
while(dis.available()>0) {
data[i] = dis.readShort();
i++;
}
dis.close();
bis.close();
fis.close();
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frq, outChannelConfig, audioFormat, length*2, AudioTrack.MODE_STREAM);
audioTrack.play();
audioTrack.write(data, 0, length);
audioTrack.stop();
//audioTrack.release(); // 不能马上release,因为write后是异步播放,此时还刚开始播放,release就不播放了
}
}