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;
        /// <summary>
        /// 當前有記錄真實人音了
        /// </summary>
        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);
        }


        /// <summary>
        /// 獲取麥克風音量
        /// </summary>
        /// <returns></returns>
        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;否則報音頻質量差的問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章