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

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

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

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

SetSpeechProperty(speechChannel, kSpeechRateProperty, newRate as NSNumber?)

установить ставку.

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

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

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

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

Спасибо!


person Aurelius Prochazka    schedule 08.04.2018    source источник


Ответы (1)


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

Пример 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.

person Nicolas Tisserand    schedule 08.04.2018
comment
Спасибо, я реализовал ваши предложения и многое другое здесь: github.com/AudioKit/AudioKit/AudioKit / Могу я спросить вашего совета, почему кнопка остановки не останавливает воспроизведение речи? - person Aurelius Prochazka; 09.04.2018
comment
Я пока не мог остановиться. Я пробовал PauseSpeechAt(speechChannel, kImmediate), StopSpeechAt(speechChannel, kImmediate), SpeakCFString(speechChannel, "" as CFString, [ kSpeechNoSpeechInterrupt: false ] as CFDictionary). Также пытался принудительно прерывать речь во время игры: SpeakCFString(speechChannel, text as CFString, [ kSpeechNoSpeechInterrupt: false ] as CFDictionary) прежде, чем у меня закончились идеи. Кажется, что все речевые пьесы ставятся в очередь и будут воспроизводиться последовательно, несмотря ни на что. По теме: stackoverflow.com/questions/44730756/stop-audiounit-speech - person Nicolas Tisserand; 09.04.2018
comment
Да, ну, я полагаю, я могу хотя бы добавить регулятор громкости через AKBooster для некоторого контроля. Еще раз спасибо за то, что изучили это! - person Aurelius Prochazka; 09.04.2018
comment
Я добавил обратный вызов SetSpeechProperty (speechChannel, kSpeechWordCFCallBack, callbackAddr). Обратный вызов будет регистрировать текущие диапазоны говорящего текста. Он показывает, что все диапазоны озвучиваются сразу после вызова SpeakCFString. Я не знаю, почему поведение отличается от Apple CocoaSpeechSynthesisExampe ... В этом примере это можно остановить. - person joshmori; 09.04.2018
comment
Похоже, SpeechChannel из audioUnit и из функции NewSpeechChannel отличается. lists.apple.com/archives/coreaudio-api/2016/ Октябрь / msg00025.html - person joshmori; 09.04.2018