【问题标题】:Android AudioRecord example [closed]Android AudioRecord 示例 [关闭]
【发布时间】:2012-01-19 21:45:22
【问题描述】:

我正在设计一个 Android 应用,我需要实现一个 AudioRecord 类来录制用户的声音。经过一些研究(没有提供足够的信息)和几次失败的尝试,我想知道是否有人可以通过发布一个关于如何使用 AudioRecord 捕获高质量声音的示例(代码)来帮助我。我真的很感激。谢谢

【问题讨论】:

    标签: android audio audiorecord android-audiorecord


    【解决方案1】:

    在这里,我向您发布了一些使用 AudioRecord API 录制优质声音的代码示例。

    注意:如果您在模拟器中使用,音质不会太好,因为我们使用的是仅在模拟器中支持的采样率 8k。在设备中使用 44.1k 的采样率以获得更好的质量。

    public class Audio_Record extends Activity {
        private static final int RECORDER_SAMPLERATE = 8000;
        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;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.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() {
    
            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();
                }
            }, "AudioRecorder Thread");
            recordingThread.start();
        }
    
            //convert short to byte
        private byte[] short2byte(short[] sData) {
            int shortArrsize = sData.length;
            byte[] bytes = new byte[shortArrsize * 2];
            for (int i = 0; i < shortArrsize; i++) {
                bytes[i * 2] = (byte) (sData[i] & 0x00FF);
                bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
                sData[i] = 0;
            }
            return bytes;
    
        }
    
        private void writeAudioDataToFile() {
            // Write the output audio in byte
    
            String filePath = "/sdcard/voice8K16bitmono.pcm";
            short sData[] = new short[BufferElements2Rec];
    
            FileOutputStream os = null;
            try {
                os = new FileOutputStream(filePath);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
    
            while (isRecording) {
                // gets the voice output from microphone to byte format
    
                recorder.read(sData, 0, BufferElements2Rec);
                System.out.println("Short writing to file" + sData.toString());
                try {
                    // // writes the data to file from buffer
                    // // stores the voice buffer
                    byte bData[] = short2byte(sData);
                    os.write(bData, 0, BufferElements2Rec * BytesPerElement);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                os.close();
            } catch (IOException e) {
                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);
        }
    }
    

    欲了解更多详情,请尝试AUDIORECORD BLOG

    编码愉快!!

    【讨论】:

    • 请问数据多久写入一次输出流?还有为什么你读短片,api不提供以字节为单位的读法吗?
    • @JamesClark 取决于您发送到服务器的大小。如果您发送的音频数据 1024 短路,即 2048 字节。那么你必须在 40 毫秒内发送到服务器。你可以读取字节也没有太大区别..
    • 补充:44100 是唯一保证在所有设备上都支持的采样率。 developer.android.com/reference/android/media/AudioRecord.html
    • 谨慎使用此解决方案,因为它将音频样本数截断为 1024,如果大小不是 1024 的倍数,这将导致录制的音频失真。应使用“AudioRecord.获取最小缓冲区大小”。也不需要调用“short2byte”。
    • 什么是 BufferElements2Rec 和 BytesPerElement。请问我怎样才能得到那个值?我是 android 音频记录的新手,现在我正在努力解决它。请。
    【解决方案2】:

    这是我为将 Android 麦克风音频流式传输到服务器进行播放而实现的端到端解决方案:Android AudioRecord to Server over UDP Playback Issues

    【讨论】:

    • 不错的代码!它解决了我的下一个问题。 +1
    猜你喜欢
    • 1970-01-01
    • 2012-01-04
    • 2012-08-14
    • 1970-01-01
    • 2011-04-04
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多