#c# #.net #speech-recognition #naudio #google-speech-api
#c# #.net #распознавание речи #naudio #google-speech-api
Вопрос:
Я преобразую речь в текст с помощью Google speech api и NAudio (с классом NAudio WaveInEvent). Вот так:https://cloud.google.com/speech-to-text/docs/streaming-recognize?hl=en (Пример C # для «Выполнения потокового распознавания речи в аудиопотоке»)
Если говорящий находится близко к микрофону, все работает красиво и быстро. Но если говорящий находится далеко от микрофона, его первые 3-5 слов не распознаются. После этого остальные слова распознаются очень хорошо. (Так что это не может быть общей проблемой с расстоянием) Больше похоже на проблему адаптации к расстоянию или, возможно, NAudio записывает не со 100%-ной громкостью.
Есть идеи по этой проблеме?
Редактировать: Вот код, который был запрошен:
static async Task<object> StreamingMicRecognizeAsync(int seconds)
{
if (NAudio.Wave.WaveIn.DeviceCount < 1)
{
Console.WriteLine("No microphone!");
return -1;
}
var speech = SpeechClient.Create();
var streamingCall = speech.StreamingRecognize();
// Write the initial request with the config.
await streamingCall.WriteAsync(
new StreamingRecognizeRequest()
{
StreamingConfig = new StreamingRecognitionConfig()
{
Config = new RecognitionConfig()
{
Encoding =
RecognitionConfig.Types.AudioEncoding.Linear16,
SampleRateHertz = 16000,
LanguageCode = "en",
},
InterimResults = true,
}
});
// Print responses as they arrive.
Task printResponses = Task.Run(async () =>
{
while (await streamingCall.ResponseStream.MoveNext(
default(CancellationToken)))
{
foreach (var result in streamingCall.ResponseStream
.Current.Results)
{
foreach (var alternative in result.Alternatives)
{
Console.WriteLine(alternative.Transcript);
}
}
}
});
// Read from the microphone and stream to API.
object writeLock = new object();
bool writeMore = true;
var waveIn = new NAudio.Wave.WaveInEvent();
waveIn.DeviceNumber = 0;
waveIn.WaveFormat = new NAudio.Wave.WaveFormat(16000, 1);
waveIn.DataAvailable =
(object sender, NAudio.Wave.WaveInEventArgs args) =>
{
lock (writeLock)
{
if (!writeMore) return;
streamingCall.WriteAsync(
new StreamingRecognizeRequest()
{
AudioContent = Google.Protobuf.ByteString
.CopyFrom(args.Buffer, 0, args.BytesRecorded)
}).Wait();
}
};
waveIn.StartRecording();
Console.WriteLine("Speak now.");
await Task.Delay(TimeSpan.FromSeconds(seconds));
// Stop recording and shut down.
waveIn.StopRecording();
lock (writeLock) writeMore = false;
await streamingCall.WriteCompleteAsync();
await printResponses;
return 0;
}
Источник: https://cloud.google.com/speech-to-text/docs/streaming-recognize?hl=en
Ответ №1:
Да, именно так все и работает. Движки используют адаптацию к уровням звука, если уровни слишком низкие, они просто пропустят первые слова и начнут распознавание только после адаптации. Точность будет ниже, чем ожидалось.
Чтобы решить эту проблему — используйте более продвинутую микрофонную матрицу, которая будет отслеживать источник звука, такой как Respeaker или Matrix, и, возможно, использовать пользовательскую систему распознавания речи, которая более устойчива к быстрым изменениям уровня звука. Это также будет дешевле, чем Google API.
Ответ №2:
В Cloud Speech API есть лучшие практики для оптимальной работы, в том числе:
Распознаватель предназначен для игнорирования фоновых голосов и шума без дополнительного шумоподавления. Однако для достижения оптимальных результатов располагайте микрофон как можно ближе к пользователю, особенно при наличии фонового шума.