日本語音声合成(AquesTalk)サンプル
準備
- 開発環境
- 株式会社 アクエストから「AquesTalk Win版」をダウンロードして中の「AquesTalk.dll」と「AquesTalkDa.dll」をソースと同じフォルダに入れる。
- 他の声も試す場合は「AquesTalk 拡張声種ライブラリ」もダウンロードしてください。
サンプルソース
Delphiで「AquesTalk.dll」と「AquesTalkDa.dll」のラッパークラスを作成して利用しています。
「AquesTalk Win版」付属のC++のソースを参考に作りましたが、完全に同じ動作をするわけではありません。
フォーム
付属のサンプルは動作ログが出力されますが、面倒くさいんで省きました。代わりに声を変えれるように音声合成DLLを選択仕直せる機能を付けました。
リスト1 サンプルプログラム
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AqTalk, ComCtrls, Buttons, ExtCtrls, DateUtils;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
ComboBox1: TComboBox;
Button1: TButton;
TrackBar1: TTrackBar;
StopButton: TButton;
GroupBox2: TGroupBox;
GroupBox3: TGroupBox;
Edit1: TEdit;
ComboBox2: TComboBox;
Label1: TLabel;
Label2: TLabel;
Button2: TButton;
LabeledEdit1: TLabeledEdit;
LabeledEdit2: TLabeledEdit;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
GroupBox4: TGroupBox;
ChangeButton: TButton;
OpenDialog1: TOpenDialog;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
SpeedLabel: TLabel;
GroupBox5: TGroupBox;
Memo1: TMemo;
Button6: TButton;
Button7: TButton;
SaveDialog1: TSaveDialog;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure StopButtonClick(Sender: TObject);
procedure ChangeButtonClick(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
private
{ Private 宣言 }
procedure WMUserDadone (var msg: TMessage); message WM_USR_DADONE;
procedure PlaySheep;
public
{ Public 宣言 }
AquesTalk: TAquesTalk;
end;
var
Form1: TForm1;
m_iSheep: Integer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
AquesTalk := TAquesTalk.Create;
OpenDialog1.InitialDir := ExtractFileDir(Application.ExeName);
SpeedLabel.Caption := IntToStr(AquesTalk.Speed);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
AquesTalk.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
AquesTalk.Play(ComboBox1.Items[ComboBox1.ItemIndex]);
end;
procedure TForm1.StopButtonClick(Sender: TObject);
begin
AquesTalk.Stop;
m_iSheep := 0;
end;
procedure TForm1.ChangeButtonClick(Sender: TObject);
begin
AquesTalk.VoiceChange(LabeledEdit1.Text, LabeledEdit2.Text);
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then begin
LabeledEdit1.Text := OpenDialog1.FileName;
end;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
if OpenDialog1.Execute then begin
LabeledEdit2.Text := OpenDialog1.FileName;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var koe, strNum, strUnit: string;
begin
strNum := Edit1.Text; //数値の取得
strUnit := ComboBox2.Items[ComboBox2.ItemIndex]; //単位の取得
//読み記号部分を抽出
strUnit := Trim(Copy(strUnit, AnsiPos(' ',strUnit), Length(strUnit)));
koe := Format('<NUMK VAL=%s COUNTER=%s>。', [strNum, strUnit]);
AquesTalk.Play(koe);
end;
procedure TForm1.Button3Click(Sender: TObject);
var koe: string;
n: TDateTime;
begin
n := Now;
koe := '<NUMK VAL=' + IntToStr(YearOf(n)) + ' COUNTER=ねん>;' +
'<NUMK VAL=' + IntToStr(MonthOf(n)) + ' COUNTER=がつ>;' +
'<NUMK VAL=' + IntToStr(DayOf(n)) + ' COUNTER=にち>デ_ス。';
AquesTalk.Play(koe);
end;
procedure TForm1.Button4Click(Sender: TObject);
var koe: string;
n: TDateTime;
begin
n := Now;
koe := '<NUMK VAL=' + IntToStr(HourOf(n)) + ' COUNTER=じ>;' +
'<NUMK VAL=' + IntToStr(MinuteOf(n)) + ' COUNTER=ふん>;' +
'<NUMK VAL=' + IntToStr(SecondOf(n)) + ' COUNTER=びょー>です。';
AquesTalk.Play(koe);
end;
procedure TForm1.PlaySheep;
var koe: string;
begin
case m_iSheep of
14: koe := 'ひつじの/メ''リーさん。';
22: koe := 'ひつじが/ころんだ。';
27: koe := 'ひつじが/いっぱい、';
45: koe := 'も''−;ねむく+なくな''ったよ、';
65: koe := 'し''つじの/セバ''_スチャン。';
else koe := Format('ひつじが/<NUMK VAL=%d COUNTER=ひき>。', [m_iSheep]);
end;
Inc(m_iSheep);
AquesTalk.Play(koe, Handle, WM_USR_DADONE, ID_SHEEP);
end;
procedure TForm1.WMUserDadone(var msg: TMessage);
begin
if (msg.LParam = ID_SHEEP) and (m_iSheep <> 0) then PlaySheep;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
m_iSheep := 1;
PlaySheep;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
AquesTalk.Speed := TrackBar1.Position;
SpeedLabel.Caption := IntToStr(AquesTalk.Speed);
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
AquesTalk.Play(Memo1.Lines.Text);
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
if SaveDialog1.Execute then begin
AquesTalk.Synthe(SaveDialog1.FileName, Memo1.Lines.Text);
end;
end;
end.
リスト2 DLLのラッパークラス
unit AqTalk;
interface
uses
Windows, SysUtils, Messages;
const
WM_USR_DADONE = WM_USER + 111;
ID_SHEEP = 999;
type
H_AQTKDA = LongWord;
TAquesTalk_Synthe = function (const koe: string;
iSpeed: Integer; var size: Integer): Pointer; stdcall;
TAquesTalk_FreeWave = procedure (wav: Pointer); stdcall;
TAquesTalkDa_PlaySync = function (const koe: String;
iSpeed: Integer = 100): Integer; stdcall;
TAquesTalkDa_Create = function : H_AQTKDA; stdcall;
TAquesTalkDa_Release = procedure (hMe: H_AQTKDA); stdcall;
TAquesTalkDa_Play = function (
hMe: H_AQTKDA;
const koe: String; iSpeed: Integer = 100;
hWnd: HWND = 0;
msg: ULONG = 0;
dwUser: ULONG = 0
): Integer; stdcall;
TAquesTalkDa_Stop = procedure (hMe: H_AQTKDA); stdcall;
TAquesTalkDa_IsPlay = function (hMe: H_AQTKDA): Integer; stdcall;
TAquesTalk = class
private
FhDll,
FhDaDll: THandle;
FHandle: THandle;
AquesTalk_Synthe: TAquesTalk_Synthe;
AquesTalk_FreeWave: TAquesTalk_FreeWave;
AquesTalkDa_PlaySync: TAquesTalkDa_PlaySync;
AquesTalkDa_Create: TAquesTalkDa_Create;
AquesTalkDa_Release: TAquesTalkDa_Release;
AquesTalkDa_Play: TAquesTalkDa_Play;
AquesTalkDa_Stop: TAquesTalkDa_Stop;
AquesTalkDa_IsPlay: TAquesTalkDa_IsPlay;
FSpeed: Integer;
procedure OpenDll(Dll, DaDll: string);
procedure CloseDll;
procedure SetSpeed(const Value: Integer);
public
constructor Create(Dll: string = 'AquesTalk.dll';
DaDll: string = 'AquesTalkDa.dll');
destructor Destroy; override;
function Synthe(FileName, Koe: string): Boolean;
function PlaySync(Koe: string): Boolean;
function Play(Koe: string; hWnd: HWND = 0; msg:
ULONG = 0; dwUser: ULONG = 0): Boolean;
procedure Stop;
function IsPlay: Boolean;
procedure VoiceChange(Dll, DaDll: string);
property Hanele: THandle read FHandle;
property Speed: Integer read FSpeed write SetSpeed;
end;
implementation
{ TAquesTalk }
procedure TAquesTalk.OpenDll(Dll, DaDll: string);
begin
CloseDll;
FhDll := LoadLibrary(PChar(Dll));
FhDaDll := LoadLibrary(PChar(DaDll));
if (FhDll <> 0) and (FhDaDll <> 0) then begin
AquesTalk_Synthe := GetProcAddress(FhDll, 'AquesTalk_Synthe');
AquesTalk_FreeWave := GetProcAddress(FhDll, 'AquesTalk_FreeWave');
AquesTalkDa_PlaySync := GetProcAddress(FhDaDll, 'AquesTalkDa_PlaySync');
AquesTalkDa_Create := GetProcAddress(FhDaDll, 'AquesTalkDa_Create');
AquesTalkDa_Release := GetProcAddress(FhDaDll, 'AquesTalkDa_Release');
AquesTalkDa_Play := GetProcAddress(FhDaDll, 'AquesTalkDa_Play');
AquesTalkDa_Stop := GetProcAddress(FhDaDll, 'AquesTalkDa_Stop');
AquesTalkDa_IsPlay := GetProcAddress(FhDaDll, 'AquesTalkDa_IsPlay');
FHandle := AquesTalkDa_Create;
end else begin
raise Exception.Create('音声合成DLLが不正です');
end;
end;
constructor TAquesTalk.Create(Dll, DaDll: string);
begin
FSpeed := 100;
OpenDll(Dll, DaDll);
end;
procedure TAquesTalk.VoiceChange(Dll, DaDll: string);
begin
OpenDll(Dll, DaDll);
end;
procedure TAquesTalk.CloseDll;
begin
if FHandle <> 0 then AquesTalkDa_Release(FHandle);
if FhDll <> 0 then FreeLibrary(FhDll);
if FhDaDll <> 0 then FreeLibrary(FhDaDll);
end;
destructor TAquesTalk.Destroy;
begin
CloseDll;
inherited;
end;
function TAquesTalk.IsPlay: Boolean;
begin
Result := AquesTalkDa_IsPlay(FHandle) = 1;
end;
function TAquesTalk.Play(Koe: string; hWnd: HWND; msg,
dwUser: ULONG): Boolean;
begin
Result := AquesTalkDa_Play(FHandle, Koe, FSpeed, hWnd, msg, dwUser) = 0;
end;
function TAquesTalk.PlaySync(Koe: string): Boolean;
begin
Result := AquesTalkDa_PlaySync(Koe, FSpeed) = 0;
end;
procedure TAquesTalk.Stop;
begin
AquesTalkDa_Stop(FHandle);
end;
function TAquesTalk.Synthe(FileName, Koe: string): Boolean;
var Size: Integer;
Wav: Pointer;
FileHandle : Integer;
begin
Wav := AquesTalk_Synthe(Koe, FSpeed, Size);
try
Result := Wav <> nil;
if not Result then Exit;
FileHandle := FileCreate(FileName);
try
FileWrite(FileHandle, Wav^, Size);
finally
FileClose(FileHandle);
end;
finally
AquesTalk_FreeWave(Wav);
end;
end;
procedure TAquesTalk.SetSpeed(const Value: Integer);
begin
if FSpeed <> Value then begin
FSpeed := Value;
if FSpeed < 50 then FSpeed := 50;
if FSpeed > 300 then FSpeed := 300;
end;
end;
end.
ダウンロード
AquesTalkサンプルソース [ Down ]DLL入手先 AquesTalk Win版
