MicroPhoneInput 自动判定音源录入+百度音频录入的问题

需求:

      进入音频录制状态,麦克风一直处于打开(录制状态); 只有当真实收到外部音源时(比如有人说话);才开始将这段音频作为真实录制的音频; 当没人说话2s,就截取这段音频作为有效音频发布出去。

(模仿实时流音频的发送)

1. 百度语音翻译和语音控制。

  要求是一段音频流传上去进行处理,这个时候麦克风处于打开,不需要用户去点按钮录制;自动判定有效音频发送。

2.这里就需要用到 Microphone.GetPosition 来做判断

源码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using System.IO;

namespace nn
{
    public class testdemo : MonoBehaviour
    {
        private enum AudioRecordResultState { start, stop }
        [SerializeField] private int maxClipLength = 300;
        [HideInInspector] public bool isRecording = false;


        private const int RECORD_TIME = 300;//最长录制5分钟

        private const int ClearAudioTime = 10;//每隔10秒清空1个无效数据;就是没有音源记录的数据

        private AudioClip recordedClip;
        private int _sampleWindow = 128;
        private float recordTimer = 0.0f;

        private static string[] micArray;

        private float limateAudioLevel = 0.1f;
        ///


        /// 当前有记录真实人音了
        ///

        private bool CurrentHaveRecordRealAudio = false;

        private AudioRecordResultState currentTyp = AudioRecordResultState.stop;

        private float disTime = 0;

        private int startsimple = 0;
        private float noAudiodisTime = 0;
        void Start()
        {
            micArray = Microphone.devices;
            // Type[] allType = GetHotfixTypes();

            // BlockBaseDataTypeList = allType.Where(type => !type.IsAbstract).Where(type => typeof(MonoBehaviour) == type.BaseType).ToList();

            // Debug.LogError(allType.Length+"   "+BlockBaseDataTypeList.Count);

            Play();
        }
        public void Play()
        {
            Debug.LogError("@@@@@@");
            if (micArray.Length == 0)
            {
                Debug.Log("No Record Device!");
                return;
            }
            noAudiodisTime = Time.time + ClearAudioTime;
            CurrentHaveRecordRealAudio = false;
            if (recordedClip != null)
            {
                Microphone.End(null);
                DestroyImmediate(recordedClip);
                recordedClip = null;
            }

            recordedClip = Microphone.Start(null, false, RECORD_TIME, 16000 ); //44100
            float a = Microphone.GetPosition(null);
            while (!(Microphone.GetPosition(null) > 0))
            {
            }

            currentTyp = AudioRecordResultState.start;
            Debug.Log("StartRecord");
        }

        public void Stop() {

            currentTyp = AudioRecordResultState.stop;
        }

        public Type[] GetHotfixTypes()
        {
           
            foreach(var a in AppDomain.CurrentDomain.GetAssemblies())
            {
                Debug.LogError(a.FullName);
            }
            return null;

        }
        void Update()
        {
            if (currentTyp == AudioRecordResultState.start)
            {
                float value = GetLevelMax();
               // Debug.LogError(value);
                if (value >= limateAudioLevel)
                {
                    disTime = Time.time + 2;

                    if (!CurrentHaveRecordRealAudio)
                    {
                        Debug.LogError("!!!!!!!!!!!!!!$$$   "+ value);
                        startsimple = Microphone.GetPosition(null)-1;
                        startsimple = Mathf.Max(0, startsimple);
                        CurrentHaveRecordRealAudio = true;
                    }
                }


                if (CurrentHaveRecordRealAudio)
                {
                    if (value < limateAudioLevel && Time.time>= disTime) {
                        Debug.LogError("!!!!!!!!!!!!!!!!!!!!11111122222");
                        //todo sendAudio
                        SendAudio();
                    }
                 
                }
                else
                {
                    if (recordedClip != null&& Time.time>= noAudiodisTime) {
                        Debug.LogError(recordedClip.length+"!!!!!!!!!!!!!!!^^ "+ ClearAudioTime);
                        Play();
                    }
                   
                }
            }
        }

        public void SendAudio() {

            CurrentHaveRecordRealAudio = false;
            disTime = Time.time + 2;
            int endPoint = Microphone.GetPosition(null);
            var samples = new float[endPoint- startsimple];

            recordedClip.GetData(samples, startsimple);

            var newrecordedClip = AudioClip.Create(recordedClip.name,
                                   (endPoint - startsimple),
                                   recordedClip.channels,
                                   recordedClip.frequency,
                                   false);

            newrecordedClip.SetData(samples, 0);

            string file;
            var data = WavUtility.FromAudioClip(newrecordedClip, out file, true);
            Destroy(newrecordedClip);
        }


        ///


        /// 获取麦克风音量
        ///

        ///
        public float GetLevelMax()
        {
            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;
            recordedClip.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;
        }

    }
}

 

百度语音上传的注意事项:

  麦克风需要16K录制  即 16000 ;而不是通常的44100;否则报音频质量差的问题

你可能感兴趣的:(unity,c#)