[Mac]談話と特殊効果(Text-to-Speech) | Cocoa練習帳

[Mac]談話と特殊効果(Text-to-Speech)

WWDCに行くと、どんな方向を目指しているのか感じ取る事が出来る。また、その場で理解できなくても、これは聞いた事があるな?と、調査のヒントを得られる。今回は、WWDCが解決の糸口になった例だ。




OS Xでテキストの内容をスピーチされる事は簡単だ。




Cocoaでは、




NSSpeechSynthesizer *synthesizer = [[NSSpeechSynthesizer alloc] init];
[synthesizer setDelegate:self];
[synthesizer startSpeakingString:@"Hello, world."];
 
- (void)speehSynthesizer:(NSSpeechSynthesizer *)sender
    didFinishSpeaking:(BOOL)finishedpeaking
{
    ...
}



Core Foundationでは、




SpeechChannel *chan;
err = NewSpeechChannel(NULL, &chan);
CFNumber *callback = CFNumberCreate(NULL, kCFNumberLongType, HighlightSpokenWord);
err = SetSpeechProperty(chan, kSpeechWordCFCallBack, callback);
err = SpeakCFString(chan, CFSTR("Hello, world."), NULL);
 
void HighlightSpokenWord(SpeechChannel chan,
    SRefCo refCon,
    CFStringRef aString,
    CFRange wordRange)
{
    ....
}



でも、それにAudio Unitを使った効果を適用させるには、どうすればいいのか?




どうして、これが出来ると思ったのかは今となっては思い出せないが、多分、WWDCでのセッションの内容が頭の片隅にあったのだろう。それで、WWDCのセッションのビデオを見直しのが、WWDC2009のSession 129『Text-to-Speech: Adventures with Alex』だった。




一度、解決の糸口をつかむと、後は芋づる式。ヘッダーファイルのコメントで説明されていた。




SpeechSynthesis.h
 
/*------------------------------------------*/
/* AudioUnit constants - new in 10.5        */
/*------------------------------------------*/
enum {
  kAudioUnitSubType_SpeechSynthesis = 'ttsp', /* kAudioUnitType_Generator */
  kAudioUnitProperty_Voice      = 3330, /* Get/Set (VoiceSpec)      */
  kAudioUnitProperty_SpeechChannel = 3331 /* Get (SpeechChannel)      */
};



指定した文章をSpeech Synthesisで喋らせ、それをAudio Unitのコンポーネントでディレイさせて再生させる例が以下だ。




AUNode

NewAUGraph(&_auGraph);
    
AudioComponentDescription
cd.componentType = kAudioUnitType_Generator;
cd.componentSubType = kAudioUnitSubType_SpeechSynthesis;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentFlags = 0;
cd.componentFlagsMask = 0;

AUGraphAddNode(_auGraph, &cd, &inputNode);

cd.componentType = kAudioUnitType_Effect;
cd.componentSubType = kAudioUnitSubType_Delay;
AUGraphAddNode(_auGraph, &cd, &effectNode);

cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_DefaultOutput;
AUGraphAddNode(_auGraph, &cd, &outputNode);

AUGraphConnectNodeInput(_auGraph, inputNode, 0, effectNode, 0);
AUGraphConnectNodeInput(_auGraph, effectNode, 0, outputNode, 0);

AUGraphOpen(_auGraph);
AUGraphInitialize(_auGraph);
    
AudioUnit
AUGraphNodeInfo(_auGraph, inputNode, NULL, &generateAudioUnit);
SpeechChannel
UInt32
AudioUnitGetProperty(generateAudioUnit, kAudioUnitProperty_SpeechChannel,


AUGraphStart(_auGraph);

SpeakCFString(channel, CFSTR("Hello, world."), NULL);



ソースコード
GitHubからどうぞ。

https://github.com/murakami/workbook/tree/master/mac/TextToSpeech - GitHub


関連情報
Speech

Speech Synthesis Programmig Guide

Using the Japanese Analysis Engine and Access Method