<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.3315.2870" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT size=2>Hi:</FONT></DIV>
<DIV><FONT size=2>&nbsp;&nbsp; I am a uviertity student wants make a network mp3 
player with sdl-sound.</FONT></DIV>
<DIV><FONT size=2>I start a thread of rtp to reciever rtp packet from network 
interface,and start a thread to decode(mp3) and playback the audio.</FONT><FONT 
size=2>I add&nbsp;the rtp-packet to a queue and&nbsp;decode it to 
a&nbsp;big&nbsp;buffer.Now the audio can be played but play 3 second then stop 
,I think the</FONT></DIV>
<DIV><FONT size=2>callback function of sdl audio confuse me.</FONT></DIV>
<DIV><FONT size=2>&nbsp;&nbsp; Need I start a new thread to prepare the big size 
buffer ,and is the callback function return after play all the data in the big 
size buffer.</FONT></DIV>
<DIV><FONT size=2>&nbsp;&nbsp; here is my program:</FONT></DIV>
<DIV><FONT size=2><BR>#include "lame.h"<BR>#include 
&lt;sys/timeb.h&gt;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>#include &lt;ctype.h&gt;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>#include &lt;stdio.h&gt;<BR>#include 
&lt;stdlib.h&gt;<BR>#include &lt;string.h&gt;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2><BR>#include "debug.h"<BR>#include "memory.h"<BR>#include 
"rtp.h"<BR>#include "SDL.h"<BR>#include "SDL_audio.h"<BR>#include 
"SDL_thread.h"<BR>#define MAXSIZE 44100*5</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>#ifdef WIN32<BR>#define WS_VERSION_ONE 
MAKEWORD(1,1)<BR>#define WS_VERSION_TWO MAKEWORD(2,2)<BR>#endif</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>#define MAXPCM 44100*5<BR>typedef struct 
pcm_data<BR>{<BR>&nbsp;uint8_t * data;<BR>&nbsp;uint32_t&nbsp; 
data_len;<BR>&nbsp;&nbsp;&nbsp; struct pcm_data * next;<BR>} 
PCM_DATA_T;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/******************global 
variable**********************/<BR>&nbsp; PCM_DATA_T 
header={NULL,0,NULL};<BR>&nbsp; PCM_DATA_T *current;<BR>&nbsp; struct rtp * 
session;<BR>&nbsp; SDL_mutex *mutex = NULL;<BR>&nbsp; static SDL_sem 
*sem;<BR>&nbsp; uint8_t&nbsp;&nbsp; *sound;&nbsp;&nbsp;&nbsp;/* Pointer to wave 
data */<BR>&nbsp;uint32_t&nbsp;&nbsp; soundlen;&nbsp;&nbsp;/* Length of wave 
data */<BR>&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; soundpos;&nbsp;&nbsp;/* 
Current play position */<BR>&nbsp; uint8_t pcmBuffer[MAXPCM];<BR>&nbsp; 
<BR>/******************************************************/<BR>static void 
<BR>usage() <BR>{<BR>&nbsp;printf("Usage: rtpdemo [switches] address 
port\n");<BR>&nbsp;printf("Valid switches are:\n");<BR>&nbsp;printf("&nbsp; 
-f\t\tFilter local packets out of receive stream.");<BR>&nbsp;printf("&nbsp; 
-l\t\tListen and do not transmit data.\n");<BR>&nbsp;exit(-1);<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2></FONT>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* 
------------------------------------------------------------------------- 
*/<BR>/* RTP callback related */</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>static void<BR>sdes_print(struct rtp *session, uint32_t ssrc, 
rtcp_sdes_type stype) {<BR>&nbsp;const char *sdes_type_names[] = 
{<BR>&nbsp;&nbsp;"end", "cname", "name", "email", "telephone", 
<BR>&nbsp;&nbsp;"location", "tool", "note", "priv"<BR>&nbsp;};<BR>&nbsp;const 
uint8_t n = sizeof(sdes_type_names) / sizeof(sdes_type_names[0]);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if (stype &gt; n) {<BR>&nbsp;&nbsp;/* Theoretically 
impossible */<BR>&nbsp;&nbsp;printf("boo! invalud sdes field %d\n", 
stype);<BR>&nbsp;&nbsp;return;<BR>&nbsp;}<BR>&nbsp;<BR>&nbsp;printf("SSRC 0x%08x 
reported SDES type %s - ", ssrc, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
sdes_type_names[stype]);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if (stype == RTCP_SDES_PRIV) {<BR>&nbsp;&nbsp;/* 
Requires extra-handling, not important for example 
*/<BR>&nbsp;&nbsp;printf("don't know how to display.\n");<BR>&nbsp;} else 
{<BR>&nbsp;&nbsp;printf("%s\n", rtp_get_sdes(session, ssrc, 
stype));<BR>&nbsp;}<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>static void<BR>addtoQueue(struct rtp *session, rtp_packet *p) 
<BR>{<BR>static uint32_t counter=0;<BR>uint16_t 
pcmBuffer[2][1152];<BR>PCM_DATA_T *temp=&amp;header;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>PCM_DATA_T * tempPacket=(PCM_DATA_T 
*)malloc(sizeof(PCM_DATA_T));/*when use the data,remeber to free the queue 
packet and xfree the rtp*/<BR>if(tempPacket==NULL)<BR>{<BR>&nbsp;printf("no 
enough memory left");<BR>&nbsp;exit(-1);<BR>}<BR>printf("Received data 
(payload=%d timestamp=%06d size=%06d) ", p-&gt;rtp_pak_pt, p-&gt;rtp_pak_ts, 
p-&gt;rtp_data_len);<BR>/*begin decode*/<BR>&nbsp;<BR>&nbsp;<BR>/*end 
decode*/<BR>SDL_mutexP(mutex);<BR>tempPacket-&gt;data=(uint8_t 
*)malloc(p-&gt;rtp_data_len);<BR>tempPacket-&gt;next 
=NULL;<BR>memcpy(tempPacket-&gt;data,p-&gt;rtp_data,p-&gt;rtp_data_len);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT 
size=2>tempPacket-&gt;data_len=p-&gt;rtp_data_len;<BR>tempPacket-&gt;next=NULL;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>while(temp-&gt;next!=NULL)//find the last 
<BR>&nbsp;{temp=temp-&gt;next;<BR>&nbsp;}<BR>temp-&gt;next=tempPacket;<BR>SDL_mutexV(mutex);<BR>SDL_SemPost(sem);<BR>printf("I 
get %d packet\n",counter++);<BR>printf("the current value is %d 
\n",SDL_SemValue(sem));</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if (p-&gt;rtp_pak_ssrc == rtp_my_ssrc(session)) 
{<BR>&nbsp;&nbsp;/* Unless filtering is enabled we are likely to 
see<BR>&nbsp;&nbsp;&nbsp;&nbsp; out packets if sending to a multicast group. 
*/<BR>&nbsp;&nbsp;printf("that I just sent.\n");<BR>&nbsp;} else 
{<BR>&nbsp;&nbsp;printf("from SSRC 0x%08x\n", p-&gt;rtp_pak_ssrc); <BR>&nbsp;} 
<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>static void<BR>rtp_event_handler(struct rtp *session, 
rtp_event *e) 
<BR>{<BR>&nbsp;rtp_packet&nbsp;*p;<BR>&nbsp;rtcp_sdes_item&nbsp;*r;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;switch(e-&gt;type) {<BR>&nbsp;case RX_RTP: 
&nbsp;<BR>&nbsp;&nbsp;p = 
(rtp_packet*)e-&gt;data;<BR>&nbsp;&nbsp;addtoQueue(session, 
p);<BR>&nbsp;&nbsp;xfree(p); /* xfree() is mandatory to release RTP packet data 
*/<BR>&nbsp;&nbsp;break;<BR>&nbsp;case RX_SDES:<BR>&nbsp;&nbsp;r = 
(rtcp_sdes_item*)e-&gt;data;<BR>&nbsp;&nbsp;sdes_print(session, e-&gt;ssrc, 
r-&gt;type);<BR>&nbsp;&nbsp;break;<BR>&nbsp;case 
RX_BYE:<BR>&nbsp;&nbsp;break;<BR>&nbsp;case 
SOURCE_CREATED:<BR>&nbsp;&nbsp;printf("New source created, SSRC = 0x%08x\n", 
e-&gt;ssrc);<BR>&nbsp;&nbsp;break;<BR>&nbsp;case 
SOURCE_DELETED:<BR>&nbsp;&nbsp;printf("Source deleted, SSRC = 0x%08x\n", 
e-&gt;ssrc);<BR>&nbsp;&nbsp;break;<BR>&nbsp;case RX_SR:<BR>&nbsp;case 
RX_RR:<BR>&nbsp;case RX_RR_EMPTY:<BR>&nbsp;case RX_RTCP_START:<BR>&nbsp;case 
RX_RTCP_FINISH:<BR>&nbsp;case RR_TIMEOUT:<BR>&nbsp;case 
RX_APP:<BR>;&nbsp;}<BR>&nbsp;fflush(stdout);<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* 
------------------------------------------------------------------------- 
*/<BR>/* Send and receive loop.&nbsp; Sender use 20ms audio mulaw packets 
*/</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>#define MULAW_BYTES&nbsp;4 * 160<BR>#define 
MULAW_PAYLOAD&nbsp;0<BR>#define MULAW_MS&nbsp;4 * 20</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2></FONT>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>static void<BR>recieve_packet(struct rtp* session, int 
send_enable) <BR>{<BR>&nbsp;struct timeval&nbsp;timeout;<BR>&nbsp;uint32_t&nbsp; 
rtp_ts;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if (send_enable) {<BR>&nbsp;&nbsp;printf("Sending and 
listening to ");<BR>&nbsp;} else {<BR>&nbsp;&nbsp;printf("Listening to 
");<BR>&nbsp;}<BR>&nbsp;printf("%s port %d (local SSRC = 0x%08x)\n", 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rtp_get_addr(session), 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
rtp_get_rx_port(session),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
rtp_my_ssrc(session));</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2></FONT>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>while(1){<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;/* Receive control 
and data packets */<BR>&nbsp;&nbsp;timeout.tv_sec&nbsp; = 
0;<BR>&nbsp;&nbsp;timeout.tv_usec = 5;<BR>&nbsp;&nbsp;rtp_recv(session, 
&amp;timeout, rtp_ts);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;/* State maintenance 
*/<BR>&nbsp;&nbsp;rtp_update(session);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;<A 
href="file://sleep">file://sleep</A>(1);<BR>&nbsp;&nbsp;xmemchk();<BR>&nbsp;}<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>static int recieverCallback(void *data)<BR>{<BR>&nbsp;struct 
timeval timeout;<BR>&nbsp;int retcode;<BR>&nbsp;&nbsp; <BR>#ifdef 
WIN32<BR>&nbsp;WSADATA WSAdata;<BR>&nbsp;if (WSAStartup(WS_VERSION_TWO, 
&amp;WSAdata) != 0 &amp;&amp; WSAStartup(WS_VERSION_ONE, &amp;WSAdata) != 0) 
{<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;printf("Windows Socket initialization 
failed.\n");<BR>&nbsp;&nbsp;return 1;<BR>&nbsp;}<BR>&nbsp;debug_msg("WSAStartup 
OK: %sz\nStatus:%s\n", WSAdata.szDescription, 
WSAdata.szSystemStatus);<BR>#endif<BR>&nbsp;<BR>//&nbsp;memcpy(address,&amp;data[sizeof(uint16_t)],sizeof(uint16_t));</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2><BR>printf("Started thread %s: My thread id is %u\n",(char 
*)data, SDL_ThreadID());<BR>&nbsp;session = rtp_init((char *)data,&nbsp;&nbsp;/* 
Host/Group IP address */ <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8000,&nbsp;&nbsp;/* 
receive port */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8000,&nbsp;&nbsp;/* transmit 
port */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16,&nbsp;&nbsp;&nbsp;/* time-to-live 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 64000,&nbsp;&nbsp;/* B/W estimate 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rtp_event_handler,&nbsp;/* RTP event 
callback */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL);&nbsp;&nbsp;/* App. specific 
data */</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if (session) {<BR>&nbsp;&nbsp;const char 
&nbsp;*username&nbsp; = "Malcovich Malcovitch";<BR>&nbsp;&nbsp;const 
char&nbsp;*telephone = "1-800-RTP-DEMO";<BR>&nbsp;&nbsp;const 
char&nbsp;*toolname&nbsp; = "RTPdemo";</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;uint32_t &nbsp;my_ssrc = 
rtp_my_ssrc(session);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;/* Set local participant info 
*/<BR>&nbsp;&nbsp;rtp_set_sdes(session, my_ssrc, 
RTCP_SDES_NAME,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username, 
strlen(username));<BR>&nbsp;&nbsp;rtp_set_sdes(session, my_ssrc, 
RTCP_SDES_PHONE,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; telephone, 
strlen(telephone));<BR>&nbsp;&nbsp;rtp_set_sdes(session, my_ssrc, 
RTCP_SDES_TOOL,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; toolname, 
strlen(toolname));</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;/* Filter out local packets if requested 
*/<BR>&nbsp;&nbsp;rtp_set_option(session, RTP_OPT_FILTER_MY_PACKETS, 
0);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;/* Run main loop 
*/<BR>&nbsp;&nbsp;recieve_packet(session, 0);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;/* Say bye-bye 
*/<BR>&nbsp;&nbsp;rtp_send_bye(session);<BR>&nbsp;&nbsp;rtp_done(session);<BR>&nbsp;} 
else {<BR>&nbsp;&nbsp;printf("Could not initialize session for %s port 
%d\n",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (char 
*)data,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
8000);<BR>&nbsp;&nbsp;return -1;<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2><BR>#ifdef 
WIN32<BR>&nbsp;Sleep(2000);<BR>&nbsp;WSACleanup();<BR>#endif</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;return(0);<BR>}<BR>/**/<BR>static void 
prepareBuffer()<BR>{<BR>uint32_t index=0;<BR>PCM_DATA_T * 
temp=&amp;header;<BR>uint16_t Buffer[2][1152];<BR>&nbsp;mp3data_struct 
mp3data;<BR>&nbsp;int counter=0;<BR>&nbsp;#define MP3SIZE 
1024*2<BR>&nbsp;uint8_t mp3buf[MP3SIZE];<BR>&nbsp;uint32_t 
ret=0;<BR>&nbsp;&nbsp; mp3data.samplerate=22050;<BR>&nbsp;&nbsp; 
mp3data.stereo=1;<BR>&nbsp;&nbsp; </FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>do{&nbsp; <BR>&nbsp;counter++;<BR>&nbsp;printf("the current 
value2 is %d 
\n",SDL_SemValue(sem));<BR>&nbsp;fflush(stdout);<BR>&nbsp;SDL_SemWait(sem);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT 
size=2>&nbsp;&nbsp;&nbsp;SDL_mutexP(mutex);<BR>&nbsp;&nbsp;if(header.next 
!=NULL)<BR>&nbsp;&nbsp;&nbsp;&nbsp; temp=header.next ;//move next</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; 
memcpy(mp3buf,temp-&gt;data,temp-&gt;data_len);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
SDL_mutexV(mutex);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>if(temp-&gt;data_len &gt;0)<BR>&nbsp;ret = 
lame_decode1_headers(mp3buf, temp-&gt;data_len , Buffer[0], Buffer[1], 
&amp;mp3data);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;&nbsp; header.next =temp-&gt;next 
;<BR>&nbsp;&nbsp;if(temp-&gt;data!=NULL) <BR>&nbsp;&nbsp; { printf("free 
temp-&gt;data now");<BR>&nbsp;&nbsp;&nbsp; free(temp-&gt;data);<BR>&nbsp;&nbsp; 
}<BR>&nbsp;if(temp!=NULL) <BR>&nbsp;{<BR>&nbsp;&nbsp;printf("free temp 
now");<BR>&nbsp;&nbsp;free(temp);<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
memcpy(&amp;pcmBuffer[index],Buffer[0] ,ret);<BR>&nbsp;&nbsp; index+=ret 
;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2><BR>&nbsp;}while(index+500&lt;MAXPCM);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2><A 
href="file://}">file://}</A>while(counter&lt;40);<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>static void audioCallback(void *unused, Uint8 *stream, int 
len)<BR>{<BR>&nbsp;<BR>#ifdef OLD</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;Uint8 *waveptr;<BR>&nbsp;int&nbsp;&nbsp;&nbsp; 
waveleft;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;/* Set up the pointers */<BR>&nbsp;waveptr = sound + 
soundpos;<BR>&nbsp;waveleft = soundlen - soundpos;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;/* Go! 
*/<BR>&nbsp;SDL_mutexP(mutex);<BR>&nbsp;<BR>&nbsp;while ( waveleft &lt;= len ) 
{<BR>&nbsp;&nbsp;SDL_MixAudio(stream, waveptr, waveleft, 
SDL_MIX_MAXVOLUME);<BR>&nbsp;&nbsp;stream += waveleft;<BR>&nbsp;&nbsp;len -= 
waveleft;<BR>&nbsp;&nbsp;waveptr = sound;<BR>&nbsp;&nbsp;waveleft = 
soundlen;<BR>&nbsp;&nbsp;soundpos = 0;<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2><BR>&nbsp;SDL_MixAudio(stream, waveptr, len, 
SDL_MIX_MAXVOLUME);<BR>&nbsp;SDL_mutexV(mutex);<BR>&nbsp;soundpos += 
len;<BR>#else<BR>&nbsp;if(soundlen&lt;=0) 
<BR>&nbsp;&nbsp;return;<BR>&nbsp;&nbsp;&nbsp; 
len=(len&gt;soundlen?soundlen:len);<BR>&nbsp;printf("the callback return 
len=%d\n",len);<BR>&nbsp;SDL_MixAudio(stream,sound,len,SDL_MIX_MAXVOLUME);<BR>&nbsp;sound+=len;<BR>&nbsp;soundlen-=len;<BR>#endif</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>}<BR>/*the callback function of thread player*/</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>static int playerCallback(void *data)<BR>{<BR>&nbsp;int 
lameret=0;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp; SDL_AudioSpec *desired, *obtained;<BR>&nbsp; /* 
Allocate a desired SDL_AudioSpec */<BR>desired=(SDL_AudioSpec 
*)malloc(sizeof(SDL_AudioSpec));</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* Allocate space for the obtained SDL_AudioSpec 
*/<BR>obtained=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* 22050Hz - FM Radio quality 
*/<BR>desired-&gt;freq=22050;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* 16-bit signed audio 
*/<BR>desired-&gt;format=AUDIO_S16LSB;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* Mono */<BR>desired-&gt;channels=1;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* Large audio buffer reduces risk of dropouts but increases 
response time */<BR>desired-&gt;samples=8192;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* Our callback function 
*/<BR>desired-&gt;callback=audioCallback;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>desired-&gt;userdata=NULL;<BR>&nbsp;if ( 
SDL_OpenAudio(desired,obtained) &lt; 0 ) {<BR>&nbsp;&nbsp;fprintf(stderr, 
"Couldn't open audio: %s\n", 
SDL_GetError());<BR>&nbsp;<BR>&nbsp;&nbsp;exit(2);<BR>&nbsp;}<BR>&nbsp;free(desired);<BR>printf("I 
have walk into player thread and going to 
prepareBuffer\n");<BR>&nbsp;/*prepare&nbsp; data mainly get rid of the queue and 
add it to a big buffer*/<BR>&nbsp;&nbsp;&nbsp; 
SDL_Delay(4000);<BR>&nbsp;printf("delay ok! going to prepare 
buffer");</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT 
size=2>&nbsp;<BR>&nbsp;&nbsp;lameret=lame_decode_init();<BR>printf("lame decode 
init ret %d\n",lameret);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;while(1)<BR>&nbsp;{<BR>&nbsp;&nbsp;&nbsp; 
prepareBuffer();<BR>&nbsp;sound=pcmBuffer;<BR>&nbsp;soundpos=0;<BR>&nbsp;soundlen=MAXPCM-500;<BR>&nbsp;SDL_PauseAudio(0);<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;/* Let the audio run */<BR>//&nbsp;printf("Using audio 
driver: %s\n", SDL_AudioDriverName(name, 32));<BR>&nbsp;while (1 
)<BR>&nbsp;&nbsp;SDL_Delay(1000);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;/* Clean up on signal 
*/<BR>&nbsp;SDL_CloseAudio();<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>/* 
------------------------------------------------------------------------- 
*/<BR>/* Main loop: parses command line and initializes RTP session */<BR>int 
main(int argc,char* argv[])<BR>{</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;int32_t&nbsp;&nbsp;ac, filter_me = 0, send_enable = 
0;<BR>&nbsp;&nbsp; &nbsp; char&nbsp;*address = NULL;<BR>&nbsp;uint16_t&nbsp;port 
= 0;<BR>&nbsp; SDL_Thread * reciever;<BR>&nbsp; SDL_Thread * player;<BR>&nbsp; 
int init_sem=0;<BR>&nbsp;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;ac = 1;<BR>&nbsp;while (argv[ac][0] == '-') 
{<BR>&nbsp;&nbsp;switch(tolower(argv[ac][1])) {<BR>&nbsp;&nbsp;case 
'f':<BR>&nbsp;&nbsp;&nbsp;filter_me = 
1;<BR>&nbsp;&nbsp;&nbsp;break;<BR>&nbsp;&nbsp;case 
'l':<BR>&nbsp;&nbsp;&nbsp;send_enable = 
0;<BR>&nbsp;&nbsp;&nbsp;break;<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;ac++;<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if (argc - ac != 2) 
{<BR>&nbsp;&nbsp;usage();<BR>&nbsp;}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;address&nbsp;= argv[ac];<BR>&nbsp;port&nbsp;= 
atoi(argv[ac + 1]);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2></FONT>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if ( SDL_Init(0) &lt; 0 ) 
<BR>&nbsp;&nbsp;{&nbsp;fprintf(stderr, "Couldn't initialize SDL: 
%s\n",SDL_GetError());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
exit(1);&nbsp;<BR>&nbsp;&nbsp; 
}<BR>&nbsp;<BR>&nbsp;atexit(SDL_Quit);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;&nbsp;&nbsp; sem = 
SDL_CreateSemaphore(init_sem);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;if ( (mutex=SDL_CreateMutex()) == NULL ) 
<BR>&nbsp;&nbsp;{&nbsp;fprintf(stderr, "Couldn't create mutex: %s\n", 
SDL_GetError());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
exit(1);<BR>&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2><BR>&nbsp;&nbsp;<BR>reciever = 
SDL_CreateThread(recieverCallback,address);<BR>player=&nbsp;&nbsp;&nbsp; 
SDL_CreateThread(playerCallback,"player");<BR>SDL_WaitThread(reciever, 
NULL);<BR>SDL_WaitThread(player, NULL);<BR>&nbsp;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=2>&nbsp;return 0;<BR>}<BR></FONT></DIV>
<DIV><FONT size=2>&nbsp;&nbsp; </FONT>&nbsp;</DIV></BODY></HTML>