Skip to content

Commit

Permalink
More on voices
Browse files Browse the repository at this point in the history
  • Loading branch information
yury committed Dec 23, 2023
1 parent d3b1bbc commit cf9eeac
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 4 deletions.
4 changes: 4 additions & 0 deletions cidre/pomace/av/av.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ Class AV_PLAYER;
Class AV_SAMPLE_BUFFER_DISPLAY_LAYER;
Class AV_SAMPLE_BUFFER_VIDEO_RENDERER;

Class AV_SPEECH_SYNTHESIS_VOICE;

__attribute__((constructor))
static void av_initializer(void)
{
Expand Down Expand Up @@ -109,6 +111,8 @@ static void av_initializer(void)
AV_SAMPLE_BUFFER_DISPLAY_LAYER = [AVSampleBufferDisplayLayer class];
AV_SAMPLE_BUFFER_VIDEO_RENDERER = [AVSampleBufferVideoRenderer class];

AV_SPEECH_SYNTHESIS_VOICE = [AVSpeechSynthesisVoice class];

initialized = 1;
}
}
Expand Down
1 change: 1 addition & 0 deletions cidre/src/av/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,4 @@ pub use speech_synthesis::Utterance as SpeechUtterance;
pub use speech_synthesis::Voice as SpeechSynthesisVoice;
pub use speech_synthesis::VoiceGender as SpeechSynthesisVoiceGender;
pub use speech_synthesis::VoiceQuality as SpeechSynthesisVoiceQuality;
pub use speech_synthesis::VoiceTraits as SpeechSynthesisVoiceTraits;
2 changes: 1 addition & 1 deletion cidre/src/av/audio/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ extern "C" {

#[cfg(test)]
mod tests {
use crate::{av, objc::Obj};
use crate::av;

#[test]
fn basics() {
Expand Down
74 changes: 71 additions & 3 deletions cidre/src/av/audio/speech_synthesis.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{define_obj_type, ns};
use crate::{arc, define_obj_type, define_options, ns, objc};

#[doc(alias = "AVSpeechBoundary")]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(isize)]
pub enum SpeechBoundery {
Expand All @@ -10,17 +11,21 @@ pub enum SpeechBoundery {
Word,
}

#[doc(alias = "AVSpeechSynthesisVoiceQuality")]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(isize)]
pub enum VoiceQuality {
/// New voice return 0 as voice quality (see tests)
Unknown = 0,
/// The basic quality version of a voice that’s on the device by default.
Default = 1,
/// The enhanced quality version of a voice that the user must download.
Enhanced,
///
/// The enhanced quality version of a voice that the user must download.
Premium,
}

#[doc(alias = "AVSpeechSynthesisVoiceGender")]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(isize)]
pub enum VoiceGender {
Expand All @@ -33,6 +38,7 @@ pub enum VoiceGender {
}

/// Markers used in the output event callback. Used for providing metadata on synthesized audio.
#[doc(alias = "AVSpeechSynthesisMarkerMark")]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(isize)]
pub enum MarkerMark {
Expand All @@ -46,7 +52,57 @@ pub enum MarkerMark {
Paragraph,
}

define_obj_type!(pub Voice(ns::Id));
define_options!(
#[doc(alias = "AVSpeechSynthesisVoiceTraits")]
pub VoiceTraits(usize)
);

impl VoiceTraits {
pub const NONE: Self = Self(0);

/// The voice is generally for novelty purposes, for example a character's voice in a game.
pub const IS_NOVELTY_VOICE: Self = Self(1 << 0);

pub const IS_PERSONAL_VOICE: Self = Self(1 << 1);
}

define_obj_type!(
#[doc(alias = "AVSpeechSynthesisVoice")]
pub Voice(ns::Id),
AV_SPEECH_SYNTHESIS_VOICE
);

impl Voice {
#[objc::cls_msg_send(speechVoices)]
pub fn speech_voices_ar() -> arc::Rar<ns::Array<Self>>;

#[objc::cls_rar_retain]
pub fn speech_voices() -> arc::R<ns::Array<Self>>;

#[objc::cls_msg_send(currentLanguageCode)]
pub fn current_lang_code_ar() -> arc::Rar<ns::String>;

#[objc::cls_rar_retain]
pub fn current_lang_code() -> arc::R<ns::String>;

#[objc::msg_send(language)]
pub fn lang(&self) -> Option<&ns::String>;

#[objc::msg_send(identifier)]
pub fn id(&self) -> &ns::String;

#[objc::msg_send(name)]
pub fn name(&self) -> &ns::String;

#[objc::msg_send(quality)]
pub fn quality(&self) -> VoiceQuality;

#[objc::msg_send(gender)]
pub fn gender(&self) -> VoiceGender;

#[objc::msg_send(audioFileSettings)]
pub fn audio_file_settings(&self) -> Option<&ns::Dictionary<ns::String, ns::Id>>;
}

define_obj_type!(pub Utterance(ns::Id));

Expand All @@ -73,6 +129,8 @@ extern "C" {
static AVSpeechUtteranceMinimumSpeechRate: f32;
static AVSpeechUtteranceMaximumSpeechRate: f32;
static AVSpeechUtteranceDefaultSpeechRate: f32;

static AV_SPEECH_SYNTHESIS_VOICE: &'static objc::Class<Voice>;
}

#[cfg(test)]
Expand All @@ -87,5 +145,15 @@ mod tests {
assert!(
av::SpeechUtterance::default_speech_rate() < av::SpeechUtterance::max_speech_rate()
);

let voice = av::SpeechSynthesisVoice::new();
voice.as_type_ref().show();
assert!(voice.id().is_empty());
assert!(voice.name().is_empty());
assert!(voice.lang().is_none());
assert_eq!(voice.quality(), av::SpeechSynthesisVoiceQuality::Unknown);
assert!(av::SpeechSynthesisVoice::speech_voices().len() > 0);
let settings = voice.audio_file_settings();
assert!(settings.is_none());
}
}

0 comments on commit cf9eeac

Please sign in to comment.