Delphi接入科大讯飞语音合成SDK

一、下载科大讯飞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.

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值