Как избавиться от звука «щелчка» в конце перевода в Microsoft Translate API в приложении Silverlight - PullRequest
2 голосов
/ 11 ноября 2010

Я использую MS Translator для отправки обратно WAV-файла текста, чтобы включить «разговор» в моем приложении Silverlight 4.

Однако в конце каждого перевода появляется странный шум щелчка (звучит так, будто кто-то включает или выключает микрофон).

Это онлайн-приложение Silverlight, демонстрирующее проблему .Напечатайте что-нибудь и переведите это (может быть на одном языке) и прослушайте конец разговора.

Могу ли я что-нибудь сделать, чтобы избавиться от этого шума?Я думал о том, чтобы прочитать WAV-файл до 90%, а затем остановить его перед звуком, но я хотел бы технически понять, почему он возвращается с шумом и где проблема, поэтому я могу найти лучшее решение для него.

ОБНОВЛЕНИЕ : После полезного указания Брэда, приведенного ниже, кажется, что проблема в WaveMediaStreamSource , который преобразует возвращенный WAV в формат, который Silverlight может использовать.

Это то же самое, что упоминается / используется в онлайн-проекте здесь .

Итак ... есть идеи, как избавиться от потрескивающего звука, когда WaveMediaStreamSource преобразует его?

Ответы [ 2 ]

2 голосов
/ 11 ноября 2010

Я не уверен, что это полезно, но похоже, что шум щелчка отсутствует в самом файле WAV.

Я использовал Fiddler , чтобы найти ответ, возвращаемый с сервера, и сохранить его в файле WAV. Открывая, что в Audacity я четко слышу перевод до конца ... нет щелчка.

Таким образом, этот щелчок может быть нормальным звуком компонента при остановке Silverlight. Однако у меня другая теория.

Сам файл WAV сэмплируется с частотой 8 кГц. Это что-то странное. Бьюсь об заклад, шум щелчка является артефактом звуковой карты или программного обеспечения (Silverlight / Audio Driver / Windows непосредственно и т. Д.) С повышением частоты дискретизации до более подходящей частоты. Это проверяемое. Попробуйте создать файл WAV и использовать Fiddler или другой прокси-инструмент HTTP для возврата WAV вместо того, что было запрошено с сервера Microsoft. Посмотрите, есть ли у вашей WAV (например, 44,1 кГц) такая же проблема.

0 голосов
/ 10 марта 2011

У меня была такая же проблема. Я уверен, что все делают. Вот как я это решил.

По сути, я добавил маркер в поток, который выполнял обратный вызов за 1 секунду до завершения воспроизведения звука. Затем этот обратный вызов запускает таймер, который вызывается через 700 мс, и этот метод останавливает звук (около 300 мс) до его завершения. Я попробовал это без этого таймера, и это было противоречиво. Кажется, если вы установите маркер на 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);
                }
            });
    }
...