Skip to content
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

AVFoundation: add ability to get the current voice #26

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

leecbaker
Copy link

This adds the ability to get the current voice in AVFoundation. This is either the most recent voice passed to set_voice(), or the system default voice.

Here's an example of this feature in use:

#[cfg(target_os = "macos")]
use cocoa_foundation::base::id;
#[cfg(target_os = "macos")]
use cocoa_foundation::foundation::NSRunLoop;
#[cfg(target_os = "macos")]
use objc::{msg_send, sel, sel_impl};

use tts::*;

fn main() -> Result<(), Error> {
    env_logger::init();
    let mut tts = Tts::default()?;

    // Check to ensure we can use this feature
    if !tts.supported_features().get_voice {
        return Err(Error::UnsupportedFeature);
    }

    // First, lets see what the default voice is. We'll print the name, and
    // say something in it (to ensure we can speak with it)
    let voice_on_start = tts.voice().unwrap();
    println!(
        "Voice on start: {}",
        voice_on_start
            .as_ref()
            .map_or("None".to_owned(), |voice: &Voice| voice.name())
    );

    if let Some(voice) = voice_on_start {
        tts.speak(format!("The default voice is {}", voice.name()), false)?;
    } else {
        tts.speak("No default voice", false)?;
    }

    // Pick a different voice
    let voices = tts.voices().unwrap();
    let chosen_voice = &voices[5];

    println!("Setting voice: {}", chosen_voice.name());
    tts.set_voice(chosen_voice).unwrap();

    // Say something with the new voice to ensure that it actually changed
    tts.speak(format!("The new voice is {}", chosen_voice.name()), false)?;

    let voice_now = &tts.voice().unwrap();
    println!(
        "Voice is now: {}",
        voice_now
            .as_ref()
            .map_or("None".to_owned(), |voice: &Voice| voice.name())
    );

    assert_eq!(
        voice_now.as_ref().map(|voice: &Voice| voice.name()),
        tts.voice()?.map(|voice| voice.name())
    );

    // The below is only needed to make the example run on MacOS because there is no NSRunLoop in this context.
    // It shouldn't be needed in an app or game that almost certainly has one already.
    #[cfg(target_os = "macos")]
    {
        let run_loop: id = unsafe { NSRunLoop::currentRunLoop() };
        unsafe {
            let _: () = msg_send![run_loop, run];
        }
    }

    Ok(())
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant