-
-
Notifications
You must be signed in to change notification settings - Fork 659
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make SAPI4 voices use WASAPI #17718
Make SAPI4 voices use WASAPI #17718
Conversation
See test results for failed build of commit 8fc0fd4c63 |
95ccfe1
to
2cc4a3e
Compare
This is a great work, and if we can merge this in the 2025.1 dev cycle, we don't have to announce to the community that Sapi4 will be deprecated, thus avoiding possible confusion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @gexgd0419! We recently decided to extend the life of SAPI 4 for the immediate future anyway, but this change is still much appreciated
Could you also remove any mention of the deprecation of SAPI4 including the warning message? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @gexgd0419
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work and will be appreciated by SAPI 4 users.
Link to issue number:
None
Summary of the issue:
This PR makes the built-in SAPI4 synthesizer use WASAPI to output audio, so that old code related to WinMM can be removed entirely.
Description of user facing changes
SAPI4 voices should work as usual.
Features supported by
WavePlayer
, such as audio ducking, leading silence trimming, and keeping audio device awake (#17571) will be able to work with SAPI4 voices.Description of development approach
Create a class to implement
IAudio
andIAudioDest
, so that it can be used as an audio output destination to replace the SAPI4 built-inMMAudioDest
which uses WinMM.SAPI4 performs audio data output on the main thread. SAPI4 expects audio data writes to be a non-blocking operation, and it should return
AUDERR_NOTENOUGHDATA
when the buffer is full. Unfortunately, that's not howWavePlayer
works, andWavePlayer.feed
blocks the current thread until there's enough space in the buffer. So a dedicated thread is created to feed data toWavePlayer
, and audio data from SAPI4 will be put in a queue first to prevent blocking the thread. Bookmarks from SAPI4 will be put in the same queue.WavePlayer.feed
returns before the audio is finished playing, butWavePlayer
can only check and invoke callback functions whenWavePlayer.feed
orWavePlayer.sync
is called. If we just keep on waiting for the next audio chunk in the queue,WavePlayer
will have no chance to call the callback functions when there is no chunk. SoWavePlayer.feed
should be called periodically, regardless of whether there's audio or bookmark in the queue.Testing strategy:
Further tests with different SAPI4 synthesizers are needed.
Known issues with pull request:
Some SAPI4 voices do not support custom audio destinations, and this is allowed by the SAPI4 spec. They choose their own way to output the audio, and therefore bypass the WASAPI WavePlayer. In fact, they also don't use
MMAudioDest
before this PR. This means that:Such voices have
TTSFEATURE_FIXEDAUDIO
in the feature flag.Code Review Checklist:
@coderabbitai summary