Android实现录音声波图

Android实现录音声波图

本文实例为大家分享了Android实现录音声波图的具体代码,供大家参考,具体内容如下

图像类:

package com.akm.test; /**  * Created by toge on 15/12/9.  */ import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.SurfaceView; import java.util.LinkedList; /**  * A view that displays audio data on the screen as a waveform.  */ public class WaveformView extends SurfaceView {     // The number of buffer frames to keep around (for a nice fade-out visualization).     private static final int HISTORY_SIZE = 6;     // To make quieter sounds still show up well on the display, we use +/- 8192 as the amplitude     // that reaches the top/bottom of the view instead of +/- 32767. Any samples that have     // magnitude higher than this limit will simply be clipped during drawing.     private static final float MAX_AMPLITUDE_TO_DRAW = 8192.0f;     // The queue that will hold historical audio data.     private final LinkedList<short[]> mAudioData;     private final Paint mPaint;     public WaveformView(Context context) {         this(context, null, 0);     }     public WaveformView(Context context, AttributeSet attrs) {         this(context, attrs, 0);     }     public WaveformView(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);         mAudioData = new LinkedList<short[]>();         mPaint = new Paint();         mPaint.setStyle(Paint.Style.STROKE);         mPaint.setColor(Color.WHITE);         mPaint.setStrokeWidth(0);         mPaint.setAntiAlias(true);     }     /**      * Updates the waveform view with a new "frame" of samples and renders it. The new frame gets      * added to the front of the rendering queue, pushing the previous frames back, causing them to      * be faded out visually.      *      * @param buffer the most recent buffer of audio samples      */     public synchronized void updateAudioData(short[] buffer) {         short[] newBuffer;         // We want to keep a small amount of history in the view to provide a nice fading effect.         // We use a linked list that we treat as a queue for this.         if (mAudioData.size() == HISTORY_SIZE) {             newBuffer = mAudioData.removeFirst();             System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);         } else {             newBuffer = buffer.clone();         }         mAudioData.addLast(newBuffer);         // Update the display.         Canvas canvas = getHolder().lockCanvas();         if (canvas != null) {             drawWaveform(canvas);             getHolder().unlockCanvasAndPost(canvas);         }     }     /**      * Repaints the view's surface.      *      * @param canvas the {@link Canvas} object on which to draw      */     private void drawWaveform(Canvas canvas) {         // Clear the screen each time because SurfaceView won't do this for us.         canvas.drawColor(Color.BLACK);         float width = getWidth();         float height = getHeight();         float centerY = height / 2;         // We draw the history from oldest to newest so that the older audio data is further back         // and darker than the most recent data.         int colorDelta = 255 / (HISTORY_SIZE + 1);         int brightness = colorDelta;         for (short[] buffer : mAudioData) {             mPaint.setColor(Color.argb(brightness, 128, 255, 192));             float lastX = -1;             float lastY = -1;             // For efficiency, we don't draw all of the samples in the buffer, but only the ones             // that align with pixel boundaries.             for (int x = 0; x < width; x++) {                 int index = (int) ((x / width) * buffer.length);                 short sample = buffer[index];                 float y = (sample / MAX_AMPLITUDE_TO_DRAW) * centerY + centerY;                 if (lastX != -1) {                     canvas.drawLine(lastX, lastY, x, y, mPaint);                 }                 lastX = x;                 lastY = y;             }             brightness += colorDelta;         }     } }

头文件:

/*  * Copyright (C) 2015 Google Inc.  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ package com.akm.test; import java.io.FileOutputStream; import java.io.IOException; /**  * Created by Akm at 15/12/1 上午10:07  * 文件制作  */ public class WAVHeader {     private byte[] mHeader;          // the complete header.     private int mSampleRate;         // sampling frequency in Hz (e.g. 44100).     private int mChannels;           // number of channels.     private int mNumSamples;         // total number of samples per channel.     private int mNumBytesPerSample;  // number of bytes per sample, all channels included.     public WAVHeader(int sampleRate, int numChannels, int numSamples) {         mSampleRate = sampleRate;         mChannels = numChannels;         mNumSamples = numSamples;         mNumBytesPerSample = 2 * mChannels;  // assuming 2 bytes per sample (for 1 channel)         mHeader = null;         setHeader();     }     public byte[] getWAVHeader() {         return mHeader;     }     public static byte[] getWAVHeader(int sampleRate, int numChannels, int numSamples) {         return new WAVHeader(sampleRate, numChannels, numSamples).mHeader;     }     public String toString() {         String str = "";         if (mHeader == null) {             return str;         }         int num_32bits_per_lines = 8;         int count = 0;         for (byte b : mHeader) {             boolean break_line = count > 0 && count % (num_32bits_per_lines * 4) == 0;             boolean insert_space = count > 0 && count % 4 == 0 && !break_line;             if (break_line) {                 str += '\n';             }             if (insert_space) {                 str += ' ';             }             str += String.format("%02X", b);             count++;         }         return str;     }     private void setHeader() {         byte[] header = new byte[46];         int offset = 0;         int size;         // set the RIFF chunk         System.arraycopy(new byte[]{'R', 'I', 'F', 'F'}, 0, header, offset, 4);         offset += 4;         size = 36 + mNumSamples * mNumBytesPerSample;         header[offset++] = (byte) (size & 0xFF);         header[offset++] = (byte) ((size >> 8) & 0xFF);         header[offset++] = (byte) ((size >> 16) & 0xFF);         header[offset++] = (byte) ((size >> 24) & 0xFF);         System.arraycopy(new byte[]{'W', 'A', 'V', 'E'}, 0, header, offset, 4);         offset += 4;         // set the fmt chunk         System.arraycopy(new byte[]{'f', 'm', 't', ' '}, 0, header, offset, 4);         offset += 4;         System.arraycopy(new byte[]{0x10, 0, 0, 0}, 0, header, offset, 4);  // chunk size = 16         offset += 4;         System.arraycopy(new byte[]{1, 0}, 0, header, offset, 2);  // format = 1 for PCM         offset += 2;         header[offset++] = (byte) (mChannels & 0xFF);         header[offset++] = (byte) ((mChannels >> 8) & 0xFF);         header[offset++] = (byte) (mSampleRate & 0xFF);         header[offset++] = (byte) ((mSampleRate >> 8) & 0xFF);         header[offset++] = (byte) ((mSampleRate >> 16) & 0xFF);         header[offset++] = (byte) ((mSampleRate >> 24) & 0xFF);         int byteRate = mSampleRate * mNumBytesPerSample;         header[offset++] = (byte) (byteRate & 0xFF);         header[offset++] = (byte) ((byteRate >> 8) & 0xFF);         header[offset++] = (byte) ((byteRate >> 16) & 0xFF);         header[offset++] = (byte) ((byteRate >> 24) & 0xFF);         header[offset++] = (byte) (mNumBytesPerSample & 0xFF);         header[offset++] = (byte) ((mNumBytesPerSample >> 8) & 0xFF);         System.arraycopy(new byte[]{0x10, 0}, 0, header, offset, 2);         offset += 2;         // set the beginning of the data chunk         System.arraycopy(new byte[]{'d', 'a', 't', 'a'}, 0, header, offset, 4);         offset += 4;         size = mNumSamples * mNumBytesPerSample;         header[offset++] = (byte) (size & 0xFF);         header[offset++] = (byte) ((size >> 8) & 0xFF);         header[offset++] = (byte) ((size >> 16) & 0xFF);         header[offset++] = (byte) ((size >> 24) & 0xFF);         mHeader = header;     }     public static byte[] getHeader(  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);         return header;     } }

测试:

package com.akm.test; import android.app.Activity; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.AudioTrack; import android.media.MediaPlayer; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.os.Message; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Chronometer; import android.widget.SeekBar; import android.widget.TextView; import com.ringdroid.R; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.ShortBuffer; import java.nio.channels.FileChannel; /**  * Created by toge on 15/11/30.  */ public class Test extends Activity implements View.OnClickListener {     WaveformView waveformView;     private Button btnStart;     private Button btnStop;     private String filePath;     private boolean mRecordingKeepGoing;     private SoundFile soundFile;     private RandomAccessFile randomAccessFile;     private int totalLength;//总长     private int duration;//时长     private int rate;//采样率     private int channelConfig;//声道     private int samples;     private int startPos;     private int bufferSize;//缓冲区大小     private int minBufferSize;//最小缓冲区     private AudioRecord audioRecord;     private AudioTrack audioTrack;     private boolean mThreadFlag;     private int i;     private int j;     private int STATUS = 1;     private int STATUS_PAUSE = 2;     private int STATUS_PREPARED = 1;     private int STATUS_RECORDING = 1;     private Thread audioTrackThread;     private Thread thread;     private int endPos;     private int curFileLength;     OnFileChangedListener onFileChangedListener;     private boolean isRewrite;     private boolean audioTrackFlag;     private int frequency = 22050;//22050;     private int recBufSize;     private String outPath;     private byte[] bytes;     private int time;     private Button btnPasue;     private Button btnPlay;     private Button btnPlay2;     private long startTime;     private long restOfTime;     private int audioFormat;//采集     private int bufferSizeInBytes;//缓冲区大小     private Button btnSave;     //    private ByteBuffer mDecodedBytes; //    private ByteBuffer mDecodedSamples;     private byte[] sampleBytes;     private MediaPlayer mediaPlayer;     private SeekBar seekBar;     private android.os.Handler handler = new android.os.Handler();     Runnable updateThread = new Runnable() {         public void run() {             // 获得歌曲现在播放位置并设置成播放进度条的值             if (mediaPlayer != null) {                 seekBar.setProgress(mediaPlayer.getCurrentPosition());                 Log.e("Test", "run------ updateThread:getCurrentPosition " + mediaPlayer.getCurrentPosition());                 // 每次延迟100毫秒再启动线程                 handler.postDelayed(updateThread, 100);             }         }     };     private Chronometer et_time;     private long falgTime;     private long pauseTime;     private long subtime;     private long beginTime;     private TextView currentTime;     private int currentProgress;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.test);         waveformView = (WaveformView) findViewById(R.id.waveform);         btnStart = (Button) findViewById(R.id.button_start);         btnPasue = (Button) findViewById(R.id.button_pasue);         btnStop = (Button) findViewById(R.id.button2_stop);         btnPlay = (Button) findViewById(R.id.button_play);         btnPlay2 = (Button) findViewById(R.id.button_play2);         btnSave = (Button) findViewById(R.id.button_save);         seekBar = (SeekBar) findViewById(R.id.sb);         et_time = (Chronometer) this.findViewById(R.id.et_time);         currentTime = (TextView) this.findViewById(R.id.currentTime);         btnStart.setOnClickListener(this);         btnPasue.setOnClickListener(this);         btnStop.setOnClickListener(this);         btnPlay.setOnClickListener(this);         btnPlay2.setOnClickListener(this);         btnSave.setOnClickListener(this);         initPar();         initRecorder(true);         initAudioTack();     }     @Override     protected void onResume() {         super.onResume();         initRecorder(false);     }     private void initAudioTack() {         minBufferSize = AudioTrack.getMinBufferSize(rate, 3, audioFormat);         Log.e("Test", "initAudioTack------ minBufferSize:" + minBufferSize);         audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, rate, 1, audioFormat, minBufferSize, AudioTrack.MODE_STREAM);     }     private void initPar() {         duration = 60 * 1000;//毫秒         rate = 44100;//声卡一般提供11.025kHz、22.05kHz和44.1kHz等不同的采样频率         channelConfig = AudioFormat.CHANNEL_IN_DEFAULT;         audioFormat = AudioFormat.ENCODING_PCM_16BIT;         restOfTime = duration;     }     private void initRecorder(boolean isNew) {         initAudioFile(isNew);         bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);         Log.d("Test", "initRecorder: bufferSize:" + bufferSize);//44100 1 2 = v fc //        int k = audioFormat * rate / 25; //        if (bufferSize % k != 0) { //            bufferSize = (k * (channelConfig + bufferSize / k)); //        }         audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, rate, channelConfig, audioFormat, bufferSize);     }     public boolean isRecording() {         return audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING;     }     private void initAudioFile(boolean isNew) {         filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/akm/t.wav";         new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/akm").mkdir();         File f = new File(filePath);         try {             if (f.exists() && isNew) {                 f.delete();             }             randomAccessFile = new RandomAccessFile(filePath, "rw");             //文件长度 = 比特率*时间             //= 采样率*位数*声道 / 8             totalLength = (rate * 1 * 16 / 8) * (duration / 1000); //            totalLength = (int) (4l * (duration * rate / 1000l));             createWaveFile(randomAccessFile, true, totalLength);             totalLength = 44 + totalLength;             randomAccessFile = new RandomAccessFile(filePath, "rw");         } catch (Exception e) {             e.printStackTrace();         }     }     private void createWaveFile(RandomAccessFile randomAccessFile, boolean b, int totalLength) {         if (b) {             try { //                randomAccessFile.write(WAVHeader.getHeader(rate,channels,samples));                 // long totalAudioLen,long totalDataLen, long longSampleRate, int channels, long byteRate                 //数据长度 文件长度 采样率 声道 比特率                 //比特率(字节/秒)= (采样频率(Hz)× 采样位数(bit) × 声道数)/ 8                 //                 long byteRate = (channelConfig * audioFormat * rate) / 8;                 byte[] bytes = WAVHeader.getHeader(totalLength - 36l, totalLength, rate, channelConfig, byteRate);                 FileChannel localFileChannel = randomAccessFile.getChannel();                 localFileChannel.map(FileChannel.MapMode.READ_WRITE, 0l, 44l).put(bytes);                 localFileChannel.close();                 Log.e("Test", "createWaveFile------ OK ");             } catch (IOException e) {                 e.printStackTrace();             }         }     }     @Override     public void onClick(View view) {         switch (view.getId()) {             case R.id.button_start:                 try {                     mRecordingKeepGoing = true;                     new Thread() {                         @Override                         public void run() {                             startRecording();                         }                     }.start();                 } catch (Exception e) {                     e.printStackTrace();                 }                 break;             case R.id.button_pasue:                 mRecordingKeepGoing = false;                 pauseRecord();                 try {//暂停后,设置文件索引为末尾                     startPos = (int) randomAccessFile.getFilePointer();                 } catch (IOException e) {                     e.printStackTrace();                 }                 pausePlay();                 break;             case R.id.button_play:                 startReview(true);                 break;             case R.id.button2_stop:                 mRecordingKeepGoing = false;                 stopRecord();                 stopPlay();                 break;             case R.id.button_save:                 startPos = currentProgress;                 if (randomAccessFile==null){                     try {                         randomAccessFile = new RandomAccessFile(filePath, "rw");                     } catch (IOException e) {                         e.printStackTrace();                     }                 }                 try {                     Log.e("Test", "onClick: pos" + randomAccessFile.getFilePointer());                     int size = ((rate * 1 * 16 / 8) * (currentProgress / 1000));                     Log.e("Test", "onClick------ size "+size);                     if (size<44){                         size = 44;                     }                     randomAccessFile.seek(size);                     randomAccessFile.write(sampleBytes);                     randomAccessFile.close();                 } catch (IOException e) {                     e.printStackTrace();                 }                 Log.e("Test", "onClick------pos "+currentProgress);                 break;             case R.id.button_play2:                 play();                 break;         }     }     private void pausePlay() {         if (mediaPlayer != null && mediaPlayer.isPlaying()) {             // 暂停音乐播放器             mediaPlayer.pause();             btnPasue.setText("续播");             seekBar.setEnabled(false);             et_time.stop();             pauseTime = SystemClock.elapsedRealtime();             // System.out.println("1 pauseTime" + pauseTime);         } else if (mediaPlayer != null                 && "续播".equals(btnPasue.getText().toString())) {             subtime += SystemClock.elapsedRealtime() - pauseTime;             // System.out.println("2 subtime:" + subtime);             mediaPlayer.start();             btnPasue.setText("暂停");             seekBar.setEnabled(true);             beginTime = falgTime + subtime;             // System.out.println("3 beginTime" + beginTime);             et_time.setBase(beginTime);             et_time.start();         }     }     private void stopPlay() {         if (mediaPlayer != null && mediaPlayer.isPlaying()) {             mediaPlayer.stop();             mediaPlayer = null;             et_time.setBase(SystemClock.elapsedRealtime());             et_time.start();             et_time.stop();             btnPlay2.setEnabled(true);             btnPlay2.setClickable(true);         }         falgTime = 0;         subtime = 0;         seekBar.setProgress(0);         seekBar.setEnabled(false);     }     private void play() {         mediaPlayer = new MediaPlayer();         try {             mediaPlayer.setDataSource(filePath);             mediaPlayer.prepareAsync();             // 为播放器注册             mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {                 public void onPrepared(MediaPlayer mp) {                     // TODO Auto-generated method stub                     mediaPlayer.start();                     btnPlay2.setEnabled(false);                     btnPlay2.setClickable(false);                     seekBar.setMax(mediaPlayer.getDuration());                     handler.post(updateThread);                     seekBar.setEnabled(true);                 }             });             // 注册播放完毕后的监听事件             mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {                 public void onCompletion(MediaPlayer mp) { //                    mediaPlayer.release(); //                    mediaPlayer = null;                     btnPlay2.setEnabled(true);                     btnPlay2.setClickable(true);                     et_time.setBase(SystemClock.elapsedRealtime());                     et_time.start();                     et_time.stop();                     seekBar.setProgress(0);                 }             });             falgTime = SystemClock.elapsedRealtime();             et_time.setBase(falgTime);             et_time.start();             et_time.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {                 @Override                 public void onChronometerTick(Chronometer chronometer) {                 }             });             seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {                 @Override                 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                     if (fromUser == true && mediaPlayer != null) {                         Log.e("Test", "onProgressChanged------ progress "+progress);                         mediaPlayer.seekTo(progress);                         falgTime = SystemClock.elapsedRealtime();                         beginTime = falgTime - seekBar.getProgress();                         et_time.setBase(beginTime); //                        et_time.start(); //                        final int ctime = mediaPlayer.getDuration() / progress;                         //时间*比特率 = 大小 (rate * 1 * 16 / 8) * (duration / 1000);                         //时间 = 大小/比特率                         int ctime = progress/((rate * 1 * 16 / 8) * (duration / 1000));                         currentTime.setText( ctime+ "s");                     }                 }                 @Override                 public void onStartTrackingTouch(SeekBar seekBar) {                 }                 @Override                 public void onStopTrackingTouch(SeekBar seekBar) { //                    startPos = seekBar.getProgress();                     currentProgress = seekBar.getProgress();                 }             });         } catch (IOException e) {             e.printStackTrace();         }         // mediaPlayer.prepare(); // c/c++ 播放器引擎的初始化         // 同步方法         // 采用异步的方式     }     private OnEventListener onEventListener;     public void setOnEventListener(OnEventListener onEventListener) {         this.onEventListener = onEventListener;     }     android.os.Handler errorHandler = new android.os.Handler() {         @Override         public void handleMessage(Message msg) {             if (onEventListener != null) {                 onEventListener.onError("error");             }         }     };     private void startThread() {         if (startPos == 0) {//开始位置             try {                 randomAccessFile.seek(44);             } catch (IOException e) {                 e.printStackTrace();             }         }         mThreadFlag = true;         i = 0;         j = -1;         STATUS = 1;         thread = new Thread() {             @Override             public void run() {                 if (startTime == 0) {                     startTime = System.currentTimeMillis();                 }                 byte[] arrayOfByte = new byte[bufferSize];                 short[] arrayOfShort = new short[bufferSize];                 while (mThreadFlag) {                     try {                         if (audioRecord == null || STATUS != 1) {                             continue;                         }                         int bufferReadResult = audioRecord.read(arrayOfByte, 0, bufferSize);                         int bufferReadResult2 = audioRecord.read(arrayOfShort, 0, bufferSize);                         Log.e("Test", "run------ bufferReadResult "+bufferReadResult);                         Log.e("Test", "run------ bufferReadResult2 "+bufferReadResult2);                         if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING || bufferReadResult <= 0) {                             break;                         }                         i = 1;                         randomAccessFile.write(arrayOfByte);                         waveformView.updateAudioData(arrayOfShort);                         byte[] tmpBuf = new byte[bufferReadResult];                         System.arraycopy(arrayOfByte, 0, tmpBuf, 0, bufferReadResult);                         audioTrack.write(tmpBuf, 0, tmpBuf.length);                         pjByteBuffer(tmpBuf);                         curFileLength = (int) randomAccessFile.length() / 1024;                         Log.e("Test", "run------ curFilelength:" + curFileLength + ",startPos:" + startPos + ",endPos:" + endPos + ",isRewrite:" + isRewrite);                         int time = (int) (System.currentTimeMillis() - startTime);                         Log.e("Test", "run------ time: " + time);                         Log.e("Test", "run------ bytes:" + arrayOfByte.length);                         Log.e("Test", "run------ getFilePointer:" + randomAccessFile.getFilePointer());                         startPos = (int) randomAccessFile.getFilePointer();                         if (time >= restOfTime) {                             stopRecord();                         }                         onFileChangedListener.onBufferRecevied(startPos, endPos, arrayOfByte, curFileLength, isRewrite); //                        Test t1 = Test.this; //                        t1.i = 1+t1.i; // //                        long length = randomAccessFile.getFilePointer() + arrayOfByte.length; //                        xxx(this,length); //                        if (endPos>curFileLength){ //                            xxx(this,endPos); //                        } //                        randomAccessFile.write(arrayOfByte); //                        onFileChangedListener.onBufferRecevied(startPos,endPos,arrayOfByte,curFileLength,isRewrite); // //                        Test t2 =Test.this; //                        t2.j = 1+t2.j; //                        if (i!=0||j!=0){ //                            continue; //                        } //                        xxx(this,false); //                        errorHandler.sendEmptyMessage(0);                     } catch (Exception e) {                         e.printStackTrace();                         errorHandler.sendEmptyMessage(0);                     }                 }             }         };         thread.start();     }     private byte[] pjArray(byte[] src, byte[] dest) {         byte[] newBytes = new byte[src.length + dest.length];         System.arraycopy(src, 0, newBytes, 0, src.length);         System.arraycopy(dest, 0, newBytes, src.length, dest.length);         return newBytes;     }     private void pjByteBuffer(byte[] tmpBuf) {         if (sampleBytes == null) {             sampleBytes = tmpBuf;         } else {             sampleBytes = pjArray(sampleBytes, tmpBuf);         }     }     private void pauseReview() {         audioTrackFlag = false;         audioTrack.pause();         audioTrack.flush();         Log.e("Test", "pauseReview------ ");     }     private void startReview(boolean b) {         if (audioTrack == null) {             initAudioTack();         }         audioTrack.play();         audioTrackFlag = true;         audioTrackThread = new Thread() {             @Override             public void run() {                 try {                     bytes = new byte[minBufferSize];                     while (randomAccessFile.read(bytes) != -1 && audioTrackFlag) {                         Log.e("Test", "run------ ");                         Log.e("Test", "run------audiotrackflag is  " + audioTrackFlag);                         Log.e("Test", "run------wrtie data in audiotrack ");                     }                     Log.e("Test", "run------ audiotrack end.");                 } catch (Exception e) {                 }             }         };         audioTrackThread.start();     }     public void pauseRecord() {         if (audioRecord != null) {             audioRecord.stop();             mThreadFlag = false;         }     }     private void reset() {         startPos = 0;         endPos = 0;         curFileLength = 44;         isRewrite = false;     }     private void resumeRecord() {         while (isRewrite) {//写文件             try {                 if (randomAccessFile.getFilePointer() != endPos || !isRewrite) {//不可写 ,或者选中位置不是文件指针所在位置                     startPos = (int) randomAccessFile.getFilePointer(); // 从文件指针位置开始                 }                 if (!isRewrite) {//不写文件                     if (44 + startPos >= endPos) {//                         continue;                     }                     isRewrite = true;                 }             } catch (IOException e) {                 e.printStackTrace();             }             audioRecord.startRecording();             if (thread == null || !mThreadFlag) {                 startThread();             }         }     }     private void startRecording() {         try {             audioRecord.startRecording(); //            if (thread==null||!mThreadFlag){ //                startThread(); //            }             startThread();             Log.e("Test", "startRecording------ ");         } catch (Exception e) {             initRecorder(true);         }     }     public int getMinBufferSize() {         return minBufferSize;     }     public void getMinBufSize() {         recBufSize = AudioRecord.getMinBufferSize(frequency, 12, 2);     }     public void setOnFileChangedListener(OnFileChangedListener onFileChangedListener) {         this.onFileChangedListener = onFileChangedListener;     }     public void setDuration(int duration) {         this.duration = duration;     }     interface OnFileChangedListener {         void onBufferRecevied(long startPos, long endPos, byte[] b1, long currenFileLength, boolean isRew);     }     interface OnEventListener {         void onError(String s);         void onRecordComplete();         void onVolumnChanged(double vl);     }     public String creatFile() { //        copyWaveFile(filePath,filePath,true);         return outPath;     }     private void moveToPrevious(long pl) {         try {             long l = 44 + 4 * (pl * rate / 1000l);             randomAccessFile.seek(l);             Log.e("Test", "moveToPrevious------ offset:" + l + " length:" + randomAccessFile.length());         } catch (Exception e) {         }     }     @Override     protected void onPause() {         super.onPause();         stopRecord();     }     @Override     protected void onStop() {         super.onStop();         closeStream();     }     private void stopRecord() {         try {             mThreadFlag = false;             time = 0;             thread = null;             if (audioRecord != null) {                 if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {                     audioRecord.stop();                     Log.e("Test", "stopRecord------ ");                 }                 audioRecord.release();                 audioRecord = null;             }             closeStream();         } catch (Exception e) {         }     }     private void closeStream() {         try {             if (randomAccessFile != null) {                 randomAccessFile.close();             }         } catch (Exception e) {         }     }     float getDensity() {         DisplayMetrics metrics = new DisplayMetrics();         getWindowManager().getDefaultDisplay().getMetrics(metrics);         return metrics.density;     } }

推荐阅读