Skip to content

Instantly share code, notes, and snippets.

@mnd999
Last active August 29, 2015 14:00
Show Gist options
  • Select an option

  • Save mnd999/11140984 to your computer and use it in GitHub Desktop.

Select an option

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

mnd999 commented Jun 18, 2014

Copy link
Copy Markdown
Author

Updated to actually be in tune

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