You’re right. There is no “en_US Apple_Alex” voice in the default {{tts-voices:}} list. {{tts en_US voice=Apple_Alex}} only existed in the old versions. Thank you so much!
Thank you for working that out! It seemed like the most likely cause. [Especially given that the same OS updates seem to have been replacing components as default and workaday as the Arial font!]
Mac desktop Anki might want to consider changing the voice names back to their previous “canonical” form. For example, changing “Apple_Samantha_(English_(US))” back to “Apple_Samantha”. This would make it so the names are the same as on iOS and so existing Anki card templates continue to work without changes.
The below code is an example of one way to do so, while preserving the enhanced and premium voices (for example, “Apple_Samantha_(Enhanced)”).
In anki/qt/aqt/tty.py:
- tidy_name = f"Apple_{original_name.replace(' ', '_')}"
---
+ VOICE_ADDITIONAL_RE = re.compile(r"^(.+?)\s+(\(.+\))$")
+ VOICE_ENHANCED_PREMIUM_RE = re.compile(r"^.*\((Enhanced|Premium)\)$")
+ m2 = VOICE_ADDITIONAL_RE.match(original_name)
+ m3 = VOICE_ENHANCED_PREMIUM_RE.match(original_name)
+ if m2 and not m3:
+ base_name = m2.group(1)
+ extra_name = m2.group(2)
+ tidy_name = f"Apple_{base_name}"
+ else:
+ tidy_name = "Apple_{original_name.replace(' ', '_')}"
And, to eliminate the duplicate lines:
- if voice:
- voices.append(voice)
---
+ if voice and voice not in voices:
+ voices.append(voice)
Hey, I read everything that was mentioned in the thread, and tried a few things, but it didn’t work. Could you please write a TLDR summary version for everyone out here, what should we do now?
See: Field Replacements - Anki Manual
Update your templates to use one of the currently available TTS voices.
Hey! I checked, and there’s no Apple voice available in the options I have — just the two I mentioned earlier. Do you know what I could try next?
I’ve always used {{tts en_US:Fieldname}} without setting any specific voice, so I’m a bit confused how the chosen voice could be “wrong,” since none was actually selected.
I do have English voices downloaded on my phone, and everything worked perfectly before the update.
Just to clarify — please don’t reply with “You have to use {{tts-voices:}} and write it correctly,” because I haven’t specified any voice plus there is no apple voice when I put that in, The thing I used is only {{tts en_US:…}}.
Thanks so much for your help!
It sounds like you need to download/enable voices in that language then. Even if you haven’t specified a voice in the past, maybe you need to now – because the fallback voice your OS is giving you isn’t very good.
How long is the output of {{tts-voices:}} when you run it on the device you are seeing the problem on?
- If it is short, could you copy and paste it in a reply so we can see exactly what you are seeing?
- If it is long, then copy and paste only the lines with “en_US” voices.
- If that is still too long, then copy and paste only the lines with “en_US” voices with names that start with “Apple_”
And, what is the exact problem you are seeing? Is it the same one as the OP, that TTS is working but the voice is robotic or strange-sounding?
If so, then you are seeing the (new) correct and expected behavior. When you use “{{tts en_US:Meaning}}”, you are giving Anki permission to pick the voice to use. It just happens that on iOS 26 and macOS 26 Tahoe, Anki is picking a strange-sounding, robotic voice to use. Perhaps Anki was choosing a better default voice in previous OS versions, but that was always Anki’s choice to make.
Edit: added:
Anki might want to add an enhancement where, if no specific voices are requested or if no requested voices are available, there can be preferred voices that are used (instead of just using the first available voice). Below is an example of code that might implement this.
In qt/aqt/tts.py:
+ # if no requested voices match, and if a preferred voice for the
+ # language is available, we fall back on it with a rank of -50
+ for avail in avail_voices:
+ if avail.lang == tag.lang:
+ if avail.lang == 'en_US' and avail.name == 'Apple_Samantha':
+ return TTSVoiceMatch(voice=avail, rank=-50)
+
- # if no preferred voices match, we fall back on language
- # with a rank of -100
+ # if no requested or preferred voices match, we fall back on
+ # the first available voice for the language, with a rank of -100
for avail in avail_voices:
if avail.lang == tag.lang:
return TTSVoiceMatch(voice=avail, rank=-100)
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.