~ubuntu-branches/ubuntu/oneiric/tuxguitar/oneiric

« back to all changes in this revision

Viewing changes to TuxGuitar-CoreAudio/jni/org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Philippe Coval
  • Date: 2008-06-19 00:30:30 UTC
  • mto: (5.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20080619003030-h719szrhsngou7c6
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
 
 
3
#include "org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI.h"
 
4
 
 
5
//#include <CoreServices/CoreServices.h> //for file stuff
 
6
#include <AudioUnit/AudioUnit.h>
 
7
#include <AudioToolbox/AudioToolbox.h> //for AUGraph
 
8
 
 
9
//#include <iostream>
 
10
 
 
11
// ------------------------------------------------------------------------------------------------
 
12
 
 
13
// This call creates the Graph and the Synth unit...
 
14
OSStatus        CreateAUGraph (AUGraph& outGraph, AudioUnit& outSynth)
 
15
{
 
16
        OSStatus result;
 
17
        //create the nodes of the graph
 
18
        AUNode synthNode, limiterNode, outNode;
 
19
        
 
20
        ComponentDescription cd;
 
21
        cd.componentManufacturer = kAudioUnitManufacturer_Apple;
 
22
        cd.componentFlags = 0;
 
23
        cd.componentFlagsMask = 0;
 
24
        
 
25
        require_noerr (result = NewAUGraph (&outGraph), home);
 
26
        
 
27
        cd.componentType = kAudioUnitType_MusicDevice;
 
28
        cd.componentSubType = kAudioUnitSubType_DLSSynth;
 
29
        
 
30
        require_noerr (result = AUGraphNewNode (outGraph, &cd, 0, NULL, &synthNode), home);
 
31
        
 
32
        cd.componentType = kAudioUnitType_Effect;
 
33
        cd.componentSubType = kAudioUnitSubType_PeakLimiter;
 
34
        
 
35
        require_noerr (result = AUGraphNewNode (outGraph, &cd, 0, NULL, &limiterNode), home);
 
36
        
 
37
        cd.componentType = kAudioUnitType_Output;
 
38
        cd.componentSubType = kAudioUnitSubType_DefaultOutput;
 
39
        require_noerr (result = AUGraphNewNode (outGraph, &cd, 0, NULL, &outNode), home);
 
40
        
 
41
        require_noerr (result = AUGraphOpen (outGraph), home);
 
42
        
 
43
        require_noerr (result = AUGraphConnectNodeInput (outGraph, synthNode, 0, limiterNode, 0), home);
 
44
        require_noerr (result = AUGraphConnectNodeInput (outGraph, limiterNode, 0, outNode, 0), home);
 
45
        
 
46
        // ok we're good to go - get the Synth Unit...
 
47
        require_noerr (result = AUGraphGetNodeInfo(outGraph, synthNode, 0, 0, 0, &outSynth), home);
 
48
        
 
49
home:
 
50
                return result;
 
51
}
 
52
 
 
53
OSStatus PathToFSSpec(const char *filename, FSSpec &outSpec)
 
54
{
 
55
        FSRef fsRef;
 
56
        OSStatus result;
 
57
        require_noerr (result = FSPathMakeRef ((const UInt8*)filename, &fsRef, 0), home);
 
58
        require_noerr (result = FSGetCatalogInfo(&fsRef, kFSCatInfoNone, NULL, NULL, &outSpec, NULL), home);
 
59
        
 
60
home:
 
61
                return result;
 
62
}
 
63
 
 
64
 
 
65
// some MIDI constants:
 
66
enum {
 
67
        kMidiMessage_ControlChange              = 0xB,
 
68
        kMidiMessage_ProgramChange              = 0xC,
 
69
        kMidiMessage_PitchBend                  = 0xE,
 
70
        kMidiMessage_BankMSBControl     = 0,
 
71
        kMidiMessage_BankLSBControl             = 32,
 
72
        kMidiMessage_NoteOn                     = 0x9
 
73
};
 
74
 
 
75
AUGraph graph = 0;
 
76
AudioUnit synthUnit;
 
77
char* bankPath = 0;
 
78
//UInt8 midiChannelInUse = 0; //we're using midi channel 1...
 
79
 
 
80
void init()
 
81
{
 
82
        
 
83
        OSStatus result;
 
84
        const int midiChannelInUse = 0;
 
85
        
 
86
        require_noerr (result = CreateAUGraph (graph, synthUnit), home);
 
87
        
 
88
        // initialize and start the graph
 
89
        require_noerr (result = AUGraphInitialize (graph), home);
 
90
        
 
91
        
 
92
        //set our bank
 
93
        require_noerr (result = MusicDeviceMIDIEvent(synthUnit,
 
94
                                                                                                 kMidiMessage_ControlChange << 4 | midiChannelInUse,
 
95
                                                                                                 kMidiMessage_BankMSBControl, 0,
 
96
                                                                                                 0/*sample offset*/), home);
 
97
        
 
98
        require_noerr (result = MusicDeviceMIDIEvent(synthUnit,
 
99
                                                                                                 kMidiMessage_ProgramChange << 4 | midiChannelInUse,
 
100
                                                                                                 0/*prog change num*/, 0,
 
101
                                                                                                 0/*sample offset*/), home);
 
102
        
 
103
        require_noerr (result = AUGraphStart (graph), home);
 
104
home:
 
105
                return;
 
106
}
 
107
void free()
 
108
{
 
109
        
 
110
        if (graph)
 
111
        {
 
112
                AUGraphStop (graph); // stop playback - AUGraphDispose will do that for us but just showing you what to do
 
113
                DisposeAUGraph (graph);
 
114
        }
 
115
}
 
116
 
 
117
void programChange(int channel, int instrument)
 
118
{
 
119
        OSStatus result;
 
120
        UInt32 progamChange = kMidiMessage_ProgramChange << 4 | channel;
 
121
        
 
122
        require_noerr (result = MusicDeviceMIDIEvent(synthUnit, progamChange, instrument, 0, 0), home);
 
123
 
 
124
home:
 
125
        return;
 
126
}
 
127
 
 
128
void controlChange(int channel, int controller, int value)
 
129
{
 
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)
 
132
        {
 
133
                return;
 
134
        }
 
135
        
 
136
        OSStatus result;
 
137
        UInt32 controlChange = kMidiMessage_ControlChange << 4 | channel;
 
138
        
 
139
        require_noerr (result = MusicDeviceMIDIEvent(synthUnit, controlChange, controller, value, 0), home);
 
140
        
 
141
home:
 
142
                return;
 
143
}
 
144
 
 
145
void pitchBend(int channel, short value)
 
146
{
 
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 );
 
150
        
 
151
        OSStatus result;
 
152
        UInt32 pitchChange = kMidiMessage_PitchBend << 4 | channel;
 
153
        
 
154
        require_noerr (result = MusicDeviceMIDIEvent(synthUnit, pitchChange, byte1, byte2, 0), home);
 
155
        
 
156
home:
 
157
                return;
 
158
}
 
159
 
 
160
void noteOn(int pitchID, int volume, int channel)
 
161
{
 
162
        OSStatus result;
 
163
        UInt32 noteOnCommand =  kMidiMessage_NoteOn << 4 | channel;
 
164
        
 
165
        /* note on */
 
166
        require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, pitchID, volume, 0), home);
 
167
        
 
168
home:
 
169
                
 
170
                return;
 
171
}
 
172
 
 
173
void noteOff(int pitchID, int volume, int channel)
 
174
{
 
175
        
 
176
        OSStatus result;
 
177
        UInt32 noteOffCommand = kMidiMessage_NoteOn << 4 | channel;
 
178
        
 
179
        // note off
 
180
        require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOffCommand, pitchID, 0, 0), home);
 
181
        
 
182
home:
 
183
                return;
 
184
}
 
185
 
 
186
/* -------------------------------------------------------------------------------------------------------------------------------- */
 
187
 
 
188
/* open port */
 
189
 
 
190
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_open(JNIEnv* env, jobject obj)
 
191
{
 
192
        
 
193
}
 
194
                                        
 
195
/* close port */
 
196
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_close(JNIEnv* env, jobject obj)
 
197
{
 
198
 
 
199
}
 
200
/*                                       
 
201
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_findDevices(JNIEnv* env, jobject obj)
 
202
{       
 
203
        
 
204
        jstring name = env->NewStringUTF( "CoreAudio midi playback");
 
205
 
 
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");      
 
209
    if (mid != 0){
 
210
        env->CallVoidMethod( obj, mid,name,client,port);
 
211
    }                   
 
212
 
 
213
}
 
214
*/
 
215
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_openDevice(JNIEnv* env, jobject obj)
 
216
{       
 
217
        init();
 
218
}
 
219
 
 
220
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_closeDevice(JNIEnv* env, jobject obj)
 
221
{
 
222
        free();
 
223
}
 
224
 
 
225
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_noteOn(JNIEnv* env, jobject ojb, jint channel, jint note, jint velocity)
 
226
{               
 
227
 
 
228
        noteOn(note, velocity, channel);
 
229
}
 
230
 
 
231
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_noteOff(JNIEnv* env, jobject ojb, jint channel, jint note, jint velocity)
 
232
{
 
233
        noteOff(note, velocity, channel);
 
234
}
 
235
 
 
236
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_programChange(JNIEnv* env, jobject ojb, jint channel, jint program)
 
237
{
 
238
        programChange(channel, program);
 
239
}
 
240
 
 
241
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_controlChange(JNIEnv* env, jobject ojb, jint channel, jint control, jint value)
 
242
{
 
243
        controlChange(channel, control, value);
 
244
}
 
245
 
 
246
JNIEXPORT void JNICALL Java_org_herac_tuxguitar_player_impl_midiport_coreaudio_MidiReceiverJNI_pitchBend(JNIEnv* env, jobject ojb, jint channel, jint value)
 
247
{
 
248
        pitchBend(channel, ((value * 127) - 8191));
 
249
 
 
250
}