为什么我无法使用滑块值控制 Apple macOS 语音合成音频单元?

Why can't I control the Apple macOS Speech Synthesis audio unit with slider values?

我正在努力将 Apple 语音合成音频单元的东西(仅适用于 macOS,不适用于 iOS)整合到 AudioKit 中,并且我已经构建了一个 AKSpeechSynthesizer Class (initially created by wangchou in this pull request) and a demo project 两者都可以在开发分支上使用音频套件。

我的项目与此非常相似 Cocoa Speech Synthesis Example 但在这个项目中,速率变量可以在每分钟的低字数 (40) 到高字数 (300 左右) 之间平滑变化).但是,我的项目以默认速率 175 开始,任何更改都会使速率减慢到爬行 - 除非您将其更改为 350,然后它会变得非常快。

我看不出我在做什么与这个例子有什么不同,因为这两个项目都依赖于

SetSpeechProperty(speechChannel, kSpeechRateProperty, newRate as NSNumber?)

设置速率。

这里是my implementation and the working one

最大的区别是我的合成器设置为音频单元,而我认为工作示例只是使用默认输出到扬声器。

频率(音高)或调制(pitchMod)的其他参数也表现出奇怪的行为,但在这些参数上不太明显,而且在两个项目中这些参数都有些有趣。

有人可以告诉我为什么我的不起作用或通过拉取请求修复它吗?任何帮助将不胜感激,并归功于代码。

谢谢!

似乎速率、音高和调制语音属性需要是整数值,没有小数部分,才能正常工作。

CocoaSpeechSynthesis 示例实际上表现出相同的行为,但将速率字段初始化为整数值。要重现该问题,请尝试先将速率设置为 333,然后再设置为 333.3。

其他音高和调制参数似乎对小数部分同样挑剔,并且似乎只有在设置为整数值时才会产生合理的结果。

不幸的是,我找不到任何在线参考文档 material 来证实这些发现,但这里有一个补丁可以让 SpeechSynthesizer 示例项目中的 3 个语音参数起作用:

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?)
        }
    }

只是对 Swift 的数字舍入方法进行了 3 次额外调用。