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

问题描述 投票:0回答:1

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

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

我只知道我可以从AudioClip创建的Microphone.Start()获取原始音频数据。我想写一些像这样的代码:

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
}

但我不确定的是:

  1. 每当我打电话给audio.GetData(fdata, 0)时,我得到的是最新的10秒声音数据,如果fdata足够大或短于10秒,如果fdata不够大,是不是?
  2. fdata是一个浮点数组,我需要的是16 kHz,16位PCM缓冲区。转换数据是否正确:u16data[i] = fdata[i] * 65535
  3. fdata中检测大声时刻和无声时刻的正确方法是什么?
unity3d audio-recording
1个回答
1
投票
  1. 不,你必须使用AudioClipMicrophone.GetPosition的当前位置开始阅读 获取录音样本中的位置。 并将选择的索引传递给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.5u16data[i] = Convert.ToUInt16(Mathf.RoundToInt(fdata[i] * short.MaxValue)); 然而,你的命名表明你实际上是在尝试获得无符号值ushort(或者UInt16)。为此你不能有负值!所以你必须向上移动浮点值才能将范围(-1.0f | 1.0f)映射到范围(0.0f | 1.0f),然后再通过ushort.MaxValue(= 65535)进行多重播放 u16data[i] = Convert.ToUInt16(Mathf.RoundToInt(fdata[i] + 1) / 2 * ushort.MaxValue);
  3. 你从AudioClip.GetData收到的是-1.0f1.0f之间音轨的增益值。 所以一个“响亮”的时刻就在那里 Mathf.Abs(fdata[i]) >= aCertainLoudThreshold; 一个“沉默”的时刻将在哪里 Mathf.Abs(fdata[i]) <= aCertainSiltenThreshold;

aCertainSiltenThreshold可能在哪里可能是0.2faCertainLoudThreshold0.8f

© www.soinside.com 2019 - 2024. All rights reserved.