Subversion Repositories svn.mios

Rev

Rev 628 | Rev 721 | Go to most recent revision | Details | Compare with Previous | 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
 
657 adamjking 151
    public int getMidiMinValue() {
152
 
153
        return 0;
154
    }
155
 
628 adamjking 156
    public String getMidiName() {
157
 
158
        if (status == NOTE_ON || status == NOTE_OFF) {
159
            return "Note " + MidiUtils.getKeyName(number);
160
        } else if (status == AFTERTOUCH) {
161
            return "Aftertouch " + MidiUtils.getKeyName(number);
162
        } else if (status == CONTROL_CHANGE) {
163
            if (highResolution) {
164
                return MidiUtils.cc14BitNames[number];
165
            } else {
166
                return MidiUtils.ccNames[number];
167
            }
168
        } else if (status == PROGRAM_CHANGE) {
169
            return "Program Change";
170
        } else if (status == CHANNEL_PRESSURE) {
171
            return "Channel Pressure";
172
        } else if (status == PITCH_BEND) {
173
            return "Pitch Bend";
174
        } else {
175
            return "undefined";
176
        }
177
    }
178
 
179
    public int getMidiNumber() {
180
        return number;
181
    }
182
 
183
    public void setMidiNumber(int number) {
184
        this.number = number;
185
 
186
        int currentStatus = getMidiStatus();
187
 
188
        setChanged();
189
        notifyObservers(NUMBER);
190
        clearChanged();
191
    }
192
 
193
    public boolean isLearn() {
194
        return learn;
195
    }
196
 
197
    public void setLearn(boolean learn) {
198
        this.learn = learn;
199
 
200
        setChanged();
201
        notifyObservers(LEARN);
202
        clearChanged();
203
    }
204
 
205
    public void createMessage() {
206
        ShortMessage message = new ShortMessage();
207
        if (receiver != null) {
208
            try {
209
 
210
                int data1 = 0;
211
                int data2 = 0;
212
 
213
                if (status == NOTE_ON || status == NOTE_OFF) {
214
                    data1 = number & 0x7F;
215
                    data2 = value & 0x7F;
216
                } else if (status == AFTERTOUCH) {
217
                    data1 = number & 0x7F;
218
                    data2 = value & 0x7F;
219
                } else if (status == CONTROL_CHANGE) {
220
 
221
                    if (highResolution
222
                            && ((number < 64) || (number < 102 && number > 97))) {
223
 
224
                        int msbNumber;
225
                        int lsbNumber;
226
 
227
                        if (number < 64) {
228
                            if (number < 32) {
229
                                msbNumber = number;
230
                                lsbNumber = number + 32;
231
                            } else {
232
                                msbNumber = number - 32;
233
                                lsbNumber = number;
234
                            }
235
                        } else {
236
                            if (number % 2 == 0) {
237
                                msbNumber = number + 1;
238
                                lsbNumber = number;
239
                            } else {
240
                                msbNumber = number;
241
                                lsbNumber = number - 1;
242
                            }
243
                        }
244
 
245
                        int lsbValue = (value) & 0x7F;
246
                        int msbValue = (value >> 7) & 0x7F;
247
 
248
                        message
249
                                .setMessage(status, channel, msbNumber,
250
                                        msbValue);
251
                        receiver.send(message, -1);
252
 
253
                        message = new ShortMessage();
254
 
255
                        message
256
                                .setMessage(status, channel, lsbNumber,
257
                                        lsbValue);
258
                        receiver.send(message, -1);
259
 
260
                        return;
261
                    } else {
262
                        data1 = number & 0x7F;
263
                        data2 = value & 0x7F;
264
                    }
265
                } else if (status == PROGRAM_CHANGE) {
266
                    data1 = value & 0x7F;
267
                    data2 = 0;
268
                } else if (status == CHANNEL_PRESSURE) {
269
                    data1 = value & 0x7F;
270
                    data2 = 0;
271
                } else if (status == PITCH_BEND) {
272
                    data1 = (value) & 0x7F;
273
                    data2 = (value >> 7) & 0x7F;
274
                }
275
 
276
                message.setMessage(status, channel, data1, data2);
277
                receiver.send(message, -1);
278
            } catch (Exception ex) {
279
                ex.printStackTrace();
280
            }
281
        }
282
    }
283
 
284
    protected void midiLearn(MidiMessage message) {
285
        if (message instanceof ShortMessage) {
286
 
287
            setMidiChannel(((ShortMessage) message).getChannel());
288
 
289
            int incomingStatus = ((ShortMessage) message).getCommand();
290
 
291
            if (incomingStatus == NOTE_OFF || incomingStatus == NOTE_ON) {
292
 
293
                setMidiStatus(NOTE_ON);
294
                setMidiNumber(((ShortMessage) message).getData1());
295
                setMidiDefaultValue(((ShortMessage) message).getData2());
296
 
297
            } else if (incomingStatus == AFTERTOUCH) {
298
 
299
                setMidiStatus(AFTERTOUCH);
300
                setMidiNumber(((ShortMessage) message).getData1());
301
                setMidiDefaultValue(((ShortMessage) message).getData2());
302
 
303
            } else if (incomingStatus == CONTROL_CHANGE) {
304
                setMidiStatus(CONTROL_CHANGE);
305
                setMidiNumber(((ShortMessage) message).getData1());
306
                if (highResolution
307
                        && ((number < 64) || (number < 102 && number > 97))) {
308
                    if (number < 64) {
309
                        if (number < 32) {
310
                            setMidiValue(
311
                                    ((ShortMessage) message).getData2() << 7,
312
                                    false);
313
                        } else {
314
                            setMidiValue(((ShortMessage) message).getData2(),
315
                                    false);
316
                        }
317
                    } else {
318
                        if (number % 2 == 0) {
319
                            setMidiValue(((ShortMessage) message).getData2(),
320
                                    false);
321
                        } else {
322
                            setMidiValue(
323
                                    ((ShortMessage) message).getData2() << 7,
324
                                    false);
325
                        }
326
                    }
327
                } else {
328
                    setMidiDefaultValue(((ShortMessage) message).getData2());
329
                }
330
            } else if (incomingStatus == PROGRAM_CHANGE) {
331
 
332
                setMidiStatus(PROGRAM_CHANGE);
333
                setMidiDefaultValue(((ShortMessage) message).getData1());
334
 
335
            } else if (incomingStatus == CHANNEL_PRESSURE) {
336
 
337
                setMidiStatus(CHANNEL_PRESSURE);
338
                setMidiDefaultValue(((ShortMessage) message).getData1());
339
 
340
            } else if (incomingStatus == PITCH_BEND) {
341
 
342
                setMidiStatus(PITCH_BEND);
343
                setMidiDefaultValue(((ShortMessage) message).getData1() & 0x7F
344
                        | (((ShortMessage) message).getData2() << 7));
345
 
346
            }
347
        }
348
    }
349
 
350
    public void send(MidiMessage message, long lTimeStamp) {
351
 
352
        if (isLearn()) {
353
            midiLearn(message);
354
            setLearn(false);
355
        } else {
356
            if (message instanceof ShortMessage) {
357
 
358
                if (channel == ((ShortMessage) message).getChannel()) {
359
 
360
                    int incomingStatus = ((ShortMessage) message).getCommand();
361
 
362
                    if ((incomingStatus == NOTE_OFF || incomingStatus == NOTE_ON)
363
                            && (status == NOTE_OFF || status == NOTE_ON)) {
364
                        if (number == ((ShortMessage) message).getData1()) {
365
                            setMidiValue(incomingStatus == NOTE_OFF ? 0
366
                                    : ((ShortMessage) message).getData2(),
367
                                    false);
368
                        }
369
                    } else if ((incomingStatus == AFTERTOUCH)
370
                            && (status == AFTERTOUCH)) {
371
                        if (number == ((ShortMessage) message).getData1()) {
372
                            setMidiValue(incomingStatus == NOTE_OFF ? 0
373
                                    : ((ShortMessage) message).getData2(),
374
                                    false);
375
                        }
376
                    } else if (incomingStatus == CONTROL_CHANGE
377
                            && status == CONTROL_CHANGE) {
378
 
379
                        int incomingNumber = ((ShortMessage) message)
380
                                .getData1();
381
                        int incomingValue = ((ShortMessage) message).getData2();
382
 
383
                        if (highResolution
384
                                && ((number < 64) || (number < 102 && number > 97))) {
385
 
386
                            if (number < 64) {
387
                                if (number < 32) {
388
                                    if (incomingNumber == number) {
389
                                        int newValue = value & 0x007F;
390
                                        newValue = newValue
391
                                                | incomingValue << 7;
392
                                        setMidiValue(newValue, false);
393
                                    } else if (incomingNumber == number + 32) {
394
                                        int newValue = value & 0x3F80;
395
                                        newValue = newValue | incomingValue;
396
                                        setMidiValue(newValue, false);
397
                                    }
398
                                } else {
399
                                    if (incomingNumber == number) {
400
                                        int newValue = value & 0x3F80;
401
                                        newValue = newValue | incomingValue;
402
                                        setMidiValue(newValue, false);
403
                                    } else if (incomingNumber == number - 32) {
404
                                        int newValue = value & 0x007F;
405
                                        newValue = newValue
406
                                                | incomingValue << 7;
407
                                        setMidiValue(newValue, false);
408
                                    }
409
                                }
410
                            } else {
411
                                if (number % 2 == 0) {
412
                                    if (incomingNumber == number + 1) {
413
                                        int newValue = value & 0x007F;
414
                                        newValue = newValue
415
                                                | incomingValue << 7;
416
                                        setMidiValue(newValue, false);
417
                                    } else if (incomingNumber == number) {
418
                                        int newValue = value & 0x3F80;
419
                                        newValue = newValue | incomingValue;
420
                                        setMidiValue(newValue, false);
421
                                    }
422
                                } else {
423
                                    if (incomingNumber == number - 1) {
424
                                        int newValue = value & 0x3F80;
425
                                        newValue = newValue | incomingValue;
426
                                        setMidiValue(newValue, false);
427
                                    } else if (incomingNumber == number) {
428
                                        int newValue = value & 0x007F;
429
                                        newValue = newValue
430
                                                | incomingValue << 7;
431
                                        setMidiValue(newValue, false);
432
                                    }
433
                                }
434
                            }
435
                        } else {
436
                            if (number == incomingNumber) {
437
                                setMidiValue(incomingValue, false);
438
                            }
439
                        }
440
                    } else if (incomingStatus == PROGRAM_CHANGE
441
                            && status == PROGRAM_CHANGE) {
442
                        setMidiValue(((ShortMessage) message).getData1(), false);
443
                    } else if (incomingStatus == CHANNEL_PRESSURE
444
                            && status == CHANNEL_PRESSURE) {
445
                        setMidiValue(((ShortMessage) message).getData1(), false);
446
                    } else if (incomingStatus == PITCH_BEND
447
                            && status == PITCH_BEND) {
448
                        setMidiValue(((ShortMessage) message).getData1() & 0x7F
449
                                | (((ShortMessage) message).getData2() << 7),
450
                                false);
451
                    }
452
                }
453
            }
454
        }
455
    }
456
 
457
    public int getMidiDefaultValue() {
458
        return defaultValue & getMidiMaxValue();
459
    }
460
 
461
    public void setMidiDefaultValue(int value) {
462
 
463
        this.defaultValue = value & getMidiMaxValue();
464
 
465
        setChanged();
466
        notifyObservers(DEFAULT_VALUE);
467
        clearChanged();
468
    }
469
 
470
    public void close() {
471
 
472
    }
473
 
474
    public boolean isHighResolution() {
475
        return highResolution;
476
    }
477
 
478
    public void setHighResolution(boolean highResolution) {
479
        this.highResolution = highResolution;
480
 
481
        setChanged();
482
        notifyObservers(HIGH_RESOLUTION);
483
        clearChanged();
484
    }
485
}