2010-11-10 61 views
2

我正在使用MS翻译器发送文本的WAV文件以在我的Silverlight 4应用程序中启用“说话”功能。如何摆脱Silverlight应用程序中Microsoft Translate API翻译结束时的“咔嗒”声

但是,在每个翻译结束时,都会有一个奇怪的咔哒声(听起来像有人在打开或关闭麦克风)。

Here is an online Silverlight app which demonstrates the issue。输入内容并翻译它(可以是相同的语言)并听讲话结束。

我能做些什么来摆脱这种噪音?我正在考虑将WAV文件读到90%,然后在声音之前停止播放,但我想从技术上理解为什么它会回来,并且问题在哪里,因此我可以找到最佳的解决方案。

UPDATE:在Brad的有用导致低于后,似乎问题在于WaveMediaStreamSource将返回的WAV转换为Silverlight可以使用的格式。

这是在online project here中提到/使用的相同的一个。

所以...任何想法如何摆脱WaveMediaStreamSource转换它时的crack sound声?

回答

2

我不确定这是否有帮助,但似乎点击噪音不在WAV文件本身。

我用Fiddler来挖掘从服务器返回的响应并将其保存到WAV文件。打开Audacity,我可以清楚地听到翻译到最后...没有点击。

因此,该点击可能是Silverlight停止组件的正常声音。但是,我有一个不同的理论。

WAV文件本身以8kHz采样。这是一个古怪的球。我敢打赌,咔嗒声是声卡或软件(银光/音频驱动程序/窗口本身等)的上传采样到更合适的速率。这是可测试的。尝试制作WAV文件,并使用Fiddler或其他HTTP代理工具返回WAV,而不是从Microsoft服务器请求的内容。看看你的WAV(例如44.1kHz)是否有相同的问题。

+0

感谢您的回答布拉德,这是一个领先的 - 你可以给我一些提示你是什么意思,通过重新调整小提琴手中不同的WAV文件?这与将声音嵌入SL应用程序并使用MediaElement播放它有何不同? – Rodney 2010-11-12 04:05:59

+0

好吧,我想出了你的意思 - 通过在Fiddler中保存Response主体,你可以获得8khz的wav文件,正如你所指出的那样,文件末尾没有crack啪声。我已经深入了解代码并在原始文章中添加了一些内容(我认为这是WaveMediaStreamSource,然后我仍然不知道如何修复它!) – Rodney 2010-11-12 11:14:36

+0

有趣。不幸的是,我从来没有为Silverlight编码,所以我没有任何进一步帮助的方法。再次,我会研究音频停止时会发生什么。如果采样速率在播放过程中突然发生变化,那么可能存在问题。 – Brad 2010-11-12 14:25:12

0

我有这个相同的问题。我相信每个人都会。这是我如何解决它。

基本上,我在音频播放完成前1秒向流中执行回调的标记添加了一个标记。然后该回调触发一个叫700ms的定时器,该方法在完成之前停止音频(大约300ms)。我没有这个计时器就试过了,它不一致。看起来好像如果你设置一个标记在结束之前发射300毫秒就不会总是发射。最好还是先等一秒钟,然后运行自己的计时器,以便在准备就绪时将其切断。

这里是相关的代码片段。希望它可以帮助别人。有很多其他的技巧来编写流畅的音频播放器,但这些代码应该至少解决您的点击问题。

public void Page_Loaded(object sender, EventArgs args) 
    { 

     mediaElement.MediaOpened += new RoutedEventHandler(mediaElement_MediaOpened); 
     mediaElement.MarkerReached += new TimelineMarkerRoutedEventHandler(mediaElement_MarkerReached); 
    } 



    Timer t; 
    void mediaElement_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e) 
    { 
     // almost completed playing the file so lets stop before the annoying click is heard 
     t = new Timer(handleStopTimerDone, "", 700, 0); 
    } 

    public void handleStopTimerDone(object state) 
    { 
     // stop the audio playing 
     Stop(); 
    } 




    private void mediaElement_MediaOpened(object sender, RoutedEventArgs e) 
    { 
     TimeSpan duration = mediaElement.NaturalDuration.TimeSpan; 
     TimelineMarker newMarker = new TimelineMarker(); 
     newMarker.Time = new TimeSpan(duration.Ticks - 10000000); 
     while (mediaElement.Markers.Count > 0) 
     { 
      mediaElement.Markers.RemoveAt(0); 
     } 
     mediaElement.Markers.Add(newMarker); 


    } 


    public void Stop() 
    { 

      this.Dispatcher.BeginInvoke(delegate() 
      { 
       mediaElement.AutoPlay = false; 
       mediaElement.Stop(); 
       mediaElement.Position = TimeSpan.FromSeconds(0); 
       if (memData != null) 
       { 
        WaveMediaStreamSource wavMss = new WaveMediaStreamSource(memData); 
        mediaElement.SetSource(wavMss); 
       } 
      }); 
    }