我有下一个“问题”在我的应用程序,我写的应用程序,会有人写文字,SAPI TTS翻译它的讲话,然后我将与输出WAV工作。我需要的是关于音素的信息(在输出WAV中有一些音素,有多长的声音说出来,等等)。好的,我使用了SpVoice.Phoneme(),并为音素添加了处理程序。好了,现在我可以在SpVoice.Phoneme()中获得持续时间SpVoice.Phoneme()是属性StreamPosition,但我不知道这意味着什么。
来自MSDN:
StreamPosition
音素开始的输出流中的字符位置。
我不明白它们是否意味着输出WAV中的“字节”位置(在哪个字节上是音素),..or毫秒时间在输出WAV..or中,这意味着什么??
例如,对于文本:
,这太高了。这太低了。这太快了。太慢了。
我得到了StreamPositions值:
职位:0
职位:120个
职位:2562
……
职位:143798
职位:147874
职位:151950
输出WAV文件有5.377098秒,最后一个音素"ow“在4.734秒左右被告知。输出WAV文件有237 568字节。因此,属性StreamPosition "147874“的值可能不是开始音素的字节。对于“定时”也是如此(因为WAV有5.3s,但是151950 ms是151,950s..so,这是关闭的)。
,那么StreamPosition是什么?(StreamPosition中的值是什么?)
我真的需要及时赶上音素开始的时间。我试过了DateTime.Now.Ticks.现在是T.当用户单击按钮开始翻译TTS时,我保存这个日期时间值,当某个处理程序捕获某个音素时,我再次捕获该值。然后我将得到currTime-startTime的值。但这种“方法”并不那么精确。总有一些分歧。SpVoice.Phoneme()有什么“方法”或者什么东西来准确地获取音素开始时间的信息吗?如果没有,有什么更好的方法来获得更准确的时间在ms?
谢谢你对我的英语的回答和建议
发布于 2012-01-30 05:00:30
好吧,我会回答自己..。我的单身汉教授用C++给我发了一些他写的代码。我坚持了两天,现在我发现我是多么的愚蠢
所以我会回答..。
属性StreamPosition实际上是输出流(可能是WAV)中的“咬”位置。
如果您想知道输出流中毫秒的位置,则需要编写以下内容:
(int)StreamPosition/(double)wavFileFormat_samplesPerSec/((double)wavFileFormat_BitsPerSample/8)
因此,您需要查找有关outputStream的信息,如bitsPerSample、SamplesPerSec,并且您将获得毫秒的计时。
发布于 2012-01-29 16:17:07
1)我不知道如何将输出保存到wav文件中,但是文件大小237 568字节比正常大(如果采样率为16 the ,为),作为5.377098秒wav文件的文件大小
为5.377098*16000*2 = 172067字节+标头(44个字节)
所以,我认为你的wav文件也包含音素事件。
2)TTS需要时间来生成输出,因此不能以这种方式计时,我建议您:
2.1)记录音素事件,就像你在1中可能做的那样
You can also refer to Windows SDK C:\程序文件\Microsoft SDKs\Windows\v7.1\Samples\winui\speech\ttsapplication
if (SUCCEEDED(hr))
{
// OriginalFmt.WaveFormatExPtr()->nSamplesPerSec;
hr = SPBindToFile( m_szWFileName, SPFM_CREATE_ALWAYS, &cpWavStream, &OriginalFmt.FormatId(), OriginalFmt.WaveFormatExPtr(),SPFEI_ALL_TTS_EVENTS);
}
if( SUCCEEDED( hr ) )
{
// Set the voice's output to the wav file instead of the speakers
hr = m_cpVoice->SetOutput(cpWavStream, TRUE);
}2.2)按流启动<=等其他事件的时间安排,我不太确定它的确切名称。
在Windows中:
while (m_cpVoice->GetEvents(1, &event, &ul) == S_OK)
{
if (event.eEventId == SPEI_VISEME)
{
printf("v: %i\'",event.lParam); // viseme
printf("t: %i\'",event.wParam); // duration of viseme
}
else if (event.eEventId == SPEI_END_INPUT_STREAM)
{
} else if (event.eEventId == SPEI_START_INPUT_STREAM)
{
}
}但是代码不在C#中
https://stackoverflow.com/questions/9050271
复制相似问题