Hello all.
The following lines of code aiming to use a midi synthesizer in order to have it play random notes.
If i use this code routing midi to any hardware port, it works fine.
If i use it to route midi to "Java Software Synthesizer" device, i can only use one (out of 16) midi channels of this device: should i attempt to concurrently use any second (or third) channel, the program breaks, and i am getting the following error:
"Invalid memory access of location 0x22795d32c rip=0x7fffffe00eca"
Please note the lines that start with "new Player".
Commenting all of them (except one), results in sending midi to one channel only - thus, no problem.
Un-commenting two lines, thus evoking a second "player" causes the error.
I tried it on Snow Leopard and on Windows, it gives a similar "invalid memory" error.
I fear that all this trouble has to do with my less-than-perfect knowledge on threading, so i would appreciate any help.
Kind Regards,
Panos
The code:
-----------------------------------------
Code:
import java.util.*;
import javax.sound.midi.*;
class Tester {
public static void main (String[] args) {
// Discover Connected Midi Devices - Start
System.out.println("\n");
System.out.println("List Of Midi Devices Available:");
System.out.println("-------------------------------");
MidiDevice.Info[] mididevices = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info deviceInfo : mididevices)
{
System.out.println("Device Name : " + deviceInfo.getName());
System.out.println("Device Description : " + deviceInfo.getDescription() + "\n");
}
// Discover Connected Midi Devices - End
try
{
MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info deviceInfo : devices) {
//System.out.println("Name : " + deviceInfo.getName());
//System.out.println("Vendor : " + deviceInfo.getVendor());
//System.out.println("Version : " + deviceInfo.getVersion());
//System.out.println("Description : " + deviceInfo.getDescription());
//System.out.println("\n");
}
new Player("4").start();
new Player("1").start();
//new Player("2").start();
//new Player("3").start();
}
catch (Exception e)
{
System.out.println("Something failed !!!");
}
}
}
class intRand {
public static int get (int[] array) {
Random generator = new Random();
int rnd = generator.nextInt(array.length);
return array[rnd];
}
}
class stringRand {
public static String get (String[] array) {
Random generator = new Random();
int rnd = generator.nextInt(array.length);
return array[rnd];
}
}
class Player extends Thread {
public Player(String str) {
super(str);
}
public void run() {
String selectedChannel = getName();
int midiChannel = Integer.parseInt(selectedChannel);
try
{
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
int numInfos = infos.length;
MidiDevice.Info deviceInfo = null;
for (int i = 0; i < numInfos; i++)
{
if (infos[i].getName().equals("Java Sound Synthesizer")) { deviceInfo = infos[i]; }
}
MidiDevice outputDevice =
MidiSystem.getMidiDevice(deviceInfo);
outputDevice.open();
ShortMessage sm = new ShortMessage();
Receiver receiver = outputDevice.getReceiver();
int sequenceSteps = 200;
int[] selectedNotes = { 70 , 80 , 75 , 67 , 51 };
int[] selectedDurations = { 100, 300, 625, 1250, 5000 };
int[] selectedVelocities = { 75 , 85 };
int[] selectedPauses = { 100, 300, 625, 1250, 5000 };
for (int i = 1; i < sequenceSteps+1; i++)
{
int n = intRand.get(selectedNotes);
int d = intRand.get(selectedDurations);
int v = intRand.get(selectedVelocities);
int p = intRand.get(selectedPauses);
// Report
System.out.println("Midi : " + (midiChannel+1) + ". Step : " + i + ". Note : " + n + ". Duration : " + d + ". Velocity : " + v + ".");
sm.setMessage(ShortMessage.NOTE_ON, midiChannel, n, v); receiver.send(sm, -1);
if (i < sequenceSteps) { Thread.sleep(d); }
if (i == sequenceSteps) { Thread.sleep(10000); }
sm.setMessage(ShortMessage.NOTE_OFF, midiChannel, n, v); receiver.send(sm, -1);
sleep(p);
}
outputDevice.close();
}
catch (Exception e)
{
System.out.println("Something failed !!!");
}
}
}