Page 1 of 1
Creating a wave file

Posted:
March 16th, 2007, 10:56 am
by PatD
Hello.
I dynamically receive wave buffers from an ISDN board. I would like to create a wave file with this buffers.
I tried to use a TWaveStorage object and used BegingRewrite, Write, EndWrite and ConvertToPCM methods but it does not work.
By debugging your code, I saw that this functions do nothing because fIo is 0. I did not find how to initialize it.
Thanks for your help.

Posted:
March 16th, 2007, 2:13 pm
by Kambiz
It means BeginRewrite fails to initialize RIFF format.
Could you please post a sample code here, so that we can find what's going wrong.

Posted:
March 16th, 2007, 4:48 pm
by PatD
Here's the code :
WAVEFORMATEX sWaveFormat;
TWaveStorage *pWave=NULL;
sWaveFormat.wFormatTag=WAVE_FORMAT_PCM;
sWaveFormat.nChannels=1;
sWaveFormat.nSamplesPerSec=8000;
sWaveFormat.nAvgBytesPerSec=8000;
sWaveFormat.nBlockAlign=8;
sWaveFormat.wBitsPerSample=8;
sWaveFormat.cbSize=sizeof(WAVEFORMATEX);
pWave->Wave->BeginRewrite(&sWaveFormat);
pWave->Wave->Write(pBfr, dwGot);
if (!pWave->Wave->EndRewrite())
Msg(919, "EndRewrite");
if (!pWave->Wave->ConvertToPCM(Mono8Bit8000Hz))
Msg(919, "ConvertToPCM");
pWave->Wave->Seek(0, soFromBeginning);
pWave->Wave->SaveToFile(pszRecordFile);
In WaveStorage.pas, the code is :
function TWave.BeginRewrite(pWaveFormat: PWaveFormatEx): Boolean;
begin
Result := False;
if fIO <> 0 then
begin
fDirty := True;
fIO := CreateStreamWaveAudio(Self, pWaveFormat, fCkRIFF, fCkData);
Result := (fIO <> 0);
end;
end;
I don't see where fIO may be initialized.

Posted:
March 16th, 2007, 5:14 pm
by Kambiz
Oops, it's my mistake!
- Code: Select all
if fIO <> 0 then
must be
- Code: Select all
if fIO = 0 then
Sorry for this inconvenience.

Posted:
March 26th, 2007, 5:57 pm
by PatD
I made the change in WaveStorage.pas. Now, when I call TWave.Write, I get an infinite loop (have a look at the attached stack.gif file).
TWave.Write calls mmioWrite that produces a call to mmIOStreamProc wich executes the following :
MMIOM_WRITEFLUSH:
try
Stream.Seek(lpmmIOInfo^.lDiskOffset, SEEK_SET);
Result := Stream.Write(Pointer(lParam1)^, lParam2);
lpmmIOInfo^.lDiskOffset := Stream.Seek(0, SEEK_CUR);
except
Result := -1;
end
In this function, Stream.Write calls back TWave.Write, and so on....
I use C++Builder 6.

Posted:
March 27th, 2007, 12:13 am
by Kambiz
Are you using the latest version (v1.80)?

Posted:
March 27th, 2007, 2:05 pm
by PatD
No, I was using version 1.70.
With version 1.80, it works.
Thanks a lot.