diff src/main/java/jp/ac/u_ryukyu/treevnc/SendSound.java @ 291:a310be14d757

send rtp+sound packet(client node version).
author oc
date Tue, 13 Jan 2015 06:43:15 +0900
parents c10e0dee7bbb
children d1ceb4b7097a
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/SendSound.java	Tue Jan 13 05:22:53 2015 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/SendSound.java	Tue Jan 13 06:43:15 2015 +0900
@@ -1,26 +1,128 @@
 package jp.ac.u_ryukyu.treevnc;
 
+import javax.sound.sampled.*;
+import java.io.ByteArrayOutputStream;
+import java.net.*;
+
 /**
  * Created by OcBookPro on 15/01/13.
  */
 public class SendSound implements Runnable {
 
-    TreeRFBProto rfb;
+    public static final int recvPort = 60004;
+    private TreeRFBProto rfb;
+    private DatagramSocket socket;
+    private boolean isStop;
 
+    private int sequenceNum;
+    private int timeStamp;
+    private int syncSourceId;
+    private byte marker;
+
+    // Destination ip and port.
+    private String destIp;
+    private String destPort;
+
+    // Constructor root version.
     public SendSound(TreeRFBProto rfb) {
         this.rfb = rfb;
     }
 
+    // Constructor node version.
+    public SendSound(TreeRFBProto rfb, String destIp, String destPort) throws UnknownHostException, SocketException {
+        this.rfb = rfb;
+        this.socket = new DatagramSocket(recvPort, InetAddress.getLocalHost());
+        this.destIp = destIp;
+        this.destPort = destPort;
+    }
+
     @Override
     public void run() {
-        for(;;) {
-            if (rfb.isTreeManager()) {
-                // root version (send packet to other nodes)
-                System.out.println("root : share sound!!\n");
-            } else {
-                // node version (send packet+RTP to root)
-                System.out.println("client node : share sound!!\n");
+        try {
+            byte[] soundPacket = new byte[160];
+
+            AudioFormat linearFormat = new AudioFormat(8000,16,1,true,false);
+            AudioFormat ulawFormat = new AudioFormat(AudioFormat.Encoding.ULAW,8000,8,1,1,8000,false);
+
+            DataLine.Info info = new DataLine.Info(TargetDataLine.class,linearFormat);
+            TargetDataLine targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
+            targetDataLine.open(linearFormat);
+            targetDataLine.start();
+
+            AudioInputStream linearStream = new AudioInputStream(targetDataLine);
+            AudioInputStream ulawStream = AudioSystem.getAudioInputStream(ulawFormat,linearStream);
+
+            byte[] byteaddress;
+            byte[] rtpPacket;
+            DatagramPacket packet = null;
+            InetSocketAddress address = null;
+
+            if (!rfb.isTreeManager()) {
+                // rtp+sound packet
+                rtpPacket = new byte[172];
+                address = new InetSocketAddress(this.destIp, Integer.parseInt(this.destPort));
             }
+
+            while(!isStop) {
+                try {
+                    ulawStream.read(soundPacket,0,soundPacket.length);
+                    if (rfb.isTreeManager()) {
+                        // soundPacketをframebufferUpdateに乗せて送信する処理
+                        return;
+                    }
+                    // client node version.
+                    rtpPacket = this.addRtpHeader(soundPacket);
+                    packet = new DatagramPacket(rtpPacket,rtpPacket.length,address);
+                    this.socket.send(packet);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
         }
     }
-}
+
+    public void stopSendSound() {
+        this.isStop = true;
+    }
+
+    private byte[] addRtpHeader(byte[] voiceData)
+    {
+        byte[] rtpHeader = new byte[12];	// RTPヘッダ
+        byte version	= -128;				// バージョン番号10000000
+        byte padding	= 0;				// パディング
+        byte extention	= 0;				// 拡張ビット
+        byte contribute	= 0;				// コントリビュートカウント
+        byte payload	= 0;				// ペイロードタイプ
+
+        // RTPヘッダーの生成
+        rtpHeader[0]  = (byte)(version | padding | extention | contribute);
+        rtpHeader[1]  = (byte)(marker | payload);
+        rtpHeader[2]  = (byte)(this.sequenceNum >> 8);
+        rtpHeader[3]  = (byte)(this.sequenceNum >> 0);
+        rtpHeader[4]  = (byte)(this.timeStamp >> 24);
+        rtpHeader[5]  = (byte)(this.timeStamp >> 16);
+        rtpHeader[6]  = (byte)(this.timeStamp >>  8);
+        rtpHeader[7]  = (byte)(this.timeStamp >>  0);
+        rtpHeader[8]  = (byte)(this.syncSourceId >> 24);
+        rtpHeader[9]  = (byte)(this.syncSourceId >> 16);
+        rtpHeader[10] = (byte)(this.syncSourceId >>  8);
+        rtpHeader[11] = (byte)(this.syncSourceId >>  0);
+
+        // シーケンス番号、タイムスタンプ、マーカービット移行
+        this.sequenceNum ++;
+        this.timeStamp += 160;
+        if(this.marker == -128)
+            this.marker = 0;
+
+        // RTPヘッダー+音声データ = RTPパケット
+        ByteArrayOutputStream out = new ByteArrayOutputStream(172);
+        out.write(rtpHeader,0,12);
+        out.write(voiceData,0,160);
+
+        return out.toByteArray();
+    }
+}
\ No newline at end of file