Subversion Repositories svn.mios

Compare Revisions

Ignore whitespace Rev 844 → Rev 845

/trunk/java/org/midibox/midi/gui/SysexSendReceiveGUI.java
34,6 → 34,7
import java.io.File;
import java.util.Observable;
import java.util.Observer;
import java.util.StringTokenizer;
 
import javax.swing.BorderFactory;
import javax.swing.JButton;
44,6 → 45,7
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JOptionPane;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
51,6 → 53,7
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import javax.swing.text.Segment;
 
import org.midibox.midi.MidiUtils;
import org.midibox.midi.SysexSendReceive;
80,7 → 83,7
 
private JTextPane sysexReceiveTextArea;
 
private JSpinner sendBufferSizeSpinner;
private JSpinner sendDelayTimeSpinner;
 
public SysexSendReceiveGUI(SysexSendReceive sysexSendReceive) {
super(new BorderLayout());
137,14 → 140,14
 
gbc.fill = GridBagConstraints.NONE;
 
JLabel label = new JLabel("Send Buffer Size (bytes): ");
JLabel label = new JLabel("Delay between F0 (ms): ");
controlButtonsPanel.add(label, gbc);
gbc.gridx++;
 
sendBufferSizeSpinner = new JSpinner(new SpinnerNumberModel(
sysexSendReceive.getSendBufferSize(), 1, 1000, 1));
sendBufferSizeSpinner.addChangeListener(this);
controlButtonsPanel.add(sendBufferSizeSpinner, gbc);
sendDelayTimeSpinner = new JSpinner(new SpinnerNumberModel(
sysexSendReceive.getSendDelayTime(), 1, 1000, 1));
sendDelayTimeSpinner.addChangeListener(this);
controlButtonsPanel.add(sendDelayTimeSpinner, gbc);
 
JPanel sendPanel = new JPanel(new GridBagLayout());
 
157,7 → 160,7
 
sysexSendTextArea = new JTextPane();
sysexSendTextArea.setBackground(Color.WHITE);
sysexSendTextArea.setEditable(false);
sysexSendTextArea.setEditable(true);
 
StyledDocument doc = sysexSendTextArea.getStyledDocument();
 
189,7 → 192,7
sysexReceiveTextArea = new JTextPane();
sysexReceiveTextArea.setBackground(Color.WHITE);
 
sysexReceiveTextArea.setEditable(false);
sysexReceiveTextArea.setEditable(true);
JScrollPane sysexReceiveTextAreaScrollPane = new JScrollPane(
sysexReceiveTextArea);
sysexReceiveTextAreaScrollPane
223,17 → 226,77
}
 
public void UIUpdate() {
boolean bUploading = (!sysexSendReceive.isCancelled() && !sysexSendReceive.isDone());
 
startButton.setEnabled(!bUploading);
browseButton.setEnabled(!bUploading);
sendDelayTimeSpinner.setEnabled(!bUploading);
stopButton.setEnabled(bUploading);
sysexSendTextArea.setEnabled(!bUploading);
sysexReceiveTextArea.setEnabled(!bUploading);
}
 
 
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "start") {
byte[] sysexData = new byte[sysexSendReceive.getSendBufferSize()];
int sysexDataOffset = 0;
 
StyledDocument doc = sysexSendTextArea.getStyledDocument();
int len = doc.getLength();
 
if( len > 0 ) {
int nleft = len;
Segment text = new Segment();
int offs = 0;
text.setPartialReturn(true);
while (nleft > 0) {
try {
doc.getText(offs, nleft, text);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error while parsing hex digits!", "Syntax Error", JOptionPane.ERROR_MESSAGE);
return;
}
 
StringTokenizer st = new StringTokenizer(text.toString());
while (st.hasMoreTokens()) {
int value;
 
try {
value = (int)java.lang.Integer.parseInt(st.nextToken(), 16);
sysexData[sysexDataOffset++] = (byte)value;
} catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Found invalid hexadecimal digit!", "Syntax Error", JOptionPane.ERROR_MESSAGE);
return;
}
}
 
nleft -= text.count;
offs += text.count;
}
 
if( sysexDataOffset > 0 ) {
final byte[] finalSysexData = sysexData;
final int finalSysexDataOffset = sysexDataOffset;
 
Thread t = new Thread() {
public void run() {
sysexSendReceive.startSend(finalSysexData, finalSysexDataOffset);
}
};
t.start();
}
}
 
} else if (e.getActionCommand() == "stop") {
sysexSendReceive.cancel();
 
} else if (e.getActionCommand() == "browse") {
onOpenSysexFile();
}
 
UIUpdate();
}
 
protected void onOpenSysexFile() {
264,12 → 327,20
 
public void stateChanged(ChangeEvent e) {
 
Object source = e.getSource();
 
if (source == sendDelayTimeSpinner) {
sysexSendReceive.setSendDelayTime(((Integer) sendDelayTimeSpinner.getValue()).intValue());
}
 
UIUpdate();
}
 
public void update(Observable observable, Object object) {
if (observable == sysexSendReceive) {
if (object == sysexSendReceive.getFile()) {
if (object == sysexSendReceive.WORKER ) {
} else if (object == sysexSendReceive.getFile()) {
fileName.setText(sysexSendReceive.getFile().getPath());
sysexSendTextArea.setText("");
StyledDocument doc = sysexSendTextArea.getStyledDocument();
try {
284,6 → 355,8
} else if (object == sysexSendReceive.getReceivedBytes()) {
 
}
 
UIUpdate();
}
}
 
/trunk/java/org/midibox/midi/SysexSendReceive.java
24,6 → 24,7
import java.util.LinkedList;
import java.util.Observable;
 
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.Receiver;
import javax.sound.midi.SysexMessage;
30,6 → 31,8
 
public class SysexSendReceive extends Observable implements Receiver {
 
public final static Object WORKER = new Object();
 
protected Receiver receiver;
 
protected File file;
42,12 → 45,19
 
protected int sendBufferSize;
 
protected int sendDelayTime;
 
protected LinkedList receivedBytes;
 
protected boolean done = true;
 
protected boolean cancelled = true;
 
public SysexSendReceive(Receiver receiver) {
super();
this.receiver = receiver;
sendBufferSize = 256;
sendBufferSize = 100000; // TK: shouldn't be changed by user since Java doesn't allow to split SysEx streams properly
sendDelayTime = 750; // delay between F0
receivedBytes = new LinkedList();
}
 
85,24 → 95,38
return sendBufferSize;
}
 
public void setSendBufferSize(int sendBufferSize) {
this.sendBufferSize = sendBufferSize;
public int getSendDelayTime() {
return sendDelayTime;
}
 
public void setSendDelayTime(int sendDelayTime) {
this.sendDelayTime = sendDelayTime;
}
 
public LinkedList getReceivedBytes() {
return receivedBytes;
}
 
public void send(MidiMessage message, long timestamp) {
if (message instanceof SysexMessage) {
receivedBytes.add(((SysexMessage) message).getData());
 
setChanged();
notifyObservers(receivedBytes);
clearChanged();
 
public boolean isDone() {
return done;
}
 
public boolean isCancelled() {
return cancelled;
}
 
public void cancel() {
synchronized (this) {
cancelled = true;
//addMessage("Process stopped by user");
notify(); // TK: finally the reason why threads where not informed
// about a cancel request and mixed the upload blocks!
}
}
 
 
public void close() {
 
}
117,4 → 141,84
 
}
}
 
 
public void send(MidiMessage message, long timestamp) {
if (!isCancelled() && !isDone()) {
if (message instanceof SysexMessage) {
receivedBytes.add(((SysexMessage) message).getData());
 
setChanged();
notifyObservers(receivedBytes);
clearChanged();
}
}
}
 
 
/////////////////////////////////////////////////////////////////////////////////
// SysEx File Sender Functions
/////////////////////////////////////////////////////////////////////////////////
 
 
public void startSend(byte[] sysexData, int sysexDataLen) {
int offset = 0;
 
cancelled = false;
done = false;
 
synchronized (this) {
 
while (!cancelled && !done && offset < sysexDataLen ) {
int sendLen = 1;
int i;
 
// update GUI
setChanged();
notifyObservers(WORKER);
clearChanged();
 
for(i=1; i<sendBufferSize && (i+offset)<sysexDataLen && sysexData[i+offset] != (byte)0xf0; ++i) {
++sendLen;
}
 
if( sendLen == 0 ) {
done = true;
break;
}
 
byte[] axSysExData = new byte[sendLen];
System.arraycopy(sysexData, offset, axSysExData, 0, sendLen);
 
try {
SysexMessage sysExMessage = new SysexMessage();
sysExMessage.setMessage(axSysExData, axSysExData.length);
receiver.send(sysExMessage, -1);
} catch (InvalidMidiDataException ex) {
cancelled = true;
System.out.println("Error: " + ex.getMessage());
break;
}
 
offset += sendLen;
 
if( offset < sysexDataLen ) {
try {
wait(sendDelayTime);
} catch (InterruptedException e) {
cancelled = true;
System.out.println("Error: SysEx task interrupted");
break;
}
} else {
done = true;
}
}
}
 
// update GUI
setChanged();
notifyObservers(WORKER);
clearChanged();
}
}