package com.tlabs.labeltool;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Line;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Mixer.Info;
import javax.sound.sampled.TargetDataLine;
/**
* Thread for recording and sending to server.
*
* @version 1.0
* @author Felix Burkhardt
*/
public class RecordThread extends Thread {
/**
* Name of server's host.
*/
String servername;
/**
* Name of file to save the recording at server.
*/
String _fileName;
/**
* Line from Microphone.
*/
TargetDataLine _line;
/**
* Bytearray to send the recording in chunks.
*/
byte[] _data;
/**
* Stream to send data to server.
*/
java.io.DataOutputStream out;
/**
* Flag to control the recording.
*/
boolean record_flag = true;
/**
* Socket for server-connection.
*/
Socket s;
/**
* The format of the recording.
*/
AudioFormat _audioFormat;
Mixer _mixer;
/**
* Port where server listens.
*/
int portNum;
ByteArrayOutputStream _baos;
/**
* @param _audioFormat
* The audioformat.
* @param servername
* The name of the server's host.
* @param portNum
* The port where the server listens.
*/
public RecordThread(AudioFormat format, String servername, int portNum,
String fn) {
_audioFormat = format;
this.servername = servername;
this.portNum = portNum;
this._fileName = fn;
}
private void printMixers() {
try {
Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo();
int i = 0;
for (Mixer.Info info : mixerInfos) {
Mixer m = AudioSystem.getMixer(info);
String mixerName = m.getMixerInfo().getName();
System.out.println("mixer--" + mixerName);
if (i++ == 0) {
_mixer = m;
}
Line.Info[] lineInfos = m.getSourceLineInfo();
for (Line.Info lineInfo : lineInfos) {
System.out.println("source---" + lineInfo);
Line line = m.getLine(lineInfo);
System.out.println("\tsource-----" + line);
}
Line.Info[] lineInfos2 = m.getTargetLineInfo();
for (Line.Info lineInfo : lineInfos2) {
System.out.println("target---" + lineInfo);
Line line = m.getLine(lineInfo);
System.out.println("\ttarget-----" + line);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* called by thread.start()
*/
public void run() {
// open a connection
openConnection(Constants.MODE_RECORD);
// Send the fileName to the server.
try {
out.writeBytes(_fileName + '\n');
} catch (IOException e) {
System.out.println("unable to send data " + e);
e.printStackTrace();
}
// Get a line from the Microphone with the specified audioFormat.
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class,
_audioFormat);
if (!AudioSystem.isLineSupported(dataLineInfo)) {
Info mixerInfo = _mixer.getMixerInfo();
String mixerName = mixerInfo.getName();
System.err.println("\ninitRec: format not supported for "
+ mixerName + "\n");
}
try {
_line = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
// _line = (TargetDataLine) _mixer.getLine(dataLineInfo);
_line.open(_audioFormat, 2000);
} catch (Exception ex) {
String mixerName = _mixer.getMixerInfo().getName();
System.err.println("Rec: line unavailable for " + mixerName + "\n");
ex.printStackTrace();
}
// Init the byteArray with a size 1/5 of the line's buffer (recommended
// by sound-api doc)
_data = new byte[_line.getBufferSize() / 5];
record_flag = true;
System.out.println("Starte Aufnahme");
// Start line for recording.
_line.start();
_baos = new ByteArrayOutputStream();
while (record_flag) {
// While not stopped read data from line and send to server.
_line.read(_data, 0, _data.length);
try {
out.write(_data);
out.flush();
_baos.write(_data);
} catch (Exception e) {
if (record_flag) {
// problem, there still should be recording
// else thread tried to write when line already closed.
System.err.println("problem writing data: " + e);
e.printStackTrace();
}
}
}
}
/**
* Method to stop the recording. Should be called by the main class if the
* user pushes the stop-button.
*/
public void stopMe() {
record_flag = false;
try {
System.out.println("baos.size: " + _baos.toByteArray().length);
_line.close();
_line = null;
s.close();
openConnection(Constants.MODE_STOP);
try {
out.writeBytes(_fileName + '\n');
} catch (IOException e) {
System.err.println("unable to send data " + e);
e.printStackTrace();
}
} catch (Exception e) {
System.err.println("problem closing socket: " + e);
e.printStackTrace();
}
}
/**
* opens a socket and stream to the server and sends the mode-number.
*/
private void openConnection(int modus) {
try {
s = new Socket(servername, portNum);
System.out.println("Verbindung mit: " + s.getInetAddress());
out = new DataOutputStream(s.getOutputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + servername + ", "
+ e);
e.printStackTrace();
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to host: "
+ servername + ", " + e);
e.printStackTrace();
}
// send modus code to server
try {
out.writeInt(modus);
} catch (IOException e) {
System.out.println("problem sending modus code: " + e);
e.printStackTrace();
}
}
}