You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi7调用MS SAPI合成语音后续短语耗时逐次增加问题求解

问题成因

你观察到的合成耗时递增,本质不是SAPI语音合成本身变慢,是统计音频字节数的实现方式存在额外性能损耗:
每次循环中调用的SpMemoryStream.GetData会将内存流内的全部历史音频数据完整拷贝为OLE变体数组,随着循环执行,流内存储的音频数据越来越多,每次拷贝操作的耗时也会线性增长,最终表现为每轮循环的总耗时越来越长。

解决方案

直接读取TSpMemoryStream自带的Size属性获取当前流的总字节数,完全不需要拷贝整个流的数据:

uses ...SpeechLib_TLB...

procedure TForm1.Button2Click(Sender: TObject);
var
    SpVoice: TSpVoice;
    SpMemoryStream: TSpMemoryStream;
    SpFileStream: TSpFileStream;
    SavedCW: Word;
    i: integer;
    list: tstrings;
    time1, time2, bytes1, bytes2: dword;
begin
    ListBox1.Clear;
    list:=tstringlist.create;
    list.loadfromfile(extractfilepath(paramstr(0)) + 'test1.txt');

    SpVoice:=TSpVoice.create(nil);

    SpMemoryStream:=TSpMemoryStream.Create(nil);
    SpMemoryStream.Format.type_:=SAFT44kHz16BitMono;

    SpVoice.AudioOutputStream:=SpMemoryStream.DefaultInterface;

    SpFileStream:=TSpFilestream.Create(nil);
    SpFileStream.Format.type_:=SAFT44kHz16BitMono;
    SpFileStream.Open(ExtractFilePath(ParamStr(0))+'test1.wav', SSFMCreateForWrite, FALSE);

    SavedCW := Get8087CW;
    Set8087CW(SavedCW or $4);
    for i:=0 to list.count-1 do begin
        time1:=gettickcount;
        // 直接读Size属性,无需拷贝全量数据
        bytes1:=SpMemoryStream.Size;
        SpVoice.Speak(list[i], 0);
        time2:=gettickcount;
        // 直接读Size属性,无需拷贝全量数据
        bytes2:=SpMemoryStream.Size;
        ListBox1.items.Add(Format('%d ms   %d Bytes   %s', [time2-time1, bytes2-bytes1, list[i]]));
        Label1.caption:=format('Item %d From %d', [i+1, list.count]);
        Application.ProcessMessages;
    end;
    Set8087CW(SavedCW);

    SpFileStream.Write(SpMemoryStream.GetData);
    SpFileStream.Free;
    SpMemoryStream.Free;
    SpVoice.free;
    list.free;

    showmessage('All done');
end;

修改后去掉了循环内的全量内存拷贝操作,每轮循环的耗时就会回归到正常的语音合成耗时,不会再出现线性递增的情况。

内容的提问来源于stack exchange,提问作者user1581016

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:54:02