Почему я не могу управлять аудиоустройством Apple macOS Speech Synthesis с помощью значений ползунка?

avatar
Aurelius Prochazka
8 апреля 2018 в 09:25
368
1
7

Я работаю над тем, чтобы включить аудиоустройство синтеза речи Apple (работает только на macOS, а не на iOS) в AudioKit, и я создал класс AKSpeechSynthesizer (первоначально созданный wangchou в этом запрос на вытягивание) и демонстрационный проект оба доступны в ветке разработки AudioKit.

Мой проект очень похож на этот Пример синтеза речи какао, но в этом проекте переменная скорости может быть изменена и плавно варьируется от небольшого количества слов в минуту (40) до большого числа (300 иш). Тем не менее, мой проект начинается с скорости по умолчанию 175, и любое изменение замедляет скорость до минимума, за исключением случаев, когда вы увеличиваете ее до 350, тогда она идет очень быстро.

Я не вижу, чем я отличаюсь от этого примера, так как оба проекта полагаются на

SetSpeechProperty(speechChannel, kSpeechRateProperty, newRate as NSNumber?)

для установки скорости.

Вот моя реализация и рабочая.

Самое большое отличие состоит в том, что мой синтезатор настроен как аудиоустройство, в то время как в рабочем примере просто используется вывод по умолчанию на динамик.

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

Может ли кто-нибудь сказать мне, почему мой не работает, или исправить это с помощью запроса на включение? Любая помощь будет принята с благодарностью и указана в коде.

Спасибо!

Источник

Ответы (1)

avatar
Nicolas Tisserand
8 апреля 2018 в 12:14
4

Похоже, что свойства скорости, высоты тона и модуляции речи должны быть целыми значениями без дробных частей, чтобы все работало правильно.

Пример CocoaSpeechSynthesis фактически демонстрирует такое же поведение, но инициализирует поле скорости целым значением. Чтобы воспроизвести проблему, попробуйте установить скорость сначала на 333, а затем, например, на 333,3.

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

К сожалению, я не смог найти в Интернете справочную документацию, подтверждающую эти выводы, но вот патч, который позволяет трем речевым параметрам работать в примере проекта SpeechSynthesizer:

diff --git a/AudioKit/Common/Nodes/Generators/Speech Synthesizer/AKSpeechSynthesizer.swift b/AudioKit/Common/Nodes/Generators/Speech Synthesizer/AKSpeechSynthesizer.swift
index 81286b8fb..324966e13 100644
--- a/AudioKit/Common/Nodes/Generators/Speech Synthesizer/AKSpeechSynthesizer.swift 
+++ b/AudioKit/Common/Nodes/Generators/Speech Synthesizer/AKSpeechSynthesizer.swift 
@@ -47,7 +47,7 @@ open class AKSpeechSynthesizer: AKNode {
                return
            }
            AKLog("Trying to set new rate")
-            let _ = SetSpeechProperty(speechChannel, kSpeechRateProperty, newRate as NSNumber?)
+            let _ = SetSpeechProperty(speechChannel, kSpeechRateProperty, newRate.rounded() as NSNumber?)
        }
    }

@@ -70,7 +70,7 @@ open class AKSpeechSynthesizer: AKNode {
                return
            }
            AKLog("Trying to set new freq")
-            let _ = SetSpeechProperty(speechChannel, kSpeechPitchBaseProperty, newFrequency as NSNumber?)
+            let _ = SetSpeechProperty(speechChannel, kSpeechPitchBaseProperty, newFrequency.rounded() as NSNumber?)
        }
    }

@@ -93,7 +93,7 @@ open class AKSpeechSynthesizer: AKNode {
                return
            }
            AKLog("Trying to set new modulation")
-            let _ = SetSpeechProperty(speechChannel, kSpeechPitchModProperty, newModulation as NSNumber?)
+            let _ = SetSpeechProperty(speechChannel, kSpeechPitchModProperty, newModulation.rounded() as NSNumber?)
        }
    }

Это всего лишь 3 дополнительных вызова метода округления чисел Swift.

Aurelius Prochazka
8 апреля 2018 в 21:34
1

Спасибо, я реализовал ваши предложения и многое другое здесь: github.com/AudioKit/AudioKit/commit/… Могу я спросить вашего совета, почему кнопка остановки не останавливает воспроизведение речи?

Nicolas Tisserand
9 апреля 2018 в 00:08
0

Я не мог остановить работу, до сих пор. Я пробовал PauseSpeechAt(speechChannel, kImmediate), StopSpeechAt(speechChannel, kImmediate), SpeakCFString(speechChannel, "" as CFString, [ kSpeechNoSpeechInterrupt: false ] as CFDictionary). Также пытался принудительно прерывать речь при воспроизведении: SpeakCFString(speechChannel, text as CFString, [ kSpeechNoSpeechInterrupt: false ] as CFDictionary), прежде чем у меня закончились идеи. Кажется, что все речевые пьесы поставлены в очередь и будут воспроизводиться последовательно, несмотря ни на что. Связанный: coderhelper.com/questions/44730756/stop-audiounit-speech

Aurelius Prochazka
9 апреля 2018 в 03:21
0

Да, ну, я полагаю, я могу хотя бы добавить регулятор громкости через AKBooster, чтобы хоть как-то управлять. Еще раз спасибо за изучение этого!

joshmori
9 апреля 2018 в 04:28
0

Я добавил обратный вызов с помощью «SetSpeechProperty (speechChannel, kSpeechWordCFCallBack, callbackAddr)». Обратный вызов будет регистрировать текущие диапазоны говорящего текста. Он показывает, что все диапазоны произносятся сразу после вызова SpeakCFString. Я не знаю, почему поведение отличается от Apple CocoaSpeechSynthesisExampe... В примере его можно остановить.

joshmori
9 апреля 2018 в 06:33
0

Похоже, что функции speechChannel "из audioUnit" и "из NewSpeechChannel" отличаются. lists.apple.com/archives/coreaudio-api/2016/Oct/msg00025.html