2014-11-06 5 views
1

Я работаю над редактированием Mespeak.js, чтобы помочь другу с проблемами визуального отслеживания.Как отложить синтез в Mespeak.js отображать слова во время воспроизведения wav

Я просматривал Mespeak.js (http://www.masswerk.at/mespeak/) и пытался выяснить, как захватить каждое слово, как говорится, а затем отображать его на экране во время воспроизведения файла wav.

Я думаю, что это связано с возвратом данных в виде массива, а затем отображением массива в качестве воспроизведения wav. Я даже не уверен, что это возможно (или как выглядят сырые данные).

Вот что я

div id="display"> 
    <span>Here.</span> 
</div> 

<script type="text/javascript"> 
var timeoutID 
var texttosend = prompt('Text to Split'); 
var res = texttosend.split(" ") 
var arrayLength = res.length; 
function refresh(word) { 
    meSpeak.speak(res[i], {speed: 100}); 
    console.log(res[i]); 
    $("#display span").text(word); 
    }; 

console.log('here'); 
for (var i = 0; i <= arrayLength; i++) { 
     timoutID = window.setTimeout(refresh(res[i]), 50000+(i*50000)); 
}; 

Есть две проблемы здесь - я думаю, что они оба связаны с задержкой. Независимо от того, что я установил значение timeoutID в текст, snythesized все сразу, и единственное отображаемое слово является последним. Я попытался использовать варианты setTimeout, и я пробовал задержку jQuery. Любые идеи о том, как помочь? Консоль.log выводит каждое слово отдельно, поэтому я знаю, что разделение текста на массив работает, и цикл работает - я думаю, что сейчас просто время.

Извините, если это не делает тонны смысла - я думаю, какая-то ясность поможет мне начать разбирать эту проблему.

+0

Что у вас есть? – placeybordeaux

+0

Обновлено сообщение с кодом. – ntett

+0

Я сделал освежающий цикл, используя найденный код [здесь] [1]. [1]: http://stackoverflow.com/questions/3583724/how-do-i-add-a-delay-in-a-javascript-loop – ntett

ответ

0

Фон: meSpeak.js отправляет входной текст во встроенный eSpeak с параметрами для рендеринга wav-файла. Этот wav-файл затем воспроизводится с использованием либо API WebAudio, либо элемента Audio. Поэтому невозможно сказать, какая часть непрерывного высказывания в настоящее время воспроизводится (поскольку мы не знаем, когда одно слово начнется или, соответственно, закончится в какой точке аудиопотока). Но, с другой стороны, есть кое-что, что мы можем знать, а именно, когда воспроизведение аудиопотока закончилось. Может быть, мы могли бы использовать этот?

Чтобы обеспечить решение этой проблемы, meSpeak.speak() выполняет функцию обратного вызова как необязательный третий аргумент, который будет вызываться после завершения воспроизведения высказывания. (См. Демо-версию JS-rap, http://www.masswerk.at/mespeak/rap/, для сложного примера.) Имейте в виду, что вы потеряете любой контекст слова в запахе, если бы вы делали это с помощью отдельных слов, поэтому вы потеряете любую мелодичную модуляцию изречение/предложение. Кроме того, между словами будет заметная задержка.

Пример:

function speakWords(txt) { 
    var words = txt.split(/\s+/); 

    function speakNext() { 
    if (words.length) { 
     var word = words.shift(); 
     console.log('speaking: ' + word); 
     meSpeak.speak(word, {}, speakNext); 
    } 
    else { 
     console.log('done.'); 
    } 
    } 

    speakNext(); 
} 

Здесь внутренняя функция «speakNext()» сдвигает следующее слово из очереди, регистрирует его и вызывает meSpeak.speak() с собой в качестве обратного вызова (3 аргумента). Итак, если звук закончен, вызывается «speakNext()» для обработки следующего слова. Если очередь в конечном итоге будет пустой, мы, наконец, удалим else-clause. (Возможно, вы захотите заменить простые записи на более сложном дисплее.)

В следующем шаге оптимизации вы можете сначала визуализировать частичные потоки (используя опцию «rawdata»), а затем воспроизвести их (используя meSpeak .play()), как:

function speakWords2(txt) { 
    var i, words, streams = []; 

    function playNext() { 
    if (i < streams.length) { 
     console.log('speaking: ' + words[i]); 
     meSpeak.play(streams[i], 1, playNext); 
     i++; 
    } 
    else { 
     console.log('done.'); 
    } 
    } 

    // split utterance and pre-render single words to stream-data 
    words = txt.split(/\s+/); 
    for (i=0; i < words.length; i++) 
     streams.push(meSpeak.speak(words[i], {rawdata: true})); 
    // now play the partial streams (words) in a callback-loop 
    i=0; 
    playNext(); 
} 

Таким образом, задержки, вызванной рендеринга аудиопотоков будет происходить в одном блоке, когда функция вызывается и предварительно оказываемых аудио-потоков (для каждого отдельного слова) будет воспроизводиться без дополнительной загрузки (в фоновом режиме). С нижней стороны это увеличит объем памяти вашего приложения, поскольку все аудиопотоки с высоким разрешением для каждого слова сохраняются в массиве «потоки» сразу.

+0

Спасибо! Я смог сопоставить звук и отображение текста, синтезируя каждое слово самостоятельно. Я использовал setTimeout jQuery и задал время для слова-на-mintue. – ntett

 Смежные вопросы

  • Нет связанных вопросов^_^