在Unity中,如何根据响度从麦克风分割用户的声音?

时间:2019-04-18 13:23:33

标签: unity3d audio-recording

我需要从连续的音频流中收集语音片段。稍后,我需要处理刚刚说过的用户语音(不是用于语音识别)。我只关注基于声音响度的声音分割。

如果至少沉默一秒钟后,他的声音变得足够响亮一会儿,然后再次沉默至少一秒钟,我说这是一个句子,应该在这里将声音分段。

我只知道我可以从<div class="container search-light-grey"> <div class="rows-search"> <div id="1"> test-01 <div> 1 </div> <div> <div> 2a </div> <div> 2b </div> <div> 2c </div> </div> </div> <div id="2">test-02</div> <div id="3">test-03</div> <div id="4">test-04</div> </div> </div>创建的AudioClip获取原始音频数据。我想写一些这样的代码:

Microphone.Start()

但是我不确定的是:

  1. 当我调用void Start() { audio = Microphone.Start(deviceName, true, 10, 16000); } void Update() { audio.GetData(fdata, 0); for(int i = 0; i < fdata.Length; i++) { u16data[i] = Convert.ToUInt16(fdata[i] * 65535); } // ... Process u16data } 的每一帧时,如果audio.GetData(fdata, 0)足够大,或者比{{1}足够大,对吗?

  2. fdata是一个浮点数组,我需要一个16 kHz,16位PCM缓冲区。像这样fdata转换数据是否正确?

  3. fdata中检测响亮时刻和沉默时刻的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

  1. 否。您必须使用Microphone.GetPosition

    AudioClip中的当前位置开始阅读
      

    获取录音样本中的位置。

    并将获得的索引传递到AudioClip.GetData

      

    使用offsetSamples参数从片段中的特定位置开始读取

    fdata = new float[clip.samples * clip.channels];
    
    var currentIndex = Microphone.GetPosition(null);
    audio.GetData(fdata, currentIndex);
    
  2. 我不明白您将其转换为什么。 fdata将包含

      

    浮动范围从-1.0f1.0fAudioClip.GetData

    因此,如果出于某种原因,您需要在short.MinValue (= -32768)short.MaxValue(= 32767)之间获取值,则可以使用

    u16data[i] = Convert.ToUInt16(fdata[i] * short.MaxValue);
    

    请注意,Convert.ToUInt16(float)

      

    值,四舍五入为最接近的16位无符号整数。如果值在两个整数之间,则返回偶数;否则,返回偶数。即4.5转换为4,5.5转换为6。

    如果某个值是例如,您可能更希望先使用Mathf.RoundToInt进行四舍五入。 4.5

    u16data[i] = Convert.ToUInt16(Mathf.RoundToInt(fdata[i] * short.MaxValue));
    

    但是,您的命名建议您实际上是在尝试获取无符号值ushort(或UInt16)。为此,您可以具有值!因此,您必须向上移动浮点值,才能将范围(-1.0f | 1.0f)映射到范围(0.0f | 1.0f),然后再乘以{{ 3}}

    u16data[i] = Convert.ToUInt16(Mathf.RoundToInt(fdata[i] + 1) / 2 * ushort.MaxValue);
    
  3. 您从ushort.MaxValue(= 65535)接收到的是-1.0f1.0f之间的音轨的增益值。

    那么“大声”的时刻就在哪里

    Mathf.Abs(fdata[i]) >= aCertainLoudThreshold;
    

    一个“沉默”的时刻将在哪里

    Mathf.Abs(fdata[i]) <= aCertainSiltenThreshold;
    

其中aCertainSiltenThreshold例如例如为0.2faCertainLoudThreshold0.8f