首页 文章

Unity3d:检查麦克风输入音量

提问于
浏览
1

我想在可视化表示中使用用户在Unity3d中输入的麦克风音量 . 所以我'd like to get a value between 0 and 1 that tell how loud the user is. I went looking for a script, but the part that handles the volume doesn' t正常工作,那部分是方法 LevelMax() . 出于某种原因, micPosiotion 永远不会高于0.我不知道 Microphone.GetPosition 除了这个之外真的做了什么:

http://docs.unity3d.com/ScriptReference/Microphone.GetPosition.html

有谁知道方法 LevelMax() 出了什么问题?我没有任何错误或任何错误 . 它正确找到我的麦克风,它正在工作 . 我测试了它 .

这是代码:

using UnityEngine;
using System.Collections;

public class MicInput : MonoBehaviour{

    public float testSound;
    public static float MicLoudness;
    private string _device;
    private AudioClip _clipRecord = new AudioClip();
    private int _sampleWindow = 128;
    private bool _isInitialized;

    void InitMic()
    {
        if (_device == null) {
            _device = Microphone.devices [0];
            _clipRecord = Microphone.Start (_device, true, 999, 44100);
            Debug.Log (_clipRecord);
        }
    }

    void StopMicrophone()
    {
        Microphone.End (_device);
    }

    float LevelMax()
    {
        float levelMax = 0;
        float[] waveData = new float[_sampleWindow];
        int micPosition = Microphone.GetPosition (null) - (_sampleWindow + 1);
        if (micPosition < 0) {
            return 0;
        }
        _clipRecord.GetData (waveData, micPosition);
        for (int i = 0; i < _sampleWindow; ++i) {
            float wavePeak = waveData [i] * waveData [i];
            if (levelMax < wavePeak) {
                levelMax = wavePeak;
            }
        }
        return levelMax;
    }

    void Update()
    {
        MicLoudness = LevelMax ();
        testSound = MicLoudness;

    }

    void OnEnable()
    {
        InitMic ();
        _isInitialized = true;
    }

    void OnDisable()
    {
        StopMicrophone ();
    }

    void OnDestory()
    {
        StopMicrophone ();
    }

    void OnApplicationFocus(bool focus)
    {
        if (focus) {
            if (!_isInitialized) {
                InitMic ();
                _isInitialized = true;
            }
        }

        if (!focus) {
            StopMicrophone ();
            _isInitialized = false;
        }
    }

}

2 回答

  • 3

    这个脚本有效 . 我刚测试了它,它在检查器中显示了麦克风的峰值水平,作为变量 testSound . 你的问题出现了一些问题,导致它无法开始录入音频录音 . 这就是为什么总是返回 micPosition 小于零的原因 .

    我能看到的唯一一点就是 LevelMax 方法中的 Microphone.GetPosition(null) . 尝试将此更改为 Microphone.GetPosition(_device)

    您可能还想通过更改行中传递的索引(在 InitMic 方法中)尝试浏览不同的音频设备:

    _device = Microphone.devices [0];
    

    尝试将其更改为1,2,3等,看看你是否只是找到了错误的音频设备 . 如果您有多个麦克风或没有使用默认麦克风,那么这可能是问题所在 .


    另外,我认为你误解了数字音频的工作原理 . GetPosition 获取麦克风正在录制的当前样本到音频片段(即最新的样本/当前样本) . 这基本上意味着它获得了已记录的样本量 . 您正在录制44.1Khz样本 . 这意味着每秒检查音频441000次,并为该单个样本分配一个级别 . 这称为采样率,可以更改 . 例如,CD使用44.1kHz的采样率,而数字视频往往使用48kHz . 记录样本的准确性由比特深度定义(但是你不要使用16比特(需要抖动),而数字媒体使用24比特(通常) . 线路:

    int micPosition = Microphone.GetPosition(null)-(_sampleWindow+1);
    

    说“找到我们在129个样本前记录的样本量” . 然后,它迭代接下来的128个样本的值,找到“最响亮”的样本并返回它 . 然后在检查员中显示 . 如果您不理解我刚才所说的任何内容,那么请研究如何记录数字音频 . 理解它的基础知识并不太复杂 .

  • 0

    你应该看看这个thread,但这里有代码可以帮助你:

    public class MicInput : MonoBehaviour {
    
            public static float MicLoudness;
    
            private string _device;
    
            //mic initialization
            void InitMic(){
                if(_device == null) _device = Microphone.devices[0];
                _clipRecord = Microphone.Start(_device, true, 999, 44100);
            }
    
            void StopMicrophone()
            {
                Microphone.End(_device);
            }
    
    
            AudioClip _clipRecord = new AudioClip();
            int _sampleWindow = 128;
    
            //get data from microphone into audioclip
            float  LevelMax()
            {
                float levelMax = 0;
                float[] waveData = new float[_sampleWindow];
                int micPosition = Microphone.GetPosition(null)-(_sampleWindow+1); // null means the first microphone
                if (micPosition < 0) return 0;
                _clipRecord.GetData(waveData, micPosition);
                // Getting a peak on the last 128 samples
                for (int i = 0; i < _sampleWindow; i++) {
                    float wavePeak = waveData[i] * waveData[i];
                    if (levelMax < wavePeak) {
                        levelMax = wavePeak;
                    }
                }
                return levelMax;
            }
    
    
    
            void Update()
            {
                // levelMax equals to the highest normalized value power 2, a small number because < 1
                // pass the value to a static var so we can access it from anywhere
                MicLoudness = LevelMax ();
            }
    
            bool _isInitialized;
            // start mic when scene starts
            void OnEnable()
            {
                InitMic();
                _isInitialized=true;
            }
    
            //stop mic when loading a new level or quit application
            void OnDisable()
            {
                StopMicrophone();
            }
    
            void OnDestroy()
            {
                StopMicrophone();
            }
    
    
            // make sure the mic gets started & stopped when application gets focused
            void OnApplicationFocus(bool focus) {
                if (focus)
                {
                    //Debug.Log("Focus");
    
                    if(!_isInitialized){
                        //Debug.Log("Init Mic");
                        InitMic();
                        _isInitialized=true;
                    }
                }      
                if (!focus)
                {
                    //Debug.Log("Pause");
                    StopMicrophone();
                    //Debug.Log("Stop Mic");
                    _isInitialized=false;
    
                }
            }
        }
    

相关问题