首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SAPI (c#)中,“定时”音素的正确方式是什么?(SpVoice.Phoneme()->streamPosition)

在SAPI (c#)中,“定时”音素的正确方式是什么?(SpVoice.Phoneme()->streamPosition)
EN

Stack Overflow用户
提问于 2012-01-29 01:54:03
回答 2查看 1.1K关注 0票数 0

我有下一个“问题”在我的应用程序,我写的应用程序,会有人写文字,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?

谢谢你对我的英语的回答和建议

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-30 05:00:30

好吧,我会回答自己..。我的单身汉教授用C++给我发了一些他写的代码。我坚持了两天,现在我发现我是多么的愚蠢

所以我会回答..。

属性StreamPosition实际上是输出流(可能是WAV)中的“咬”位置。

如果您想知道输出流中毫秒的位置,则需要编写以下内容:

(int)StreamPosition/(double)wavFileFormat_samplesPerSec/((double)wavFileFormat_BitsPerSample/8)

因此,您需要查找有关outputStream的信息,如bitsPerSample、SamplesPerSec,并且您将获得毫秒的计时。

票数 1
EN

Stack Overflow用户

发布于 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中可能做的那样

代码语言:javascript
复制
You can also refer to Windows SDK 

C:\程序文件\Microsoft SDKs\Windows\v7.1\Samples\winui\speech\ttsapplication

代码语言:javascript
复制
           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中:

代码语言:javascript
复制
    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#中

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9050271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档