【问题标题】:android: Detect sound levelandroid:检测声级
【发布时间】:2012-12-20 07:49:58
【问题描述】:

使用MediaRecorder 我从设备的麦克风中捕捉声音。从我得到的声音中,我只需要分析音量(声音响度),而无需将声音保存到文件中。

两个问题:

  1. 如何及时获取声音在给定时刻的响度?
  2. 如何在不将声音保存到文件的情况下进行分析?

谢谢。

【问题讨论】:

    标签: android audio


    【解决方案1】:
    1. 使用mRecorder.getMaxAmplitude();

    2. 对于声音的分析而不保存所有你需要的是使用mRecorder.setOutputFile("/dev/null");

    举个例子,希望对你有帮助

    public class SoundMeter {
    
        private MediaRecorder mRecorder = null;
    
        public void start() {
                if (mRecorder == null) {
                        mRecorder = new MediaRecorder();
                        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                        mRecorder.setOutputFile("/dev/null"); 
                        mRecorder.prepare();
                        mRecorder.start();
                }
        }
    
        public void stop() {
                if (mRecorder != null) {
                        mRecorder.stop();       
                        mRecorder.release();
                        mRecorder = null;
                }
        }
    
        public double getAmplitude() {
                if (mRecorder != null)
                        return  mRecorder.getMaxAmplitude();
                else
                        return 0;
    
        }
    }
    

    【讨论】:

    • 我喜欢 /dev/null,但我不明白如何每秒获得几次 MaxAmplitude。
    • 我需要连续记录声级(每秒100次)。录制的声级(响度)应该是从我录制的那一刻起。
    • 我解决了。 getMaxAmplitude() 返回在 android 开发网站上是这样解释的:自上次调用以来测量的最大绝对幅度,或第一次调用时为 0,并获取任何秒这个值我使用了计时器。
    • 谢谢安娜。你知道任何关于使用 AudioRecorder 和声音分析的教程吗?我无法在该领域找到更多好的信息 - 或者我不擅长在信息来源之间进行选择。
    • Ana Llera ,getAmplitude() 返回整数。 MB 最佳使用 int getAmplitude()?
    【解决方案2】:

    如果您想分析直接从麦克风获取的声音样本而不将数据保存在文件中,则需要使用 AudioRecord 对象,如下所示:

    int sampleRate = 8000;
    try {
        bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
        audio = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, bufferSize);
    } catch (Exception e) {
        android.util.Log.e("TrackingFlow", "Exception", e);
    }
    

    然后你必须在准备好后开始录制:

    audio.startRecording();
    

    现在是时候开始阅读示例了:

    short[] buffer = new short[bufferSize];
    
        int bufferReadResult = 1;
    
        if (audio != null) {
    
            // Sense the voice...
            bufferReadResult = audio.read(buffer, 0, bufferSize);
            double sumLevel = 0;
            for (int i = 0; i < bufferReadResult; i++) {
                sumLevel += buffer[i];
            }
            lastLevel = Math.abs((sumLevel / bufferReadResult));
    

    最后一个代码结合了所有不同的样本幅度,并将平均值分配给 lastLeveL 变量,有关更多详细信息,您可以转到此post

    问候!

    【讨论】:

    • 这个算法坏了——你不能像这样把值加起来,因为这些是有符号的值。您必须取 数量级 并对它们进行平均。
    • @Martin:“lastLevel”是 MaxAmplitude 吗?实际上我需要计算 'dbValue' 和 'MeanLevelTotal' 值,而且我没有使用预先录制的文件。我正在做现场录音。
    【解决方案3】:

    我玩过一些录音源代码应用程序,但花了一段时间才得到它。

    您可以复制 Google 的 NoiseAlert 源代码——我使用的 SoundMeter 代码。

    getMaxAmplitude 的范围从 0 到 32768。我懒得使用的 EMA 东西。

    在您的主要活动中,您必须声明一个 MediaRecorder 对象并按照 Anna 所引用的方式调用其 start() 函数。

    更多信息可以参考我的项目: http://kaitagsd.wordpress.com/2013/03/25/arduino-project-amplify-part-2-i-e-how-to-transmit-send-data-from-android-to-arduino-bluesmirf-silver-using-bluetooth/ 我需要通过蓝牙发送声音幅度的值。

    确切的代码在这里:https://github.com/garytse89/Amplify/tree/master/Android%20Code/src/com/garytse89/allin

    只浏览与关联的 MediaRecorder 对象有关的部分。

    【讨论】:

    猜你喜欢
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 2020-03-14
    相关资源
    最近更新 更多