如何让TTS 5.4生成WAV类型的TSpMemoryStream流后用DSPK组件从内存中读出语音

qq_16697501 2015-03-20 07:07:44
开发环境 win7 Delphi7

主要目的:调用win7自带的SAPI 5.4(TTS)生成语音流,并通过DSPack组件分别在电脑左右的声道发音。由于反复使用频率较高,所以未生成语音文件而生成语音流,通过内存中读取的方式。

为解决于是在网上搜索到一些文章,并在
http://www.delphi2007.net/delphiblog/html/delphi_200711515440514966.html提示下修改了DSpack, 增加了
function TFilterGraph.RendStream(Stream: TStream): HRESULT; 的方法。

现在问题来了,在调用TTS 的TSpMemoryStream类生成OleVariant类型 如何转换为 TStream类型让DSpack组件读出来????
除此外是否还有更好办法,1.只要满足TTS生成语音,2. 发声时可选左右声道也就是拥有类似Balance的属性,3.生成语音文件不存于硬盘。

谢谢各位大神,大牛,大哥!有没看懂问题的,小弟随时回复!!!
    SpMemoryStream1.Format.type_:=SAFT8kHz8BitMono;
SpMemoryStream1.SetData(Music);
sp.AudioOutputStream:=SpMemoryStream1.DefaultInterface;
sp.Speak(Memo1.Text,SVSFlagsAsync);
sp.WaitUntilDone(-1);
Music:=SpMemoryStream1.GetData;
这段是调用TTS的TSpMemoryStream生成的(Music:OleVariant;)不知对了没有?

...全文
1685 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
darlingpeng 2015-11-22
  • 打赏
  • 举报
回复
大家好, 我想下载SAPI5.4版本,用于XP系统,但就是找不到下载的地址?谁有?
qq_16697501 2015-03-25
  • 打赏
  • 举报
回复
自己顶一下!求高手帮忙!
TTS是否支持输出内存流????
qq_16697501 2015-03-21
  • 打赏
  • 举报
回复
引用 1 楼 frtrnr 的回复:
看看哪种适合你(未测试)
代码一:
Do you mean a variant array of bytes?

function VarBytesFromStream(s: TStream; Size: integer): OleVariant;
var
p: pchar;
begin
Result := varArrayCreate([0, Size-1], VarByte);
p := varArrayLock(Result);
try
S.Read(p^, Size);
finally
varArrayUnlock(Result);
end
end;

procedure VarBytesToStream(const Value:OleVariant; s: TStream);
var
p: pchar;
size: integer;
begin
size := VarArrayHighBound(value,1) - VarArrayLowBound(value,1) + 1;
p := VarArrayLock(Value);
try
S.Write(p^, Size);
finally
VarArrayUnlock(Value)
end;
end;


代码二:

function MemoryStreamToOleVariant(Strm: TMemoryStream):
OleVariant;
var
Data: PByteArray;
begin
Result := VarArrayCreate ([0, Strm.Size - 1], varByte);
Data := VarArrayLock(Result);
try
Strm.Position := 0;
Strm.ReadBuffer(Data^, Strm.Size);
finally
VarArrayUnlock(Result);
end;
end;

function OleVariantToMemoryStream(OV: OleVariant):
TMemoryStream;
var
Data: PByteArray;
Size: integer;
begin
Result := TMemoryStream.Create;
try
Size := VarArrayHighBound (OV, 1) - VarArrayLowBound
(OV, 1) + 1;
Data := VarArrayLock(OV);
try
Result.Position := 0;
Result.WriteBuffer(Data^, Size);
finally
VarArrayUnlock(OV);
end;
except
Result.Free;
Result := nil;
end;
end;
代码二之前已经试过, 转换后貌似格式不对未能发声。
刚刚试了你给的代码一中的procedure VarBytesToStream(const Value:OleVariant; s: TStream)方法; 调试中在S.Write(p^, Size); 时报错,错误如图,是哪里不对呢?望请再指教,谢谢!
qq_16697501 2015-03-21
  • 打赏
  • 举报
回复
经过测试,把TTS的TSpMemoryStream生成在内存的语音流,以char类型转换,数据结果与实际文件输出的wav文件数据(注:所播报的语音内容都为:1234)对比相差甚远。以Byte类型转换,结果也是不一致。 请问,TTS的TSpMemoryStream是否是语音流的输出???????或者是我TSpMemoryStream使用不对,请各位大神指教!
frtrnr 2015-03-21
  • 打赏
  • 举报
回复
看看哪种适合你(未测试) 代码一: Do you mean a variant array of bytes? function VarBytesFromStream(s: TStream; Size: integer): OleVariant; var p: pchar; begin Result := varArrayCreate([0, Size-1], VarByte); p := varArrayLock(Result); try S.Read(p^, Size); finally varArrayUnlock(Result); end end; procedure VarBytesToStream(const Value:OleVariant; s: TStream); var p: pchar; size: integer; begin size := VarArrayHighBound(value,1) - VarArrayLowBound(value,1) + 1; p := VarArrayLock(Value); try S.Write(p^, Size); finally VarArrayUnlock(Value) end; end; 代码二: function MemoryStreamToOleVariant(Strm: TMemoryStream): OleVariant; var Data: PByteArray; begin Result := VarArrayCreate ([0, Strm.Size - 1], varByte); Data := VarArrayLock(Result); try Strm.Position := 0; Strm.ReadBuffer(Data^, Strm.Size); finally VarArrayUnlock(Result); end; end; function OleVariantToMemoryStream(OV: OleVariant): TMemoryStream; var Data: PByteArray; Size: integer; begin Result := TMemoryStream.Create; try Size := VarArrayHighBound (OV, 1) - VarArrayLowBound (OV, 1) + 1; Data := VarArrayLock(OV); try Result.Position := 0; Result.WriteBuffer(Data^, Size); finally VarArrayUnlock(OV); end; except Result.Free; Result := nil; end; end;

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧