Subversion Repositories svn.mios

Rev

Rev 657 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
628 adamjking 1
/*
2
 * @(#)MidiParameter.java   beta8   2006/04/23
3
 *
4
 * Copyright (C) 2008    Adam King (adamjking@optusnet.com.au)
5
 *
6
 * This application is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This application is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this application; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
 
21
package org.midibox.midi;
22
 
23
import java.util.Observable;
24
 
25
import javax.sound.midi.MidiMessage;
26
import javax.sound.midi.Receiver;
27
import javax.sound.midi.ShortMessage;
28
 
29
public class MidiParameter extends Observable implements Receiver {
30
 
31
    public final static int NOTE_OFF = ShortMessage.NOTE_OFF;
32
 
33
    public final static int NOTE_ON = ShortMessage.NOTE_ON;
34
 
35
    public final static int AFTERTOUCH = ShortMessage.POLY_PRESSURE;
36
 
37
    public final static int CONTROL_CHANGE = ShortMessage.CONTROL_CHANGE;
38
 
39
    public final static int PROGRAM_CHANGE = ShortMessage.PROGRAM_CHANGE;
40
 
41
    public final static int CHANNEL_PRESSURE = ShortMessage.CHANNEL_PRESSURE;
42
 
43
    public final static int PITCH_BEND = ShortMessage.PITCH_BEND;
44
 
45
    public final static Object STATUS = new Object();
46
 
47
    public final static Object CHANNEL = new Object();
48
 
49
    public final static Object NUMBER = new Object();
50
 
51
    public final static Object VALUE = new Object();
52
 
53
    public final static Object DEFAULT_VALUE = new Object();
54
 
55
    public final static Object LEARN = new Object();
56
 
57
    public final static Object HIGH_RESOLUTION = new Object();
58
 
59
    protected Receiver receiver;
60
 
61
    protected int channel;
62
 
63
    protected int status;
64
 
65
    protected int value;
66
 
67
    protected int number;
68
 
69
    protected int defaultValue;
70
 
71
    protected int type;
72
 
73
    protected boolean learn;
74
 
75
    protected boolean highResolution;
76
 
77
    public MidiParameter(Receiver receiver, int status, int channel,
78
            int number, int value, int defaultValue) {
79
        setReceiver(receiver);
80
        setMidiStatus(status);
81
        setMidiChannel(channel);
82
        setMidiNumber(number);
83
        setMidiValue(value, false);
84
        setHighResolution(false);
85
        setMidiDefaultValue(defaultValue);
86
    }
87
 
88
    public Receiver getReceiver() {
89
        return receiver;
90
    }
91
 
92
    protected void setReceiver(Receiver receiver) {
93
        this.receiver = receiver;
94
    }
95
 
96
    public int getMidiStatus() {
97
        return status;
98
    }
99
 
100
    public void setMidiStatus(int status) {
101
 
102
        this.status = status;
103
 
104
        setChanged();
105
        notifyObservers(STATUS);
106
        clearChanged();
107
    }
108
 
109
    public int getMidiChannel() {
110
        return channel;
111
    }
112
 
113
    public void setMidiChannel(int channel) {
114
 
115
        this.channel = channel;
116
 
117
        setChanged();
118
        notifyObservers(CHANNEL);
119
        clearChanged();
120
    }
121
 
122
    public int getMidiValue() {
123
        return value & getMidiMaxValue();
124
    }
125
 
126
    public void setMidiValue(int value, boolean forward) {
127
 
128
        this.value = value & getMidiMaxValue();
129
 
130
        if (forward) {
131
            createMessage();
132
        }
133
 
134
        setChanged();
135
        notifyObservers(VALUE);
136
        clearChanged();
137
    }
138
 
139
    public int getMidiMaxValue() {
140
 
141
        int currentStatus = getMidiStatus();
142
 
143
        if (currentStatus == PITCH_BEND
144
                || (currentStatus == CONTROL_CHANGE && highResolution)) {
145
            return 16383;
146
        } else {
147
            return 127;
148
        }
149
    }
150
 
151
    public String getMidiName() {
152
 
153
        if (status == NOTE_ON || status == NOTE_OFF) {
154
            return "Note " + MidiUtils.getKeyName(number);
155
        } else if (status == AFTERTOUCH) {
156
            return "Aftertouch " + MidiUtils.getKeyName(number);
157
        } else if (status == CONTROL_CHANGE) {
158
            if (highResolution) {
159
                return MidiUtils.cc14BitNames[number];
160
            } else {
161
                return MidiUtils.ccNames[number];
162
            }
163
        } else if (status == PROGRAM_CHANGE) {
164
            return "Program Change";
165
        } else if (status == CHANNEL_PRESSURE) {
166
            return "Channel Pressure";
167
        } else if (status == PITCH_BEND) {
168
            return "Pitch Bend";
169
        } else {
170
            return "undefined";
171
        }
172
    }
173
 
174
    public int getMidiNumber() {
175
        return number;
176
    }
177
 
178
    public void setMidiNumber(int number) {
179
        this.number = number;
180
 
181
        int currentStatus = getMidiStatus();
182
 
183
        setChanged();
184
        notifyObservers(NUMBER);
185
        clearChanged();
186
    }
187
 
188
    public boolean isLearn() {
189
        return learn;
190
    }
191
 
192
    public void setLearn(boolean learn) {
193
        this.learn = learn;
194
 
195
        setChanged();
196
        notifyObservers(LEARN);
197
        clearChanged();
198
    }
199
 
200
    public void createMessage() {
201
        ShortMessage message = new ShortMessage();
202
        if (receiver != null) {
203
            try {
204
 
205
                int data1 = 0;
206
                int data2 = 0;
207
 
208
                if (status == NOTE_ON || status == NOTE_OFF) {
209
                    data1 = number & 0x7F;
210
                    data2 = value & 0x7F;
211
                } else if (status == AFTERTOUCH) {
212
                    data1 = number & 0x7F;
213
                    data2 = value & 0x7F;
214
                } else if (status == CONTROL_CHANGE) {
215
 
216
                    if (highResolution
217
                            && ((number < 64) || (number < 102 && number > 97))) {
218
 
219
                        int msbNumber;
220
                        int lsbNumber;
221
 
222
                        if (number < 64) {
223
                            if (number < 32) {
224
                                msbNumber = number;
225
                                lsbNumber = number + 32;
226
                            } else {
227
                                msbNumber = number - 32;
228
                                lsbNumber = number;
229
                            }
230
                        } else {
231
                            if (number % 2 == 0) {
232
                                msbNumber = number + 1;
233
                                lsbNumber = number;
234
                            } else {
235
                                msbNumber = number;
236
                                lsbNumber = number - 1;
237
                            }
238
                        }
239
 
240
                        int lsbValue = (value) & 0x7F;
241
                        int msbValue = (value >> 7) & 0x7F;
242
 
243
                        message
244
                                .setMessage(status, channel, msbNumber,
245
                                        msbValue);
246
                        receiver.send(message, -1);
247
 
248
                        message = new ShortMessage();
249
 
250
                        message
251
                                .setMessage(status, channel, lsbNumber,
252
                                        lsbValue);
253
                        receiver.send(message, -1);
254
 
255
                        return;
256
                    } else {
257
                        data1 = number & 0x7F;
258
                        data2 = value & 0x7F;
259
                    }
260
                } else if (status == PROGRAM_CHANGE) {
261
                    data1 = value & 0x7F;
262
                    data2 = 0;
263
                } else if (status == CHANNEL_PRESSURE) {
264
                    data1 = value & 0x7F;
265
                    data2 = 0;
266
                } else if (status == PITCH_BEND) {
267
                    data1 = (value) & 0x7F;
268
                    data2 = (value >> 7) & 0x7F;
269
                }
270
 
271
                message.setMessage(status, channel, data1, data2);
272
                receiver.send(message, -1);
273
            } catch (Exception ex) {
274
                ex.printStackTrace();
275
            }
276
        }
277
    }
278
 
279
    protected void midiLearn(MidiMessage message) {
280
        if (message instanceof ShortMessage) {
281
 
282
            setMidiChannel(((ShortMessage) message).getChannel());
283
 
284
            int incomingStatus = ((ShortMessage) message).getCommand();
285
 
286
            if (incomingStatus == NOTE_OFF || incomingStatus == NOTE_ON) {
287
 
288
                setMidiStatus(NOTE_ON);
289
                setMidiNumber(((ShortMessage) message).getData1());
290
                setMidiDefaultValue(((ShortMessage) message).getData2());
291
 
292
            } else if (incomingStatus == AFTERTOUCH) {
293
 
294
                setMidiStatus(AFTERTOUCH);
295
                setMidiNumber(((ShortMessage) message).getData1());
296
                setMidiDefaultValue(((ShortMessage) message).getData2());
297
 
298
            } else if (incomingStatus == CONTROL_CHANGE) {
299
                setMidiStatus(CONTROL_CHANGE);
300
                setMidiNumber(((ShortMessage) message).getData1());
301
                if (highResolution
302
                        && ((number < 64) || (number < 102 && number > 97))) {
303
                    if (number < 64) {
304
                        if (number < 32) {
305
                            setMidiValue(
306
                                    ((ShortMessage) message).getData2() << 7,
307
                                    false);
308
                        } else {
309
                            setMidiValue(((ShortMessage) message).getData2(),
310
                                    false);
311
                        }
312
                    } else {
313
                        if (number % 2 == 0) {
314
                            setMidiValue(((ShortMessage) message).getData2(),
315
                                    false);
316
                        } else {
317
                            setMidiValue(
318
                                    ((ShortMessage) message).getData2() << 7,
319
                                    false);
320
                        }
321
                    }
322
                } else {
323
                    setMidiDefaultValue(((ShortMessage) message).getData2());
324
                }
325
            } else if (incomingStatus == PROGRAM_CHANGE) {
326
 
327
                setMidiStatus(PROGRAM_CHANGE);
328
                setMidiDefaultValue(((ShortMessage) message).getData1());
329
 
330
            } else if (incomingStatus == CHANNEL_PRESSURE) {
331
 
332
                setMidiStatus(CHANNEL_PRESSURE);
333
                setMidiDefaultValue(((ShortMessage) message).getData1());
334
 
335
            } else if (incomingStatus == PITCH_BEND) {
336
 
337
                setMidiStatus(PITCH_BEND);
338
                setMidiDefaultValue(((ShortMessage) message).getData1() & 0x7F
339
                        | (((ShortMessage) message).getData2() << 7));
340
 
341
            }
342
        }
343
    }
344
 
345
    public void send(MidiMessage message, long lTimeStamp) {
346
 
347
        if (isLearn()) {
348
            midiLearn(message);
349
            setLearn(false);
350
        } else {
351
            if (message instanceof ShortMessage) {
352
 
353
                if (channel == ((ShortMessage) message).getChannel()) {
354
 
355
                    int incomingStatus = ((ShortMessage) message).getCommand();
356
 
357
                    if ((incomingStatus == NOTE_OFF || incomingStatus == NOTE_ON)
358
                            && (status == NOTE_OFF || status == NOTE_ON)) {
359
                        if (number == ((ShortMessage) message).getData1()) {
360
                            setMidiValue(incomingStatus == NOTE_OFF ? 0
361
                                    : ((ShortMessage) message).getData2(),
362
                                    false);
363
                        }
364
                    } else if ((incomingStatus == AFTERTOUCH)
365
                            && (status == AFTERTOUCH)) {
366
                        if (number == ((ShortMessage) message).getData1()) {
367
                            setMidiValue(incomingStatus == NOTE_OFF ? 0
368
                                    : ((ShortMessage) message).getData2(),
369
                                    false);
370
                        }
371
                    } else if (incomingStatus == CONTROL_CHANGE
372
                            && status == CONTROL_CHANGE) {
373
 
374
                        int incomingNumber = ((ShortMessage) message)
375
                                .getData1();
376
                        int incomingValue = ((ShortMessage) message).getData2();
377
 
378
                        if (highResolution
379
                                && ((number < 64) || (number < 102 && number > 97))) {
380
 
381
                            if (number < 64) {
382
                                if (number < 32) {
383
                                    if (incomingNumber == number) {
384
                                        int newValue = value & 0x007F;
385
                                        newValue = newValue
386
                                                | incomingValue << 7;
387
                                        setMidiValue(newValue, false);
388
                                    } else if (incomingNumber == number + 32) {
389
                                        int newValue = value & 0x3F80;
390
                                        newValue = newValue | incomingValue;
391
                                        setMidiValue(newValue, false);
392
                                    }
393
                                } else {
394
                                    if (incomingNumber == number) {
395
                                        int newValue = value & 0x3F80;
396
                                        newValue = newValue | incomingValue;
397
                                        setMidiValue(newValue, false);
398
                                    } else if (incomingNumber == number - 32) {
399
                                        int newValue = value & 0x007F;
400
                                        newValue = newValue
401
                                                | incomingValue << 7;
402
                                        setMidiValue(newValue, false);
403
                                    }
404
                                }
405
                            } else {
406
                                if (number % 2 == 0) {
407
                                    if (incomingNumber == number + 1) {
408
                                        int newValue = value & 0x007F;
409
                                        newValue = newValue
410
                                                | incomingValue << 7;
411
                                        setMidiValue(newValue, false);
412
                                    } else if (incomingNumber == number) {
413
                                        int newValue = value & 0x3F80;
414
                                        newValue = newValue | incomingValue;
415
                                        setMidiValue(newValue, false);
416
                                    }
417
                                } else {
418
                                    if (incomingNumber == number - 1) {
419
                                        int newValue = value & 0x3F80;
420
                                        newValue = newValue | incomingValue;
421
                                        setMidiValue(newValue, false);
422
                                    } else if (incomingNumber == number) {
423
                                        int newValue = value & 0x007F;
424
                                        newValue = newValue
425
                                                | incomingValue << 7;
426
                                        setMidiValue(newValue, false);
427
                                    }
428
                                }
429
                            }
430
                        } else {
431
                            if (number == incomingNumber) {
432
                                setMidiValue(incomingValue, false);
433
                            }
434
                        }
435
                    } else if (incomingStatus == PROGRAM_CHANGE
436
                            && status == PROGRAM_CHANGE) {
437
                        setMidiValue(((ShortMessage) message).getData1(), false);
438
                    } else if (incomingStatus == CHANNEL_PRESSURE
439
                            && status == CHANNEL_PRESSURE) {
440
                        setMidiValue(((ShortMessage) message).getData1(), false);
441
                    } else if (incomingStatus == PITCH_BEND
442
                            && status == PITCH_BEND) {
443
                        setMidiValue(((ShortMessage) message).getData1() & 0x7F
444
                                | (((ShortMessage) message).getData2() << 7),
445
                                false);
446
                    }
447
                }
448
            }
449
        }
450
    }
451
 
452
    public int getMidiDefaultValue() {
453
        return defaultValue & getMidiMaxValue();
454
    }
455
 
456
    public void setMidiDefaultValue(int value) {
457
 
458
        this.defaultValue = value & getMidiMaxValue();
459
 
460
        setChanged();
461
        notifyObservers(DEFAULT_VALUE);
462
        clearChanged();
463
    }
464
 
465
    public void close() {
466
 
467
    }
468
 
469
    public boolean isHighResolution() {
470
        return highResolution;
471
    }
472
 
473
    public void setHighResolution(boolean highResolution) {
474
        this.highResolution = highResolution;
475
 
476
        setChanged();
477
        notifyObservers(HIGH_RESOLUTION);
478
        clearChanged();
479
    }
480
}