├── README.md
├── VoiceChat_Client
├── .gitignore
├── build.xml
├── manifest.mf
├── nbproject
│ ├── build-impl.xml
│ ├── genfiles.properties
│ ├── private
│ │ ├── config.properties
│ │ ├── private.properties
│ │ └── private.xml
│ ├── project.properties
│ └── project.xml
└── src
│ ├── AudioChannel.java
│ ├── Client.java
│ ├── GUI.form
│ ├── GUI.java
│ └── MicThread.java
├── VoiceChat_Comm
├── .gitignore
├── build.xml
├── manifest.mf
├── nbproject
│ ├── build-impl.xml
│ ├── genfiles.properties
│ ├── private
│ │ ├── config.properties
│ │ ├── private.properties
│ │ └── private.xml
│ ├── project.properties
│ └── project.xml
└── src
│ ├── ErrorMessage.java
│ ├── Message.java
│ ├── SoundPacket.java
│ └── Utils.java
└── VoiceChat_Server
├── .gitignore
├── build.xml
├── lib
├── cling-core-1.0.5.jar
├── cling-support-1.0.5.jar
└── teleal-common-1.0.13.jar
├── manifest.mf
├── nbproject
├── build-impl.xml
├── genfiles.properties
├── private
│ ├── config.properties
│ ├── private.properties
│ └── private.xml
├── project.properties
└── project.xml
└── src
├── ClientConnection.java
├── GUI.form
├── GUI.java
├── Log.java
└── Server.java
/README.md:
--------------------------------------------------------------------------------
1 | # VoiceChat
2 |
3 | VoiceChat is a simple VoIP application written in Java that supports uPnP, conversations with multiple users and basic compression with comfort noise.
4 |
5 | ## Download
6 | [Download from my site](http://downloads.fdossena.com/geth.php?r=voicechat-bin) (Requires [Java](http://java.com))
7 |
8 | ## Usage
9 | If you want to play with the code, just import the projects into Netbeans
10 |
11 | ## Compatibility
12 | Multiplaform, Java SE 7
13 |
14 | ## Screenshots
15 | 
16 | 
17 |
18 | ## License
19 | Copyright (C) 2015 Federico Dossena
20 |
21 | This program is free software: you can redistribute it and/or modify
22 | it under the terms of the GNU General Public License as published by
23 | the Free Software Foundation, either version 3 of the License, or
24 | (at your option) any later version.
25 |
26 | This program is distributed in the hope that it will be useful,
27 | but WITHOUT ANY WARRANTY; without even the implied warranty of
28 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 | GNU General Public License for more details.
30 |
31 | You should have received a copy of the GNU General Public License
32 | along with this program. If not, see .
33 |
--------------------------------------------------------------------------------
/VoiceChat_Client/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | dist/
3 |
--------------------------------------------------------------------------------
/VoiceChat_Client/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Builds, tests, and runs the project VoiceChat_Client.
12 |
13 |
73 |
74 |
--------------------------------------------------------------------------------
/VoiceChat_Client/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | X-COMMENT: Main-Class will be added automatically by build
3 |
4 |
--------------------------------------------------------------------------------
/VoiceChat_Client/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=12915718
2 | build.xml.script.CRC32=5d70ffe9
3 | build.xml.stylesheet.CRC32=8064a381@1.68.1.46
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=12915718
7 | nbproject/build-impl.xml.script.CRC32=e90885cd
8 | nbproject/build-impl.xml.stylesheet.CRC32=5a01deb7@1.68.1.46
9 |
--------------------------------------------------------------------------------
/VoiceChat_Client/nbproject/private/config.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adolfintel/voicechat/10878e2beb334ff863f66914f3b2852c72c0d410/VoiceChat_Client/nbproject/private/config.properties
--------------------------------------------------------------------------------
/VoiceChat_Client/nbproject/private/private.properties:
--------------------------------------------------------------------------------
1 | compile.on.save=true
2 | do.depend=false
3 | do.jar=true
4 | javac.debug=true
5 | javadoc.preview=true
6 | user.properties.file=C:\\Users\\dosse\\AppData\\Roaming\\NetBeans\\7.4\\build.properties
7 |
--------------------------------------------------------------------------------
/VoiceChat_Client/nbproject/private/private.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | file:/C:/Users/dosse/Documents/NetBeansProjects/VoiceChat_Client/src/GUI.java
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/VoiceChat_Client/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | annotation.processing.enabled=true
2 | annotation.processing.enabled.in.editor=false
3 | annotation.processing.processors.list=
4 | annotation.processing.run.all.processors=true
5 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
6 | application.title=VoiceChat_Client
7 | application.vendor=dosse
8 | build.classes.dir=${build.dir}/classes
9 | build.classes.excludes=**/*.java,**/*.form
10 | # This directory is removed when the project is cleaned:
11 | build.dir=build
12 | build.generated.dir=${build.dir}/generated
13 | build.generated.sources.dir=${build.dir}/generated-sources
14 | # Only compile against the classpath explicitly listed here:
15 | build.sysclasspath=ignore
16 | build.test.classes.dir=${build.dir}/test/classes
17 | build.test.results.dir=${build.dir}/test/results
18 | # Uncomment to specify the preferred debugger connection transport:
19 | #debug.transport=dt_socket
20 | debug.classpath=\
21 | ${run.classpath}
22 | debug.test.classpath=\
23 | ${run.test.classpath}
24 | # This directory is removed when the project is cleaned:
25 | dist.dir=dist
26 | dist.jar=${dist.dir}/VoiceChat_Client.jar
27 | dist.javadoc.dir=${dist.dir}/javadoc
28 | endorsed.classpath=
29 | excludes=
30 | includes=**
31 | jar.archive.disabled=${jnlp.enabled}
32 | jar.compress=false
33 | jar.index=${jnlp.enabled}
34 | javac.classpath=\
35 | ${reference.VoiceChat_Comm.jar}
36 | # Space-separated list of extra javac options
37 | javac.compilerargs=
38 | javac.deprecation=false
39 | javac.processorpath=\
40 | ${javac.classpath}
41 | javac.source=1.7
42 | javac.target=1.7
43 | javac.test.classpath=\
44 | ${javac.classpath}:\
45 | ${build.classes.dir}
46 | javac.test.processorpath=\
47 | ${javac.test.classpath}
48 | javadoc.additionalparam=
49 | javadoc.author=false
50 | javadoc.encoding=${source.encoding}
51 | javadoc.noindex=false
52 | javadoc.nonavbar=false
53 | javadoc.notree=false
54 | javadoc.private=false
55 | javadoc.splitindex=true
56 | javadoc.use=true
57 | javadoc.version=false
58 | javadoc.windowtitle=
59 | jnlp.codebase.type=no.codebase
60 | jnlp.descriptor=application
61 | jnlp.enabled=false
62 | jnlp.mixed.code=default
63 | jnlp.offline-allowed=false
64 | jnlp.signed=false
65 | jnlp.signing=
66 | jnlp.signing.alias=
67 | jnlp.signing.keystore=
68 | main.class=GUI
69 | manifest.file=manifest.mf
70 | meta.inf.dir=${src.dir}/META-INF
71 | mkdist.disabled=false
72 | platform.active=default_platform
73 | project.VoiceChat_Comm=../VoiceChat_Comm
74 | reference.VoiceChat_Comm.jar=${project.VoiceChat_Comm}/dist/VoiceChat_Comm.jar
75 | run.classpath=\
76 | ${javac.classpath}:\
77 | ${build.classes.dir}
78 | # Space-separated list of JVM arguments used when running the project
79 | # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
80 | # or test-sys-prop.name=value to set system properties for unit tests):
81 | run.jvmargs=
82 | run.test.classpath=\
83 | ${javac.test.classpath}:\
84 | ${build.test.classes.dir}
85 | source.encoding=UTF-8
86 | src.dir=src
87 | test.src.dir=test
88 |
--------------------------------------------------------------------------------
/VoiceChat_Client/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.java.j2seproject
4 |
5 |
6 | VoiceChat_Client
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | VoiceChat_Comm
17 | jar
18 |
19 | jar
20 | clean
21 | jar
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/VoiceChat_Client/src/AudioChannel.java:
--------------------------------------------------------------------------------
1 |
2 | import java.io.ByteArrayInputStream;
3 | import java.io.ByteArrayOutputStream;
4 | import java.util.ArrayList;
5 | import java.util.zip.GZIPInputStream;
6 | import javax.sound.sampled.AudioFormat;
7 | import javax.sound.sampled.AudioSystem;
8 | import javax.sound.sampled.DataLine;
9 | import javax.sound.sampled.SourceDataLine;
10 |
11 | /*
12 | * To change this template, choose Tools | Templates and open the template in
13 | * the editor.
14 | */
15 | /**
16 | * this thread plays the sound coming from one of the users that are connected
17 | * on the server. each user has its own AudioChannel.
18 | *
19 | * @author dosse
20 | */
21 | public class AudioChannel extends Thread {
22 |
23 | private long chId; //an id unique for each user. generated by IP and port
24 | private ArrayList queue = new ArrayList(); //queue of messages to be played
25 | private int lastSoundPacketLen = SoundPacket.defaultDataLenght;
26 | private long lastPacketTime = System.nanoTime();
27 |
28 | public boolean canKill() { //returns true if it's been a long time since last received packet
29 | if (System.nanoTime() - lastPacketTime > 5000000000L) {
30 | return true; //5 seconds with no data
31 | } else {
32 | return false;
33 | }
34 | }
35 |
36 | public void closeAndKill() {
37 | if (speaker != null) {
38 | speaker.close();
39 | }
40 | stop();
41 | }
42 |
43 | public AudioChannel(long chId) {
44 | this.chId = chId;
45 | }
46 |
47 | public long getChId() {
48 | return chId;
49 | }
50 |
51 | public void addToQueue(Message m) { //adds a message to the play queue
52 | queue.add(m);
53 | }
54 | private SourceDataLine speaker = null; //speaker
55 |
56 | @Override
57 | public void run() {
58 | try {
59 | //open channel to sound card
60 | AudioFormat af = SoundPacket.defaultFormat;
61 | DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
62 | speaker = (SourceDataLine) AudioSystem.getLine(info);
63 | speaker.open(af);
64 | speaker.start();
65 | //sound card ready
66 | for (;;) { //this infinite cycle checks for new packets to be played in the queue, and plays them. to avoid busy wait, a sleep(10) is executed at the beginning of each iteration
67 | if (queue.isEmpty()) { //nothing to play, wait
68 | Utils.sleep(10);
69 | continue;
70 | } else {//we got something to play
71 | lastPacketTime = System.nanoTime();
72 | Message in = queue.get(0);
73 | queue.remove(in);
74 | if (in.getData() instanceof SoundPacket) { //it's a sound packet, send it to sound card
75 | SoundPacket m = (SoundPacket) (in.getData());
76 | if (m.getData() == null) {//sender skipped a packet, play comfort noise
77 | byte[] noise = new byte[lastSoundPacketLen];
78 | for (int i = 0; i < noise.length; i++) {
79 | noise[i] = (byte) ((Math.random() * 3) - 1);
80 | }
81 | speaker.write(noise, 0, noise.length);
82 | } else {
83 | //decompress data
84 | GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(m.getData()));
85 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
86 | for (;;) {
87 | int b = gis.read();
88 | if (b == -1) {
89 | break;
90 | } else {
91 | baos.write((byte) b);
92 | }
93 | }
94 | //play decompressed data
95 | byte[] toPlay=baos.toByteArray();
96 | speaker.write(toPlay, 0, toPlay.length);
97 | lastSoundPacketLen = m.getData().length;
98 | }
99 | } else { //not a sound packet, trash
100 | continue; //invalid message
101 | }
102 | }
103 | }
104 | } catch (Exception e) { //sound card error or connection error, stop
105 | System.out.println("receiverThread " + chId + " error: " + e.toString());
106 | if (speaker != null) {
107 | speaker.close();
108 | }
109 | stop();
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/VoiceChat_Client/src/Client.java:
--------------------------------------------------------------------------------
1 |
2 | import java.io.IOException;
3 | import java.io.ObjectInputStream;
4 | import java.io.ObjectOutputStream;
5 | import java.net.Socket;
6 | import java.net.UnknownHostException;
7 | import java.util.ArrayList;
8 |
9 | /*
10 | * To change this template, choose Tools | Templates and open the template in
11 | * the editor.
12 | */
13 | /**
14 | * Connects to the server, then starts receiving messages. Creates
15 | * a MicThread that sends microphone data to the server, and creates an instance
16 | * of AudioThread for each user.
17 | * @author dosse
18 | */
19 | public class Client extends Thread {
20 |
21 | private Socket s;
22 | private ArrayList chs = new ArrayList();
23 | private MicThread st;
24 |
25 | public Client(String serverIp, int serverPort) throws UnknownHostException, IOException {
26 | s = new Socket(serverIp, serverPort);
27 | }
28 |
29 | @Override
30 | public void run() {
31 | try {
32 | ObjectInputStream fromServer = new ObjectInputStream(s.getInputStream()); //create object streams with the server
33 | ObjectOutputStream toServer = new ObjectOutputStream(s.getOutputStream());
34 | try {
35 | Utils.sleep(100); //wait for the GUI microphone test to release the microphone
36 | st = new MicThread(toServer); //creates a MicThread that sends microphone data to the server
37 | st.start(); //starts the MicThread
38 | } catch (Exception e) { //error acquiring microphone. causes: no microphone or microphone busy
39 | System.out.println("mic unavailable " + e);
40 | }
41 | for (;;) { //this infinite cycle checks for new data from the server, then sends it to the correct AudioChannel. if needed, a new AudioChannel is created
42 |
43 | if (s.getInputStream().available() > 0) { //we got something from the server (workaround: used available method from InputStream instead of the one from ObjetInputStream because of a bug in the JRE)
44 | Message in = (Message) (fromServer.readObject()); //read message
45 | //decide which audio channel should get this message
46 | AudioChannel sendTo = null;
47 | for (AudioChannel ch : chs) {
48 | if (ch.getChId() == in.getChId()) {
49 | sendTo = ch;
50 | }
51 | }
52 | if (sendTo != null) {
53 | sendTo.addToQueue(in);
54 | } else { //new AudioChannel is needed
55 | AudioChannel ch = new AudioChannel(in.getChId());
56 | ch.addToQueue(in);
57 | ch.start();
58 | chs.add(ch);
59 | }
60 | }else{ //see if some channels need to be killed and kill them
61 | ArrayList killMe=new ArrayList();
62 | for(AudioChannel c:chs) if(c.canKill()) killMe.add(c);
63 | for(AudioChannel c:killMe){c.closeAndKill(); chs.remove(c);}
64 | Utils.sleep(1); //avoid busy wait
65 | }
66 | }
67 | } catch (Exception e) { //connection error
68 | System.out.println("client err " + e.toString());
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/VoiceChat_Client/src/GUI.form:
--------------------------------------------------------------------------------
1 |
2 |
3 |
136 |
--------------------------------------------------------------------------------
/VoiceChat_Client/src/GUI.java:
--------------------------------------------------------------------------------
1 |
2 | import javax.sound.sampled.AudioFormat;
3 | import javax.sound.sampled.AudioSystem;
4 | import javax.sound.sampled.DataLine;
5 | import javax.sound.sampled.TargetDataLine;
6 | import javax.swing.JOptionPane;
7 |
8 | /*
9 | * To change this template, choose Tools | Templates and open the template in
10 | * the editor.
11 | */
12 | /**
13 | *
14 | * @author dosse
15 | */
16 | public class GUI extends javax.swing.JFrame {
17 | private MicTester micTester;
18 | //this class is used to test the microphone. it manages the volume meter
19 | private class MicTester extends Thread{
20 | private TargetDataLine mic = null;
21 | public MicTester() {
22 |
23 | }
24 | @Override
25 | public void run() {
26 |
27 | try {
28 | AudioFormat af = SoundPacket.defaultFormat;
29 | DataLine.Info info = new DataLine.Info(TargetDataLine.class, null);
30 | mic = (TargetDataLine) (AudioSystem.getLine(info));
31 | mic.open(af);
32 | mic.start();
33 | } catch (Exception e) {
34 | JOptionPane.showMessageDialog(rootPane,"Microphone not detected.\nPress OK to close this program", "Error",JOptionPane.ERROR_MESSAGE);
35 | System.exit(0);
36 | }
37 | for (;;) {
38 | Utils.sleep(10);
39 | if(mic.available()>0){
40 | byte[] buff=new byte[SoundPacket.defaultDataLenght];
41 | mic.read(buff,0,buff.length);
42 | long tot=0;
43 | for(int i=0;i//GEN-BEGIN:initComponents
71 | private void initComponents() {
72 |
73 | ip = new javax.swing.JTextField();
74 | start = new javax.swing.JButton();
75 | port = new javax.swing.JTextField();
76 | jLabel1 = new javax.swing.JLabel();
77 | jLabel3 = new javax.swing.JLabel();
78 | micLev = new javax.swing.JProgressBar();
79 | jLabel2 = new javax.swing.JLabel();
80 | jLabel4 = new javax.swing.JLabel();
81 | micVol = new javax.swing.JSlider();
82 |
83 | setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
84 | setResizable(false);
85 |
86 | ip.setText("127.0.0.1");
87 |
88 | start.setText("Connect");
89 | start.addActionListener(new java.awt.event.ActionListener() {
90 | public void actionPerformed(java.awt.event.ActionEvent evt) {
91 | startActionPerformed(evt);
92 | }
93 | });
94 |
95 | port.setText("1049");
96 |
97 | jLabel1.setText("Server IP and port");
98 |
99 | jLabel3.setText("Mic level");
100 |
101 | jLabel2.setText("If the mic level doesn't move as you speak, the mic volume is too low");
102 |
103 | jLabel4.setText("Mic volume");
104 |
105 | micVol.setMaximum(300);
106 | micVol.setMinimum(50);
107 | micVol.setValue(100);
108 | micVol.addChangeListener(new javax.swing.event.ChangeListener() {
109 | public void stateChanged(javax.swing.event.ChangeEvent evt) {
110 | micVolStateChanged(evt);
111 | }
112 | });
113 |
114 | javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
115 | getContentPane().setLayout(layout);
116 | layout.setHorizontalGroup(
117 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
118 | .addGroup(layout.createSequentialGroup()
119 | .addContainerGap()
120 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
121 | .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 338, Short.MAX_VALUE)
122 | .addComponent(start, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
123 | .addGroup(layout.createSequentialGroup()
124 | .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
125 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
126 | .addComponent(ip)
127 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
128 | .addComponent(port, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE))
129 | .addGroup(layout.createSequentialGroup()
130 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
131 | .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
132 | .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 63, Short.MAX_VALUE))
133 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
134 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
135 | .addComponent(micLev, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
136 | .addComponent(micVol, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
137 | .addContainerGap())
138 | );
139 | layout.setVerticalGroup(
140 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
141 | .addGroup(layout.createSequentialGroup()
142 | .addContainerGap()
143 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
144 | .addComponent(ip, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
145 | .addComponent(port, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
146 | .addComponent(jLabel1))
147 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
148 | .addComponent(start)
149 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
150 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
151 | .addComponent(jLabel3)
152 | .addComponent(micLev, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
153 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
154 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
155 | .addComponent(micVol, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
156 | .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
157 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
158 | .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
159 | .addContainerGap())
160 | );
161 |
162 | pack();
163 | }// //GEN-END:initComponents
164 |
165 | private void startActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startActionPerformed
166 | try {
167 | new Client(ip.getText(), Integer.parseInt(port.getText())).start(); //connect to specified server at specified port
168 | } catch (Exception ex) { //connection failed
169 | JOptionPane.showMessageDialog(rootPane, ex,"Error",JOptionPane.ERROR_MESSAGE);
170 | return;
171 | }
172 | //connected, disable buttons
173 | micTester.close();
174 | ip.setEnabled(false);
175 | port.setEnabled(false);
176 | start.setEnabled(false);
177 | micLev.setVisible(false);
178 | jLabel1.setEnabled(false);
179 | jLabel3.setVisible(false);
180 | micVol.setVisible(false);
181 | jLabel4.setVisible(false);
182 | jLabel2.setVisible(false);
183 | setSize(getWidth(),getHeight()-75);
184 | }//GEN-LAST:event_startActionPerformed
185 |
186 | private void micVolStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_micVolStateChanged
187 | MicThread.amplification=((double)(micVol.getValue()))/100.0;
188 | }//GEN-LAST:event_micVolStateChanged
189 |
190 | /**
191 | * @param args the command line arguments
192 | */
193 | public static void main(String args[]) {
194 | /*
195 | * Set the Nimbus look and feel
196 | */
197 | //
198 | /*
199 | * If Nimbus (introduced in Java SE 6) is not available, stay with the
200 | * default look and feel. For details see
201 | * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
202 | */
203 | try {
204 | for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
205 | if ("Nimbus".equals(info.getName())) {
206 | javax.swing.UIManager.setLookAndFeel(info.getClassName());
207 | break;
208 | }
209 | }
210 | } catch (ClassNotFoundException ex) {
211 | java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
212 | } catch (InstantiationException ex) {
213 | java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
214 | } catch (IllegalAccessException ex) {
215 | java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
216 | } catch (javax.swing.UnsupportedLookAndFeelException ex) {
217 | java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
218 | }
219 | //
220 |
221 | /*
222 | * Create and display the form
223 | */
224 | java.awt.EventQueue.invokeLater(new Runnable() {
225 |
226 | @Override
227 | public void run() {
228 | new GUI().setVisible(true);
229 | }
230 | });
231 | }
232 | // Variables declaration - do not modify//GEN-BEGIN:variables
233 | private javax.swing.JTextField ip;
234 | private javax.swing.JLabel jLabel1;
235 | private javax.swing.JLabel jLabel2;
236 | private javax.swing.JLabel jLabel3;
237 | private javax.swing.JLabel jLabel4;
238 | private javax.swing.JProgressBar micLev;
239 | private javax.swing.JSlider micVol;
240 | private javax.swing.JTextField port;
241 | private javax.swing.JButton start;
242 | // End of variables declaration//GEN-END:variables
243 | }
244 |
--------------------------------------------------------------------------------
/VoiceChat_Client/src/MicThread.java:
--------------------------------------------------------------------------------
1 |
2 | import java.io.ByteArrayOutputStream;
3 | import java.io.IOException;
4 | import java.io.ObjectOutputStream;
5 | import java.util.zip.GZIPOutputStream;
6 | import javax.sound.sampled.AudioFormat;
7 | import javax.sound.sampled.AudioSystem;
8 | import javax.sound.sampled.DataLine;
9 | import javax.sound.sampled.LineUnavailableException;
10 | import javax.sound.sampled.TargetDataLine;
11 |
12 | /*
13 | * To change this template, choose Tools | Templates
14 | * and open the template in the editor.
15 | */
16 | /**
17 | * reads data from microphone and sends it to the server
18 | *
19 | * @author dosse
20 | */
21 | public class MicThread extends Thread {
22 |
23 | public static double amplification = 1.0;
24 | private ObjectOutputStream toServer;
25 | private TargetDataLine mic;
26 |
27 | public MicThread(ObjectOutputStream toServer) throws LineUnavailableException {
28 | this.toServer = toServer;
29 | //open microphone line, an exception is thrown in case of error
30 | AudioFormat af = SoundPacket.defaultFormat;
31 | DataLine.Info info = new DataLine.Info(TargetDataLine.class, null);
32 | mic = (TargetDataLine) (AudioSystem.getLine(info));
33 | mic.open(af);
34 | mic.start();
35 | }
36 |
37 | @Override
38 | public void run() {
39 | for (;;) {
40 | if (mic.available() >= SoundPacket.defaultDataLenght) { //we got enough data to send
41 | byte[] buff = new byte[SoundPacket.defaultDataLenght];
42 | while (mic.available() >= SoundPacket.defaultDataLenght) { //flush old data from mic to reduce lag, and read most recent data
43 | mic.read(buff, 0, buff.length); //read from microphone
44 | }
45 | try {
46 | //this part is used to decide whether to send or not the packet. if volume is too low, an empty packet will be sent and the remote client will play some comfort noise
47 | long tot = 0;
48 | for (int i = 0; i < buff.length; i++) {
49 | buff[i] *= amplification;
50 | tot += Math.abs(buff[i]);
51 | }
52 | tot *= 2.5;
53 | tot /= buff.length;
54 | //create and send packet
55 | Message m = null;
56 | if (tot == 0) {//send empty packet
57 | m = new Message(-1, -1, new SoundPacket(null));
58 | } else { //send data
59 | //compress the sound packet with GZIP
60 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
61 | GZIPOutputStream go = new GZIPOutputStream(baos);
62 | go.write(buff);
63 | go.flush();
64 | go.close();
65 | baos.flush();
66 | baos.close();
67 | m = new Message(-1, -1, new SoundPacket(baos.toByteArray())); //create message for server, will generate chId and timestamp from this computer's IP and this socket's port
68 | }
69 | toServer.writeObject(m); //send message
70 | } catch (IOException ex) { //connection error
71 | stop();
72 | }
73 | } else {
74 | Utils.sleep(10); //sleep to avoid busy wait
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | dist/
3 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Builds, tests, and runs the project VoiceChat_Comm.
12 |
13 |
73 |
74 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | X-COMMENT: Main-Class will be added automatically by build
3 |
4 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/nbproject/build-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 | Must set src.dir
224 | Must set test.src.dir
225 | Must set build.dir
226 | Must set dist.dir
227 | Must set build.classes.dir
228 | Must set dist.javadoc.dir
229 | Must set build.test.classes.dir
230 | Must set build.test.results.dir
231 | Must set build.classes.excludes
232 | Must set dist.jar
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 | Must set javac.includes
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 | No tests executed.
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 | Must set JVM to use for profiling in profiler.info.jvm
713 | Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
714 |
715 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 | Must select some files in the IDE or set javac.includes
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 |
991 | To run this application from the command line without Ant, try:
992 |
993 | java -jar "${dist.jar.resolved}"
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1029 |
1030 |
1031 |
1032 |
1033 |
1034 |
1035 |
1036 |
1037 |
1038 |
1039 |
1040 | Must select one file in the IDE or set run.class
1041 |
1042 |
1043 |
1044 | Must select one file in the IDE or set run.class
1045 |
1046 |
1047 |
1052 |
1053 |
1054 |
1055 |
1056 |
1057 |
1058 |
1059 |
1060 |
1061 |
1062 |
1063 |
1064 |
1065 |
1066 |
1067 |
1068 |
1069 |
1070 |
1071 | Must select one file in the IDE or set debug.class
1072 |
1073 |
1074 |
1075 |
1076 | Must select one file in the IDE or set debug.class
1077 |
1078 |
1079 |
1080 |
1081 | Must set fix.includes
1082 |
1083 |
1084 |
1085 |
1086 |
1087 |
1088 |
1093 |
1096 |
1097 | This target only works when run from inside the NetBeans IDE.
1098 |
1099 |
1100 |
1101 |
1102 |
1103 |
1104 |
1105 |
1106 | Must select one file in the IDE or set profile.class
1107 | This target only works when run from inside the NetBeans IDE.
1108 |
1109 |
1110 |
1111 |
1112 |
1113 |
1114 |
1115 |
1116 | This target only works when run from inside the NetBeans IDE.
1117 |
1118 |
1119 |
1120 |
1121 |
1122 |
1123 |
1124 |
1125 |
1126 |
1127 |
1128 |
1129 | This target only works when run from inside the NetBeans IDE.
1130 |
1131 |
1132 |
1133 |
1134 |
1135 |
1136 |
1137 |
1138 |
1139 |
1140 |
1141 |
1142 |
1143 |
1144 |
1145 |
1146 |
1147 |
1148 |
1149 |
1150 |
1151 |
1154 |
1155 |
1156 |
1157 |
1158 |
1159 |
1160 |
1161 |
1162 |
1163 |
1164 |
1165 |
1166 |
1167 | Must select one file in the IDE or set run.class
1168 |
1169 |
1170 |
1171 |
1172 |
1173 | Must select some files in the IDE or set test.includes
1174 |
1175 |
1176 |
1177 |
1178 | Must select one file in the IDE or set run.class
1179 |
1180 |
1181 |
1182 |
1183 | Must select one file in the IDE or set applet.url
1184 |
1185 |
1186 |
1187 |
1192 |
1193 |
1194 |
1195 |
1196 |
1197 |
1198 |
1199 |
1200 |
1201 |
1202 |
1203 |
1204 |
1205 |
1206 |
1207 |
1208 |
1209 |
1210 |
1211 |
1212 |
1213 |
1214 |
1215 |
1216 |
1217 |
1218 |
1219 |
1220 |
1221 |
1222 |
1223 |
1224 |
1225 |
1226 |
1227 |
1228 |
1233 |
1234 |
1235 |
1236 |
1237 |
1238 |
1239 |
1240 |
1241 |
1242 |
1243 |
1244 |
1245 |
1246 |
1247 |
1248 |
1249 |
1250 |
1251 |
1252 |
1253 |
1254 |
1255 |
1256 |
1257 |
1258 |
1259 | Must select some files in the IDE or set javac.includes
1260 |
1261 |
1262 |
1263 |
1264 |
1265 |
1266 |
1267 |
1268 |
1269 |
1270 |
1271 |
1276 |
1277 |
1278 |
1279 |
1280 |
1281 |
1282 |
1283 | Some tests failed; see details above.
1284 |
1285 |
1286 |
1287 |
1288 |
1289 |
1290 |
1291 |
1292 | Must select some files in the IDE or set test.includes
1293 |
1294 |
1295 |
1296 | Some tests failed; see details above.
1297 |
1298 |
1299 |
1300 | Must select some files in the IDE or set test.class
1301 | Must select some method in the IDE or set test.method
1302 |
1303 |
1304 |
1305 | Some tests failed; see details above.
1306 |
1307 |
1308 |
1313 |
1314 | Must select one file in the IDE or set test.class
1315 |
1316 |
1317 |
1318 | Must select one file in the IDE or set test.class
1319 | Must select some method in the IDE or set test.method
1320 |
1321 |
1322 |
1323 |
1324 |
1325 |
1326 |
1327 |
1328 |
1329 |
1330 |
1331 |
1336 |
1337 | Must select one file in the IDE or set applet.url
1338 |
1339 |
1340 |
1341 |
1342 |
1343 |
1344 |
1349 |
1350 | Must select one file in the IDE or set applet.url
1351 |
1352 |
1353 |
1354 |
1355 |
1356 |
1357 |
1358 |
1363 |
1364 |
1365 |
1366 |
1367 |
1368 |
1369 |
1370 |
1371 |
1372 |
1373 |
1374 |
1375 |
1376 |
1377 |
1378 |
1379 |
1380 |
1381 |
1382 |
1383 |
1384 |
1385 |
1386 |
1387 |
1388 |
1389 |
1390 |
1391 |
1392 |
1393 |
1394 |
1395 |
1396 |
1397 |
1398 |
1399 |
1400 |
1401 |
1402 |
1403 |
1404 |
1405 |
1406 |
1407 |
1408 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=d9d52e4f
2 | build.xml.script.CRC32=57187d24
3 | build.xml.stylesheet.CRC32=8064a381@1.68.1.46
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=d9d52e4f
7 | nbproject/build-impl.xml.script.CRC32=a271bca2
8 | nbproject/build-impl.xml.stylesheet.CRC32=5a01deb7@1.68.1.46
9 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/nbproject/private/config.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adolfintel/voicechat/10878e2beb334ff863f66914f3b2852c72c0d410/VoiceChat_Comm/nbproject/private/config.properties
--------------------------------------------------------------------------------
/VoiceChat_Comm/nbproject/private/private.properties:
--------------------------------------------------------------------------------
1 | compile.on.save=true
2 | do.depend=false
3 | do.jar=true
4 | javac.debug=true
5 | javadoc.preview=true
6 | user.properties.file=C:\\Users\\dosse\\AppData\\Roaming\\NetBeans\\7.4\\build.properties
7 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/nbproject/private/private.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | annotation.processing.enabled=true
2 | annotation.processing.enabled.in.editor=false
3 | annotation.processing.processors.list=
4 | annotation.processing.run.all.processors=true
5 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
6 | application.title=VoiceChat_Comm
7 | application.vendor=dosse
8 | build.classes.dir=${build.dir}/classes
9 | build.classes.excludes=**/*.java,**/*.form
10 | # This directory is removed when the project is cleaned:
11 | build.dir=build
12 | build.generated.dir=${build.dir}/generated
13 | build.generated.sources.dir=${build.dir}/generated-sources
14 | # Only compile against the classpath explicitly listed here:
15 | build.sysclasspath=ignore
16 | build.test.classes.dir=${build.dir}/test/classes
17 | build.test.results.dir=${build.dir}/test/results
18 | # Uncomment to specify the preferred debugger connection transport:
19 | #debug.transport=dt_socket
20 | debug.classpath=\
21 | ${run.classpath}
22 | debug.test.classpath=\
23 | ${run.test.classpath}
24 | # This directory is removed when the project is cleaned:
25 | dist.dir=dist
26 | dist.jar=${dist.dir}/VoiceChat_Comm.jar
27 | dist.javadoc.dir=${dist.dir}/javadoc
28 | endorsed.classpath=
29 | excludes=
30 | includes=**
31 | jar.archive.disabled=${jnlp.enabled}
32 | jar.compress=false
33 | jar.index=${jnlp.enabled}
34 | javac.classpath=
35 | # Space-separated list of extra javac options
36 | javac.compilerargs=
37 | javac.deprecation=false
38 | javac.processorpath=\
39 | ${javac.classpath}
40 | javac.source=1.7
41 | javac.target=1.7
42 | javac.test.classpath=\
43 | ${javac.classpath}:\
44 | ${build.classes.dir}
45 | javac.test.processorpath=\
46 | ${javac.test.classpath}
47 | javadoc.additionalparam=
48 | javadoc.author=false
49 | javadoc.encoding=${source.encoding}
50 | javadoc.noindex=false
51 | javadoc.nonavbar=false
52 | javadoc.notree=false
53 | javadoc.private=false
54 | javadoc.splitindex=true
55 | javadoc.use=true
56 | javadoc.version=false
57 | javadoc.windowtitle=
58 | jnlp.codebase.type=no.codebase
59 | jnlp.descriptor=application
60 | jnlp.enabled=false
61 | jnlp.mixed.code=default
62 | jnlp.offline-allowed=false
63 | jnlp.signed=false
64 | jnlp.signing=
65 | jnlp.signing.alias=
66 | jnlp.signing.keystore=
67 | main.class=ErrorMessage
68 | manifest.file=manifest.mf
69 | meta.inf.dir=${src.dir}/META-INF
70 | mkdist.disabled=false
71 | platform.active=default_platform
72 | run.classpath=\
73 | ${javac.classpath}:\
74 | ${build.classes.dir}
75 | # Space-separated list of JVM arguments used when running the project
76 | # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
77 | # or test-sys-prop.name=value to set system properties for unit tests):
78 | run.jvmargs=
79 | run.test.classpath=\
80 | ${javac.test.classpath}:\
81 | ${build.test.classes.dir}
82 | source.encoding=UTF-8
83 | src.dir=src
84 | test.src.dir=test
85 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.java.j2seproject
4 |
5 |
6 | VoiceChat_Comm
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/src/ErrorMessage.java:
--------------------------------------------------------------------------------
1 |
2 | import javax.swing.JOptionPane;
3 |
4 | /*
5 | * To change this template, choose Tools | Templates
6 | * and open the template in the editor.
7 | */
8 |
9 | /**
10 | *
11 | * @author dosse
12 | */
13 | public class ErrorMessage {
14 | public static void main(String args[]){
15 | JOptionPane.showMessageDialog(new JOptionPane(),"This is a library, not a program.\nPlease run VoiceChat_Server or VoiceChat_Client");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/src/Message.java:
--------------------------------------------------------------------------------
1 |
2 | import java.io.Serializable;
3 |
4 | /*
5 | * To change this template, choose Tools | Templates
6 | * and open the template in the editor.
7 | */
8 |
9 | /**
10 | * container for any type of object to be sent
11 | * @author dosse
12 | */
13 | public class Message implements Serializable{
14 | private long chId; //-1 means from client to server, otherwise chId generated by the server
15 | private long timestamp, //-1 means from client to server, otherwise timeStamp of the moment when the server receives the message
16 | ttl=2000; //2 seconds TTL
17 | private Object data; //can carry any type of object. in this program, i used a sound packet, but it could be a string, a chunk of video, ...
18 |
19 |
20 | public Message(long chId, long timestamp, Object data) {
21 | this.chId = chId;
22 | this.timestamp = timestamp;
23 | this.data = data;
24 | }
25 |
26 | public void setTimestamp(long timestamp) {
27 | this.timestamp = timestamp;
28 | }
29 |
30 | public long getChId() {
31 | return chId;
32 | }
33 |
34 | public Object getData() {
35 | return data;
36 | }
37 |
38 | public long getTimestamp() {
39 | return timestamp;
40 | }
41 |
42 | public long getTtl() {
43 | return ttl;
44 | }
45 | public void setTtl(long ttl) {
46 | this.ttl = ttl;
47 | }
48 |
49 | public void setChId(long chId) {
50 | this.chId = chId;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/src/SoundPacket.java:
--------------------------------------------------------------------------------
1 |
2 | import java.io.Serializable;
3 | import javax.sound.sampled.AudioFormat;
4 |
5 | /*
6 | * To change this template, choose Tools | Templates
7 | * and open the template in the editor.
8 | */
9 |
10 | /**
11 | * some sound
12 | * @author dosse
13 | */
14 | public class SoundPacket implements Serializable{
15 | public static AudioFormat defaultFormat=new AudioFormat(11025f, 8, 1, true, true); //11.025khz, 8bit, mono, signed, big endian (changes nothing in 8 bit) ~8kb/s
16 | public static int defaultDataLenght=1200; //send 1200 samples/packet by default
17 | private byte[] data; //actual data. if null, comfort noise will be played
18 |
19 | public SoundPacket(byte[] data) {
20 | this.data = data;
21 | }
22 |
23 | public byte[] getData() {
24 | return data;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/VoiceChat_Comm/src/Utils.java:
--------------------------------------------------------------------------------
1 |
2 | import java.io.BufferedReader;
3 | import java.io.InputStreamReader;
4 | import java.net.InetAddress;
5 | import java.net.URL;
6 | import java.net.UnknownHostException;
7 |
8 |
9 |
10 | /*
11 | * To change this template, choose Tools | Templates
12 | * and open the template in the editor.
13 | */
14 |
15 | /**
16 | * contains some static methods used here and there in the code
17 | * @author dosse
18 | */
19 | public class Utils {
20 | public static void sleep(int ms){
21 | try {Thread.sleep(ms);} catch (InterruptedException ex) {}
22 | }
23 | public static String getExternalIP(){
24 | try {
25 | URL myIp=new URL("http://checkip.dyndns.org/");
26 | BufferedReader in=new BufferedReader(new InputStreamReader(myIp.openStream()));
27 | String s=in.readLine();
28 | return s.substring(s.lastIndexOf(":")+2,s.lastIndexOf("