如何获取流音频转换结果的开始时间和结束时间?
How can I get begin time and end time for the conversion result of stream audio?
我正在使用 azure-speech 来识别音频流,来自 speech_recognition_samples.cpp,来自 class RecognitionResult 我只能获取文本和 m_duration,但我如何才能开始演讲结果的时间和结束时间?我知道 e.Result->Offset()
可以 return 偏移量,但我仍然对此感到困惑,我的代码是
void recognizeSpeech() {
std::shared_ptr<SpeechConfig> config = SpeechConfig::FromSubscription("****", "****");
config->RequestWordLevelTimestamps();
auto pushStream = AudioInputStream::CreatePushStream();
std::cout << "created push\n" << std::endl;
auto audioInput = AudioConfig::FromStreamInput(pushStream);
auto recognizer = SpeechRecognizer::FromConfig(config, audioInput);
promise<void> recognitionEnd;
recognizer->Recognizing.Connect([](const SpeechRecognitionEventArgs& e)
{
cout << "Recognizing:" << e.Result->Text << std::endl
<< " Offset=" << e.Result->Offset() << std::endl
<< " Duration=" << e.Result->Duration() << std::endl;
});
recognizer->Recognized.Connect([](const SpeechRecognitionEventArgs& e)
{
if (e.Result->Reason == ResultReason::RecognizedSpeech)
{
cout << "RECOGNIZED: Text=" << e.Result->Text << std::endl
<< " Offset=" << e.Result->Offset() << std::endl
<< " Duration=" << e.Result->Duration() << std::endl;
}
else if (e.Result->Reason == ResultReason::NoMatch)
{
cout << "NOMATCH: Speech could not be recognized." << std::endl;
}
});
recognizer->Canceled.Connect([&recognitionEnd](const SpeechRecognitionCanceledEventArgs& e)
{
switch (e.Reason)
{
case CancellationReason::EndOfStream:
cout << "CANCELED: Reach the end of the file." << std::endl;
break;
case CancellationReason::Error:
cout << "CANCELED: ErrorCode=" << (int)e.ErrorCode << std::endl;
cout << "CANCELED: ErrorDetails=" << e.ErrorDetails << std::endl;
recognitionEnd.set_value();
break;
default:
cout << "CANCELED: received unknown reason." << std::endl;
}
});
recognizer->SessionStopped.Connect([&recognitionEnd](const SessionEventArgs& e)
{
cout << "Session stopped.";
recognitionEnd.set_value(); // Notify to stop recognition.
});
WavFileReader reader(FILE_NAME);
vector<uint8_t> buffer(1000);
recognizer->StartContinuousRecognitionAsync().wait();
int readSamples = 0;
while((readSamples = reader.Read(buffer.data(), (uint32_t)buffer.size())) != 0)
{
pushStream->Write(buffer.data(), readSamples);
}
pushStream->Close();
recognitionEnd.get_future().get();
recognizer->StopContinuousRecognitionAsync().get();
}
结果是
Recognizing:my
Offset=6800000
Duration=2700000
Recognizing:my voice is
Offset=6800000
Duration=8500000
Recognizing:my voice is my
Offset=6800000
Duration=9800000
Recognizing:my voice is my passport
Offset=6800000
Duration=14400000
Recognizing:my voice is my passport verify me
Offset=6800000
Duration=26100000
RECOGNIZED: Text=My voice is my passport, verify me.
Offset=6800000
Duration=28100000
CANCELED: Reach the end of the file.
为什么每次结果的偏移量都是6800000?我认为它应该不断增加,例如:
“my”的开始偏移量为0,“my”的结束偏移量为100000,
“my voice is”的开始偏移量为 0,“my voice is”的结束偏移量为 200000。
然后我就可以在sentence.But中获取“我的声音是”的开始时间和结束时间现在我如何才能在每个结果的句子中获取开始时间和结束时间?
如果您仔细查看输出 - 有两个事件:
识别和识别
正在识别:
中间识别结果的事件识别信号被接收到。
已识别:
Recognized 事件表示收到 最终 识别结果。
所以你看到的偏移量是针对完整句子的(已识别的事件 - 通常在第一次停顿之前):我的声音是我的护照,验证我。 所以对于所有识别(中间)事件,偏移量将相同。因此,如果您有另一个 recognized 事件,您会看到顺序偏移。因此,如果您在音频中有另一个句子 - 您可能会看到额外的识别事件和偏移量 - 像您期望的那样增长。
更新:
补充说明:
对于每个已识别的事件,持续时间从零开始增长。
持续时间计数从零遍历到完整识别事件的持续时间。
例如
Recognizing:my
Offset=6800000
Duration=2700000
Recognizing:my voice is
Offset=6800000
Duration=8500000
因此,如果您想要一个偏移量:My Voice is
- 您可以添加前一个 6800000 + 2700000(开始时间)的初始偏移量和持续时间,结束时间为 6800000 + 8500000(当前持续时间) )
更新 2
RECOGNIZED: Text=My voice is my passport, verify me.
Offset=6800000
Duration=28100000
它们在 100 纳秒内(10 ^-7 秒)
让我们来处理你的情况
您的偏移量是 6800000,即 0.68 秒
这意味着句子(或该音频流的完整识别事件)已从整个音频的第 0.68 秒开始。
发声(“我的声音是我的护照,验证我。”)的持续时间或完整时间为 2.8(28100000) 秒。
第二句(已识别事件)的偏移量将大于此持续时间。
持续时间可以小于或大于偏移量:
在整个音频的第3秒,我可以毫不停顿地说出4秒长的音频流。
偏移量为 3 秒,持续时间为 4 秒
我正在使用 azure-speech 来识别音频流,来自 speech_recognition_samples.cpp,来自 class RecognitionResult 我只能获取文本和 m_duration,但我如何才能开始演讲结果的时间和结束时间?我知道 e.Result->Offset()
可以 return 偏移量,但我仍然对此感到困惑,我的代码是
void recognizeSpeech() {
std::shared_ptr<SpeechConfig> config = SpeechConfig::FromSubscription("****", "****");
config->RequestWordLevelTimestamps();
auto pushStream = AudioInputStream::CreatePushStream();
std::cout << "created push\n" << std::endl;
auto audioInput = AudioConfig::FromStreamInput(pushStream);
auto recognizer = SpeechRecognizer::FromConfig(config, audioInput);
promise<void> recognitionEnd;
recognizer->Recognizing.Connect([](const SpeechRecognitionEventArgs& e)
{
cout << "Recognizing:" << e.Result->Text << std::endl
<< " Offset=" << e.Result->Offset() << std::endl
<< " Duration=" << e.Result->Duration() << std::endl;
});
recognizer->Recognized.Connect([](const SpeechRecognitionEventArgs& e)
{
if (e.Result->Reason == ResultReason::RecognizedSpeech)
{
cout << "RECOGNIZED: Text=" << e.Result->Text << std::endl
<< " Offset=" << e.Result->Offset() << std::endl
<< " Duration=" << e.Result->Duration() << std::endl;
}
else if (e.Result->Reason == ResultReason::NoMatch)
{
cout << "NOMATCH: Speech could not be recognized." << std::endl;
}
});
recognizer->Canceled.Connect([&recognitionEnd](const SpeechRecognitionCanceledEventArgs& e)
{
switch (e.Reason)
{
case CancellationReason::EndOfStream:
cout << "CANCELED: Reach the end of the file." << std::endl;
break;
case CancellationReason::Error:
cout << "CANCELED: ErrorCode=" << (int)e.ErrorCode << std::endl;
cout << "CANCELED: ErrorDetails=" << e.ErrorDetails << std::endl;
recognitionEnd.set_value();
break;
default:
cout << "CANCELED: received unknown reason." << std::endl;
}
});
recognizer->SessionStopped.Connect([&recognitionEnd](const SessionEventArgs& e)
{
cout << "Session stopped.";
recognitionEnd.set_value(); // Notify to stop recognition.
});
WavFileReader reader(FILE_NAME);
vector<uint8_t> buffer(1000);
recognizer->StartContinuousRecognitionAsync().wait();
int readSamples = 0;
while((readSamples = reader.Read(buffer.data(), (uint32_t)buffer.size())) != 0)
{
pushStream->Write(buffer.data(), readSamples);
}
pushStream->Close();
recognitionEnd.get_future().get();
recognizer->StopContinuousRecognitionAsync().get();
}
结果是
Recognizing:my
Offset=6800000
Duration=2700000
Recognizing:my voice is
Offset=6800000
Duration=8500000
Recognizing:my voice is my
Offset=6800000
Duration=9800000
Recognizing:my voice is my passport
Offset=6800000
Duration=14400000
Recognizing:my voice is my passport verify me
Offset=6800000
Duration=26100000
RECOGNIZED: Text=My voice is my passport, verify me.
Offset=6800000
Duration=28100000
CANCELED: Reach the end of the file.
为什么每次结果的偏移量都是6800000?我认为它应该不断增加,例如: “my”的开始偏移量为0,“my”的结束偏移量为100000, “my voice is”的开始偏移量为 0,“my voice is”的结束偏移量为 200000。 然后我就可以在sentence.But中获取“我的声音是”的开始时间和结束时间现在我如何才能在每个结果的句子中获取开始时间和结束时间?
如果您仔细查看输出 - 有两个事件:
识别和识别
正在识别: 中间识别结果的事件识别信号被接收到。
已识别: Recognized 事件表示收到 最终 识别结果。
所以你看到的偏移量是针对完整句子的(已识别的事件 - 通常在第一次停顿之前):我的声音是我的护照,验证我。 所以对于所有识别(中间)事件,偏移量将相同。因此,如果您有另一个 recognized 事件,您会看到顺序偏移。因此,如果您在音频中有另一个句子 - 您可能会看到额外的识别事件和偏移量 - 像您期望的那样增长。
更新:
补充说明: 对于每个已识别的事件,持续时间从零开始增长。 持续时间计数从零遍历到完整识别事件的持续时间。
例如
Recognizing:my
Offset=6800000
Duration=2700000
Recognizing:my voice is
Offset=6800000
Duration=8500000
因此,如果您想要一个偏移量:My Voice is
- 您可以添加前一个 6800000 + 2700000(开始时间)的初始偏移量和持续时间,结束时间为 6800000 + 8500000(当前持续时间) )
更新 2
RECOGNIZED: Text=My voice is my passport, verify me.
Offset=6800000
Duration=28100000
它们在 100 纳秒内(10 ^-7 秒)
让我们来处理你的情况
您的偏移量是 6800000,即 0.68 秒
这意味着句子(或该音频流的完整识别事件)已从整个音频的第 0.68 秒开始。
发声(“我的声音是我的护照,验证我。”)的持续时间或完整时间为 2.8(28100000) 秒。
第二句(已识别事件)的偏移量将大于此持续时间。
持续时间可以小于或大于偏移量:
在整个音频的第3秒,我可以毫不停顿地说出4秒长的音频流。
偏移量为 3 秒,持续时间为 4 秒