Skip to content

Instantly share code, notes, and snippets.

@mnd999
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mnd999/11140984 to your computer and use it in GitHub Desktop.
Save mnd999/11140984 to your computer and use it in GitHub Desktop.
80s Midi Synth
import javax.sound.midi.ShortMessage
import javax.sound.midi.Synthesizer
import javax.sound.midi.Receiver
import javax.sound.midi.MidiSystem
import javax.sound.midi.MidiChannel
import javax.sound.midi.MidiMessage
import scala.swing._
import scala.swing.event._
import scala.util.Random
import javax.sound.midi.Instrument
object EightysSynth extends SimpleSwingApplication {
val synth = MidiSystem.getSynthesizer()
val synthRcvr = synth.getReceiver()
synth.open()
playTune(List(62,62,64,62,67,65,0,
62, 62, 64, 62 ,69, 67, 0,
62, 62, 74, 71, 67, 65, 64, 0,
72, 72, 71,67, 69, 67))
def playNote(note : Integer, channel : Integer = 4) : Int = {
val myMsg = new ShortMessage();
// Play the note Middle C (60) moderately loud
// (velocity = 93)on channel 4 (zero-based).
myMsg.setMessage(ShortMessage.NOTE_ON, channel, note, 100)
val pitch = note
synthRcvr.send(myMsg, -1)
pitch
}
def stopNote(note: Integer, channel: Integer = 4) {
val sm3 = new ShortMessage()
sm3.setMessage(ShortMessage.NOTE_OFF, channel, note, 0)
synthRcvr.send(sm3, -1)
}
def playTune(notes : List[Integer] ) {
val t2 = new Thread( new Runnable {
def run() {
notes.foreach( note => {
playNote(note, 3)
Thread.sleep(500)
stopNote(note, 3)
})
}
} )
t2.start()
}
def top = new MainFrame {
contents = new BoxPanel(Orientation.Vertical) {
val combobox = new ComboBox(synth.getAvailableInstruments())
contents += new Label ("Uber Mega Piano from the 80s")
contents += combobox
listenTo(keys)
listenTo(combobox.selection)
listenTo(combobox.keys)
reactions += {
case KeyPressed(_, key, _, _) => {
playNote(keyToPitch(key))
}
case KeyReleased (_,key,_,_) => {
stopNote(keyToPitch(key))
}
case SelectionChanged(`combobox`) => {
val instr = combobox.selection.item
synth.loadInstrument(instr)
val sm2 = new ShortMessage( );
sm2.setMessage(ShortMessage.PROGRAM_CHANGE, 4, instr.getPatch().getProgram(), 0);
synthRcvr.send(sm2, -1)
requestFocus
//synth.getChannels()(4).programChange(instr.getPatch().getBank(), instr.getPatch().getProgram())
}
}
focusable = true
requestFocus
}
// Now even tuned
def keyToPitch(key: Key.Value): Int = key match {
case Key.Q => 53
case Key.Key2 => 54
case Key.W => 55
case Key.Key3 => 56
case Key.E => 57
case Key.Key4 => 58
case Key.R => 59
case Key.Key5 => 0
case Key.T => 60 // C
case Key.Key6 => 61
case Key.Y => 62 // D
case Key.Key7 => 63
case Key.U => 64 // E
case Key.Key8 => 0
case Key.I => 65 // F
case Key.Key9 => 66
case Key.O => 67 // G
case Key.Key0 => 68
case Key.P => 69 // A
case Key.Minus => 70
case Key.OpenBracket => 71 // B
case Key.CloseBracket => 72
case x => println(x); 50
}
}
}
@mnd999
Copy link
Author

mnd999 commented Jun 18, 2014

Updated to actually be in tune

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment