Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

alac_decode implemented, but buggy. seqno bug corrected.

  • Loading branch information...
commit fb45f92b5421786eba99a996d6b5e854260362a4 1 parent 375fcbb
bencall authored April 23, 2011
2  src/AudioData.java
@@ -5,5 +5,5 @@
5 5
  */
6 6
 public class AudioData {
7 7
 	public boolean ready;
8  
-	public byte[] data;
  8
+	public int[] data;
9 9
 }
106  src/AudioServer.java
@@ -5,8 +5,21 @@
5 5
  */
6 6
 
7 7
 import java.io.IOException;
  8
+import java.io.StringReader;
8 9
 import java.net.DatagramPacket;
9 10
 import java.net.DatagramSocket;
  11
+import java.security.KeyPair;
  12
+import java.security.Security;
  13
+import java.util.concurrent.locks.Condition;
  14
+import java.util.concurrent.locks.Lock;
  15
+import java.util.concurrent.locks.ReentrantLock;
  16
+
  17
+import javax.crypto.Cipher;
  18
+import javax.crypto.spec.IvParameterSpec;
  19
+import javax.crypto.spec.SecretKeySpec;
  20
+
  21
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
  22
+import org.bouncycastle.openssl.PEMReader;
10 23
 
11 24
 import com.beatofthedrum.alacdecoder.*;
12 25
 
@@ -14,7 +27,8 @@
14 27
 	// Constantes
15 28
 	public static final int BUFFER_FRAMES = 512;	// Total buffer size (number of frame)
16 29
 	public static final int START_FILL = 282;		// Alac will wait till there are START_FILL frames in buffer
17  
-	
  30
+	public static final int MAX_PACKET = 2048;		// Also in UDPListener (possible to merge it in one place?)
  31
+
18 32
 	// Variables d'instances
19 33
 	int[]fmtp;								// Sound infos
20 34
 	AudioData[] audioBuffer;				// Buffer audio
@@ -24,9 +38,23 @@
24 38
 	int writeIndex;
25 39
 	int actualBufSize;
26 40
 	DatagramSocket sock, csock;
27  
-	
  41
+	// Keys
  42
+	byte[] aesiv;
  43
+	byte[] aeskey;
  44
+	//Decoder
  45
+	AlacFile alac;
  46
+	int frameSize;
  47
+	// Mutex locks
  48
+    private final Lock lock = new ReentrantLock();
  49
+    private final Condition bufferOkCond = lock.newCondition();
  50
+
28 51
 	public AudioServer(byte[] aesiv, byte[] aeskey, int[] fmtp, int controlPort, int timingPort){
  52
+		// Init instance var
29 53
 		this.fmtp = fmtp;
  54
+		this.aesiv = aesiv;
  55
+		this.aeskey = aeskey;
  56
+		
  57
+		// Init functions
30 58
 		this.initDecoder();
31 59
 		this.initBuffer();
32 60
 		this.initRTP();		
@@ -56,14 +84,14 @@ private void initRTP(){
56 84
 	}
57 85
 	
58 86
 	private void initDecoder(){
59  
-//		int frameSize = fmtp[1];
  87
+		frameSize = fmtp[1];
60 88
 //		int samplingRate = fmtp[11];
61 89
 		int sampleSize = fmtp[3];
62 90
 		if (sampleSize != 16){
63 91
 			return;
64 92
 		}
65 93
 		
66  
-		AlacFile alac = AlacDecodeUtils.create_alac(sampleSize, 2);
  94
+		alac = AlacDecodeUtils.create_alac(sampleSize, 2);
67 95
 		alac.setinfo_max_samples_per_frame = 3;
68 96
 		alac.setinfo_7a = fmtp[2];
69 97
 		alac.setinfo_sample_size = sampleSize;
@@ -92,32 +120,36 @@ public void packetReceived(DatagramSocket socket, DatagramPacket packet) {
92 120
 			}
93 121
 			
94 122
 			//seqno is on two byte
95  
-			int seqno = ((int)pktp[2] << 8) + (pktp[3] & 0xff); 
  123
+			int seqno = (int)((pktp[2] & 0xff)*256 + (pktp[3] & 0xff)); 
  124
+
96 125
 			this.putPacketInBuffer(seqno, pktp);
97 126
 		}
98 127
 	}
99 128
 	
100 129
 	private void putPacketInBuffer(int seqno, byte[] data){
101 130
 	    // Ring buffer may be implemented in a Hashtable in java (simplier), but is it fast enough?
  131
+
  132
+		// We lock the thread
  133
+		lock.lock();
102 134
 		
103 135
 		if(!synced){
104 136
 			writeIndex = seqno;
105 137
 			readIndex = seqno;
106 138
 			synced = true;
107 139
 		}
108  
-		
  140
+		System.out.println("ID: " + (seqno % BUFFER_FRAMES));
109 141
 		if (seqno == writeIndex){													// Packet we expected
110  
-			audioBuffer[(seqno % BUFFER_FRAMES)].data = this.alac_decode(data);	// With (seqno % BUFFER_FRAMES) we loop from 0 to BUFFER_FRAMES
111  
-			audioBuffer[(seqno % BUFFER_FRAMES)].ready = true;
  142
+			// audioBuffer[(seqno % BUFFER_FRAMES)].data = this.alac_decode(data);		// With (seqno % BUFFER_FRAMES) we loop from 0 to BUFFER_FRAMES
  143
+			//audioBuffer[(seqno % BUFFER_FRAMES)].ready = true;
112 144
 			writeIndex++;
113 145
 		} else if(seqno > writeIndex){												// Too early, did we miss some packet between writeIndex and seqno?
114 146
 			this.request_resend(writeIndex, seqno);
115  
-			audioBuffer[(seqno % BUFFER_FRAMES)].data = this.alac_decode(data);
116  
-			audioBuffer[(seqno % BUFFER_FRAMES)].ready = true;
  147
+			//audioBuffer[(seqno % BUFFER_FRAMES)].data = this.alac_decode(data);
  148
+			//audioBuffer[(seqno % BUFFER_FRAMES)].ready = true;
117 149
 			writeIndex = seqno + 1;
118 150
 		} else if(seqno > readIndex){												// readIndex < seqno < writeIndex not yet played but too late. Still ok
119  
-			audioBuffer[(seqno % BUFFER_FRAMES)].data = this.alac_decode(data);
120  
-			audioBuffer[(seqno % BUFFER_FRAMES)].ready = true;
  151
+			//audioBuffer[(seqno % BUFFER_FRAMES)].data = this.alac_decode(data);
  152
+			//audioBuffer[(seqno % BUFFER_FRAMES)].ready = true;
121 153
 		} else {
122 154
 			System.err.println("Late packet with seq. numb.: " + seqno);			// Really to late
123 155
 		}
@@ -128,8 +160,11 @@ private void putPacketInBuffer(int seqno, byte[] data){
128 160
 	    	actualBufSize = actualBufSize + BUFFER_FRAMES;
129 161
 	    }
130 162
 	    
  163
+	    // We unlock the tread
  164
+	    lock.unlock();
  165
+	    
131 166
 	    if(!decoder_isStopped && actualBufSize > START_FILL){
132  
-		    // TODO Signal to alac thread that it is ready
  167
+// TODO	    	bufferOkCond.signal();
133 168
 	    }
134 169
 	    
135 170
 	}
@@ -139,8 +174,51 @@ private void request_resend(int writeIndex2, int seqno) {
139 174
 		
140 175
 	}
141 176
 
142  
-	private byte[] alac_decode(byte[] data){
  177
+	private int[] alac_decode(byte[] data){
143 178
 		// TODO Auto-generated method stub
  179
+		
  180
+	    byte[] packet = new byte[MAX_PACKET];
  181
+	    int i;
  182
+	    for (i=0; i+16<=data.length; i += 16){
  183
+	    	// 16 byte block data
  184
+	    	byte[] buffer = new byte[16];
  185
+	    	for (int j=0 ; j<16 ; j++){
  186
+	    		buffer[j] = data[i+j];
  187
+	    	}
  188
+	      	
  189
+	    	// Encrypt
  190
+	    	byte[] buf = this.encryptAES(buffer);
  191
+	    	
  192
+	    	// We merge everything
  193
+	      	for (int j=0 ; j<16 ; j++){
  194
+	    		packet[i+j] = buf[j];
  195
+	    	}
  196
+	    }
  197
+
  198
+	    // The rest of the packet is unencrypted
  199
+	    for (int k = 0; i<(data.length % 16); i++){
  200
+	    	packet[i] = data[k];
  201
+	    }
  202
+	    
  203
+	    int[] outbuffer = new int[frameSize*4];		// FrameSize * 4
  204
+	    int outputsize = 0;
  205
+	    AlacDecodeUtils.decode_frame(alac, packet, outbuffer, outputsize);
  206
+	    
  207
+		return outbuffer;
  208
+	}
  209
+	
  210
+		
  211
+	public byte[] encryptAES(byte[] array){
  212
+		try{
  213
+			SecretKeySpec k = new SecretKeySpec(aeskey, "AES");
  214
+			Cipher c = Cipher.getInstance("AES/CBC/NoPadding");
  215
+			c.init(Cipher.DECRYPT_MODE, k, new IvParameterSpec(aesiv));
  216
+	        return c.doFinal(array);
  217
+
  218
+		}catch(Exception e){
  219
+			e.printStackTrace();
  220
+		}
  221
+		
144 222
 		return null;
145 223
 	}
146 224
 }
1  src/UDPListener.java
@@ -16,6 +16,7 @@
16 16
 	UDPDelegate delegate;
17 17
 	
18 18
 	public UDPListener(DatagramSocket socket, UDPDelegate delegate){
  19
+		super();
19 20
 		this.socket = socket;
20 21
 		this.delegate = delegate;
21 22
 		this.start();

0 notes on commit fb45f92

Please sign in to comment.
Something went wrong with that request. Please try again.