我在循环中调用generateVoiceFil方法,生成一个音频文件,文件能正常生成,但每次最后在FreeMem(synth_speech)出错,请高手指点!function TvoiceFileFrm.generateVoiceFile(filepath: string; content: string): Integer;
const TTS_FLAG_DATA_END: Integer = 2;
var
  configs, params, session_id: pchar;
  ret: integer;
  synth_text: pchar;
  text_len: integer;
  iFileHandle: integer;
  synth_status: integer;
  synth_speech_len: DWORD;
  synth_speech: Pointer;
  rwcnt: Integer;
  ttsword: string;
  saveFilepath: string;
  genError: Boolean;
begin
  generateVoiceFile := -1;
  pwavePcmHdr := @wavePcmHdr;
  if Assigned(pwavePcmHdr) then
  begin
    //ShowMessage('assigned');
  end else begin
    ShowMessage('not assigned');
    Exit;
  end;  with pwavePcmHdr^ do
  begin
    riff := 'RIFF';
    size_8 := 0;
    wave := 'WAVE';
    fmt := 'fmt ';
    dmFmtsize := 16;
    format_tag := 1;
    channels := 1;
    samples_per_sec := 16000;
    avg_bytes_per_sec := 32000;
    block_align := 2;
    bits_per_sample := 16;
    data := 'data';
    data_size := 0;
  end;  //genError := False;
  configs := 'server_url=dev.voicecloud.cn/index.htm, timeout=10000, coding_libs=speex.dll';
  // configs := ' appid=4ebde063';  ret := QTTSInit(configs);
  if 0 <> ret then
  begin
    showmessage('QTTSInit failed, error code is : ' + inttostr(ret));
    //genError := True;
    //if genError then Exit;
  end;  // session begin
  params := 'ssm=1,  ent=intp65, auf=audio/L16;rate=16000';  session_id := QTTSSessionBegin(params, ret);
  if 0 <> ret then
  begin
    showmessage('QTTSSessionBegin failed, error code is: ' + inttostr(ret));
  end;  ttsword := content;  synth_text := pchar(ttsword);
  text_len := strlen(pchar(synth_text));
  ret := QTTSTextPut(session_id, synth_text, text_len, nil);
  if 0 <> ret then
  begin
    showmessage('QTTSTextPut failed, error code is ' + inttostr(ret));
  end;  saveFilepath := filepath;
  iFileHandle := FileCreate(saveFilepath, fmOpenWrite);
  if iFileHandle <= 0 then
  begin
    showmessage('Can not open file "synth_speech.wav"');
  end;  FileWrite(iFileHandle, pwavePcmHdr^, sizeof(pwavePcmHdr^));
  GetMem(synth_speech, 2 * 1024 * 1024);
  while TTS_FLAG_DATA_END <> synth_status do
  begin
    synth_speech := QTTSAudioGet(session_id, synth_speech_len, synth_status, ret);    if 0 <> ret then
    begin
      showmessage('QTTSAudioGet failed, error code is' + inttostr(ret));
      genError := True;
      if genError then Exit; Break    end;    if (nil <> synth_speech) and (0 <> synth_speech_len) then
    begin
      FileWrite(iFileHandle, synth_speech^, synth_speech_len);
      pwavePcmHdr^.data_size := pwavePcmHdr^.data_size + synth_speech_len;
    end;
  end;  pwavePcmHdr^.size_8 := pwavePcmHdr^.data_size + 36;  FileSeek(iFileHandle, 4, 0);
  FileWrite(iFileHandle, pwavePcmHdr^.size_8, sizeof(pwavePcmHdr^.size_8));
  FileSeek(iFileHandle, 40, 0);
  FileWrite(iFileHandle, pwavePcmHdr^.data_size, sizeof(pwavePcmHdr^.data_size));
  fileclose(iFileHandle);
  ret := QTTSSessionEnd(session_id, 'normal end');
  session_id := nil;
  ret := QTTSFini();  FreeMem(synth_speech); // wrong here ?
  pwavePcmHdr := nil;
  
  if 0 <> ret then
  begin
    showmessage('QTTSFini failed, error code is ' + inttostr(ret));
  end;
  generateVoiceFile := 0;
end;

解决方案 »

  1.   

    仔细看一下每个步骤,包括调用的其它函数,是否在getmem后,对synth_speech进行了改写,这样freemem发现不是最原始的指针就会出错
      

  2.   

    synth_speech := QTTSAudioGet(session_id, synth_speech_len, synth_status, ret);
    从这句看,貌似内存是在QTTSAudioGet里头分配好的,而你用FreeMem释放QTTSAudioGet分配的内存而不是释放自己分配的内存,肯定报错
      

  3.   

    我把getmem /freemem 注释掉,问题还在,说明不是getmem /freemem 的问题,
    我的指针释放 不对吗?