package com.frinika.codeexamples;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.List;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Soundbank;
import javax.sound.midi.MidiDevice.Info;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import uk.org.toot.audio.core.AudioBuffer;
import uk.org.toot.audio.core.AudioProcess;
import uk.org.toot.audio.server.AudioClient;
import uk.org.toot.audio.server.AudioServer;
import uk.org.toot.audio.server.AudioServerConfiguration;
import uk.org.toot.audio.server.AudioServerServices;
import uk.org.toot.audio.server.IOAudioProcess;
import uk.org.toot.audio.server.MultiIOJavaSoundAudioServer;
import uk.org.toot.swingui.audioui.serverui.AudioServerUIServices;
import com.sun.media.sound.AudioSynthesizer;
/**
* Use the toot audio system for a low latency midi keyboard --> Gervill setup
* Hardwired for a virtual piano
*
*/
public class PlaySynth {
static AudioServer server;
private static AudioServerConfiguration serverConfig;
public static void main(String[] args) throws Exception {
// open the audio server.
server = new MultiIOJavaSoundAudioServer();
final AudioBuffer buff = server.createAudioBuffer("BUFF");
List<String> list = server.getAvailableOutputNames();
Object a[] = new Object[list.size()];
a = list.toArray(a);
Object selectedValue = JOptionPane.showInputDialog(null,
"Select audio output", "Please", JOptionPane.INFORMATION_MESSAGE,
null, a, a[0]);
final IOAudioProcess out = server.openAudioOutput((String) selectedValue,
"output");
// find the Gervill
Info infodev[] = MidiSystem.getMidiDeviceInfo();
Info synthInfo = null;
for (Info info : infodev) {
System.out.println(info);
if (info.getName().equals("Gervill")) {
synthInfo = info;
break;
}
}
MidiDevice outDev = MidiSystem.getMidiDevice(synthInfo);
AudioSynthesizer audosynth = (AudioSynthesizer) outDev;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
MidiDevice dev = null;
for (int i = 0; i < infos.length; i++) {
System.out.println(infos[i].getName());
}
for (int i = 0; i < infos.length; i++) {
// System.out.println(infos[i].getName());
// if (infos[i].getName().equals("SL [hw:1,0]"))
if (infos[i].getName().equals("CP300 [hw:2,0]"))
// if(infos[i].getName().equals("MIDI Yoke NT: 1"))
{
MidiDevice.Info rtinfo = infos[i];
dev = MidiSystem.getMidiDevice(rtinfo);
if (dev.getMaxTransmitters() != 0)
break;
dev = null;
}
}
if (dev == null) return;
dev.open();
final AudioProcess synthVoice = createSynthAudioProcess(audosynth);
// Connect the synth audio directly to the output
AudioClient client = new AudioClient() {
public void setEnabled(boolean arg0) {
}
public void work(int arg0) {
synthVoice.processAudio(buff);
out.processAudio(buff);
}
};
// Load a sound font
// Connect synth to the midi input
Receiver du = audosynth.getReceiver();
dev.getTransmitter().setReceiver(new FilterReceiver(du));
// start the audio server
server.setClient(client);
server.start();
serverConfig = AudioServerServices
.createServerConfiguration(server);
configure();
System.out.println("Is active, press enter to stop");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
System.out.println("Stop...");
dev.close();
audosynth.close();
System.exit(0);
}
static class FilterReceiver implements Receiver {
protected Receiver chained;
public FilterReceiver(Receiver chained) {
this.chained = chained;
}
public void send(MidiMessage mess, long timeStamp) {
if (mess.getStatus() >= ShortMessage.MIDI_TIME_CODE) {
// System.out.println(mess + " " + mess.getStatus() );
return;
}
// make time stamp -1 (otherwise bad timing)
if (mess instanceof ShortMessage) {
ShortMessage shm = (ShortMessage) mess;
int cmd = shm.getCommand();
if (cmd != 240) {
int chn = shm.getChannel();
int dat1 = shm.getData1();
int dat2 = shm.getData2();
System.out.println(" cmd:" + cmd + " chn:" + chn + " data:"
+ dat1 + " " + dat2);
}
}
chained.send(mess, -1);
}
public void close() {
chained.close();
}
}
// Wrap the synth output in a AudioProcess
static AudioProcess createSynthAudioProcess(AudioSynthesizer audosynth)
throws MidiUnavailableException {
AudioFormat.Encoding PCM_FLOAT = new AudioFormat.Encoding("PCM_FLOAT");
AudioFormat format = new AudioFormat(PCM_FLOAT, 44100, 32, 2, 4 * 2,
44100, ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN));
final AudioInputStream ais = audosynth.openStream(format, null);
System.out.println("PCM_FLOAT Encoding used!");
final AudioProcess synthVoice = new AudioProcess() {
byte[] streamBuffer = null;
float[] floatArray = null;
FloatBuffer floatBuffer = null;
public void close() {
}
public void open() {
}
public int processAudio(AudioBuffer buffer) {
if (buffer == null)
return 0;
if (streamBuffer == null
|| streamBuffer.length != buffer.getSampleCount() * 8) {
ByteBuffer bytebuffer = ByteBuffer.allocate(
buffer.getSampleCount() * 8).order(
ByteOrder.nativeOrder());
streamBuffer = bytebuffer.array();
floatArray = new float[buffer.getSampleCount() * 2];
floatBuffer = bytebuffer.asFloatBuffer();
}
try {
ais.read(streamBuffer, 0, buffer.getSampleCount() * 8);
} catch (IOException e) {
e.printStackTrace();
}
floatBuffer.position(0);
floatBuffer.get(floatArray);
float[] left = buffer.getChannel(0);
float[] right = buffer.getChannel(1);
for (int n = 0; n < buffer.getSampleCount() * 2; n += 2) {
left[n / 2] = floatArray[n];
right[n / 2] = floatArray[n + 1];
}
return AUDIO_OK;
}
};
return synthVoice;
}
static JFrame configureFrame;
/**
*
* Allow user to play with server parameters.
*
*/
public static void configure() {
if (configureFrame != null) {
configureFrame.setVisible(true);
return;
}
final JComponent ui = AudioServerUIServices.createServerUI(server,
serverConfig);
if (ui == null)
return; // no server ui
configureFrame = new JFrame();
configureFrame.setAlwaysOnTop(true);
configureFrame.setContentPane(ui);
configureFrame.pack();
configureFrame.setVisible(true);
}
}