Board index » cppbuilder » Sending and using MemoryStream with Indy?

Sending and using MemoryStream with Indy?


2004-06-18 07:16:40 AM
cppbuilder10
Hi:
I'm using some Delphi voice components (VC Components by LakeOfSoft)
for audio processing(recording, encoding,resampling, playback etc..)
I'm trying to send the voice data using a stream over Indy sockets, but
I'm sure I'm doing something wrong, and I can't get it working.
Maybe I'm doing something bad with streams, but don't know what.
Can someone give me some help?
Thanks a lot
On Server Side:
[...]
TMemoryStream* ReceivedStream = new TMemoryStream();
[...]
void __fastcall TDMVoz::IdTCPServer1Execute(TIdPeerThread *AThread)
{
int size = AThread->Connection->ReadInteger(false);
AThread->Connection->ReadStream(ReceivedStream, -1, false);
codecOut->write(StreamRecibido, size, NULL); //feed the Delphi audio
//codec with the stream
}
//---------------------------------------------------------------------------
On Client Side:
[...]
TMemoryStream* StreamVoice;
StreamVoice = new TMemoryStream;
[...]
void __fastcall TDMVoz::codecInDataAvailable(unavclInOutPipe *sender,
Pointer data, DWORD len)
{
StreamVoice->Clear();
StreamVoice->Write(data, len); //Write data to memory stream
if(!bIsServer)
{ //If we are "client"
//We pass the data to Indy client socket
if(IdTCPClient1->Connected())
{
IdTCPClient1->WriteInteger(len, false);//Write stream length
//Write the stream
IdTCPClient1->WriteStream(StreamVoice, true, true, 0);
}
}
else
{ //we are the server
TList* pList = IdTCPServer1->Threads->LockList();
TIdPeerThread* Thread;
try
{
for (int i = 0; i < pList->Count; i++)
{ //Write the stream to all the threads in
TCPServer(only 1) Thread = (TIdPeerThread*)pList->Items[i];
Thread->Connection->WriteStream(StreamVoice, true, true, 0);
}
}
__finally
{
IdTCPServer1->Threads->UnlockList();
}
}
}
//---------------------------------------------------------------------------
 
 

Re:Sending and using MemoryStream with Indy?

"A.Gil" < XXXX@XXXXX.COM >wrote in message
Quote
On Server Side:
[...]
TMemoryStream* ReceivedStream = new TMemoryStream();
[...]
I do not recommend that you use a single global stream instance. It will be
shared will all connections, and thus can be overwritten and corrupted if
multiple clients transmit data at the same time. You should move the stream
to be local inside the OnExecute event handler so that you have a fresh
stream each time new data arrives. For example:
void __fastcall TDMVoz::IdTCPServer1Execute(TIdPeerThread *AThread)
{
TMemoryStream* ReceivedStream = new TMemoryStream;
try
{
AThread->Connection->ReadStream(ReceivedStream, -1, false);
ReceivedStream->Position = 0;
codecOut->write(ReceivedStream->Memory, ReceivedStream->Size,
NULL);
}
__finally {
delete ReceivedStream;
}
}
Quote
int size = AThread->Connection->ReadInteger(false);
AThread->Connection->ReadStream(ReceivedStream, -1, false);
Why are you transmitting the stream length twice? You don't need to do
that. You should send it just once.
Quote
On Client Side:

[...]
TMemoryStream* StreamVoice;
StreamVoice = new TMemoryStream;
[...]
Again, I do not recommend using a global stream. Use a local one instead,
ie:
void __fastcall TDMVoz::codecInDataAvailable(unavclInOutPipe *sender,
Pointer data, DWORD len)
{
TMemoryStream *StreamVoice = new TMemoryStream;
try
{
StreamVoice->Write(data, len);
if( !bIsServer )
{
if( IdTCPClient1->Connected() )
IdTCPClient1->WriteStream(StreamVoice, true, true, 0);
}
else
{
TList* pList = IdTCPServer1->Threads->LockList();
TIdPeerThread* Thread;
try
{
for (int i = 0; i < pList->Count; ++i)
{
Thread = (TIdPeerThread*)pList->Items[i];
Thread->Connection->WriteStream(StreamVoice, true,
true, 0);
}
}
__finally {
IdTCPServer1->Threads->UnlockList();
}
}
}
__finally {
delete StreamVoice;
}
}
Alternatively, for the client side, you can do away with the stream
altogether and just send the raw data directly, ie:
void __fastcall TDMVoz::codecInDataAvailable(unavclInOutPipe *sender,
Pointer data, DWORD len)
{
if( !bIsServer )
{
if( IdTCPClient1->Connected() )
{
IdTCPClient1->WriteInteger(len);
IdTCPClient1->WriteBuffer(data, len);
}
}
else
{
TList* pList = IdTCPServer1->Threads->LockList();
TIdPeerThread* Thread;
try
{
for (int i = 0; i < pList->Count; ++i)
{
Thread = (TIdPeerThread*)pList->Items[i];
Thread->Connection->WriteInteger(len);
Thread->Connection->WriteBuffer(data, len);
}
}
__finally {
IdTCPServer1->Threads->UnlockList();
}
}
}
Gambit