public class PCMDownloader extends Thread {
PlayAudio m_pa;
Socket s;
boolean m_bIsForceStop = false;
String m_hostaddr = "";
String m_errstr = "";
public PCMDownloader( PlayAudio pa ) {
m_pa = pa;
}
int readall( DataInputStream dis, byte[] buf, int len ) throws IOException {
int spos = 0;
int remain = len;
int readlen = 0;
while( true ){
try{
readlen = dis.read( buf, spos, remain );
if( readlen < 0 ){
return -1;
}
if( remain - readlen <= 0 ){
break;
}
spos += readlen;
remain -= readlen;
}
catch( SocketException e ){
if( m_bIsForceStop == false ){
m_errstr = e.getMessage();
}
}
catch( Exception e ){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw );
e.printStackTrace( pw );
pw.flush();
String str = sw.toString();
System.out.println( "Exception: " + e + "TRACE:" + str );
m_errstr = str;
return -1;
}
}
return 0;
}
static int byte2DWORD( byte[] bytes, int startpos ) {
return ( ( (short)bytes[ startpos ] ) & 0xFF ) << 24
| ( ( (short)bytes[ startpos + 1 ] ) & 0xFF ) << 16
| ( ( (short)bytes[ startpos + 2 ] ) & 0xFF ) << 8
| ( ( (short)bytes[ startpos + 3 ] ) & 0xFF );
}
static int byte2WORD( byte[] bytes, int startpos ) {
return ( ( (short)bytes[ startpos ] ) & 0xFF ) << 8
| ( ( (short)bytes[ startpos + 1 ] ) & 0xFF );
}
public void recv( Socket s ) throws IOException {
byte[] recvbuf = new byte[ 1024 * 1024 ];
InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream( is );
while( true ){
int ret = readall( dis, recvbuf, 24 );
if( ret < 0
|| recvbuf[ 0 ] != 'F'
|| recvbuf[ 1 ] != '*'
|| recvbuf[ 2 ] != 'C'
|| recvbuf[ 3 ] != 'K' ){
dis.close();
s.close();
break;
}
Calendar c = SystemTime2Calendar( recvbuf, 4 );
int wavdatasize = byte2DWORD( recvbuf, 20 );
if( readall( dis, recvbuf, wavdatasize ) < 0 ){
dis.close();
s.close();
break;
}
m_pa.addData( c, recvbuf, wavdatasize );
}
}
static Calendar SystemTime2Calendar( byte[] bytes, int startpos ) {
Calendar c = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) );
c.clear();
c.set( byte2WORD( bytes, startpos ),
byte2WORD( bytes, startpos + 2 ) - 1,
byte2WORD( bytes, startpos + 6 ),
byte2WORD( bytes, startpos + 8 ),
byte2WORD( bytes, startpos + 10 ),
byte2WORD( bytes, startpos + 12 ) );
c.set( Calendar.MILLISECOND, byte2WORD( bytes, startpos + 14 ) );
return c;
}
public void run() {
init();
loop();
}
public void setHostAddr( String s ) {
m_hostaddr = s;
}
public void forcestop() {
try{
m_bIsForceStop = true;
s.close();
}
catch( Exception e ){
}
m_errstr = "disconnected";
}
public boolean recvWaveData( Socket s ) throws IOException {
InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream( is );
byte[] recvbuf = new byte[ 12 ];
int ret = readall( dis, recvbuf, 12 );
boolean bret = false;
if( ret == 0
&& recvbuf[ 0 ] == 'f'
&& recvbuf[ 1 ] == '*'
&& recvbuf[ 2 ] == 'c'
&& recvbuf[ 3 ] == 'k' ){
int wBitsPerSample;
int nChannels;
int nSamplesPerSec;
wBitsPerSample = byte2WORD( recvbuf, 4 );
nChannels = byte2WORD( recvbuf, 6 );
nSamplesPerSec = byte2DWORD( recvbuf, 8 );
m_pa.init( wBitsPerSample, nChannels, nSamplesPerSec );
bret = true;
}
return bret;
}
public void loop() {
while( m_bIsForceStop == false ){
try{
int port = 1234;
s = new Socket( m_hostaddr, port );
m_errstr = "connected to " + m_hostaddr + ":" + port;
if( recvWaveData( s ) == false ){
s.close();
continue;
}
recv( s );
}
catch( Exception e ){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw );
e.printStackTrace( pw );
pw.flush();
String str = sw.toString();
m_errstr = str;
System.out.println( "Exception: " + e + "TRACE:" + str );
}
}
}
void init()
{
m_errstr = "";
m_bIsForceStop = false;
}
}