话题427636的标题是: 微软TTS语音引擎如何更换男女声?(急!) (300分)<br>分类:非技术问题 009 (2000-12-29 9:51:00) <br><br> <br>006 (2000-12-29 12:15:00) <br>我也想知道 <br> <br>wjiachun (2000-12-29 13:26:00) <br>?? <br> <br>visualabc (2000-12-29 13:29:00) <br>好象是换*。DIC吧<br>我也清楚。不要问我 <br> <br>cat.yy (2000-12-29 15:59:00) <br>? <br> <br>009 (2000-12-29 18:09:00) <br>到底有没有人会呀?<br>全是问号什么意思?骗分吗? <br> <br>枫 (2000-12-29 22:59:00) <br>我想应该在TTS里的SDK里有解释 <br> <br>房客 (2000-12-30 0:20:00) <br>金山词霸发声使用的是微软TTS引擎。 <br>如果是基于金山词霸:<br>硬盘上目录<br>c:/program files/common files/microsoft shared/speechenglish/tts<br>女声:<br>female.cfg<br>female.vce<br>female8.cfg<br>female8.vce//都删了就成男声了<br><br>//下边是如何调用<br>工程菜单中的导入类型库菜单,选择windows/ <br>speech目录下的vtxtauto.tlb文件,<br>单击确定后delphi会自动生成vtxauto_TLB.pas文件,它包含了TTS的com接口。 <br>应用如下: <br>uses vtxauto_TLB; <br>var TTS: ivtxtauto; <br>用前: <br>TTS:=covtxtauto_.Create ; <br>TTS.Register('project1','project1'); <br>用后: <br>TTS:=nil; <br>TTs.speak('要读的字符串',vtxtst_reading); <br>TTs.stopspeaking; // 停止 <br>TTs.set_speed(1); // 速度 <br><br> <br>009 (2000-12-30 9:31:00) <br>楼上的,我指的是程序中如何实现?删文件的方法太没有专业精神了吧? <br> <br>CJ (2000-12-30 13:44:00) <br>//a component I've used, it works good<br><br>unit mSpeech;<br><br>{<br> Monster Speech 1.1.0<br> written by Chen Yu (monster)<br><br> E-Mail: mftp@21cn.com ICQ UIN: 6740755<br> Homepage: http://homepages.msn.com/RedmondAve/mftp/<br><br> Suggestions and bug reports are warm welcomed.<br><br> This file used a Delphi translation of Speech API from<br> Project JEDI, and full package of this translation can<br> be found on JEDI's web page: http://www.delphi-jedi.org/<br>}<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> ComObj, ActiveX, Speech;<br><br>{$I mspeech.msg}<br><br>type<br> TMSpeechEngineInfo = record<br> Name: String;<br> Language: String;<br> Manufacturer: String;<br> Product: String;<br> ModeID: String;<br> EngineID: String;<br> Speaker: String;<br> Style: String;<br> Gender: String;<br> Age: Integer;<br> Features: Integer;<br> Interfaces: Integer;<br> MaxPitch: Word;<br> MinPitch: Word;<br> MaxRealTime: LongWord;<br> MinRealTime: LongWord;<br> MaxSpeed: LongWord;<br> MinSpeed: LongWord;<br> MaxVolume: LongWord;<br> MinVolume: LongWord;<br> end;<br><br> TSpeechDialog = (sdAbout, sdGeneral, sdLexicon, sdTranslate);<br> TSpeechOutput = (soFile, soGeneral);<br> TMSVisualEvent = procedure(Sender: TObject; Hints: LongWord; Mouth: PTTSMouth) of object;<br><br>type<br> EMSpeechException = class(Exception);<br> TMSpeech = class;<br><br> TTSNotifySink = class(TInterfacedObject, ITTSNotifySink)<br> private<br> FOwner: TMSpeech;<br> protected<br> function AttribChanged(dwAttribute: DWORD): HResult; stdcall;<br> function AudioStart(qTimeStamp: QWORD): HResult; stdcall;<br> function AudioStop(qTimeStamp: QWORD): HResult; stdcall;<br> function Visual(qTimeStamp: QWORD;<br> cIPAPhoneme: Char;<br> cEnginePhoneme: Char;<br> dwHints: DWORD;<br> apTTSMouth: PTTSMouth): HResult; stdcall;<br> public<br> constructor Create(AOwner: TMSpeech);<br> end;<br><br> TTSBufNotifySink = class(TInterfacedObject, ITTSBufNotifySink)<br> private<br> FOwner: TMSpeech;<br> protected<br> function TextDataDone(qTimeStamp: QWORD; dwFlags: DWORD): HResult; stdcall;<br> function TextDataStarted(qTimeStamp: QWORD): HResult; stdcall;<br> function BookMark(qTimeStamp: QWORD; dwMarkNum: DWORD): HResult; stdcall;<br> function WordPosition(qTimeStamp: QWORD; dwByteOffset: DWORD): HResult; stdcall;<br> public<br> constructor Create(AOwner: TMSpeech);<br> end;<br><br> TMSpeech = class(TComponent)<br> private<br> FEngines: TStrings;<br> FEngineStarted: Boolean;<br> FFile: WideString;<br> FIAF: IAudioFile;<br> FIAMD: IAudioMultimediaDevice;<br> FInfo: TMSpeechEngineInfo;<br> FInit: Boolean;<br> FITTSAttributes: ITTSAttributes;<br> FITTSCentral: ITTSCentral;<br> FITTSDialogs: ITTSDialogs;<br> FITTSEnum: ITTSEnum;<br> FKey: LongWord;<br> FOutput: TSpeechOutput;<br> FPaused: Boolean;<br> FText: TStrings;<br> FTTSNotifySink: ITTSNotifySink;<br> FTTSBufNotifySink: ITTSBufNotifySink;<br> FVersion, DummyS: String;<br> PModeInfo: PTTSModeInfo;<br><br> function GetInterface(Index: Integer): IUnknown;<br> function GetPitch: Word;<br> function GetRealTime: LongWord;<br> function GetSpeed: LongWord;<br> function GetVolume: LongWord;<br> procedure SetText(const Value: TStrings);<br> procedure SetPitch(const Value: Word);<br> procedure SetRealTime(const Value: LongWord);<br> procedure SetSpeed(const Value: LongWord);<br> procedure SetVolume(const Value: LongWord);<br><br> procedure BeforeSelectEngine;<br> procedure Init;<br> procedure InitAudio;<br> procedure PostSelectEngine;<br> procedure PostSelectEngine2(ModeInfo: TTSModeInfo);<br><br> function GetAudioDevice: IUnknown;<br> protected<br> FOnStart, FOnStop: TNotifyEvent;<br> FOnVisual: TMSVisualEvent;<br> FPos: LongWord;<br><br> procedure FlushFile;<br> public<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br> procedure Inject(Command: String);<br> procedure Pause;<br> procedure Resume;<br> procedure SelectEngine(EngineName: String); overload;<br> procedure SelectEngine(EngineMode: TTSModeInfo); overload;<br> procedure Show(DialogType: TSpeechDialog; ParentWnd: HWND = 0);<br> procedure Speak;<br> procedure Stop;<br><br> function GetEngineInfo(EngineName: String; var Info: TMSpeechEngineInfo): Boolean;<br><br> property Engines: TStrings read FEngines;<br> property Info: TMSpeechEngineInfo read FInfo;<br> property Interfaces[Index: Integer]: IUnknown read GetInterface;<br> property Paused: Boolean read FPaused;<br> property Pitch: Word read GetPitch write SetPitch;<br> property Position: LongWord read FPos;<br> property RealTime: LongWord read GetRealTime write SetRealTime;<br> property Speed: LongWord read GetSpeed write SetSpeed;<br> property Volume: LongWord read GetVolume write SetVolume;<br> published<br> property Filename: WideString read FFile write FFile;<br> property Output: TSpeechOutput read FOutput write FOutput;<br> property Text: TStrings read FText write SetText;<br> property Version: String read FVersion write DummyS;<br><br> property OnStart: TNotifyEvent read FOnStart write FOnStart;<br> property OnStop: TNotifyEvent read FOnStop write FOnStop;<br> property OnVisual: TMSVisualEvent read FOnVisual write FOnVisual;<br> end;<br><br>implementation<br><br>{ TMSpeech: implementation of DirectTextToSpeech}<br><br>{ construction/deconstruction }<br><br>constructor TMSpeech.Create(AOwner: TComponent);<br>begin<br> inherited;<br><br> FEngines := TStringList.Create;<br> FText := TStringList.Create;<br><br> FKey := 0;<br> FPos := 0;<br> FOutput := soGeneral;<br> FPaused := False;<br> FVersion := 'Monster Speech 1.1.0';<br><br> Init;<br>end;<br><br>destructor TMSpeech.Destroy;<br>begin<br> FInit := False;<br> FEngines.Free;<br> FText.Free;<br><br> if Assigned(PModeInfo) then Dispose(PModeInfo);<br><br> inherited;<br>end;<br><br>{ Methods }<br><br>procedure TMSpeech.Init;<br>var ModeInfo: TTSModeInfo;<br> EngineCount: Integer;<br>begin<br> FInit := True;<br> FEngineStarted := False;<br> try<br> { Enumerate engines }<br> OleCheck(CoCreateInstance(CLSID_TTSEnumerator, Nil, CLSCTX_ALL, IID_ITTSEnum, FITTSEnum));<br> OleCheck(FITTSEnum.Reset);<br> OleCheck(FITTSEnum.Next(1, ModeInfo, @EngineCount));<br><br> while EngineCount > 0 do<br> begin<br> FEngines.Add(String(ModeInfo.szModeName));<br> OleCheck(FITTSEnum.Next(1, ModeInfo, @EngineCount));<br> end;<br> except<br> FInit := False;<br> end;<br>end;<br><br>procedure TMSpeech.InitAudio;<br>begin<br> case Output of<br> soFile:<br> OleCheck(CoCreateInstance(CLSID_AudioDestFile, nil, CLSCTX_ALL,<br> IID_IAudioFile, FIAF));<br> soGeneral:<br> OleCheck(CoCreateInstance(CLSID_MMAudioDest, nil, CLSCTX_ALL,<br> IID_IAudioMultiMediaDevice, FIAMD));<br> end;<br>end;<br><br>function TMSpeech.GetAudioDevice;<br>begin<br> case Output of<br> soFile:<br> Result := FIAF;<br> soGeneral:<br> Result := FIAMD;<br> end;<br>end;<br><br>procedure TMSpeech.FlushFile;<br>begin<br> if FOutput = soFile then FIAF.Flush; // close file<br>end;<br><br>procedure TMSpeech.Inject;<br>begin<br> FITTSCentral.Inject(PChar(Command));<br>end;<br><br>procedure TMSpeech.BeforeSelectEngine;<br>begin<br> { Check if audio device is available }<br> InitAudio;<br><br> { Unregister old notify interface }<br> if FKey > 0 then<br> begin<br> FITTSCentral.UnRegister(FKey);<br> FKey := 0;<br> end;<br><br> { Create notify interfaces }<br> FTTSBufNotifySink := TTSBufNotifySink.Create(Self);<br> FTTSNotifySink := TTSNotifySink.Create(Self);<br>end;<br><br>procedure TMSpeech.SelectEngine(EngineName: String);<br>var Index, EngineCount: Integer;<br> ModeInfo: TTSModeInfo;<br>begin<br> if not FInit then<br> raise EMSpeechException.Create('msgSENotInited');<br><br> Index := Engines.IndexOf(EngineName);<br> if Index < 0 then<br> raise EMSpeechException.Create(msgSENotFound);<br><br> { Select Engine }<br> FEngineStarted := True;<br> try<br> BeforeSelectEngine;<br> OleCheck(FITTSEnum.Reset);<br> OleCheck(FITTSEnum.Skip(Index));<br> OleCheck(FITTSEnum.Next(1, ModeInfo, @EngineCount));<br><br> if Assigned(PModeInfo) then Dispose(PModeInfo);<br> New(PModeInfo);<br> PModeInfo^ := ModeInfo;<br><br> OleCheck(FITTSEnum.Select(PModeInfo^.gModeID,<br> FITTSCentral, GetAudioDevice));<br><br> PostSelectEngine;<br> PostSelectEngine2(ModeInfo);<br> except<br> FEngineStarted := False;<br> end;<br>end;<br><br>procedure TMSpeech.SelectEngine(EngineMode: TTSModeInfo);<br>var FITTSFind: ITTSFind;<br> ModeInfo: TTSModeInfo;<br>begin<br> if not FInit then<br> raise EMSpeechException.Create(msgSENotInited);<br><br> { Find and Select Engine }<br> FEngineStarted := True;<br> try<br> try<br> BeforeSelectEngine;<br> OleCheck(CoCreateInstance(CLSID_TTSEnumerator, nil, CLSCTX_ALL,<br> IID_ITTSFind, FITTSFind));<br> OleCheck(FITTSFind.QueryInterface(IID_ITTSEnum, FITTSEnum));<br> OleCheck(FITTSFind.Find(EngineMode, nil, ModeInfo));<br><br> if Assigned(PModeInfo) then Dispose(PModeInfo);<br> New(PModeInfo);<br> PModeInfo^ := ModeInfo;<br><br> OleCheck(FITTSFind.Select(PModeInfo^.gModeID,<br> FITTSCentral, GetAudioDevice));<br><br> PostSelectEngine;<br> PostSelectEngine2(ModeInfo);<br> except<br> FEngineStarted := False;<br> end;<br> finally<br> FITTSFind._Release;<br> end;<br>end;<br><br>procedure TMSpeech.PostSelectEngine;<br>begin<br> OleCheck(FITTSCentral.QueryInterface(IID_ITTSAttributes, FITTSAttributes));<br> OleCheck(FITTSCentral.QueryInterface(IID_ITTSDialogs, FITTSDialogs));<br> OleCheck(FITTSCentral.Register(Pointer(FTTSNotifySink),<br> IID_ITTSNotifySink, FKey));<br>end;<br><br>procedure TMSpeech.PostSelectEngine2;<br>var CurrentPitch: Word;<br> CurrentRealTime, CurrentSpeed: LongWord;<br>begin<br> { Retrieve Engine Information }<br> FInfo.Language := StrPas(ModeInfo.Language.szDialect);<br> with FInfo, ModeInfo do<br> begin<br> Name := StrPas(szModeName);<br> Manufacturer := StrPas(szMfgName);<br> Product := StrPas(szProductName);<br> ModeID := GUIDToString(gModeID);<br> EngineID := GUIDToString(gEngineID);<br> Speaker := StrPas(szSpeaker);<br> Style := StrPas(szStyle);<br><br> case wGender of<br> 0: Gender := 'NEUTRAL';<br> 1: Gender := 'FEMALE';<br> 2: Gender := 'MALE';<br> end;<br><br> Age := wAge;<br> Features := dwFeatures;<br> Interfaces := dwInterfaces;<br><br> with FITTSAttributes do<br> begin<br> PitchGet(CurrentPitch);<br> PitchSet(TTSATTR_MAXPITCH);<br> PitchGet(MaxPitch);<br> PitchSet(TTSATTR_MINPITCH);<br> PitchGet(MinPitch);<br> PitchSet(CurrentPitch);<br><br> RealTimeGet(CurrentRealTime);<br> RealTimeSet(TTSATTR_MAXREALTIME);<br> RealTimeGet(MaxRealTime);<br> RealTimeSet(TTSATTR_MINREALTIME);<br> RealTimeGet(MinRealTime);<br> RealTimeSet(CurrentRealTime);<br><br> SpeedGet(CurrentSpeed);<br> SpeedSet(TTSATTR_MAXSPEED);<br> SpeedGet(MaxSpeed);<br> SpeedSet(TTSATTR_MINSPEED);<br> SpeedGet(MinSpeed);<br> SpeedSet(CurrentSpeed);<br><br> { According to MS's help file }<br> MaxVolume := 100;<br> MinVolume := 0;<br> end;<br> end;<br>end;<br><br>procedure TMSpeech.Pause;<br>begin<br> OleCheck(FITTSCentral.AudioPause);<br> FPaused := True;<br>end;<br><br>procedure TMSpeech.Resume;<br>begin<br> OleCheck(FITTSCentral.AudioResume);<br> FPaused := False;<br>end;<br><br>procedure TMSpeech.Show;<br>begin<br> case DialogType of<br> sdAbout: OleCheck(FITTSDialogs.AboutDlg(ParentWnd, nil));<br> sdGeneral: OleCheck(FITTSDialogs.GeneralDlg(ParentWnd, nil));<br> sdLexicon: OleCheck(FITTSDialogs.LexiconDlg(ParentWnd, nil));<br> sdTranslate: OleCheck(FITTSDialogs.TranslateDlg(ParentWnd, nil));<br> end;<br>end;<br><br>procedure TMSpeech.Speak;<br>var SData : TSData;<br>begin<br> if not FInit then<br> raise EMSpeechException.Create(msgSENotInited);<br><br> if not FEngineStarted then<br> raise EMSpeechException.Create(msgSENotStarted);<br><br> FPaused := False;<br>// OleCheck(FITTSCentral.AudioReset);<br><br> try<br> if FOutput = soFile then<br> if FIAF.DoSet(PWideChar(Filename), 1) < 0 then<br> raise EMSpeechException.Create('msgCannotOpenFile');<br><br> SData.dwSize := Length(FText.Text) + 1;<br> SData.pData := PChar(FText.Text);<br> OleCheck(FITTSCentral.TextData (CHARSET_TEXT, 0,<br> SData, Pointer(FTTSBufNotifySink), IID_ITTSBufNotifySink));<br> except<br> end;<br>end;<br><br>procedure TMSpeech.Stop;<br>begin<br> FPaused := False;<br> OleCheck(FITTSCentral.AudioReset);<br>end;<br><br>function TMSpeech.GetEngineInfo;<br>var Index, EngineCount: Integer;<br> ModeInfo: TTSModeInfo;<br>begin<br> Result := False;<br><br> if not FInit then Exit;<br> Index := Engines.IndexOf(EngineName);<br> if Index < 0 then Exit;<br><br> if FITTSEnum.Reset < 0 then Exit;<br> if FITTSEnum.Skip(Index) < 0 then Exit;<br> if FITTSEnum.Next(1, ModeInfo, @EngineCount) < 0 then Exit;<br><br> { Retrieve Engine Information }<br> FillChar(Result, Sizeof(Result), 0);<br> Info.Language := StrPas(ModeInfo.Language.szDialect);<br> with Info, ModeInfo do<br> begin<br> Name := StrPas(szModeName);<br> Manufacturer := StrPas(szMfgName);<br> Product := StrPas(szProductName);<br> ModeID := GUIDToString(gModeID);<br> EngineID := GUIDToString(gEngineID);<br> Speaker := StrPas(szSpeaker);<br> Style := StrPas(szStyle);<br><br> case wGender of<br> 0: Gender := 'NEUTRAL';<br> 1: Gender := 'FEMALE';<br> 2: Gender := 'MALE';<br> end;<br><br> Age := wAge;<br> Features := dwFeatures;<br> Interfaces := dwInterfaces;<br><br> MaxVolume := 100;<br> end;<br> Result := True;<br>end;<br><br>{ Setting/Getting properties }<br><br>{ Undocumented property, for advanced user only }<br>function TMSpeech.GetInterface;<br>begin<br> case Index of<br> 0: Result := GetAudioDevice;<br> 1: Result := FITTSCentral;<br> 2: Result := FITTSAttributes;<br> 3: Result := FITTSDialogs;<br> end;<br>end;<br><br>function TMSpeech.GetPitch;<br>begin<br> FITTSAttributes.PitchGet(Result);<br>end;<br><br>procedure TMSpeech.SetPitch;<br>begin<br> FITTSCentral.Inject(PChar('/Pit=' + IntToStr(Value) + '/'));<br>// FITTSAttributes.PitchSet(Value);<br>end;<br><br>function TMSpeech.GetRealTime;<br>begin<br> FITTSAttributes.RealTimeGet(Result);<br>end;<br><br>procedure TMSpeech.SetRealTime;<br>begin<br> FITTSAttributes.RealTimeSet(Value);<br>end;<br><br>function TMSpeech.GetSpeed;<br>begin<br> FITTSAttributes.SpeedGet(Result);<br>end;<br><br><br>procedure TMSpeech.SetSpeed;<br>begin<br> FITTSCentral.Inject(PChar('/Spd=' + IntToStr(Value) + '/'));<br>// FITTSAttributes.SpeedSet(Value);<br>end;<br><br>{$ifdef MANUAL_SET_AND_GET_VOLUME}<br>function TMSpeech.GetVolume;<br>begin<br> FITTSAttributes.VolumeGet(Result);<br>end;<br><br>procedure TMSpeech.SetVolume;<br>begin<br> FITTSCentral.Inject(PChar('/Vol=' + IntToStr(Volume) + '/'));<br>end;<br>{$else}<br>function TMSpeech.GetVolume;<br>var CurrentVolume: LongWord;<br>begin<br> FITTSAttributes.VolumeGet(CurrentVolume);<br> Result := LoWord(CurrentVolume) * 100 div 65535;<br>end;<br><br>procedure TMSpeech.SetVolume;<br>var TempVolume: LongWord;<br>begin<br> TempVolume := 65535 * Value div 100;<br> TempVolume := MakeWParam(TempVolume, TempVolume);<br> FITTSCentral.Inject(PChar('/Vol=' + IntToStr(TempVolume) + '/'));<br>// OleCheck(FITTSAttributes.VolumeSet(TempVolume));<br>end;<br>{$endif}<br><br>procedure TMSpeech.SetText;<br>begin<br> FText.Assign(Value);<br>end;<br><br>{ TTSNotifySink }<br><br>constructor TTSNotifySink.Create;<br>begin<br> FOwner := AOwner;<br>end;<br><br>function TTSNotifySink.AttribChanged;<br>begin<br> Result := 0;<br>end;<br><br>function TTSNotifySink.AudioStart;<br>begin<br> if Assigned(FOwner.FOnStart) then FOwner.FOnStart(Self);<br> Result := 0;<br>end;<br><br>function TTSNotifySink.AudioStop;<br>begin<br> FOwner.FlushFile;<br> if Assigned(FOwner.FOnStop) then FOwner.FOnStop(Self);<br> Result := 0;<br>end;<br><br>function TTSNotifySink.Visual;<br>begin<br> if Assigned(FOwner.FOnVisual) then FOwner.FOnVisual(Self, dwHints, apTTSMouth);<br> Result := 0;<br>end;<br><br>{ TTSBufNotifySink }<br><br>constructor TTSBufNotifySink.Create;<br>begin<br> FOwner := AOwner;<br>end;<br><br>function TTSBufNotifySink.BookMark;<br>begin<br> Result := 0;<br>end;<br><br>function TTSBufNotifySink.TextDataDone;<br>begin<br> Result := 0;<br>end;<br><br>function TTSBufNotifySink.TextDataStarted;<br>begin<br> Result := 0;<br>end;<br><br>function TTSBufNotifySink.WordPosition;<br>begin<br> FOwner.FPos := dwByteOffset;<br> Result := 0;<br>end;<br><br>end. <br> <br>009 (2000-12-31 12:28:00) <br>go on <br> <br>zyuz (2001-01-16 16:47:00) <br>我怎么好象没有看明白。。。。 <br> <br>zyy04 (2001-01-16 18:02:00) <br>说清楚你用的是Speech 4,还是Speech 5? <br> <br>悲酥清风 (2001-04-02 13:15:00) <br>009:请自己提前或结束你的帖子,谢谢合作。 <br> <br>wjiachun (2001-06-17 20:17:00) <br>接受答案了. <br> <br><br>CJ的回答最终被接受。