如何在不同Android设备中得到有效的AudioRecord实例

如题所述

第1个回答  2017-03-13
import java.nio.ByteBuffer; 
 
import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder.AudioSource; 
import android.os.Process; 
 
/** 
 * Basically what this class does is construct a valid AudioRecord Object, wrap AudioRecord methods, and provide 
 * conversion to decibels. It also caches the AudioRecord configuration and prevents multiple instances of the recorder. 
 *  
 * @author Michael-Pardo/billhoo 
 * @version 0.1 2013-2-18 
 */ 
// TODO(billhoo) the AudioMeter.createAudioRecord() method always returned the first matched configuration currently, 
// if the first combination [8000Hz + PCM16 + IN_MONO] is valid, method returns, but there is no way if I wanna use 
// 16000Hz instead, so this method should be changed to a clever one in the future. 
public class AudioMeter extends Thread { 
 
    // /////////////////////////////////////////////////////////////// 
    // PRIVATE CONSTANTS 
 
    private static final float MAX_REPORTABLE_AMP = 32767f; 
    private static final float MAX_REPORTABLE_DB  = 90.3087f; 
 
    // /////////////////////////////////////////////////////////////// 
    // PRIVATE MEMBERS 
 
    private AudioRecord        mAudioRecord; 
    private int                mSampleRate; 
    private short              mAudioFormat; 
    private short              mChannelConfig; 
 
    private short[]            mBuffer; 
    private int                mBufferSize        = AudioRecord.ERROR_BAD_VALUE; 
 
    private int                mLocks             = 0; 
 
    // /////////////////////////////////////////////////////////////// 
    // CONSTRUCTOR 
 
    private AudioMeter() { 
        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO); // set the AudioMeter thread in URGENT_AUDIO 
                                                                         // priority. 
        createAudioRecord(); 
    } 
 
    // /////////////////////////////////////////////////////////////// 
    // PUBLIC METHODS 
 
    public static AudioMeter getInstance() { 
        return InstanceHolder.INSTANCE; 
    } 
 
    public float getAmplitude() { 
        return (float) (MAX_REPORTABLE_DB + (20 * Math.log10(getRawAmplitude() 
                / MAX_REPORTABLE_AMP))); 
    } 
 
    public synchronized void startRecording() { 
        if (mAudioRecord == null 
                || mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) { 
            throw new IllegalStateException( 
                    "startRecording() called on an uninitialized AudioRecord."); 
        } 
 
        if (mLocks == 0) { 
            mAudioRecord.startRecording(); 
        } 
 
        mLocks++; 
    } 
 
    public synchronized void stopRecording() { 
        mLocks--; 
 
        if (mLocks == 0) { 
            if (mAudioRecord != null) { 
                mAudioRecord.stop(); 
                mAudioRecord.release(); 
                mAudioRecord = null; 
            } 
        } 
    } 
 
    /** 
     * Reads audio data from the audio hardware for recording into a direct buffer. If this buffer is not a direct 
     * buffer, this method will always return 0. 
     *  
     * @param audioBuffer 
     *            the direct buffer to which the recorded audio data is written. 
     * @param sizeInBytes 
     *            the number of requested bytes. 
     * @return the number of bytes that were read or or {@link #ERROR_INVALID_OPERATION} if the object wasn't properly 
     *         initialized, or {@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes. The 
     *         number of bytes will not exceed sizeInBytes. 
     */ 
    public int read(ByteBuffer audioBuffer, int sizeInBytes) { 
        return mAudioRecord.read(audioBuffer, sizeInBytes); 
    } 

    public int read(short[] audioData, int offsetInShorts, int sizeInShorts) { 
        return mAudioRecord.read(audioData, offsetInShorts, sizeInShorts); 
    } 
 

    public int read(byte[] audioData, int offsetInBytes, int sizeInBytes) { 
        return mAudioRecord.read(audioData, offsetInBytes, sizeInBytes); 
    } 
 
 
    public int getSampleRate() { 
        return mSampleRate; 
    } 
 
   
    public int getAudioFormat() { 
        return mAudioFormat; 
    } 
 

    public int getChannelConfiguration() { 
        return mChannelConfig; 
    } 
 

    public int getAudioRecordState() { 
        return mAudioRecord.getState(); 
    } 
 

 
    private void createAudioRecord() { 
        if (mSampleRate > 0 && mAudioFormat > 0 && mChannelConfig > 0) { 
            mAudioRecord = new AudioRecord(AudioSource.MIC, mSampleRate, 
                    mChannelConfig, mAudioFormat, mBufferSize); 
            return; 
        } 
 

        for (int sampleRate : new int[] { 8000, 11025, 16000, 22050, 32000, 
                44100, 47250, 48000 }) { 
            for (short audioFormat : new short[] { 
                    AudioFormat.ENCODING_PCM_16BIT, 
                    AudioFormat.ENCODING_PCM_8BIT }) { 
                for (short channelConfig : new short[] { 
                        AudioFormat.CHANNEL_IN_MONO, 
                        AudioFormat.CHANNEL_IN_STEREO, 
                        AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                        AudioFormat.CHANNEL_CONFIGURATION_STEREO }) { 
 
                    // Try to initialize 
                    try { 
                        mBufferSize = AudioRecord.getMinBufferSize(sampleRate, 
                                channelConfig, audioFormat); 
 
                        if (mBufferSize < 0) { 
                            continue; 
                        } 
 
                        mBuffer = new short[mBufferSize]; 
                        mAudioRecord = new AudioRecord(AudioSource.MIC, 
                                sampleRate, channelConfig, audioFormat, 
                                mBufferSize); 
 
                        if (mAudioRecord.getState() == AudioRecord.STATE_INITIALIZED) { 
                            mSampleRate = sampleRate; 
                            mAudioFormat = audioFormat; 
                            mChannelConfig = channelConfig; 
                            return; 
                        } 
 
                        mAudioRecord.release(); 
                        mAudioRecord = null; 
                    } catch (Exception e) { 
                        // Do nothing 
                    } 
                } 
            } 
        } 
 
               throw new IllegalStateException( 
                "getInstance() failed : no suitable audio configurations on this device."); 
    } 
 
    private int getRawAmplitude() { 
        if (mAudioRecord == null) { 
            createAudioRecord(); 
        } 
 
        final int bufferReadSize = mAudioRecord.read(mBuffer, 0, mBufferSize); 
 
        if (bufferReadSize < 0) { 
            return 0; 
        } 
 
        int sum = 0; 
        for (int i = 0; i < bufferReadSize; i++) { 
            sum += Math.abs(mBuffer[i]); 
        } 
 
        if (bufferReadSize > 0) { 
            return sum / bufferReadSize; 
        } 
 
        return 0; 
    } 
 

    private static class InstanceHolder { 
        private static final AudioMeter INSTANCE = new AudioMeter(); 
    } 

如何在不同Android设备中得到有效的AudioRecord实例
import android.media.AudioRecord; import android.media.MediaRecorder.AudioSource; import android.os.Process; \/** * Basically what this class does is construct a valid AudioRecord Object, wrap AudioRecord methods, and provide * conversion to decibels. It also caches the AudioRecord configuration...

Android音视频【十三】OpenSL ES介绍&基于OpenSL ES实现音频采集_百度...
在实际开发中,首先在AndroidManifest.xml中添加录音权限,然后在项目中链接OpenSLES库。OpenSL ES的开发基于Objects和Interfaces概念,通过创建和管理对象来实现音频功能。创建SLEngineItf对象后,设置输入输出配置,创建录音器并开始录音,通过SLRecordItf接口控制录音状态。采集到的音频数据通过回调函数处理,并在...

如何使用 AudioRecorder 中的录制音频Android
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 onCrea...

如何使Android录音实现内录功能
DEFAULT 默认。在源码 system\/media\/audio\/include\/system\/audio.h配置默认项 无 MIC 麦克风 无 VOICE_UPLINK 电话录音上行线路 android.permission.CAPTURE_AUDIO_OUTPUT,系统权限不允许第三方app使用 VOICE_DOWNLINK 电话录音下行线路 android.permission.CAPTURE_AUDIO_OUTPUT,系统...

如何计算在Android的声音频率是多少
1. 通过AudioRecord类读取Mic传入的数据 2. 对读取的数据进行快速傅立叶变换 3. 计算出进过计算后的复数的模即为需要的频率 第一步很好实现,new 一个AudioRecord即可实现读取mic的输入,简略版代码如下:AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate, AudioFormat...

Android Audio System 之一:AudioTrack如何与AudioFlinger交换_百 ...
现在先通过一个例子来了解一下如何使用 AudioTrack,ToneGenerator是android中产生电话拨号音和其他音调波形的一个实现,我们就以它为例子:ToneGenerator的初始化函数:bool ToneGenerator::initAudioTrack() { \/\/ Open audio track in mono, PCM 16bit\/\/, default sampling rate, default buffer size mp...

如何采集一帧音频
在Android开发中,AudioRecord 类提供了一个帮助你确定这个 bufferSizeInBytes 的函数,原型如下:int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat);不同的厂商的底层实现是不一样的,但无外乎就是根据上面的计算公式得到一帧的大小,音频缓冲区的大小则必须是一帧大小的2...

安卓 能用mediarecorder和mediaplayer实现即时语音吗
public void onMarkerReached(AudioRecord recorder) { \/\/ TODO Auto-generated method stub } };这个特性使用时有个注意点,就是回调只会发生在实际数据读取之后,也就是使用者通过read方法读取出periodInFrames这么多数据时才会触发这个回调,否则什么也不会发生。MeidaPlayer播放音频文件 [java] view ...

如何正确地在Android上计算WebRtc
WebRtc AECM在Android(三星GT-I9100G),并得到了echo抵消“差不多”,但很难计算好值“msInSndCardBuf”的具有编程。 这里的事情,咱之前已经做了: 使用AudioRecord和AudioTrack来处理实时音频的东西,echo出现。 包装WebRtcAecm函数于JNI。 使用WebRtcAecm JNI接口来处理这种echo的东西。咱把它与240...

WebRTC 实现 Android 传屏 demo
在WebRTC中,JavaAudioDeviceModule用于实现音视频的录制与播放,底层采用AudioRecord和AudioTrack。创建PeerConnectionFactory时设置AudioDeviceModule即可。DataChannel专门用于传输音视频流外的数据,如实时文字聊天、文件传输等。通过DataChannel.send()方法相互发送数据,onMessage()回调获取远端发送的数据。DataChannel...

相似回答