实现audioRecord的getMaxAmplitude方法

13

我在我的应用程序中使用AudioRecord而不是MediaRecorder,它工作得很好,但是我有一个逻辑高度依赖于最大振幅,使用AudioRecord非常难以获得。以下是我读取缓冲区时正在使用的内容:

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

但对我来说这不起作用,因为值变化非常快,我需要实现类似于audioRecord的getMaxAmplitude()函数。

3个回答

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

你在这里犯了一个错误吗? 我认为它应该是

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

4

此代码可以满足您的需求并且更多......,它会输出最大点数到一个Excel可读取的文件中。 (我自己也在解决这个问题,所以时机刚刚好。)

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

}

嗨,我正在使用这种方法来录制音频。但是创建的文件无法播放。你能帮忙解决吗? - Vikash
嗨,Vikash,我已经有一段时间没有使用这段代码了,尽管它并不是为了记录音频以便播放而设计的。我当时使用audiorecorder作为临时模拟数字转换器,所以只对数值感兴趣。 - Killer Penguin

3
如果您的编码是ENCODING_PCM_16BIT,那么您应该使用:
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));
}

更多信息请查看 如何在Android中以"wav"格式录制声音


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接