Могу вагоны разгружать
0,2
рейтинг
15 апреля 2011 в 15:31

Голосовой переводчик для Mac OS X

В недалёком прошлом лишь в фантастических фильмах можно было видеть «чудо коробочки», в которые говоришь, а в результате слышишь перевод сказанного на другом языке. Но прогресс идёт…

Я очень давно ждал, когда Google откроет API своего сервиса распознавания речи (в своих продуктах компания его использует). Несколько месяцев назад я перевернул «этот ваш ёнтернет», но безрезультатно. И вот на днях я вижу топик на Хабре Используем Google Voice Search в своем приложении .NET! Я был неимоверно счастлив. Топик ссылается на оригинальную статью Accessing Google speech API / Chrome 11. Всё внимательно изучил и «расковырял» исходники Chrome.

Google Speech Recognition API пока неофициальный и стал доступен общественности благодаря браузеру Chrome.

Варианты его использования поистине безграничны. А если объединить это с морфологическими модулями, то может наворотить просто чумовых дел в сфере управления голосом.

Для демонстрации и создания «каркасного движка» (для своих дальнейших нужд) я сделал «Голосовой переводчик» для Mac OS X за пару дней. Это симбиоз технологий Google, Microsoft (произношение) и открытого проекта ffmpeg (конвертация во flac). Это именно голосовой переводчик — никакого набора текста. Просто произносите фразу и слушаете её перевод. Да, качество распознавания может быть не идеальным, но на коротких чётких фразах вполне приемлемо.

Вот видео работы программы:


Как обычно, этот топик я разделю на две части. Одна для обычных пользователей, кто захочет «побаловаться» этой программой. Другая для разработчиков (я предоставлю исходные коды базового проекта).

ДЛЯ ПОЛЬЗОВАТЕЛЕЙ


Загрузить программу можно по ссылке (Mac OS X 10.6+).

Интерфейс программы очень простой. Выбираете нужное языковое направление (в этом демонстрационном проекте я сделал лишь два направления, но сервисы поддерживают намного большее количество языков). Нажимаете кнопку «Записать» и произнесите фразу. Запись автоматически прекратится через 5 секунд или вы можете самостоятельно ее остановить. Всё — слушаем перевод :).





ДЛЯ РАЗРАБОТЧИКОВ


Исходный код на github.

В проекте используется уже собранный бинарный конвертер ffmpeg для конвертации записанного звука во flac. Если вы захотите перенести проект на iOS, то можно использовать статическую библиотеку из проекта libFlac.

Для HUD интерфейс в проекте используется уже собранный BGHUDAppKit framework.

Для обработки JSON используется JSON framework.

Дополнительно (для упрощения) используются некоторые классы из Google Data API.

ЗАПИСЬ ЗВУКА

Звук записывается с помощью стандартной библиотеки QTKit (QuickTime Kit).

Вот код инициализации сессии захвата звуковых данных:
    BOOL success = NO;<br/>
 <br/>
    mCaptureSession = [[QTCaptureSession alloc] init];<br/>
 <br/>
    QTCaptureDevice *audioDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeSound];<br/>
 <br/>
    if (!audioDevice)<br/>
    {<br/>
        [mCaptureSession release], mCaptureSession = nil;<br/>
 <br/>
        [textLabel setStringValue:NSLocalizedString(@"AudioError"@"")];<br/>
        [button setHidden:YES];<br/>
        [popUp setHidden:YES];<br/>
        [textLabel setHidden:NO];<br/>
    }<br/>
 <br/>
    success = [audioDevice open:NULL];<br/>
 <br/>
    if (!success)<br/>
    {<br/>
        [mCaptureSession release], mCaptureSession = nil;<br/>
 <br/>
        [textLabel setStringValue:NSLocalizedString(@"AudioError"@"")];<br/>
        [button setHidden:YES];<br/>
        [popUp setHidden:YES];<br/>
        [textLabel setHidden:NO];<br/>
    }<br/>
 <br/>
    mCaptureAudioDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice:audioDevice];<br/>
    success = [mCaptureSession addInput:mCaptureAudioDeviceInput error:NULL];<br/>
 <br/>
    if (!success)<br/>
    {<br/>
        [mCaptureSession release], mCaptureSession = nil;<br/>
        [mCaptureAudioDeviceInput release], mCaptureAudioDeviceInput = nil;<br/>
 <br/>
        [textLabel setStringValue:NSLocalizedString(@"AudioError"@"")];<br/>
        [button setHidden:YES];<br/>
        [popUp setHidden:YES];<br/>
        [textLabel setHidden:NO];<br/>
    }<br/>
 <br/>
    mCaptureMovieFileOutput = [[QTCaptureMovieFileOutput alloc] init];<br/>
    success = [mCaptureSession addOutput:mCaptureMovieFileOutput error:NULL];<br/>
 <br/>
    if (!success)<br/>
    {<br/>
        [mCaptureSession release], mCaptureSession = nil;<br/>
        [mCaptureAudioDeviceInput release], mCaptureAudioDeviceInput = nil;<br/>
        [mCaptureMovieFileOutput release], mCaptureMovieFileOutput = nil;<br/>
 <br/>
        //error handler<br/>
    }<br/>
 <br/>
    [mCaptureMovieFileOutput setDelegate:self];<br/>
 <br/>
    [mCaptureMovieFileOutput setCompressionOptions:[QTCompressionOptions compressionOptionsWithIdentifier:@"QTCompressionOptionsHighQualityAACAudio"] forConnection:[[mCaptureMovieFileOutput connections] objectAtIndex:0]];<br/>
 <br/>
    [mCaptureSession startRunning];        <br/>
 

Теперь, чтобы начать запись в файл мы выполняем:
[mCaptureMovieFileOutput recordToOutputFileURL:path];

Чтобы закончить запись:
[mCaptureMovieFileOutput recordToOutputFileURL:nil];


КОНВЕРТАЦИЯ

После того, как мы получили звуковой файл, конвертируем его в формат flac с помощью ffmpeg:
    NSTask *aTask = [[NSTask alloc] init];<br/>
    NSMutableArray *args = [NSMutableArray array];<br/>
 <br/>
    [args addObject:@"-i"];<br/>
    [args addObject:@"record.m4a"];<br/>
    [args addObject:@"-acodec"];<br/>
    [args addObject:@"flac"];<br/>
    [args addObject:@"-ac"];<br/>
    [args addObject:@"1"];<br/>
    [args addObject:@"-ar"];<br/>
    [args addObject:@"16000"];<br/>
    [args addObject:@"record.flac"];<br/>
    [aTask setCurrentDirectoryPath:recordPath];<br/>
    [aTask setLaunchPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"ffmpeg"]];<br/>
    [aTask setArguments:args];<br/>
    [aTask launch];<br/>
    [aTask waitUntilExit];<br/>
    [aTask release];


ОБЩЕНИЕ С СЕТЕВЫМИ СЕРВИСАМИ

После конвертации запускаем процесс распознавания. Он реализован в отдельном классе GoogleASR. Объект этого класса отсылает запрос (асинхронно) на https://www.google.com/speech-api/v1/recognize, обрабатывает результат и сообщает делегату содержание распознавания или информирует об ошибке. Процесс обработки ответа от сервера очень корректный — он полностью (алгоритм) скопирован из браузера Chrome. В классе всего один основной метод:
- (void)speechRecognition:(NSString *)flacPath language:(NSString *)language


Далее передаем распознанный текст объекту класса GoogleTranslate. Он переводит текст и сообщает делегату результат перевода или информирует об ошибке. Основной метод:
- (void)translate:(NSString *)text from:(NSString *)inLanguage to:(NSString *)outLanguage


Далее в ход вступает объект класса MicrosoftTTS. Он получает аудио данные и передаёт их делегату или информирует об ошибке. Основной метод:
- (void)textToSpeech:(NSString *)text language:(NSString *)language


Не забудьте получить свой Bing AppID у Microsoft (это делается бесплатно) и вставить его в класса MicrosoftTTS, в SpeechURL.

Экспериментируйте!
Юрий Юрьев @Kyrie1965
карма
126,2
рейтинг 0,2
Могу вагоны разгружать
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое

Комментарии (27)

  • +2
    Вместо Microsoft можно также было бы использовать Google Text to Speech, у него мне произношение нравится гораздо больше.
    • +1
      Можете поменять в проекте класс MicrosoftTTS на любой другой синтезатор — он специально выделен отдельным классом. В моём случае выбор был сделан в пользу Microsoft TTS из-за, что сервис позволяет озвучивать за один запрос текст объёмом 500 символов.
      • +2
        А так получилось очень даже неплохо. Можно даже переписать с учётом кросплатформенности, повесить программку в трей и захватывать речь по хоткею (можно пока нажата клавиша). Ммм, мне понравилась идея, сделаю на питоне.
  • +7
    я ему сказал fuck, а он истошным голосом начала орать «РЕШЕТКА РЕШЕТКА РЕШЕТКА РЕШЕТКА»)
    • +1
      Манерная дама :).
    • +1
      хорошо, что не «Я идиот, убейте меня кто-нибудь!»
    • +1
      А если сказать «fuck it!», она начинает орать «РЕШЕТКА, РЕШЕТКА, РЕШЕТКА ВАМ НУЖНА.»
  • 0
    жаль что только для Mac OS :(
    • 0
      Код очень простой и легко переносим на любую платформу и любой язык, кто-нибудь что-нибудь сделает для практики и для другой системы.
      • 0
        надеюсь:)
      • –1
        Под линукс думаю легче всего будет сделать. qt и ffmpeg уже есть.
  • +1
    Отличный проект. И вообще, хочу сказать большое спасибо за Переводчик для мака.
    • 0
      Пожалуйста.
      • 0
        А можете реализовать экспорт в аудио-файл?
        Хорошо было бы как-нибудь сделать так, чтобы в скайп, к примеру, транслировался переведенный голос, а твой нет. (эмуляция микрофона(?))
        • 0
          Развивать именно «Голосовой переводчик» (в текущем виде) не буду — я его сделал для демонстрации возможностей сетевых сервисов, доступных разработчикам, и для дальнейших своих нужд.

          Если кто-то захочет его доработать или использовать по любому назначению, то я выложил полный исходный код проекта.
          • 0
            Расстраивает, но, все же, большое вам спасибо!
        • 0
          Мне уже страшно за того, кто с вами будет общаться по скайпу
          • 0
            Мысль берет свое начало с далеких вмерен, когда мы пользовались еще irc (Mirc),
            я тогда еще подумал, что вот, в будущем можно будет просто произносить что-то, а твой голос будет пропечатываться в чате, что не нужно будет каждый символ долбить на клавиатуре, как и сейчас мы это делаем.
            Сказал «Голосовая клавиатура», а потом просто диктуешь, текст вводится, произнес «tab, tab, Enter», хотя, с веб 3.0 таб-таб уже не нужно будет произносить. :)
            Вот такие фантазии были с тех времен, сохраняют и по сей день свое начало. В этом будто что-то магическое есть. Кто бывал в интернете с тех времен — хорошо поймет меня. «tab, tab, Enter»
  • 0
    Синтезатор голоса от Microsoft сосет по-полной! по-моему гораздо хуже Гугловского.
  • 0
    что я делаю не так? после любой фразы на любом языке выскакивает: «Ошибка обработки данных».
    это все из-за :«with special thanks to: Mom»? =)
    • 0
      Причин может быть много. Откройте программу Консоль и посмотрите, какие служебные сообщения выдаются в момент ошибки.

      Самая распространенная проблема — это низкий уровень звука при записи (в файле тишина).
  • 0
    отлично все работает!
    было бы круто добавить кнопку повтора переведенного голоса и индикатор громкости.
  • 0
    не пашет.
  • 0
    хотя сорре, неправильно были выставлены настройки у микрофона.
  • 0
    А почему ограничение — именно 5 секунд? Гугл плохо переваривает более длинные фразы?
  • 0
    Спасибо! На неделе задавались этим вопросом!
  • 0
    Кажись, не фурычит она больше :(

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.