一、下载科大讯飞Win版本SDK
二、将SDK中的bin目录下的资源文件拷贝值新建工程目录,并建立dll引入单元,将c++dll头文件转成delphi
unit UnitXF;
interface
const
HDANET_DLL = 'msc.dll';
type
wave_pcm_hdr = record
riff: array [0 .. 3] of AnsiChar; // = "RIFF"
size_8: Integer; // = FileSize - 8
wave: array [0 .. 3] of AnsiChar; // = "WAVE"
fmt: array [0 .. 3] of AnsiChar; // 1 // = "fmt "
fmt_size: Integer; // = 下一个结构体的大小 : 16
format_tag: SmallInt; // = PCM : 1
channels: SmallInt; // = 通道数 : 1
samples_per_sec: Integer; // = 采样率 : 8000 | 6000 | 11025 | 16000
avg_bytes_per_sec: Integer;
// = 每秒字节数 : samples_per_sec * bits_per_sample / 8
block_align: SmallInt; // = 每采样点字节数 : wBitsPerSample / 8
bits_per_sample: SmallInt; // = 量化比特数: 8 | 16
data: array [0 .. 3] of AnsiChar; // = "data";
data_size: Integer; // = 纯数据长度 : FileSize - 44
end;
tts_result_ntf_handler = procedure(const sessionID: PAnsiChar;
audio: PAnsiChar; audioLen: Integer; synthStatus: Integer; ced: Integer;
const audioInfo: PAnsiChar; audioInfoLen: Integer;
userData: Pointer); stdcall;
tts_status_ntf_handler = procedure(const sessionID: PAnsiChar; itype: Integer;
status: Integer; param1: Integer; param2: Pointer;
userData: Pointer); stdcall;
tts_error_ntf_handler = procedure(const sessionID: PAnsiChar;
errorCode: Integer; detail: PAnsiChar; userData: Pointer); stdcall;
function MSPLogin(const usr: PAnsiChar; const pwd: PAnsiChar;
const params: PAnsiChar): Integer; stdcall;
function MSPLogout(): Integer; stdcall;
function QTTSSessionBegin(params: PAnsiChar; errorCode: PInteger)
: PAnsiChar; stdcall;
function QTTSTextPut(sessionID: PAnsiChar; textString: PAnsiChar;
textLen: Integer; params: PAnsiChar): Integer; stdcall;
function QTTSAudioGet(sessionID: PAnsiChar; audioLen: PWord;
synthStatus: PInteger; errorCode: PInteger):Pointer;stdcall;
function QTTSAudioInfo(sessionID: PAnsiChar): PAnsiChar; stdcall;
function QTTSSessionEnd(sessionID: PAnsiChar; hints: PAnsiChar)
: Integer; stdcall;
function QTTSGetParam(sessionID: PAnsiChar; paramName: PAnsiChar;
paramValue: PAnsiChar; valueLen: PInteger): Integer; stdcall;
function QTTSRegisterNotify(sessionID: PAnsiChar;
rsltCb: tts_result_ntf_handler; statusCb: tts_status_ntf_handler;
errCb: tts_error_ntf_handler; userData: Pointer): Integer; stdcall;
implementation
function MSPLogin; external HDANET_DLL;
function MSPLogout; external HDANET_DLL;
function QTTSSessionBegin; external HDANET_DLL;
function QTTSTextPut; external HDANET_DLL;
function QTTSAudioGet; external HDANET_DLL;
function QTTSAudioInfo; external HDANET_DLL;
function QTTSSessionEnd; external HDANET_DLL;
function QTTSGetParam; external HDANET_DLL;
function QTTSRegisterNotify; external HDANET_DLL;
end.
三、在新工程中引入转好的delphi单元,并使用:
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm3 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
uses UnitXF;
{$R *.dfm}
procedure TForm3.Button1Click(Sender: TObject);
var
session_begin_params, filename, text: PAnsiChar;
rt: Integer;
sessionID: PAnsiChar;
fp: TFileStream;
wav_hdr: wave_pcm_hdr;
data: Pointer;
audio_len: Word;
synth_status: Integer;
begin
session_begin_params :=
PAnsiChar(
'engine_type = local, voice_name = xiaoyan, text_encoding = GB2312, tts_res_path = fo|res\\tts\\xiaoyan.jet;fo|res\\tts\\common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2');
filename := PAnsiChar('tts_sample.wav');
text := PAnsiChar('今天天气好极了');
fp := TFileStream.Create(filename, fmCreate);
if fp = nil then
begin
ShowMessage('生成文件失败');
exit;
end;
rt := -1;
sessionID := QTTSSessionBegin(session_begin_params, @rt);
if rt <> 0 then
begin
exit;
end;
rt := QTTSTextPut(sessionID, text, Length(text), nil);
if rt <> 0 then
begin
QTTSSessionEnd(sessionID, PAnsiChar('TextPutError'));
fp.Free;
exit;
end;
strpcopy(@wav_hdr.riff, PAnsiChar('RIFF'));
wav_hdr.size_8 := 0;
strpcopy(@wav_hdr.wave, PAnsiChar('WAVE'));
strpcopy(@wav_hdr.fmt, PAnsiChar('fmt '));
wav_hdr.fmt_size := 16;
wav_hdr.format_tag := 1;
wav_hdr.channels := 1;
wav_hdr.samples_per_sec := 16000;
wav_hdr.avg_bytes_per_sec := 32000;
wav_hdr.block_align := 2;
wav_hdr.bits_per_sample := 16;
strpcopy(@wav_hdr.data, PAnsiChar('data'));
wav_hdr.data_size := 0;
fp.Write(@wav_hdr, SizeOf(wav_hdr));
audio_len := 0;
synth_status := 1;
while True do
begin
// 获取合成音频
data := QTTSAudioGet(sessionID, @audio_len, @synth_status, @rt);
if rt <> 0 then
begin
Break;
end;
if data <> nil then
begin
fp.Write(data, audio_len);
wav_hdr.data_size := wav_hdr.data_size + audio_len; // 计算data_size大小
end;
if synth_status = 2 then
begin
Break;
end;
end;
if rt <> 0 then
begin
QTTSSessionEnd(sessionID, PAnsiChar('AudioGetError'));
fp.Free;
ShowMessage('失败:' + IntToStr(rt));
exit;
end;
// 修正wav文件头数据的大小
wav_hdr.size_8 := wav_hdr.size_8 + wav_hdr.data_size + (SizeOf(wav_hdr) - 8);
// 将修正过的数据写回文件头部,音频文件为wav格式
fp.Seek(4, 0);
// 写入size_8的值
fp.Write(@wav_hdr.size_8, SizeOf(wav_hdr.size_8));
fp.Seek(40, 0); // 将文件指针偏移到存储data_size值的位置
// 写入data_size的值
fp.Write(@wav_hdr.data_size, SizeOf(wav_hdr.data_size));
fp.Free;
// 合成完毕
rt := QTTSSessionEnd(sessionID, 'Normal');
if rt <> 0 then
begin
ShowMessage('合并失败');
end;
ShowMessage('合并成功');
end;
procedure TForm3.Button2Click(Sender: TObject);
var
login_params: PAnsiChar;
rt: Integer;
begin
rt := -1;
// 登录参数,appid与msc库绑定,请勿随意改动
login_params := PAnsiChar('appid = 5e004cda, work_dir = .');
rt := MSPLogin(nil, nil, login_params);
if rt = 0 then
begin
ShowMessage('调用成功');
end;
end;
procedure TForm3.Button3Click(Sender: TObject);
begin
MSPLogout;
end;
end.