import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import javax.media.sound.midi.*;
public class ToySynth extends Frame
implements MouseListener {
static int VOLUME_CONTROLLER = 7;
static int PAN_CONTROLLER = 10;
static int EXPRESSION_CONTROLLER = 11;
static int SUSTAIN_CONTROLLER = 64;
static int REVERB_CONTROLLER = 90;
static int REVERB_LEVEL_CONTROLLER = 91;
Synthesizer synth = null;
Soundbank soundbank = null;
MidiChannel midiChannels[];
Instrument instruments[];
int transpose = 24;
int pan = 64;
int programNumber = 5;
int lastKeyNumber = 0;
int channelNumber = 0;
int velocity = 64;
Button setChannelButton = new Button("Set Channel");
Label instrumentLabel = new Label(" ");
Label velocityLabel = new Label("64 ");
Label pressureLabel = new Label("64 ");
Label bendLabel = new Label("64 ");
Label volLabel = new Label("100 ");
Label panLabel = new Label("64 ");
Label revLabel = new Label("64 ");
Scrollbar velocityScrollbar = null;
Scrollbar pressureScrollbar = null;
Scrollbar bendScrollbar = null;
Scrollbar volScrollbar = null;
Scrollbar panScrollbar = null;
Scrollbar revScrollbar = null;
Checkbox muteCheckbox = null;
Checkbox monoCheckbox = null;
Checkbox soloCheckbox = null;
Checkbox sustainCheckbox = null;
Button soundOffButton = null;
Button quitButton = null;
Button statusButton = null;
static Choice []instr = new Choice [8];
static Choice channelChoice;
Panel instrumentsPanel = new Panel();
Panel instrumentsPanel1 = new Panel();
Panel instrumentsPanel2 = new Panel();
Panel instrumentsPanel3 = new Panel();
Panel keyboardPanel = new Panel();
boolean singleNoteMode = true;
public ToySynth() {
// -----------------------------------------------
// create the Synthesizer and get our MidiChannels
// -----------------------------------------------
synth = MidiSystem.getSynthesizer(null);
if( synth == null ) {
System.out.println(
"Could not get default synthesizer");
System.exit(1);
}
// load the soundbank
try{
soundbank = synth.getDefaultSoundbank();
} catch (Exception e) {
System.out.println(
"Exception getting soundbank url: " + e);
System.exit(1);
}
// populate the instrument choice boxes
instruments = soundbank.getInstruments();
int index = 0;
for(int i=0; i<8; i++) {
instr[i] = new Choice();
for(int j=0; j<16; j++) {
instr[i].add( instruments[index].getName() );
index++;
}
}
// load the first instrument
synth.loadInstrument( instruments[0] );
midiChannels = synth.getChannels();
channelNumber = 0;
instrumentLabel.setText ( "Instrument: " +
instruments[midiChannels[
channelNumber].getProgram()].getName() );
// Make sure we can release our resources and
// exit cleanly.
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// --------------
// set up the GUI
// --------------
setLayout(new GridLayout(4, 1));
setBackground(Color.lightGray);
// keyboard panel
keyboardPanel.setLayout(null);
// absolutely no layout
// create the 6 octaves
for (int i = 0; i < 6; i++) {
// black key first
for (int j = 0; j < 6; j++) {
if (j == 2)
continue; // there's no E# in black
int keyOffset = 1;
switch(j) {
case 0:
keyOffset = 1; break;
case 1:
keyOffset = 3; break;
case 2:
System.out.println(
"Something's very Wrong!");
System.exit(1);
case 3:
keyOffset = 6; break;
case 4:
keyOffset = 8; break;
case 5:
keyOffset = 10; break;
}
pianoKey k =
new pianoKey(i*12 + keyOffset, false);
k.setBounds(X(i*28 + j*4 + 3),
Y(0), D(2), D(11));
k.addMouseListener(this);
keyboardPanel.add(k);
}
for (int j = 0; j < 7; j++) {
int keyOffset = 1;
switch(j) {
case 0:
keyOffset = 0; break;
case 1:
keyOffset = 2; break;
case 2:
keyOffset = 4; break;
case 3:
keyOffset = 5; break;
case 4:
keyOffset = 7; break;
case 5:
keyOffset = 9; break;
case 6:
keyOffset = 11; break;
}
int keyNumber = i*12 + keyOffset;
pianoKey k =
new pianoKey(i*12 + keyOffset, true);
k.setBounds(X(i*28 + j*4), Y(0), D(4), D(20));
k.addMouseListener(this);
keyboardPanel.add(k);
}
}
add(keyboardPanel);
// instruments panel
instrumentsPanel = new Panel(new GridLayout(3,1));
instrumentsPanel1 = new Panel(new FlowLayout());
instrumentsPanel2 = new Panel(new GridLayout(1,4));
instrumentsPanel3 = new Panel(new GridLayout(1,4));
for(int i=0; i<8; i++) {
instr[i].addItemListener(new programChange(this));
}
channelChoice = new Choice();
for(int i=0;i<16;i++) {
channelChoice.add(Integer.toString(i+1));
}
channelChoice.addItemListener(
new channelChange(this));
instrumentsPanel1.add(instrumentLabel);
instrumentsPanel1.add(new Label("Channel: "));
instrumentsPanel1.add(channelChoice);
instrumentsPanel2.add(instr[0]);
instrumentsPanel2.add(instr[1]);
instrumentsPanel2.add(instr[2]);
instrumentsPanel2.add(instr[3]);
instrumentsPanel3.add(instr[4]);
instrumentsPanel3.add(instr[5]);
instrumentsPanel3.add(instr[6]);
instrumentsPanel3.add(instr[7]);
instrumentsPanel.add(instrumentsPanel1);
instrumentsPanel.add(instrumentsPanel2);
instrumentsPanel.add(instrumentsPanel3);
instrumentsPanel.validate();
add(instrumentsPanel);
/////////////////////////////////////////////////////
Panel p = new Panel(new FlowLayout());
Panel p1 = new Panel(new FlowLayout());
velocityScrollbar =
new Scrollbar(Scrollbar.VERTICAL, -64, 1, -127, 0);
velocityScrollbar.addAdjustmentListener (
new AdjustmentListener() {
public void adjustmentValueChanged (
AdjustmentEvent e) {
velocity =
-((Scrollbar)e.getSource()).getValue ();
velocityLabel.setText(
Integer.toString(velocity) );
}
});
pressureScrollbar =
new Scrollbar(Scrollbar.VERTICAL, -64, 1, -127, 0);
pressureScrollbar.addAdjustmentListener (
new AdjustmentListener() {
public void adjustmentValueChanged (
AdjustmentEvent e) {
int pressure =
-((Scrollbar)e.getSource()).getValue ();
pressureLabel.setText(
Integer.toString(pressure) );
midiChannels[channelNumber].setChannelPressure(
pressure);
}
});
bendScrollbar =
new Scrollbar(Scrollbar.VERTICAL, -64, 1, -127, 0);
bendScrollbar.addAdjustmentListener (
new AdjustmentListener() {
public void adjustmentValueChanged (
AdjustmentEvent e) {
int bend =
-((Scrollbar)e.getSource()).getValue ();
bendLabel.setText( Integer.toString(bend) );
midiChannels[channelNumber].setPitchBend(bend);
}
});
volScrollbar = new Scrollbar(
Scrollbar.VERTICAL, -100, 1, -127, 0);
volScrollbar.addAdjustmentListener (
new AdjustmentListener() {
public void adjustmentValueChanged (
AdjustmentEvent e) {
int vol =
-((Scrollbar)e.getSource()).getValue ();
volLabel.setText( Integer.toString(vol) );
midiChannels[channelNumber].controlChange(
VOLUME_CONTROLLER,vol);
}
});
panScrollbar =
new Scrollbar(Scrollbar.VERTICAL, -64, 1, -127, 0);
panScrollbar.addAdjustmentListener (
new AdjustmentListener() {
public void adjustmentValueChanged (
AdjustmentEvent e) {
int pan =
-((Scrollbar)e.getSource()).getValue ();
panLabel.setText( Integer.toString(pan) );
midiChannels[channelNumber].controlChange(
PAN_CONTROLLER,pan);
}
});
revScrollbar =
new Scrollbar(Scrollbar.VERTICAL, -64, 1, -127, 0);
revScrollbar.addAdjustmentListener (
new AdjustmentListener() {
public void adjustmentValueChanged (
AdjustmentEvent e) {
int rev =
-((Scrollbar)e.getSource()).getValue ();
revLabel.setText( Integer.toString(rev) );
midiChannels[channelNumber].controlChange(
REVERB_LEVEL_CONTROLLER, rev);
}
});
muteCheckbox = new Checkbox ("Mute", false);
muteCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (muteCheckbox.getState()) {
midiChannels[channelNumber].setMute(true);
} else {
midiChannels[channelNumber].setMute(false);
}
}
});
monoCheckbox = new Checkbox ("Mono", false);
monoCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (monoCheckbox.getState()) {
midiChannels[channelNumber].setMono(true);
} else {
midiChannels[channelNumber].setMono(false);
}
}
});
soloCheckbox = new Checkbox ("Solo", false);
soloCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (soloCheckbox.getState()) {
midiChannels[channelNumber].setSolo(true);
} else {
midiChannels[channelNumber].setSolo(false);
}
}
});
sustainCheckbox = new Checkbox ("Sustain", false);
sustainCheckbox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (sustainCheckbox.getState())
midiChannels[channelNumber].controlChange(
SUSTAIN_CONTROLLER,127);
else
midiChannels[channelNumber].controlChange(
SUSTAIN_CONTROLLER,0);
}
});
soundOffButton = new Button("Sound OFF");
soundOffButton.setBackground(Color.yellow);
soundOffButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
for(int i=0;i<16;i++)
midiChannels[i].allNotesOff();
}
});
quitButton = new Button("QUIT");
quitButton.setBackground(Color.red);
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
statusButton = new Button("Status");
statusButton.setBackground(Color.lightGray);
statusButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
printStatus();
}
});
p.add(new Label("Ch Vol:"));
p.add(volScrollbar);
p.add(volLabel);
p.add(new Label("Ch Pan:"));
p.add(panScrollbar);
p.add(panLabel);
p.add(new Label("Ch Rev:"));
p.add(revScrollbar);
p.add(revLabel);
p.add(new Label("Ch Bend:"));
p.add(bendScrollbar);
p.add(bendLabel);
p.add(new Label("Vel:"));
p.add(velocityScrollbar);
p.add(velocityLabel);
p.add(new Label("Press:"));
p.add(pressureScrollbar);
p.add(pressureLabel);
p1.add(sustainCheckbox);
p1.add(muteCheckbox);
p1.add(monoCheckbox);
p1.add(soloCheckbox);
p1.add(statusButton);
p1.add(soundOffButton);
p1.add(quitButton);
add(p);
add(p1);
setTitle("General MIDI");
setSize(800, 400);
setVisible(true);
pack();
show();
updateGUIStatus();
} // end ToySynth()
final int xOffset = 40;
final int yOffset = 10;
int X (int x) {
return (x*4 + xOffset);
}
int Y (int x) {
return (x*4 + yOffset);
}
int D (int x) {
return (x*4);
}
public void updateGUIStatus() {
// update all the GUI fields to reflect the status
// of the current channel
// NOTE: THIS IS NOT FUNCTIONAL IN JAVA SOUND
// 0.85 EA RELEASE
//int temp;
//// volume
//temp =
midiChannels[channelNumber].getController(
VOLUME_CONTROLLER);
//volScrollbar.setValue( - temp );
//volLabel.setText( Integer.toString( temp ));
//// pan
//temp =
midiChannels[channelNumber].getController(
PAN_CONTROLLER);
//panScrollbar.setValue( - temp );
//panLabel.setText( Integer.toString( temp ));
//// pitch bend
//temp = midiChannels[channelNumber].getPitchBend();
//bendScrollbar.setValue( - temp );
//bendLabel.setText( Integer.toString( temp ));
//// reverb
//temp =
midiChannels[channelNumber].getController(
REVERB_LEVEL_CONTROLLER);
//revScrollbar.setValue( - temp );
//revLabel.setText( Integer.toString( temp ));
//// pressure
//temp =
//midiChannels[channelNumber].getChannelPressure();
//pressureScrollbar.setValue( - temp );
//pressureLabel.setText( Integer.toString( temp ));
//// mute
//muteCheckbox.setState(
midiChannels[channelNumber].getMute() );
//// sustain
//sustainCheckbox.setState(
midiChannels[channelNumber].getController(
SUSTAIN_CONTROLLER)==0 ? false : true );
//// mono
//monoCheckbox.setState(
midiChannels[channelNumber].getMono() );
//// solo
//soloCheckbox.setState(
midiChannels[channelNumber].getSolo() );
}
public void printStatus() {
System.out.println(
"CURRENT STATUS - note that some
functionality here is not");
System.out.println(
" implemented in Java
Sound 0.86");
System.out.println(" Current channel : " +
channelNumber);
System.out.println(" Program : " +
midiChannels[channelNumber].getProgram() );
System.out.println(" Channel volume : " +
midiChannels[channelNumber].getController(
VOLUME_CONTROLLER) );
System.out.println(" Channel pan : " +
midiChannels[channelNumber].getController(
PAN_CONTROLLER) );
System.out.println(" Channel bend : " +
midiChannels[channelNumber].getPitchBend() );
System.out.println(" Channel pressure : " +
midiChannels[channelNumber].getChannelPressure() );
System.out.println(" Channel reverb : " +
midiChannels[channelNumber].getController(
REVERB_CONTROLLER) );
System.out.println(" Channel reverb level: " +
midiChannels[channelNumber].getController(
REVERB_LEVEL_CONTROLLER) );
System.out.println(" Channel sustain : " +
midiChannels[channelNumber].getController(
SUSTAIN_CONTROLLER) );
System.out.println(" Channel mute : " +
midiChannels[channelNumber].getMute() );
System.out.println(" Channel mono : " +
midiChannels[channelNumber].getMono() );
System.out.println(" Channel solo : " +
midiChannels[channelNumber].getSolo() );
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
Component component = e.getComponent();
if ( ! (component instanceof Label) )
return;
int keyNumber =
((pianoKey) component).keyNumber + transpose;
if (singleNoteMode) {
lastKeyNumber = keyNumber;
midiChannels[channelNumber].noteOn(
keyNumber, velocity);
return;
}
}
public void mouseReleased(MouseEvent e) {
Component component = e.getComponent();
if ( ! (component instanceof Label) )
return;
if (singleNoteMode) {
midiChannels[channelNumber].noteOff(
lastKeyNumber, velocity);
return;
}
}
public void mouseEntered(MouseEvent e) {
//System.out.println(
// "mouseEntered event handler...");
}
public void mouseExited(MouseEvent e) {
//System.out.println("mouseExited event handler...");
}
// -------------------
// class programChange
// -------------------
class programChange implements ItemListener {
ToySynth ts = null;
public programChange( ToySynth ts ) {
this.ts = ts;
}
public void itemStateChanged(ItemEvent e) {
Object component = e.getSource();
if( ! (component instanceof Choice) ) return;
Choice c = (Choice)component;
int index=0;
if (c.equals(instr[0]))
index = 0 + c.getSelectedIndex();
else if (c.equals(instr[1]))
index = 16 + c.getSelectedIndex();
else if (c.equals(instr[2]))
index = 32 + c.getSelectedIndex();
else if (c.equals(instr[3]))
index = 48 + c.getSelectedIndex();
else if (c.equals(instr[4]))
index = 64 + c.getSelectedIndex();
else if (c.equals(instr[5]))
index = 80 + c.getSelectedIndex();
else if (c.equals(instr[6]))
index = 96 + c.getSelectedIndex();
else if (c.equals(instr[7]))
index = 112 + c.getSelectedIndex();
synth.loadInstrument( instruments[index] );
midiChannels[channelNumber].programChange(index);
instrumentLabel.setText ( "Instrument: " +
instruments[index].getName() );
ts.validate();
}
}
class channelChange implements ItemListener {
ToySynth ts;
public channelChange( ToySynth ts ) {
this.ts = ts;
}
public void itemStateChanged(ItemEvent e) {
Object component = e.getSource();
if( ! (component instanceof Choice) ) return;
Choice c = (Choice)component;
int newchannel = c.getSelectedIndex();
// update the channel
channelNumber = newchannel;
// update GUI fields for status of this channel
instrumentLabel.setText ( "Instrument: " +
instruments[midiChannels[
channelNumber].getProgram()].getName() );
ts.updateGUIStatus();
ts.validate();
}
}
// --------------
// class pianoKey
// --------------
class pianoKey extends Label {
public int keyNumber;
pianoKey(int keyNumber, boolean white) {
this.keyNumber = keyNumber;
if (white) {
setBackground(Color.white);
}
else
setBackground(Color.black);
}
public void paint (Graphics g) {
g.drawRect(0, 0, getSize().width - 1,
getSize().height -1 );
}
public void middleC(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int x = getSize().width / 2;
int y = getSize().height - getSize().height / 4;
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.blue);
g2.fillOval(x, y, 3, 3);
}
}
// ----
// MAIN
// ----
public static void main( String[] args) {
ToySynth ts = new ToySynth();
}
}
/*
* "@(#)ToySynth.java 1.6 99/04/22
*
* Copyright (c) 1999 Sun Microsystems, Inc. All
* Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive,
* royalty free, license to use, modify and
* redistribute this software in source and binary
* code form, provided that i) this copyright notice
* and license appear on all copies of the software;
* and ii) Licensee does not utilize the software in
* a manner which is disparaging to Sun.
*
* This software is provided "AS IS," without a
* warranty of any kind. ALL EXPRESS OR IMPLIED
* CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS
* LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING,
* MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS
* BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED
* AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING
* OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use
* in on-line control of aircraft, air traffic,
* aircraft navigation or aircraft communications; or
* in the design, construction, operation or
* maintenance of any nuclear facility. Licensee
* represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
|