我需要从连续的音频流中收集语音片段。稍后,我需要处理刚刚说过的用户语音(不是用于语音识别)。我只关注基于声音响度的声音分割。
如果至少沉默一秒钟后,他的声音变得足够响亮一会儿,然后再次沉默至少一秒钟,我说这是一个句子,应该在这里将声音分段。
我只知道我可以从<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()
但是我不确定的是:
当我调用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}足够大,对吗?
fdata
是一个浮点数组,我需要一个16 kHz,16位PCM缓冲区。像这样fdata
转换数据是否正确?
在fdata
中检测响亮时刻和沉默时刻的正确方法是什么?
答案 0 :(得分:1)
否。您必须使用Microphone.GetPosition
AudioClip
中的当前位置开始阅读
获取录音样本中的位置。
并将获得的索引传递到AudioClip.GetData
使用offsetSamples参数从片段中的特定位置开始读取
fdata = new float[clip.samples * clip.channels];
var currentIndex = Microphone.GetPosition(null);
audio.GetData(fdata, currentIndex);
我不明白您将其转换为什么。 fdata
将包含
浮动范围从
-1.0f
到1.0f
(AudioClip.GetData
)
因此,如果出于某种原因,您需要在short.MinValue
(= -32768)和short.MaxValue
(= 32767)之间获取值,则可以使用
u16data[i] = Convert.ToUInt16(fdata[i] * short.MaxValue);
值,四舍五入为最接近的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);
您从ushort.MaxValue
(= 65535)接收到的是-1.0f
和1.0f
之间的音轨的增益值。
那么“大声”的时刻就在哪里
Mathf.Abs(fdata[i]) >= aCertainLoudThreshold;
一个“沉默”的时刻将在哪里
Mathf.Abs(fdata[i]) <= aCertainSiltenThreshold;
其中aCertainSiltenThreshold
例如例如为0.2f
和aCertainLoudThreshold
是0.8f
。