我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android实现录音声波图

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android实现录音声波图

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

图像类:

package com.akm.test;


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;


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);
    }

    
    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);
        }
    }

    
    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;
        }
    }
}

头文件:



package com.akm.test;

import java.io.FileOutputStream;
import java.io.IOException;


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;


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[] class="lazy" data-src, byte[] dest) {
        byte[] newBytes = new byte[class="lazy" data-src.length + dest.length];

        System.arraycopy(class="lazy" data-src, 0, newBytes, 0, class="lazy" data-src.length);
        System.arraycopy(dest, 0, newBytes, class="lazy" data-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;
    }


}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android实现录音声波图

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android实现录音声波图

这篇文章主要为大家详细介绍了Android实现录音声波图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

Android中语音声波控件以及条形波控件怎么用

这篇文章主要为大家展示了“Android中语音声波控件以及条形波控件怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Android中语音声波控件以及条形波控件怎么用”这篇文章吧。SoundW
2023-05-30

Android实现录音静音降噪

这篇文章主要为大家详细介绍了Android实现录音静音降噪,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

Android录制声音文件(音频)并播放

本文实例为大家分享了Android录制音频文件的具体代码,供大家参考,具体内容如下1、这个demo中没有对多次点击同一个声音文件做详细处理,偶尔会有崩溃,用的时候需要注意。 2、按住录音按钮录音过程中,只对竖直方向处理了一下,水平方向没写;
2022-06-06

Android实现音频录音与播放

这篇文章主要为大家详细介绍了Android实现音频录音与播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

vue实现录音功能js-audio-recorder带波浪图效果的示例

这篇文章主要介绍了vue实现录音功能js-audio-recorder带波浪图效果,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-11-13

windows7系统怎么调节声音的波形图文教程

点击电脑的左下角扬声器 进入这个里的 扬声器图标 进入之后是这样的 进入[级别python]选项卡 编程客栈 &nbpythonsp; 进入第一个[平衡www.cppcns.comB]的选项只要调节 左前和右前两个选项的变化大小取不
2023-05-30

Java怎么实现图像与声音效果

这篇文章主要介绍“Java怎么实现图像与声音效果”,在日常操作中,相信很多人在Java怎么实现图像与声音效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么实现图像与声音效果”的疑惑有所帮助!接下来
2023-06-03

Android实现多媒体录音笔

记事本涉及到的仅仅是对string 的存储,而且在读取上并不存在什么难点,直接用textview显示便可以了。需要做的主要是使用SQLite对数据进行一个整理。 而录音笔需要考虑的就相对较多了:比如录音时中断,录音时用户点击播放按钮;未录音
2022-06-06

Android如何实现录音功能

这篇文章给大家分享的是有关Android如何实现录音功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。本文介绍了Android实现录音的实例代码(MediaRecorder),分享给大家,具体如下:Android
2023-05-30

Android实现云知声版离线语音合成

目录简介在线合成和离线合成(合成速度)集成方法在AndroidManifest.xml设置所需要的权限使用方法总结简介 科大讯飞:合成速度快,准确度高,模型多。但问题也是相当明显,只有在线合成是免费的,离线则是一笔不小的开销。 百度:是专门
2022-06-07

android MediaRecorder实现录屏时带录音功能

下面说说android的事把 最近是不是也会遇到需求中需要用到录屏录音的功能,最近也是遇到的 现在整理完记录一下 首先呢,录音录屏需要权限 先贴一个动态权限类public class TalAllow {/*** RECORD_AUDIO
2022-06-07

Android使用AudioRecord实现录音功能

这篇文章主要为大家详细介绍了Android使用AudioRecord实现录音功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

HTML5中怎么实现声音录制/播放功能

这篇文章主要介绍HTML5中怎么实现声音录制/播放功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!html代码:
2023-06-09

Android使用Flutter实现录音插件

这篇文章主要介绍了基于flutter实现录音功能,介绍了如何录音,如何把文件存放到本地,这些都是我们平常使用这个功能会遇到的问题。在使用的过程中遇到的问题也有列出,需要的朋友可以参考下
2022-11-13

Android实现拍照、录像、录音代码范例

本文主要介绍Android实现拍照、录像、录音代码的资料,这里整理了详细的代码,有需要的小伙伴可以参考下。RecordActivity.java package com.cons.dcg.collect; import java.io
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录