Implement getMaxAmplitude for audioRecord

醉酒当歌 提交于 2019-12-04 20:25:36

问题


I am using audioRecord instead of mediarecorder in my app it's working fine but I have a logic that depends highly on the maxamplitude which is really hard to obtain using the audiorecord here is what I am using when reading the buffer

 private void writeAudioDataToFile(){
        byte data[] = new byte[bufferSize];

        String filename = getTempFilename();
        FileOutputStream os = null;

        try {
            os = new FileOutputStream(filename);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int read = 0;
        max=0;
        if(null != os){
            while(isRecording){
                read = recorder.read(buffer, 0, bufferSize);
                int ab = (buffer[0] & 0xff) << 8 | buffer[1];
                amplitude = Math.abs(ab);

            if(amplitude>0&&amplitude<25000)
                isSilence=true;         
            else
                isSilence=false;

                //System.out.println(">>>>>>>>>>>"+amplitude);
                if(AudioRecord.ERROR_INVALID_OPERATION != read){
                    try {
                        os.write(buffer);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

but this doesn't work for me as the value changes real fast I need to implement something like getMaxAmplitude() for audioRecord.


回答1:


This does what you want and more... then it outputs the max points to a file which is readable in excel. (I was solving this problem myself, so timing is fortuitous.)

package com.example.audiorecord;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;


public class MainActivity extends Activity {
        private static final int RECORDER_SAMPLERATE = 44100;
        private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
        private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
        private AudioRecord recorder = null;
        private Thread recordingThread = null;
        private boolean isRecording = false;
        private String floatString = "";

        Calendar c = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat("ddMMMyyyy_HHmmss");
        String formattedDate = df.format(c.getTime());

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            setButtonHandlers();
            enableButtons(false);

            int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
                    RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 
        }

        private void setButtonHandlers() {
            ((Button) findViewById(R.id.btnStart)).setOnClickListener(btnClick);
            ((Button) findViewById(R.id.btnStop)).setOnClickListener(btnClick);
        }

        private void enableButton(int id, boolean isEnable) {
            ((Button) findViewById(id)).setEnabled(isEnable);
        }

        private void enableButtons(boolean isRecording) {
            enableButton(R.id.btnStart, !isRecording);
            enableButton(R.id.btnStop, isRecording);
        }

        int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
        int BytesPerElement = 2; // 2 bytes in 16bit format

        private void startRecording() {
            final File logFile = new File("sdcard/log_"+formattedDate+".txt");
               if (!logFile.exists())
               {
                  try
                  {
                     logFile.createNewFile();
                  } 
                  catch (IOException e)
                  {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                  }
               }

            recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    RECORDER_SAMPLERATE, RECORDER_CHANNELS,
                    RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);

            recorder.startRecording();
            isRecording = true;
            recordingThread = new Thread(new Runnable() {
                public void run() {
                    writeAudioDataToFile(logFile);
                }
            }, "AudioRecorder Thread");
            recordingThread.start();
        }


        private void writeAudioDataToFile(File logFile) {
            // Write the output audio in byte

            short sData[] = new short[BufferElements2Rec];
            while (isRecording) {
                // gets the voice output from microphone to byte format

                recorder.read(sData, 0, BufferElements2Rec);
                String sDataString = "";
                double sDataMax = 0;
                for(int i=0; i<sData.length; i++){
                    if(Math.abs(sData[i])>=sDataMax){sDataMax=Math.abs(sData[i]);};
                    sDataString += "\n" + sDataMax;

                }

               try
               {
                  //BufferedWriter for performance, true to set append to file flag
                  BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
                  buf.append(sDataString);
                  buf.newLine();
                  buf.close();
               }
               catch (IOException e)
               {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }
        }
        }
        private void stopRecording() {
            // stops the recording activity
            if (null != recorder) {
                isRecording = false;
                recorder.stop();
                recorder.release();
                recorder = null;
                recordingThread = null;
            }
        }

        private View.OnClickListener btnClick = new View.OnClickListener() {
            public void onClick(View v) {
                switch (v.getId()) {
                case R.id.btnStart: {
                    enableButtons(true);
                    startRecording();
                    break;
                }
                case R.id.btnStop: {
                    enableButtons(false);
                    stopRecording();
                    break;
                }
                }
            }
        };

        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                finish();
            }
            return super.onKeyDown(keyCode, event);
        }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}



回答2:


int amplitude = (buffer[0] & 0xff) << 8 | buffer[1];
amplitude = Math.abs(ab);

Do you make a mistake here? I think it should be

int ab = (buffer[0] & 0xff) << 8 | buffer[1];
int amplitude = Math.abs(ab);



回答3:


If your encoding is ENCODING_PCM_16BIT , Then you should use

private int cAmplitude= 0;

while(isRecording) {
    read = recorder.read(data, 0, bufferSize);

    for (int i=0; i<read/2; i++) {
        short curSample = getShort(data[i*2], data[i*2+1]);
        if (curSample > cAmplitude) {
            cAmplitude = curSample;
        }
    }

    Log.d("amplitude",Integer.toString(cAmplitude));
    cAmplitude = 0;
}

private short getShort(byte argB1, byte argB2) {
    return (short)(argB1 | (argB2 << 8));
}

For more info, have a look at How to record voice in "wav" format in Android



来源:https://stackoverflow.com/questions/11700149/implement-getmaxamplitude-for-audiorecord

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!