3
#include "org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI.h"
5
//#include <CoreServices/CoreServices.h> //for file stuff
6
#include <AudioUnit/AudioUnit.h>
7
#include <AudioToolbox/AudioToolbox.h> //for AUGraph
11
// ------------------------------------------------------------------------------------------------
13
// This call creates the Graph and the Synth unit...
14
OSStatus CreateAUGraph (AUGraph& outGraph, AudioUnit& outSynth)
17
//create the nodes of the graph
18
AUNode synthNode, limiterNode, outNode;
20
ComponentDescription cd;
21
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
22
cd.componentFlags = 0;
23
cd.componentFlagsMask = 0;
25
require_noerr (result = NewAUGraph (&outGraph), home);
27
cd.componentType = kAudioUnitType_MusicDevice;
28
cd.componentSubType = kAudioUnitSubType_DLSSynth;
30
require_noerr (result = AUGraphNewNode (outGraph, &cd, 0, NULL, &synthNode), home);
32
cd.componentType = kAudioUnitType_Effect;
33
cd.componentSubType = kAudioUnitSubType_PeakLimiter;
35
require_noerr (result = AUGraphNewNode (outGraph, &cd, 0, NULL, &limiterNode), home);
37
cd.componentType = kAudioUnitType_Output;
38
cd.componentSubType = kAudioUnitSubType_DefaultOutput;
39
require_noerr (result = AUGraphNewNode (outGraph, &cd, 0, NULL, &outNode), home);
41
require_noerr (result = AUGraphOpen (outGraph), home);
43
require_noerr (result = AUGraphConnectNodeInput (outGraph, synthNode, 0, limiterNode, 0), home);
44
require_noerr (result = AUGraphConnectNodeInput (outGraph, limiterNode, 0, outNode, 0), home);
46
// ok we're good to go - get the Synth Unit...
47
require_noerr (result = AUGraphGetNodeInfo(outGraph, synthNode, 0, 0, 0, &outSynth), home);
53
OSStatus PathToFSSpec(const char *filename, FSSpec &outSpec)
57
require_noerr (result = FSPathMakeRef ((const UInt8*)filename, &fsRef, 0), home);
58
require_noerr (result = FSGetCatalogInfo(&fsRef, kFSCatInfoNone, NULL, NULL, &outSpec, NULL), home);
65
// some MIDI constants:
67
kMidiMessage_ControlChange = 0xB,
68
kMidiMessage_ProgramChange = 0xC,
69
kMidiMessage_PitchBend = 0xE,
70
kMidiMessage_BankMSBControl = 0,
71
kMidiMessage_BankLSBControl = 32,
72
kMidiMessage_NoteOn = 0x9
78
//UInt8 midiChannelInUse = 0; //we're using midi channel 1...
84
const int midiChannelInUse = 0;
86
require_noerr (result = CreateAUGraph (graph, synthUnit), home);
88
// initialize and start the graph
89
require_noerr (result = AUGraphInitialize (graph), home);
93
require_noerr (result = MusicDeviceMIDIEvent(synthUnit,
94
kMidiMessage_ControlChange << 4 | midiChannelInUse,
95
kMidiMessage_BankMSBControl, 0,
96
0/*sample offset*/), home);
98
require_noerr (result = MusicDeviceMIDIEvent(synthUnit,
99
kMidiMessage_ProgramChange << 4 | midiChannelInUse,
100
0/*prog change num*/, 0,
101
0/*sample offset*/), home);
103
require_noerr (result = AUGraphStart (graph), home);
112
AUGraphStop (graph); // stop playback - AUGraphDispose will do that for us but just showing you what to do
113
DisposeAUGraph (graph);
117
void programChange(int channel, int instrument)
120
UInt32 progamChange = kMidiMessage_ProgramChange << 4 | channel;
122
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, progamChange, instrument, 0, 0), home);
128
void controlChange(int channel, int controller, int value)
130
// ignore these values, they mess up playback. i have no idea why TuxGuitar sends them or what they are supposed to do.
131
if(controller==100 or controller==101)
137
UInt32 controlChange = kMidiMessage_ControlChange << 4 | channel;
139
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, controlChange, controller, value, 0), home);
145
void pitchBend(int channel, short value)
147
value+=(short)0x2000; // center value
148
unsigned char byte1=(unsigned char)(value & 0x7f); // 7 bit bytes
149
unsigned char byte2=(unsigned char)( (value >> 7 ) & 0x7f );
152
UInt32 pitchChange = kMidiMessage_PitchBend << 4 | channel;
154
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, pitchChange, byte1, byte2, 0), home);
160
void noteOn(int pitchID, int volume, int channel)
163
UInt32 noteOnCommand = kMidiMessage_NoteOn << 4 | channel;
166
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, pitchID, volume, 0), home);
173
void noteOff(int pitchID, int volume, int channel)
177
UInt32 noteOffCommand = kMidiMessage_NoteOn << 4 | channel;
180
require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOffCommand, pitchID, 0, 0), home);
186
/* -------------------------------------------------------------------------------------------------------------------------------- */
190
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_open(JNIEnv* env, jobject obj)
196
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_close(JNIEnv* env, jobject obj)
201
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_findDevices(JNIEnv* env, jobject obj)
204
jstring name = env->NewStringUTF( "CoreAudio midi playback");
206
//Add a new MidiDevice to the java class
207
jclass cl = env->GetObjectClass( obj);
208
jmethodID mid = env->GetMethodID( cl, "addDevice", "(Ljava/lang/String;II)V");
210
env->CallVoidMethod( obj, mid,name,client,port);
215
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_openDevice(JNIEnv* env, jobject obj)
220
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_closeDevice(JNIEnv* env, jobject obj)
225
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_noteOn(JNIEnv* env, jobject ojb, jint channel, jint note, jint velocity)
228
noteOn(note, velocity, channel);
231
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_noteOff(JNIEnv* env, jobject ojb, jint channel, jint note, jint velocity)
233
noteOff(note, velocity, channel);
236
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_programChange(JNIEnv* env, jobject ojb, jint channel, jint program)
238
programChange(channel, program);
241
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_controlChange(JNIEnv* env, jobject ojb, jint channel, jint control, jint value)
243
controlChange(channel, control, value);
246
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_pitchBend(JNIEnv* env, jobject ojb, jint channel, jint value)
248
pitchBend(channel, ((value * 127) - 8191));