www.pudn.com > VOIP(H323).rar > oortp.c


	/* 
 * Copyright (C) 2004 by Objective Systems, Inc. 
 * 
 * This software is furnished under an open source license and may be  
 * used and copied only in accordance with the terms of this license.  
 * The text of the license may generally be found in the root  
 * directory of this installation in the LICENSE.txt file.  It  
 * can also be viewed online at the following URL: 
 * 
 *   http://www.obj-sys.com/open/license.html 
 * 
 * Any redistributions of this file including modified versions must  
 * maintain this copyright notice. 
 * 
 *****************************************************************************/ 
//followed is added for adaptation to easyg7231.h 
#ifndef _cplusplus 
#define bool unsigned char 
#define false 0 
#define true !false 
#endif 
//above is added for adaptation to easyg7231.h 
 
#include "oortp.h" 
#include "g711.h" 
/*Added by Karl on 2004-11-17 below*/ 
#include "va_g729a.h" 
#include "ootypes.h" 
/*Added by Karl on 2004-11-17 above*/ 
/*Added by Karl on 2005-01-12 below*/ 
#include "EasyG7231.h" 
#include "EasyG728.h" 
#include "g72x.h" 
/*Added by Karl on 2005-01-12 above*/ 
#ifdef _WIN32 
#include "ooWave.h" 
#include  
#else 
#include "oomedialx.h" 
#endif 
 
/*Added by Karl on 2004-11-16 below*/ 
#define T_H245AudioCapability_nonStandard 1 
#define T_H245AudioCapability_g711Alaw64k 2 
#define T_H245AudioCapability_g711Alaw56k 3 
#define T_H245AudioCapability_g711Ulaw64k 4 
#define T_H245AudioCapability_g711Ulaw56k 5 
/*Modified by Karl on 2005-01-12 below*/ 
#define T_H245AudioCapability_g721_40k  6 
#define T_H245AudioCapability_g721_32k  7 
#define T_H245AudioCapability_g721_24k  8 
//#define T_H245AudioCapability_g722_64k  6 
//#define T_H245AudioCapability_g722_56k  7 
//#define T_H245AudioCapability_g722_48k  8 
/*Modified by Karl on 2005-01-12 above*/ 
#define T_H245AudioCapability_g7231     9 
#define T_H245AudioCapability_g728      10 
#define T_H245AudioCapability_g729      11 
#define T_H245AudioCapability_g729AnnexA 12 
#define T_H245AudioCapability_is11172AudioCapability 13 
#define T_H245AudioCapability_is13818AudioCapability 14 
#define T_H245AudioCapability_g729wAnnexB 15 
#define T_H245AudioCapability_g729AnnexAwAnnexB 16 
#define T_H245AudioCapability_g7231AnnexCCapability 17 
#define T_H245AudioCapability_gsmFullRate 18 
#define T_H245AudioCapability_gsmHalfRate 19 
#define T_H245AudioCapability_gsmEnhancedFullRate 20 
#define T_H245AudioCapability_genericAudioCapability 21 
#define T_H245AudioCapability_g729Extensions 22 
#define T_H245AudioCapability_vbd       23 
#define T_H245AudioCapability_audioTelephonyEvent 24 
#define T_H245AudioCapability_audioTone 25 
#define T_H245AudioCapability_extElem1  26 
/*Added by Karl on 2004-11-16 above*/ 
extern int	gnOutBuffCounter; 
 
/* Initialize the media plug-in */ 
int ooInitializePlugin() 
{ 
   /* Open the log file for write */ 
   fpLog = NULL; 
   fpLog = fopen("media.log", "w"); 
   if(fpLog == NULL) 
   { 
      printf("\nERROR:Failed to open media.log log file"); 
      return -1; 
   } 
    
#ifdef _WIN32  
   OOLOG2(1, "Initializing sockets api"); 
   ooSocketsInit(); 
#else 
   ooOpenAudioDevice(); 
#endif 
   return 0; 
} 
 
/* Create a transmit RTP channel. This creates a UDP socket for transmit  
   and initializes the seqNo, timeStamp and ssrc for transmit session 
*/ 
int oomCreateTransmitRTPChannel(int* channelId, char * destip, int port) 
{ 
   int ret; 
   OOLOG4(1, "StartOf:CreateTransmitRTPChannel:Destination %s:%d", destip,  
          port); 
#ifdef _WIN32 
   InitializeCriticalSection(&gReadMutex); 
#endif 
   if(destip == 0) 
   { 
      OOLOG2(1, "ERROR: NULL ip address"); 
      return -1; 
   } 
   if(port == 0) 
   { 
      OOLOG2(1, "ERROR: port can not be zero"); 
      return -1; 
   } 
   memset(&gXmitChannel, 0, sizeof(struct OORTPChannel)); 
   strcpy(gXmitChannel.ip, destip); 
   gXmitChannel.port = port; 
 
   /* Create transmit socket */ 
   ret = ooSocketCreateUDP (&(gXmitChannel.sock)); 
   if(ret != 0) 
   { 
      OOLOG2(1, "ERROR: Creation of rtp socket failed"); 
      return -1; 
   } 
    
#ifdef _WIN32 
   /* Generate a random seqNo to start with */ 
   /* 65536 is max rtp seqNo after which it is reset*/ 
   srand((unsigned)time( NULL ) ); 
   gXmitChannel.seqNo = (unsigned short)((unsigned long)(rand() % 65536));  
   /* Assign a random value to synchronization source */ 
   gXmitChannel.ssrc = (unsigned long)rand(); 
   /* generate a random timestamp. This will be incremented monotonically*/ 
   gXmitChannel.timestamp = (unsigned long) rand(); 
#else 
   srandom(time(0)); 
   gXmitChannel.seqNo = (unsigned short)((unsigned long)(random() % 65536));  
   /* Assign a random value to synchronization source */ 
   gXmitChannel.ssrc = (unsigned long)random(); 
   /* generate a random timestamp. This will be incremented monotonically*/ 
   gXmitChannel.timestamp = (unsigned long) random(); 
#endif    
    
   gXmitThrdHdl = 0; 
   gXmitChannel.status = OO_CHAN_OPEN; 
   OOLOG2(1, "EndOf:CreateTransmitRTPChannel"); 
   return 0; 
} 
 
/* Close the transmit RTP channel*/ 
int oomCloseTransmitRTPChannel(int channelId) 
{ 
   int i=0, ret=0; 
   OOLOG2(1, "StartOf:CloseTransmitRTPChannel"); 
   /* First stop the transmit thread if running */ 
   if(gXmitThrdHdl != 0) 
   { 
      gXmitFileLoop = 0; 
      gXmitMicLoop = 0; 
      i = 0; 
      while(gXmitThrdHdl != 0) 
      { 
        // ooSleep(1000); 
		  Sleep(1000); 
         if(i++ == 3) 
         { 
            OOLOG2(1, "ERROR: Transmit thread not exiting..."); 
            exit(0); 
         } 
      } 
   } 
   /* Now close the socket */ 
   if(gXmitChannel.status == OO_CHAN_OPEN) 
   { 
#ifdef _WIN32 
      DeleteCriticalSection(&gReadMutex); 
#endif 
      ret = ooSocketClose(gXmitChannel.sock); 
      if(ret != 0)  
      { 
         OOLOG2(1, "Warning: Failed to close the xmit RTP socket"); 
         return -1; 
      } 
      gXmitChannel.status = OO_CHAN_CLOSE; 
   } 
   OOLOG2(1, "EndOf:CloseTransmitRTPChannel"); 
   return 0; 
} 
 
/* Create Receive RTP channel. Basically, creates a socket for  
   receiving RTP packets. The socket is bound to ip and port which 
   will be communicated to the remote endpoint via H.245 signalling 
*/ 
 
int oomCreateReceiveRTPChannel(int* channelId, char * localip, int localport) 
{ 
   int ret; 
   OOIPADDR ipAddr; 
   OOLOG4(1, "StartOf:CreateReceiveRTPChannel: local %s:%d", localip,  
          localport); 
#ifdef _WIN32 
   InitializeCriticalSection(&gPlayMutex); 
#endif 
   memset(&gRecvChannel, 0, sizeof(struct OORTPChannel)); 
   strcpy(gRecvChannel.ip, localip); 
   gRecvChannel.port = localport; 
    
   /* Create receive socket */ 
   ret = ooSocketCreateUDP (&(gRecvChannel.sock)); 
   if(ret != 0) 
   { 
      OOLOG2(1, "ERROR: Creation of rtp socket failed"); 
      return -1; 
   } 
   ret = ooSocketStrToAddr (localip, &ipAddr); 
   if(ret != 0) 
   { 
      OOLOG2(1, "ERROR: IP address conversion failed"); 
      return -1; 
   } 
   ret = ooSocketBind (gRecvChannel.sock, ipAddr, localport);  
   if(ret != 0) 
   { 
      OOLOG2(1, "ERROR: Socket bind failed"); 
      return -1; 
   } 
   /* Initailze seqNo, ssrc and timestamp */ 
   gRecvChannel.seqNo = 0;  
   /* Assign a random value to synchronization source */ 
   gRecvChannel.ssrc = 0; 
   /* generate a random timestamp. This will be incremented monotonically*/ 
   gRecvChannel.timestamp = 0; 
   gRecvChannel.status = OO_CHAN_OPEN; 
   OOLOG2(1, "EndOf:CreateReceiveRTPChannel:"); 
   return 0; 
} 
 
/* Close the receive RTP channel. Stops any receive thread running on the 
   channel and then closes the socket. 
*/ 
int oomCloseReceiveRTPChannel(int channelId) 
{ 
   int i, ret=0; 
   OOLOG2(1, "StartOf:CloseReceiveRTPChannel"); 
   /* Stop the receive thread, if running */ 
   if(gRecvThrdHdl != 0) 
   { 
      gRecvPlayLoop = 0; 
      i = 0; 
      while(gRecvThrdHdl != 0) 
      { 
        // ooSleep(1000); 
		  Sleep(1000); 
         if(i++ == 3) 
         { 
            OOLOG2(1, "ERROR: Receive thread not exiting..."); 
            exit(0); 
         } 
      } 
   } 
   /* Close the socket */ 
   if(gRecvChannel.status == OO_CHAN_OPEN) 
   { 
#ifdef _WIN32 
      DeleteCriticalSection(&gPlayMutex); 
#endif 
      ret = ooSocketClose(gRecvChannel.sock); 
      if(ret != 0) 
      { 
         OOLOG2(1, "Warning: Failed to close the receive RTP socket"); 
         return -1; 
      } 
      gRecvChannel.status = OO_CHAN_CLOSE; 
   } 
   OOLOG2(1, "EndOf:CloseReceiveRTPChannel"); 
   return 0; 
} 
 
/* Start transmitting wave file. Note that a transmit RTP channel 
   has to be created before using this function. 
*/ 
int oomStartTransmitWaveFile(int channelId, char * filename) 
{ 
   int ret =0; 
   OOLOG2(1, "StartOf:StartTransmitWaveFile"); 
   if(gXmitChannel.status != OO_CHAN_OPEN) 
   { 
      OOLOG2(1,"ERROR:Transmit RTP channel is not open"); 
      return -1; 
   } 
   /* Open the wave file for read */ 
   ret = ooOpenWaveFileForRead(filename); 
   if( ret < 0) 
   { 
      OOLOG3(1, "ERROR: Failed to open the %s wave file for read", filename); 
      return -1; 
   } 
 
   /* Create a thread which will read from the wave file and transmit data 
      as rtp packets.  
   */ 
#ifdef _WIN32 
   gXmitThrdHdl = CreateThread(0, 0,  
                    (LPTHREAD_START_ROUTINE)ooTransmitFileThreadFunc, 0, 0, 0); 
#else 
   pthread_create(&gXmitThrdHdl, NULL, ooTransmitFileThreadFuncLnx, 0); 
#endif 
 
   OOLOG2(1, "EndOf:StartTransmitWaveFile"); 
   return 0; 
} 
/* Stop the wave file transmission. Basically stops the transmit thread 
*/ 
int oomStopTransmitWaveFile(int channelId) 
{ 
   OOLOG2(1, "StartOf:StopTransmitWaveFile"); 
   gXmitFileLoop = 0; 
   OOLOG2(1, "EndOf:StopTransmitWaveFile"); 
   return 0; 
} 
 
/* Start capturing data from microphone and transmitting as RTP packets. 
*/    
/*Modified by Karl on 2004-11-17 below*/ 
int oomStartTransmitMic(int channelId,struct ooAppContext *context) 
/*Modified by Karl on 2004-11-17 above*/ 
{ 
   int ret =0; 
   int type; 
   OOLOG2(1, "StartOf:StartTransmitMic"); 
#ifdef _WIN32 
  // ret = ooOpenMic(); /* Open the Mic device for read */ 
  /* if( ret < 0) 
   { 
      OOLOG2(1, "ERROR: Failed to open the Mic device"); 
      return -1; 
   }*/ 
   /* Start thread which will read data from Mic, and transmit it as RTP  
      packets. 
   */    
      /*Modified by Karl on 2004-11-16 below */ 
 
   type = context->endCapability->transmitAudioCapability->t; 
   if(type == T_H245AudioCapability_g729AnnexA){ 
	   gXmitThrdHdl = CreateThread(0, 0,  
                    (LPTHREAD_START_ROUTINE)ooG729ATransmitMicThreadFunc, 0, 0, 0);	    
   } 
   if(type == T_H245AudioCapability_g711Ulaw64k){ 
	   gXmitThrdHdl = CreateThread(0, 0,  
                    (LPTHREAD_START_ROUTINE)ooG711TransmitMicThreadFunc, 0, 0, 0); 
   } 
   /*Added by Karl on 2004-11-26 below */ 
   if(type == T_H245AudioCapability_g721_32k){ 
	   gXmitThrdHdl = CreateThread(0, 0,  
                    (LPTHREAD_START_ROUTINE)ooG721TransmitMicThreadFunc, 0, 0, 0); 
   } 
   /*Modified by Karl on 2004-11-16 above */ 
   /*Added by Karl on 2005-01-13 below */ 
   if(type == T_H245AudioCapability_g728){ 
	   gXmitThrdHdl = CreateThread(0, 0,  
                    (LPTHREAD_START_ROUTINE)ooG728TransmitMicThreadFunc, 0, 0, 0); 
   } 
   if(type == T_H245AudioCapability_g7231){ 
	   gXmitThrdHdl = CreateThread(0, 0,  
                    (LPTHREAD_START_ROUTINE)ooG7231TransmitMicThreadFunc, 0, 0, 0); 
   } 
   /*Added by Karl on 2005-01-13 above */ 
    
#else 
   pthread_create(&gXmitThrdHdl, NULL, ooTransmitMicThreadFuncLnx, 0); 
#endif 
   OOLOG2(1, "EndOf:StartTransmitMic"); 
 
 
   return 0; 
} 
 
/* Stop the transmit Mic thread */ 
int oomStopTransmitMic(int channelId) 
{ 
   OOLOG2(1, "StartOf:StopTransmitMic"); 
   gXmitMicLoop = 0; 
   OOLOG2(1, "EndOf:StopTransmitMic"); 
   return 0; 
} 
 
/* Start receiving audio on Receive RTP channel and playing it on 
   speakers.  
*/ 
/*Modified by karl on 2004-11-17 below */ 
int oomStartReceiveAudioAndPlayback(int channelId,struct ooAppContext* context) 
/*Modified by karl on 2004-11-17 above */ 
{ 
   int ret = 0; 
#ifdef _WIN32 
   WAVEFORMATEX waveFormat; 
    
   /* Wave format of the audio to be played.*/ 
   waveFormat.wFormatTag = WAVE_FORMAT_PCM; 
   waveFormat.nChannels = 1; 
   waveFormat.nSamplesPerSec = 8000; 
   waveFormat.nAvgBytesPerSec = 16000; 
   waveFormat.nBlockAlign = 2; 
   waveFormat.wBitsPerSample = 16; 
   waveFormat.cbSize = 0; 
#endif 
 
   OOLOG2(1, "StartOf:StartReceiveAudioAndPlayback"); 
#ifdef _WIN32 
   /*Open the speaker device */ 
   ret = ooOpenSpeaker(&ghWaveOut, waveFormat); 
   if(ret != 0) 
   { 
      OOLOG2(1, "ERROR: Failed to open the Wave-out device"); 
      return -1; 
   } 
 
   /*Create  a thread which will receive rtp packets and playback the audio 
     on the speaker device. 
   */ 
   /* Modified by Karl on 2004-11-16 below*/ 
   if(context->endCapability->receiveAudioCapability->t == T_H245AudioCapability_g729AnnexA){ 
	   gRecvThrdHdl = CreateThread(0, 0,  
                  (LPTHREAD_START_ROUTINE)ooG729AReceiveSpeakerThreadFunc, 0, 0, 0); 
   } 
   if(context->endCapability->receiveAudioCapability->t == T_H245AudioCapability_g711Ulaw64k){ 
	   gRecvThrdHdl = CreateThread(0, 0,  
                  (LPTHREAD_START_ROUTINE)ooG711ReceiveSpeakerThreadFunc, 0, 0, 0); 
   } 
   if(context->endCapability->receiveAudioCapability->t == T_H245AudioCapability_g721_32k){ 
	   gRecvThrdHdl = CreateThread(0, 0,  
                  (LPTHREAD_START_ROUTINE)ooG721ReceiveSpeakerThreadFunc, 0, 0, 0);	    
   } 
   /* Modified by Karl on 2004-11-16 above*/ 
   /* Modified by Karl on 2005-01-13 below*/ 
   if(context->endCapability->receiveAudioCapability->t == T_H245AudioCapability_g728){ 
	   gRecvThrdHdl = CreateThread(0, 0,  
                  (LPTHREAD_START_ROUTINE)ooG728ReceiveSpeakerThreadFunc, 0, 0, 0);	    
   } 
   if(context->endCapability->receiveAudioCapability->t == T_H245AudioCapability_g7231){ 
	   gRecvThrdHdl = CreateThread(0, 0,  
                  (LPTHREAD_START_ROUTINE)ooG7231ReceiveSpeakerThreadFunc, 0, 0, 0);	    
   } 
   /* Modified by Karl on 2005-01-13 above*/ 
#else 
   pthread_create(&gRecvThrdHdl, NULL, ooReceiveSpeakerThreadFuncLnx, 0); 
#endif 
   OOLOG2(1, "EndOf:StartReceiveAudioAndPlayback"); 
   return 0; 
} 
 
/* Stops the receive and playback audio thread. */ 
int oomStopReceiveAudioAndPlayback(int channelId) 
{ 
   OOLOG2(1, "StartOf:StopReceiveAudioAndPlayback"); 
   gRecvPlayLoop = 0; 
   OOLOG2(1, "EndOf:StopReceiveAudioAndPlayback"); 
   return 0; 
} 
 
#ifdef _WIN32 
/*Added by Karl on 2004-11-17 below */ 
/* Thread function to receive G729A RTP data and play it onto the 
   speaker device. 
*/ 
int ooG729AReceiveSpeakerThreadFunc() 
{ 
   int ret = 0, i; 
   char * pcSndBuf; 
   short * psSndBuf; 
   unsigned char psTempBuf[1024]; 
   struct timeval timeout; 
   fd_set readfds; 
   unsigned char	serial[10]; 
   short			synth[80]; 
   int				bfi; 
   unsigned char buffer[1024];  
   OOLOG2(1, "StartOf:G729AnnexA ReceiveSpeakerThread"); 
   va_g729a_init_decoder();//Initialize the G729A decoder 
   gRecvPlayLoop = 1; /* start recv loop */ 
   while(1) 
   { 
      if(!gRecvPlayLoop) 
      { 
         OOLOG2(1, "Exiting from RecvPlay loop "); 
         break; 
      } 
      FD_ZERO(&readfds); 
      FD_SET(gRecvChannel.sock, &readfds); 
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0; 
      /* Check whether there is data for read */ 
      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0,  
                           0, &timeout); 
 
      if(FD_ISSET(gRecvChannel.sock, &readfds)) 
      { 
         pcSndBuf = (char*) malloc(1024); 
         if(pcSndBuf == 0) 
         { 
            OOLOG2(1, "ERROR: Memalloc for playback buffer failed"); 
         } 
         else{ 
            ret = ooSocketRecvFrom (gRecvChannel.sock, buffer,  
                                    1024, 0, 0); 
                         
            /* We have a RTP packet in buffer. Assume that data always begins  
               from 12th octet, since standard RTP header length is 12. 
               Convert G711 data to 16 bit PCM. 
            */ 
             
            psSndBuf = (short*)pcSndBuf; 
			for (i=0;i<1024;i++) 
			{ 
               psTempBuf[i] = buffer[i]; 
			} 
			 
			/*--------------------------------------------------------------* 
     		* Call the G729 decoder.                                            * 
	    	*--------------------------------------------------------------*/ 
			//第一段10byte 
			for(i=0;i<10;i++) 
			{ 
				serial[i]=psTempBuf[i+12]; 
			} 
            bfi = 0; 
		    va_g729a_decoder(serial, synth, bfi); 
            for( i =0; i < 80; i++) 
            {                
				psSndBuf[i] = synth[i];               
                
            } 
			//第二段10byte 
			for(i=0;i<10;i++) 
			{ 
				serial[i]=psTempBuf[i+22]; 
			} 
            bfi = 0; 
		    va_g729a_decoder(serial, synth, bfi); 
            for( i =0; i < 80; i++) 
            {                
				psSndBuf[i+80] = synth[i];               
                
            } 
			//第三段10byte 
			for(i=0;i<10;i++) 
			{ 
				serial[i]=psTempBuf[i+32]; 
			} 
            bfi = 0; 
		    va_g729a_decoder(serial, synth, bfi); 
            for( i =0; i < 80; i++) 
            {                
				psSndBuf[i+160] = synth[i];               
                
            } 
			/*for( i =12; i < ret; i++) 
            {                 
               psSndBuf[i-12] = (short)ulaw2linear((unsigned char)(buffer[i]));               
                
            }*/ 
            /* Play the data buffer onto the speaker device*/             
            //ooPlayWaveBuffer(ghWaveOut, (char*)psSndBuf, (i-12)*sizeof(short)); 
			ooPlayWaveBuffer(ghWaveOut, (char*)psSndBuf, (240)*sizeof(short)); 
            pcSndBuf =0; 
         } 
      } 
   } 
   /*Close speaker*/ 
   if(ooCloseSpeaker(ghWaveOut) != 0) 
      OOLOG2(1, "ERROR:Closing Speaker device"); 
   gRecvThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G729AnnexA ReceiveSpeakerThread"); 
   return 0; 
} 
/*Added by Karl on 2004-11-17 above */ 
 
/*Modified by Karl on 2004-11-17 below */ 
/* Thread function to receive G711 uLaw RTP data and play it onto the 
   speaker device. 
*/ 
int ooG711ReceiveSpeakerThreadFunc() 
/*Modified by Karl on 2004-11-17 above */ 
{ 
   int ret = 0, i; 
   char * pcSndBuf; 
   short * psSndBuf; 
   struct timeval timeout; 
   fd_set readfds; 
   /*unsigned*/ char buffer[1024];  
   OOLOG2(1, "StartOf:G711 uLaw ReceiveSpeakerThread"); 
   gRecvPlayLoop = 1; /* start recv loop */ 
   while(1) 
   { 
      if(!gRecvPlayLoop) 
      { 
         OOLOG2(1, "Exiting from RecvPlay loop "); 
         break; 
      } 
      FD_ZERO(&readfds); 
      FD_SET(gRecvChannel.sock, &readfds); 
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0; 
      /* Check whether there is data for read */ 
      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0,  
                           0, &timeout); 
 
      if(FD_ISSET(gRecvChannel.sock, &readfds)) 
      { 
         pcSndBuf = (char*) malloc(1024); 
         if(pcSndBuf == 0) 
         { 
            OOLOG2(1, "ERROR: Memalloc for playback buffer failed"); 
         } 
         else{ 
            ret = ooSocketRecvFrom (gRecvChannel.sock, buffer,  
                                    1024, 0, 0); 
                         
            /* We have a RTP packet in buffer. Assume that data always begins  
               from 12th octet, since standard RTP header length is 12. 
               Convert G711 data to 16 bit PCM. 
            */ 
             
            psSndBuf = (short*)pcSndBuf; 
            for( i =12; i < ret; i++) 
            {                 
               psSndBuf[i-12] = (short)ulaw2linear((unsigned char)(buffer[i])); 
               /*c = (short)ulaw2linear((unsigned char)(buffer[i])); 
               pcSndBuf[j++]= (unsigned char) ((c>>8) & 0xff); 
               pcSndBuf[j++] = (unsigned char) (c & 0xff);*/ 
            } 
            /* Play the data buffer onto the speaker device*/ 
            /*ooPlayWaveBuffer(ghWaveOut, (char*)pcSndBuf, j);*/ 
            ooPlayWaveBuffer(ghWaveOut, (char*)psSndBuf, (i-12)*sizeof(short)); 
            pcSndBuf =0; 
         } 
      } 
   } 
   /*Close speaker*/ 
   if(ooCloseSpeaker(ghWaveOut) != 0) 
      OOLOG2(1, "ERROR:Closing Speaker device"); 
   gRecvThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G711 uLaw ReceiveSpeakerThread"); 
   return 0; 
} 
 
 
 
/* Read the wave file and transmit wave file data 
   as rtp packets on RTP transmit channel. 
*/ 
static int ooTransmitFileThreadFunc() 
{ 
   int DataTxed=0; 
   long audioDataSize; 
   int ret = 0; 
   char databuf[480]; 
   short *tempBuf; 
   unsigned char sendBuf[252]; /* additional 12 bytes for RTP header */ 
   int marker = 1; /* Only first packet has marker bit set */ 
   int i; 
   OOLOG2(1, "StartOf:TransmitFileThread"); 
    
   gXmitFileLoop = 1; 
   while(1) 
   { 
      if(!gXmitFileLoop) 
         break; 
      /* Number of bytes read is returned and stored in audioDataSize */ 
 
      audioDataSize = ooReadWaveFileData(databuf, 480); 
 
      if(audioDataSize>0) /* If any data is read */ 
      { 
         DataTxed += audioDataSize; 
         /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */ 
         sendBuf[0] = 0x80;  
         sendBuf[1] = 0x00; /* RTP Payload type PCM ulaw Need to use #define */ 
         if(marker) 
         { 
            sendBuf[1] |= 0x80; /* Set marker bit for first packet */ 
            marker = 0; 
         } 
         /*packet sequence number*/ 
         *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo); 
         /*packet timestamp*/ 
         *((long  *)(sendBuf + 4)) = ooHTONL((long)gXmitChannel.timestamp); 
         /*packet ssrc*/ 
         *((long  *)(sendBuf + 8)) = ooHTONL((long)gXmitChannel.ssrc); 
          
         if(gXmitChannel.seqNo == 65535) 
            gXmitChannel.seqNo = 0; /* Seq num wrap around */ 
         else 
            gXmitChannel.seqNo += 1; 
 
         /* Next timestamp is current timestamp + play duration of the  
            current buffer. 
         */ 
         gXmitChannel.timestamp += 480; 
         tempBuf = (short*) databuf; 
         /* Copy PCM audio data into sendBuf as ulaw audio data*/ 
         for(i=0; i<(audioDataSize/2); i++) 
         { 
            sendBuf[12+i] = (unsigned char) linear2ulaw((int)*(tempBuf+i)); 
         } 
         /* transmit rtp packet */ 
         ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
                     (audioDataSize/2+12), gXmitChannel.ip, gXmitChannel.port); 
         if(ret<0) 
         { 
            OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
            return -1; 
         } 
         Sleep(2);/* Just slows down the transmit rate a bit */ 
      } 
      else{ 
         if(DataTxed == gWaveFile.dataSize) 
         { 
            printf("File transmission over\n"); 
            gXmitFileLoop = 0; 
         } 
         else{ 
            OOLOG2(1, "ERROR: Data read failure"); 
            gXmitFileLoop = 0; 
         } 
      } 
   } 
   /* Close the wave file */ 
   ret = ooCloseWaveFile(); 
   if(ret < 0) 
   { 
      OOLOG2(1, "ERROR: Failed to close the open wave file"); 
      return -1; 
   } 
   gXmitThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:TransmitFileThread"); 
   return 0; 
} 
 
/*Added by Karl on 2004-11-17 below */ 
/* Thread function to read data from microphone and transmit it 
   as G729A rtp packets. 
*/ 
static int ooG729ATransmitMicThreadFunc() 
{    
   unsigned char sendBuf[42]; 
   short* tempBuf; 
   int marker = 1;  
   unsigned int i; 
   int ret; 
   short			speech[80]; 
   unsigned char	serial[10]; 
   OOLOG2(1, "StartOf:G729AnnexA TransmitMicThread"); 
   ret = ooOpenMic();/* Open the Mic device*/ 
   if(ret < 0) 
   { 
      OOLOG2(1, "ERROR: Opening the Mic device"); 
      return -1; 
   } 
   //Initialization of G729 encoder 
   va_g729a_init_encoder(); 
   /* Start data capture */ 
   ooStartMicDataCapture(ghWaveIn); 
   gXmitMicLoop = 1; 
   while(1) 
   { 
      if(!gXmitMicLoop) 
         break; 
      if(gpWaveHead != 0) 
      { 
         //memset(sendBuf, 0, 252); 
         memset(sendBuf, 0, 42); 
         memset(speech, 0, 80); 
		 memset(serial, 0, 10);		  
 
         /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */ 
         sendBuf[0] = 0x80;  
         /* RTP Payload type PCM ulaw Need to use #define */ 
         sendBuf[1] = 0x00;  
         if(marker) 
         { 
            sendBuf[1] |= 0x80; /* Set marker bit for first packet */ 
            marker = 0; 
         } 
         /*packet sequence number*/ 
         *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo); 
         /*packet timestamp*/ 
         *((long  *)(sendBuf + 4)) = ooHTONL((long)gXmitChannel.timestamp); 
         /*packet ssrc*/ 
         *((long  *)(sendBuf + 8)) = ooHTONL((long)gXmitChannel.ssrc); 
          
         if(gXmitChannel.seqNo == 65535) 
            gXmitChannel.seqNo = 0; /* Seq num wrap around */ 
         else 
            gXmitChannel.seqNo += 1; 
 
         /* Next timestamp is current timestamp + play duration of the  
            current buffer 
         */ 
         gXmitChannel.timestamp += OORTPPACKETDATASIZE; 
          
		 /* Copy PCM audio data into sendBuf as  audio data*/ 
         tempBuf = (short*)gpWaveHead->pWaveHdr->lpData; 
		  
		 //压缩第一段80byte 
		 for(i=0;i<80;i++) 
		 { 
             speech[i]=tempBuf[i]; 
		 } 
		 va_g729a_encoder(speech, serial); 
         for(i=0; i<10; i++) 
         { 
            sendBuf[12+i] = serial[i]; 
         } 
		 //压缩第二段80byte 
		 for(i=0;i<80;i++) 
		 { 
             speech[i]=tempBuf[80+i]; 
		 } 
		 va_g729a_encoder(speech, serial); 
         for(i=0; i<10; i=i+1) 
         { 
            sendBuf[22+i] = serial[i]; 
         } 
		 //压缩第三段80byte 
		 for(i=0;i<80;i++) 
		 { 
             speech[i]=tempBuf[160+i]; 
		 } 
		 va_g729a_encoder(speech, serial); 
         for(i=0; i<10; i=i+1) 
         { 
            sendBuf[32+i] = serial[i]; 
         } 
         /* Convert data into g711 ulaw and copy to sendBuf */ 
         /*tempBuf = (short*)gpWaveHead->pWaveHdr->lpData; 
         for(i=0; i<(gpWaveHead->pWaveHdr->dwBytesRecorded/2); i=i+1) 
         { 
            sendBuf[12+i] = (unsigned char) linear2ulaw((int)*(tempBuf+i)); 
         }*/ 
         /* transmit rtp packet */ 
		 ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
                              30+12,  
                              gXmitChannel.ip, gXmitChannel.port); 
         //ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
         //                     (gpWaveHead->pWaveHdr->dwBytesRecorded/2+12),  
         //                     gXmitChannel.ip, gXmitChannel.port); 
         if(ret<0) 
         { 
            OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
            return -1; 
         } 
         /* Requeue the buffer into the Mic device for data capture. */ 
         if(waveInAddBuffer(ghWaveIn, gpWaveHead->pWaveHdr,  
                            sizeof(WAVEHDR)) != MMSYSERR_NOERROR) 
         { 
            OOLOG2(1, "ERROR: In adding wave-in buffers"); 
            return -1; 
         } 
         EnterCriticalSection(&gReadMutex); 
         gQueuedBufCount++; /* Increase the count of queued buffers by one*/ 
         ooRemoveHeadOfWaveBufferList(); 
         LeaveCriticalSection(&gReadMutex); 
      } 
      else 
         Sleep(5); /*else sleep for 5 ms*/ 
   }/*End of while loop*/ 
   ooCloseMic(ghWaveIn); 
   gXmitThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G729AnnexA TransmitMicThread"); 
   return 0; 
} 
/*Added by Karl on 2004-11-17 above */ 
 
/*Modified by Karl on 2004-11-17 below */ 
/* Thread function to read data from microphone and transmit it 
   as G711 rtp packets. 
*/ 
static int ooG711TransmitMicThreadFunc() 
/*Modified by Karl on 2004-11-17 below */ 
{ 
   unsigned char sendBuf[252]; 
   short* tempBuf; 
   int marker = 1;  
   unsigned int i; 
   int ret; 
   OOLOG2(1, "StartOf:G711 TransmitMicThread"); 
   ret = ooOpenMic();/* Open the Mic device*/ 
   if(ret < 0) 
   { 
      OOLOG2(1, "ERROR: Opening the Mic device"); 
      return -1; 
   } 
 
 
   /* Start data capture */ 
   ooStartMicDataCapture(ghWaveIn); 
   gXmitMicLoop = 1; 
   while(1) 
   { 
      if(!gXmitMicLoop) 
         break; 
      if(gpWaveHead != 0) 
      { 
         memset(sendBuf, 0, 252); 
         /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */ 
         sendBuf[0] = 0x80;  
         /* RTP Payload type PCM ulaw Need to use #define */ 
         sendBuf[1] = 0x00;  
         if(marker) 
         { 
            sendBuf[1] |= 0x80; /* Set marker bit for first packet */ 
            marker = 0; 
         } 
         /*packet sequence number*/ 
         *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo); 
         /*packet timestamp*/ 
         *((long  *)(sendBuf + 4)) = ooHTONL((long)gXmitChannel.timestamp); 
         /*packet ssrc*/ 
         *((long  *)(sendBuf + 8)) = ooHTONL((long)gXmitChannel.ssrc); 
          
         if(gXmitChannel.seqNo == 65535) 
            gXmitChannel.seqNo = 0; /* Seq num wrap around */ 
         else 
            gXmitChannel.seqNo += 1; 
 
         /* Next timestamp is current timestamp + play duration of the  
            current buffer 
         */ 
         gXmitChannel.timestamp += OORTPPACKETDATASIZE; 
                
         /* Convert data into g711 ulaw and copy to sendBuf */ 
         tempBuf = (short*)gpWaveHead->pWaveHdr->lpData; 
         for(i=0; i<(gpWaveHead->pWaveHdr->dwBytesRecorded/2); i=i+1) 
         { 
            sendBuf[12+i] = (unsigned char) linear2ulaw((int)*(tempBuf+i)); 
         } 
         /* transmit rtp packet */ 
         ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
                              (gpWaveHead->pWaveHdr->dwBytesRecorded/2+12),  
                              gXmitChannel.ip, gXmitChannel.port); 
         if(ret<0) 
         { 
            OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
            return -1; 
         } 
         /* Requeue the buffer into the Mic device for data capture. */ 
         if(waveInAddBuffer(ghWaveIn, gpWaveHead->pWaveHdr,  
                            sizeof(WAVEHDR)) != MMSYSERR_NOERROR) 
         { 
            OOLOG2(1, "ERROR: In adding wave-in buffers"); 
            return -1; 
         } 
         EnterCriticalSection(&gReadMutex); 
         gQueuedBufCount++; /* Increase the count of queued buffers by one*/ 
         ooRemoveHeadOfWaveBufferList(); 
         LeaveCriticalSection(&gReadMutex); 
      } 
      else 
         Sleep(5); /*else sleep for 5 ms*/ 
   }/*End of while loop*/ 
   ooCloseMic(ghWaveIn); 
   gXmitThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G711 TransmitMicThread"); 
   return 0; 
} 
 
/*Added by Karl on 2005-01-13 below */ 
/* Thread function to receive G728 RTP data and play it onto the 
   speaker device. 
*/ 
int ooG728ReceiveSpeakerThreadFunc() 
{ 
   int ret = 0, i; 
   char * pcSndBuf; 
   short * psSndBuf; 
   unsigned char psTempBuf[1024]; 
   struct timeval timeout; 
   fd_set readfds; 
   unsigned char	serial[L_G728_FRAME_COMPRESSED]; 
   short			synth[L_G728_FRAME]; 
   //CODER_HANDLE hDecoder; 
 
   unsigned char buffer[1024];  
   OOLOG2(1, "StartOf:G728 ReceiveSpeakerThread"); 
   //hDecoder = G728_init_decoder(  );//Initialize the G728 decoder 
   gRecvPlayLoop = 1; /* start recv loop */ 
   while(1) 
   { 
      if(!gRecvPlayLoop) 
      { 
         OOLOG2(1, "Exiting from RecvPlay loop "); 
         break; 
      } 
      FD_ZERO(&readfds); 
      FD_SET(gRecvChannel.sock, &readfds); 
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0; 
      /* Check whether there is data for read */ 
      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0,  
                           0, &timeout); 
 
      if(FD_ISSET(gRecvChannel.sock, &readfds)) 
      { 
         pcSndBuf = (char*) malloc(1024); 
         if(pcSndBuf == 0) 
         { 
            OOLOG2(1, "ERROR: Memalloc for playback buffer failed"); 
         } 
         else{ 
            ret = ooSocketRecvFrom (gRecvChannel.sock, buffer,  
                                    1024, 0, 0); 
                         
            /* We have a RTP packet in buffer. Assume that data always begins  
               from 12th octet, since standard RTP header length is 12. 
               Convert G728 data to 16 bit PCM. 
            */ 
             
            psSndBuf = (short*)pcSndBuf; 
			for (i=0;i<1024;i++) 
			{ 
               psTempBuf[i] = buffer[i]; 
			} 
			 
			/*--------------------------------------------------------------* 
     		* Call the G728 decoder.                                            * 
	    	*--------------------------------------------------------------*/ 
			//第一段20byte 
			for(i=0;i<20;i++) 
			{ 
				serial[i]=psTempBuf[i+12]; 
			} 
            //G728_decoder(hDecoder, serial, synth ); 
            for( i =0; i < 80; i++) 
            {                
				psSndBuf[i] = synth[i];               
                
            } 
			//第二段20byte 
			for(i=0;i<20;i++) 
			{ 
				serial[i]=psTempBuf[i+32]; 
			} 
            //G728_decoder(hDecoder, serial, synth ); 
            for( i =0; i < 80; i++) 
            {                
				psSndBuf[i+80] = synth[i];  
                
            } 
			//第三段20byte 
			for(i=0;i<20;i++) 
			{ 
				serial[i]=psTempBuf[i+52]; 
			} 
            //G728_decoder(hDecoder, serial, synth ); 
            for( i =0; i < 80; i++) 
            {                
				psSndBuf[i+160] = synth[i];               
                
            } 
            /* Play the data buffer onto the speaker device*/ 
			ooPlayWaveBuffer(ghWaveOut, (char*)psSndBuf, (240)*sizeof(short)); 
            pcSndBuf =0; 
         } 
      } 
   } 
   /*Close speaker*/ 
   //G728_release_decoder( hDecoder ); 
   if(ooCloseSpeaker(ghWaveOut) != 0) 
      OOLOG2(1, "ERROR:Closing Speaker device"); 
   gRecvThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G728 ReceiveSpeakerThread"); 
   return 0; 
} 
 
/* Thread function to read data from microphone and transmit it 
   as G728 rtp packets. 
*/ 
static int ooG728TransmitMicThreadFunc() 
{    
   unsigned char sendBuf[72]; 
   short* tempBuf; 
   int marker = 1;  
   unsigned int i; 
   int ret; 
   short			speech[L_G728_FRAME]; 
   unsigned char	serial[L_G728_FRAME_COMPRESSED]; 
   //CODER_HANDLE hEncoder; 
   OOLOG2(1, "StartOf:G728 TransmitMicThread"); 
   ret = ooOpenMic();/* Open the Mic device*/ 
   if(ret < 0) 
   { 
      OOLOG2(1, "ERROR: Opening the Mic device"); 
      return -1; 
   } 
   //Initialization of G728 encoder 
   //hEncoder = G728_init_encoder( ); 
   /* Start data capture */ 
   ooStartMicDataCapture(ghWaveIn); 
   gXmitMicLoop = 1; 
   while(1) 
   { 
      if(!gXmitMicLoop) 
         break; 
      if(gpWaveHead != 0) 
      {          
         memset(sendBuf, 0, 72); 
         memset(speech, 0, 80); 
		 memset(serial, 0, 20);		  
 
         /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */ 
         sendBuf[0] = 0x80;  
         /* RTP Payload type PCM ulaw Need to use #define */ 
         sendBuf[1] = 0x00;  
         if(marker) 
         { 
            sendBuf[1] |= 0x80; /* Set marker bit for first packet */ 
            marker = 0; 
         } 
         /*packet sequence number*/ 
         *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo); 
         /*packet timestamp*/ 
         *((long  *)(sendBuf + 4)) = ooHTONL((long)gXmitChannel.timestamp); 
         /*packet ssrc*/ 
         *((long  *)(sendBuf + 8)) = ooHTONL((long)gXmitChannel.ssrc); 
          
         if(gXmitChannel.seqNo == 65535) 
            gXmitChannel.seqNo = 0; /* Seq num wrap around */ 
         else 
            gXmitChannel.seqNo += 1; 
 
         /* Next timestamp is current timestamp + play duration of the  
            current buffer 
         */ 
         gXmitChannel.timestamp += OORTPPACKETDATASIZE; 
          
		 /* Copy PCM audio data into sendBuf as  audio data*/ 
         tempBuf = (short*)gpWaveHead->pWaveHdr->lpData; 
		 /* Convert data into g728 and copy to sendBuf */ 
		 //压缩第一段80byte 
		 for(i=0;i<80;i++) 
		 { 
             speech[i]=tempBuf[i]; 
		 } 
		 //G728_encoder(hEncoder, speech, serial); 
         for(i=0; i<20; i++) 
         { 
            sendBuf[12+i] = serial[i]; 
         } 
		 //压缩第二段80byte 
		 for(i=0;i<80;i++) 
		 { 
             speech[i]=tempBuf[80+i]; 
		 } 
		 //G728_encoder(hEncoder, speech, serial); 
         for(i=0; i<20; i=i+1) 
         { 
            sendBuf[32+i] = serial[i]; 
         } 
		 //压缩第三段80byte 
		 for(i=0;i<80;i++) 
		 { 
             speech[i]=tempBuf[160+i]; 
		 } 
		 //G728_encoder(hEncoder, speech, serial); 
         for(i=0; i<20; i=i+1) 
         { 
            sendBuf[52+i] = serial[i]; 
         }          
          
         /* transmit rtp packet */ 
		 ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
                              60+12,  
                              gXmitChannel.ip, gXmitChannel.port); 
         if(ret<0) 
         { 
            OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
            return -1; 
         } 
         /* Requeue the buffer into the Mic device for data capture. */ 
         if(waveInAddBuffer(ghWaveIn, gpWaveHead->pWaveHdr,  
                            sizeof(WAVEHDR)) != MMSYSERR_NOERROR) 
         { 
            OOLOG2(1, "ERROR: In adding wave-in buffers"); 
            return -1; 
         } 
         EnterCriticalSection(&gReadMutex); 
         gQueuedBufCount++; /* Increase the count of queued buffers by one*/ 
         ooRemoveHeadOfWaveBufferList(); 
         LeaveCriticalSection(&gReadMutex); 
      } 
      else 
         Sleep(5); /*else sleep for 5 ms*/ 
   }/*End of while loop*/ 
   //G728_release_encoder( hEncoder ); 
   ooCloseMic(ghWaveIn); 
   gXmitThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G728 TransmitMicThread"); 
   return 0; 
} 
 
 
 
 
/* Thread function to receive G7231 RTP data and play it onto the 
   speaker device. 
*/ 
int ooG7231ReceiveSpeakerThreadFunc() 
{ 
   int ret = 0, i; 
   char * pcSndBuf; 
   short * psSndBuf; 
   unsigned char psTempBuf[1024]; 
   struct timeval timeout; 
   fd_set readfds; 
   unsigned char	serial[L_G7231_FRAME_COMPRESSED_53]; 
   short			synth[L_G7231_FRAME]; 
   //CODER_HANDLE hDecoder; 
 
   unsigned char buffer[1024];  
   OOLOG2(1, "StartOf:G7231 ReceiveSpeakerThread"); 
   //hDecoder = EasyG7231_init_decoder( false );//Initialize the G7231 decoder 
   gRecvPlayLoop = 1; /* start recv loop */ 
   while(1) 
   { 
      if(!gRecvPlayLoop) 
      { 
         OOLOG2(1, "Exiting from RecvPlay loop "); 
         break; 
      } 
      FD_ZERO(&readfds); 
      FD_SET(gRecvChannel.sock, &readfds); 
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0; 
      /* Check whether there is data for read */ 
      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0,  
                           0, &timeout); 
 
      if(FD_ISSET(gRecvChannel.sock, &readfds)) 
      { 
         pcSndBuf = (char*) malloc(1024); 
         if(pcSndBuf == 0) 
         { 
            OOLOG2(1, "ERROR: Memalloc for playback buffer failed"); 
         } 
         else{ 
            ret = ooSocketRecvFrom (gRecvChannel.sock, buffer,  
                                    1024, 0, 0); 
                         
            /* We have a RTP packet in buffer. Assume that data always begins  
               from 12th octet, since standard RTP header length is 12. 
               Convert G7231 data to 16 bit PCM. 
            */ 
             
            psSndBuf = (short*)pcSndBuf; 
			for (i=0;i<1024;i++) 
			{ 
               psTempBuf[i] = buffer[i]; 
			} 
			 
			/*--------------------------------------------------------------* 
     		* Call the G7231 decoder.                                       * 
	    	*--------------------------------------------------------------*/			 
			for(i=0;ipWaveHdr->lpData; 
		 /* Convert data into g7231 and copy to sendBuf */		  
		 for(i=0;i<240;i++) 
		 { 
             speech[i]=tempBuf[i]; 
		 } 
//		 EasyG7231_encoder(hEncoder, speech, serial); 
         for(i=0; i<20; i++) 
         { 
            sendBuf[12+i] = serial[i]; 
         }		  
          
         /* transmit rtp packet */ 
		 ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
                              20+12,  
                              gXmitChannel.ip, gXmitChannel.port); 
         if(ret<0) 
         { 
            OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
            return -1; 
         } 
         /* Requeue the buffer into the Mic device for data capture. */ 
         if(waveInAddBuffer(ghWaveIn, gpWaveHead->pWaveHdr,  
                            sizeof(WAVEHDR)) != MMSYSERR_NOERROR) 
         { 
            OOLOG2(1, "ERROR: In adding wave-in buffers"); 
            return -1; 
         } 
         EnterCriticalSection(&gReadMutex); 
         gQueuedBufCount++; /* Increase the count of queued buffers by one*/ 
         ooRemoveHeadOfWaveBufferList(); 
         LeaveCriticalSection(&gReadMutex); 
      } 
      else 
         Sleep(5); /*else sleep for 5 ms*/ 
   }/*End of while loop*/ 
//   EasyG7231_release_encoder( hEncoder ); 
   ooCloseMic(ghWaveIn); 
   gXmitThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G7231 TransmitMicThread"); 
   return 0; 
} 
/*Added by Karl on 2005-01-13 above */ 
 
 
/*Added by Karl on 2004-11-24 below */ 
/* Thread function to receive G721 RTP data and play it onto the 
   speaker device. 
*/ 
int ooG721ReceiveSpeakerThreadFunc() 
{ 
   int ret = 0, i;    
   struct timeval timeout; 
   fd_set readfds; 
   unsigned char buffer[1024];  
   short * psSndBuf; 
    
   /*G721*/ 
   struct g72x_state	state; 
   short		 sample; 
   int	dec_bits; 
   int resid = 0; 
   int nBit = 4;//G721=4 
   int out_size; 
   int iCount; 
   //short sample_short; 
    
   int idataSamples = 0; 
   unsigned char pDataTrack[240]; 
   unsigned char in_byte; 
   unsigned char in_byte1; 
   unsigned char in_byte2;    
    
   out_size = sizeof (char); 
   dec_bits = 4; 
   g72x_init_state(&state); 
   /*G721*/ 
 
   OOLOG2(1, "StartOf:G721 ReceiveSpeakerThread");    
   gRecvPlayLoop = 1; /* start recv loop */ 
   memset(pDataTrack,0,240); 
   while(1) 
   { 
      if(!gRecvPlayLoop) 
      { 
         OOLOG2(1, "Exiting from RecvPlay loop "); 
         break; 
      } 
      FD_ZERO(&readfds); 
      FD_SET(gRecvChannel.sock, &readfds); 
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0; 
      /* Check whether there is data for read */ 
      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0,  
                           0, &timeout); 
 
      if(FD_ISSET(gRecvChannel.sock, &readfds)) 
      { 
         psSndBuf = (short *) malloc(1024); 
         if(psSndBuf == 0) 
         { 
            OOLOG2(1, "ERROR: Memalloc for playback buffer failed"); 
         } 
         else{ 
            ret = ooSocketRecvFrom (gRecvChannel.sock, buffer,  
                                    1024, 0, 0); 
                         
            /* We have a RTP packet in buffer. Assume that data always begins  
               from 12th octet, since standard RTP header length is 12. 
               Convert G721 data to 16 bit PCM. 
            */ 
			/*Decode data by g721 */ 
			for (i = 0; i < 120; i++) {				 
				in_byte1 = buffer[i+12]; 
				in_byte2 = buffer[i+12]; 
				in_byte1 = in_byte1 >> 4; 
				in_byte2 = in_byte2 << 4; 
				in_byte2 = in_byte2 >> 4; 
                in_byte = in_byte1;				 
				iCount = 2 * i;				 
				sample = g721_decoder(in_byte1, AUDIO_ENCODING_LINEAR, &state); 
				psSndBuf[iCount] = sample;						 
				iCount++;					 
				sample = g721_decoder(in_byte2, AUDIO_ENCODING_LINEAR, &state); 
				psSndBuf[iCount] = sample;						 
			}	 
			 
            /* Play the data buffer onto the speaker device*/             
			ooPlayWaveBuffer(ghWaveOut, (unsigned char*)psSndBuf, (240)*sizeof(short)); 
			psSndBuf = 0; 
         } 
      } 
   } 
   /*Close speaker*/ 
   if(ooCloseSpeaker(ghWaveOut) != 0) 
      OOLOG2(1, "ERROR:Closing Speaker device"); 
   gRecvThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G721 ReceiveSpeakerThread"); 
   return 0; 
} 
/*Added by Karl on 2004-11-24 above */ 
 
/*Added by Karl on 2004-11-23 below */ 
/* Thread function to read data from microphone and transmit it 
   as G721 rtp packets. 
*/ 
static int ooG721TransmitMicThreadFunc() 
{ 
   unsigned char sendBuf[132];    
   short* tempBuf; 
   int marker = 1;  
   int i;    
   int ret; 
   /*G721*/ 
   struct g72x_state	state; 
   int code; 
   int resid = 0; 
   int nBit = 4;//G721=4 
   short sample_short;    
   int idataSamples = 0; 
   BYTE *pDataTrack; 
   g72x_init_state(&state); 
   /*G721*/ 
 
   OOLOG2(1, "StartOf:G721 TransmitMicThread"); 
   ret = ooOpenMic();/* Open the Mic device*/ 
   if(ret < 0) 
   { 
      OOLOG2(1, "ERROR: Opening the Mic device"); 
      return -1; 
   }    
   /* Start data capture */ 
   ooStartMicDataCapture(ghWaveIn); 
   gXmitMicLoop = 1; 
   while(1) 
   { 
      if(!gXmitMicLoop) 
         break; 
      if(gpWaveHead != 0) 
      {          
         memset(sendBuf, 0, 132);        		  
 
         /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */ 
         sendBuf[0] = 0x80;  
         /* RTP Payload type PCM ulaw Need to use #define */ 
         sendBuf[1] = 0x00;  
         if(marker) 
         { 
            sendBuf[1] |= 0x80; /* Set marker bit for first packet */ 
            marker = 0; 
         } 
         /*packet sequence number*/ 
         *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo); 
         /*packet timestamp*/ 
         *((long  *)(sendBuf + 4)) = ooHTONL((long)gXmitChannel.timestamp); 
         /*packet ssrc*/ 
         *((long  *)(sendBuf + 8)) = ooHTONL((long)gXmitChannel.ssrc); 
          
         if(gXmitChannel.seqNo == 65535) 
            gXmitChannel.seqNo = 0; /* Seq num wrap around */ 
         else 
            gXmitChannel.seqNo += 1; 
 
         /* Next timestamp is current timestamp + play duration of the  
            current buffer 
         */ 
         gXmitChannel.timestamp += OORTPPACKETDATASIZE; 
          
		 /* Copy PCM audio data into sendBuf as  audio data*/ 
         tempBuf = (short*)gpWaveHead->pWaveHdr->lpData; 
 
		 idataSamples = gpWaveHead->pWaveHdr->dwBytesRecorded/2; 
		  
		  
		 //Encode data  
		 gnOutBuffCounter = 0;	//Reset output buffer counter at first 
     	 pDataTrack = (unsigned char*) malloc(1024); 
		 for (i = 0; i < idataSamples; i++) { 
	 		sample_short = tempBuf[i];//pSrcBuff[i]; 
	  		code = g721_encoder(sample_short, AUDIO_ENCODING_LINEAR, &state); 
			resid = pack_output(code, nBit, pDataTrack); 
		 } 
		 //Write zero codes until all residual codes are written out */ 
		 while (resid) { 
	 	 	resid = pack_output(0, nBit, pDataTrack); 
		 } 
 
		 for(i = 0; i < idataSamples/2; i++){ 
             sendBuf[12+i] = pDataTrack[i]; 
		 } 
         /* transmit rtp packet */ 
		 /*because G721 is 32kbps,the length is dataSample*(32/64)+12*/ 
		 ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
                              idataSamples/2+12,  
                              gXmitChannel.ip, gXmitChannel.port);          
         if(ret<0) 
         { 
            OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
            return -1; 
         } 
         /* Requeue the buffer into the Mic device for data capture. */ 
         if(waveInAddBuffer(ghWaveIn, gpWaveHead->pWaveHdr,  
                            sizeof(WAVEHDR)) != MMSYSERR_NOERROR) 
         { 
            OOLOG2(1, "ERROR: In adding wave-in buffers"); 
            return -1; 
         } 
         EnterCriticalSection(&gReadMutex); 
         gQueuedBufCount++; /* Increase the count of queued buffers by one*/ 
         ooRemoveHeadOfWaveBufferList(); 
         LeaveCriticalSection(&gReadMutex); 
      } 
      else 
         Sleep(5); /*else sleep for 5 ms*/ 
   }/*End of while loop*/ 
   ooCloseMic(ghWaveIn); 
   gXmitThrdHdl = 0; 
   ExitThread(0); 
   OOLOG2(1, "EndOf:G721 TransmitMicThread"); 
   return 0; 
} 
/*Added by Karl on 2004-11-23 above */ 
 
#endif 
#ifndef _WIN32 
/* Thread function to read data from microphone and transmit it 
   as rtp packets. 
*/ 
static int ooTransmitMicThreadFuncLnx() 
{ 
   unsigned char sendBuf[252]; 
   short buffer[OORTPPACKETDATASIZE]; 
   int marker = 1;  
   int i; 
   int bytesRead, ret; 
   OOLOG2(1, "StartOf:TransmitMicThread"); 
    
   gXmitMicLoop = 1; 
   while(1) 
   { 
      if(!gXmitMicLoop) 
         break; 
      memset(sendBuf, 0, 252); 
      /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */ 
      sendBuf[0] = 0x80;  
      /* RTP Payload type PCM ulaw Need to use #define */ 
      sendBuf[1] = 0x00;  
      if(marker) 
      { 
         sendBuf[1] |= 0x80; /* Set marker bit for first packet */ 
         marker = 0; 
      } 
      /*packet sequence number*/ 
      *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo); 
      /*packet timestamp*/ 
      *((long  *)(sendBuf + 4)) = ooHTONL((long)gXmitChannel.timestamp); 
      /*packet ssrc*/ 
      *((long  *)(sendBuf + 8)) = ooHTONL((long)gXmitChannel.ssrc); 
          
      if(gXmitChannel.seqNo == 65535) 
         gXmitChannel.seqNo = 0; /* Seq num wrap around */ 
      else 
         gXmitChannel.seqNo += 1; 
 
      /* Next timestamp is current timestamp + play duration of the  
         current buffer 
      */ 
      gXmitChannel.timestamp += OORTPPACKETDATASIZE; 
                
      /* Convert data into g711 ulaw and copy to sendBuf */ 
	  bytesRead = ooGetMicAudioBuffer((unsigned char*)buffer,  
                                          OORTPPACKETDATASIZE*sizeof(short)); 
      for(i=0; i<(bytesRead/sizeof(short)); i++) 
         sendBuf[12+i] = (unsigned char) linear2ulaw((short)buffer[i]); 
  
  
      /* transmit rtp packet */ 
      ret = ooSocketSendTo(gXmitChannel.sock, sendBuf, 
                           (bytesRead/sizeof(short)+12),  
                           gXmitChannel.ip, gXmitChannel.port); 
      if(ret<0) 
      { 
         OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
         return -1; 
      } 
      ooSleep(5); /*sleep for 5 ms*/ 
   }/*End of while loop*/ 
    
   gXmitThrdHdl = 0; 
   pthread_exit(0); 
   OOLOG2(1, "EndOf:TransmitMicThread"); 
   return 0; 
} 
 
/* Thread function to receive RTP data and play it onto the 
   speaker device. 
*/ 
 
static int ooReceiveSpeakerThreadFuncLnx() 
{ 
   int ret = 0, i, j; 
   char * pcSndBuf; 
   struct timeval timeout; 
   short c; 
   fd_set readfds; 
   char buffer[1024];  
   OOLOG2(1, "StartOf:ReceiveSpeakerThread"); 
   gRecvPlayLoop = 1; /* start recv loop */ 
   while(1) 
   { 
      if(!gRecvPlayLoop) 
      { 
         OOLOG2(1, "Exiting from RecvPlay loop "); 
         break; 
      } 
      FD_ZERO(&readfds); 
      FD_SET(gRecvChannel.sock, &readfds); 
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0; 
      /* Check whether there is data for read */ 
      ret = ooSocketSelect(gRecvChannel.sock+1, &readfds, 0,  
                           0, &timeout); 
 
      if(FD_ISSET(gRecvChannel.sock, &readfds)) 
      { 
         pcSndBuf = (char*) malloc(1024); 
         if(pcSndBuf == 0) 
         { 
            OOLOG2(1, "ERROR: Memalloc for playback buffer failed"); 
         } 
         else{ 
            ret = ooSocketRecvFrom (gRecvChannel.sock, buffer,  
                                    1024, 0, 0); 
                         
            /* We have a RTP packet in buffer. Assume that data always begins  
               from 12th octet, since standard RTP header length is 12. 
               Convert G711 data to 16 bit PCM. 
            */ 
            j = 0; 
            for( i =12; i < ret; i++) 
            {                            
               c = (short)ulaw2linear((unsigned char)(buffer[i])); 
               pcSndBuf[j++]= (unsigned char) ((c>>8) & 0xff); 
               pcSndBuf[j++] = (unsigned char) (c & 0xff); 
            } 
            /* Play the data buffer onto the speaker device*/ 
            ooPlayAudioBuffer(pcSndBuf, j); 
            pcSndBuf =0; 
         } 
      } 
   } 
    
   gRecvThrdHdl = 0; 
   pthread_exit(0);    
   OOLOG2(1, "EndOf:ReceiveSpeakerThread"); 
   return 0; 
} 
 
 
/* Read the wave file and transmit wave file data 
   as rtp packets on RTP transmit channel. 
*/ 
static int ooTransmitFileThreadFuncLnx() 
{ 
   int DataTxed=0; 
   long audioDataSize; 
   int ret = 0; 
   char databuf[480]; 
   short *tempBuf; 
   unsigned char sendBuf[252]; /* additional 12 bytes for RTP header */ 
   int marker = 1; /* Only first packet has marker bit set */ 
   int i; 
   OOLOG2(1, "StartOf:TransmitFileThread"); 
    
   gXmitFileLoop = 1; 
   while(1) 
   { 
      if(!gXmitFileLoop) 
         break; 
      /* Number of bytes read is returned and stored in audioDataSize */ 
 
      audioDataSize = ooReadWaveFileData(databuf, 480); 
 
      if(audioDataSize>0) /* If any data is read */ 
      { 
         DataTxed += audioDataSize; 
         /* RTP version = 2, padding = 0, extension = 0, CSRC = 0 */ 
         sendBuf[0] = 0x80;  
         sendBuf[1] = 0x00; /* RTP Payload type PCM ulaw Need to use #define */ 
         if(marker) 
         { 
            sendBuf[1] |= 0x80; /* Set marker bit for first packet */ 
            marker = 0; 
         } 
         /*packet sequence number*/ 
         *((short *)(sendBuf + 2)) = ooHTONS((short)gXmitChannel.seqNo); 
         /*packet timestamp*/ 
         *((long  *)(sendBuf + 4)) = ooHTONL((long)gXmitChannel.timestamp); 
         /*packet ssrc*/ 
         *((long  *)(sendBuf + 8)) = ooHTONL((long)gXmitChannel.ssrc); 
          
         if(gXmitChannel.seqNo == 65535) 
            gXmitChannel.seqNo = 0; /* Seq num wrap around */ 
         else 
            gXmitChannel.seqNo += 1; 
 
         /* Next timestamp is current timestamp + play duration of the  
            current buffer. 
         */ 
         gXmitChannel.timestamp += 480; 
         tempBuf = (short*) databuf; 
         /* Copy PCM audio data into sendBuf as ulaw audio data*/ 
         for(i=0; i<(audioDataSize/2); i++) 
         { 
            sendBuf[12+i] = (unsigned char) linear2ulaw((int)*(tempBuf+i)); 
         } 
         /* transmit rtp packet */ 
         ret = ooSocketSendTo(gXmitChannel.sock, sendBuf,  
                     (audioDataSize/2+12), gXmitChannel.ip, gXmitChannel.port); 
         if(ret<0) 
         { 
            OOLOG2(1, "ERROR: Failed to transmit rtp packet"); 
            return -1; 
         } 
         ooSleep(2);/* Just slows down the transmit rate a bit */ 
      } 
      else{ 
         gXmitFileLoop = 0; 
         OOLOG2(1, "End of file transmission"); 
      } 
   } 
   /* Close the wave file */ 
   ret = ooCloseWaveFile(); 
   if(ret < 0) 
   { 
      OOLOG2(1, "ERROR: Failed to close the open wave file"); 
      return -1; 
   } 
   gXmitThrdHdl = 0; 
   pthread_exit(0);    
   OOLOG2(1, "EndOf:TransmitFileThread"); 
   return 0; 
} 
 
#endif