Subversion Repositories svn.mios

Rev

Rev 628 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
628 adamjking 1
/*
2
 * @(#)MidiParameterControl.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 javax.sound.midi.MidiMessage;
24
import javax.sound.midi.Receiver;
25
import javax.sound.midi.ShortMessage;
26
 
721 adamjking 27
public class MidiParameterControl extends MidiParameter  implements Receiver {
628 adamjking 28
 
721 adamjking 29
    public final static Object DEFAULT_VALUE = new Object();
30
 
31
    public final static Object LEARN = new Object();
32
 
628 adamjking 33
    public final static Object RECEIVE = new Object();
34
 
35
    public final static Object SEND = new Object();
36
 
37
    public final static Object GLOBAL = new Object();
38
 
39
    public final static int RANGE = 0;
40
 
41
    public final static int BOOLEAN = 1;
42
 
43
    protected boolean receive;
44
 
45
    protected boolean send;
46
 
47
    protected boolean global;
721 adamjking 48
 
49
    protected Receiver receiver;
50
 
51
    protected int defaultValue;
628 adamjking 52
 
721 adamjking 53
    protected int type;
628 adamjking 54
 
721 adamjking 55
    protected boolean learn;
56
 
628 adamjking 57
    public MidiParameterControl(int type, Receiver receiver, int status,
58
            int channel, int number, int value, int defaultValue) {
721 adamjking 59
        super(status, channel, number, value);
60
        setReceiver(receiver);
61
        setMidiDefaultValue(defaultValue);
628 adamjking 62
        setType(type);
63
        setGlobal(true);
64
        setReceive(true);
65
        setSend(true);
66
    }
67
 
68
    public boolean isReceive() {
69
        return receive;
70
    }
71
 
72
    public void setReceive(boolean respond) {
73
        this.receive = respond;
74
 
75
        setChanged();
76
        notifyObservers(RECEIVE);
77
        clearChanged();
78
    }
79
 
80
    public boolean isSend() {
81
        return send;
82
    }
83
 
84
    public void setSend(boolean send) {
85
        this.send = send;
86
 
87
        setChanged();
88
        notifyObservers(SEND);
89
        clearChanged();
90
    }
91
 
92
    public boolean isGlobal() {
93
        return global;
94
    }
95
 
96
    public void setGlobal(boolean global) {
97
 
98
        this.global = global;
99
 
100
        setChanged();
101
        notifyObservers(GLOBAL);
102
        clearChanged();
103
    }
721 adamjking 104
 
628 adamjking 105
    public int getType() {
106
        return type;
107
    }
108
 
109
    public void setType(int type) {
110
        this.type = type;
111
    }
112
 
113
    public void setMidiValue(int value, boolean forward) {
114
 
115
        if (type != RANGE) {
116
            value = (value > 0) ? getMidiDefaultValue() : 0;
117
        }
118
 
721 adamjking 119
        super.setMidiValue(value);
120
 
121
        if (forward) {
122
            createMessage();
123
        }
628 adamjking 124
    }
125
 
126
    public boolean isMidiValueOn() {
127
        return getMidiValue() > 0;
128
    }
129
 
130
    public void setMidiValueOn(boolean on, boolean forward) {
131
        setMidiValue(on ? 1 : 0, forward);
132
    }
133
 
721 adamjking 134
    public Receiver getReceiver() {
135
        return receiver;
136
    }
137
 
138
    protected void setReceiver(Receiver receiver) {
139
        this.receiver = receiver;
140
    }
141
 
142
    public boolean isLearn() {
143
        return learn;
144
    }
145
 
146
    public void setLearn(boolean learn) {
147
        this.learn = learn;
148
 
149
        setChanged();
150
        notifyObservers(LEARN);
151
        clearChanged();
152
    }
153
 
628 adamjking 154
    public void createMessage() {
721 adamjking 155
 
628 adamjking 156
        if (send) {
721 adamjking 157
 
158
        ShortMessage message = new ShortMessage();
159
        if (receiver != null) {
160
            try {
161
 
162
                int data1 = 0;
163
                int data2 = 0;
164
 
165
                if (status == NOTE_ON || status == NOTE_OFF) {
166
                    data1 = number & 0x7F;
167
                    data2 = value & 0x7F;
168
                } else if (status == AFTERTOUCH) {
169
                    data1 = number & 0x7F;
170
                    data2 = value & 0x7F;
171
                } else if (status == CONTROL_CHANGE) {
172
 
173
                    if (highResolution
174
                            && ((number < 64) || (number < 102 && number > 97))) {
175
 
176
                        int msbNumber;
177
                        int lsbNumber;
178
 
179
                        if (number < 64) {
180
                            if (number < 32) {
181
                                msbNumber = number;
182
                                lsbNumber = number + 32;
183
                            } else {
184
                                msbNumber = number - 32;
185
                                lsbNumber = number;
186
                            }
187
                        } else {
188
                            if (number % 2 == 0) {
189
                                msbNumber = number + 1;
190
                                lsbNumber = number;
191
                            } else {
192
                                msbNumber = number;
193
                                lsbNumber = number - 1;
194
                            }
195
                        }
196
 
197
                        int lsbValue = (value) & 0x7F;
198
                        int msbValue = (value >> 7) & 0x7F;
199
 
200
                        message
201
                                .setMessage(status, channel, msbNumber,
202
                                        msbValue);
203
                        receiver.send(message, -1);
204
 
205
                        message = new ShortMessage();
206
 
207
                        message
208
                                .setMessage(status, channel, lsbNumber,
209
                                        lsbValue);
210
                        receiver.send(message, -1);
211
 
212
                        return;
213
                    } else {
214
                        data1 = number & 0x7F;
215
                        data2 = value & 0x7F;
216
                    }
217
                } else if (status == PROGRAM_CHANGE) {
218
                    data1 = value & 0x7F;
219
                    data2 = 0;
220
                } else if (status == CHANNEL_PRESSURE) {
221
                    data1 = value & 0x7F;
222
                    data2 = 0;
223
                } else if (status == PITCH_BEND) {
224
                    data1 = (value) & 0x7F;
225
                    data2 = (value >> 7) & 0x7F;
226
                }
227
 
228
                message.setMessage(status, channel, data1, data2);
229
                receiver.send(message, -1);
230
            } catch (Exception ex) {
231
                ex.printStackTrace();
232
            }
628 adamjking 233
        }
721 adamjking 234
        }
628 adamjking 235
    }
236
 
721 adamjking 237
    protected void midiLearn(MidiMessage message) {
238
        if (message instanceof ShortMessage) {
239
 
240
            setGlobal(false);
241
 
242
            setMidiChannel(((ShortMessage) message).getChannel());
243
 
244
            int incomingStatus = ((ShortMessage) message).getCommand();
245
 
246
            if (incomingStatus == NOTE_OFF || incomingStatus == NOTE_ON) {
247
 
248
                setMidiStatus(NOTE_ON);
249
                setMidiNumber(((ShortMessage) message).getData1());
250
                setMidiDefaultValue(((ShortMessage) message).getData2());
251
 
252
            } else if (incomingStatus == AFTERTOUCH) {
253
 
254
                setMidiStatus(AFTERTOUCH);
255
                setMidiNumber(((ShortMessage) message).getData1());
256
                setMidiDefaultValue(((ShortMessage) message).getData2());
257
 
258
            } else if (incomingStatus == CONTROL_CHANGE) {
259
                setMidiStatus(CONTROL_CHANGE);
260
                setMidiNumber(((ShortMessage) message).getData1());
261
                if (highResolution
262
                        && ((number < 64) || (number < 102 && number > 97))) {
263
                    if (number < 64) {
264
                        if (number < 32) {
265
                            setMidiValue(
266
                                    ((ShortMessage) message).getData2() << 7,
267
                                    false);
268
                        } else {
269
                            setMidiValue(((ShortMessage) message).getData2(),
270
                                    false);
271
                        }
272
                    } else {
273
                        if (number % 2 == 0) {
274
                            setMidiValue(((ShortMessage) message).getData2(),
275
                                    false);
276
                        } else {
277
                            setMidiValue(
278
                                    ((ShortMessage) message).getData2() << 7,
279
                                    false);
280
                        }
281
                    }
282
                } else {
283
                    setMidiDefaultValue(((ShortMessage) message).getData2());
284
                }
285
            } else if (incomingStatus == PROGRAM_CHANGE) {
286
 
287
                setMidiStatus(PROGRAM_CHANGE);
288
                setMidiDefaultValue(((ShortMessage) message).getData1());
289
 
290
            } else if (incomingStatus == CHANNEL_PRESSURE) {
291
 
292
                setMidiStatus(CHANNEL_PRESSURE);
293
                setMidiDefaultValue(((ShortMessage) message).getData1());
294
 
295
            } else if (incomingStatus == PITCH_BEND) {
296
 
297
                setMidiStatus(PITCH_BEND);
298
                setMidiDefaultValue(((ShortMessage) message).getData1() & 0x7F
299
                        | (((ShortMessage) message).getData2() << 7));
300
 
301
            }
302
        }
303
    }
304
 
305
    public int getMidiDefaultValue() {
306
        return defaultValue & getMidiMaxValue();
307
    }
308
 
309
    public void setMidiDefaultValue(int value) {
310
 
311
        this.defaultValue = value & getMidiMaxValue();
312
 
313
        setChanged();
314
        notifyObservers(DEFAULT_VALUE);
315
        clearChanged();
316
    }
317
 
318
    public void close() {
319
 
320
    }
321
 
628 adamjking 322
    public void send(MidiMessage message, long lTimeStamp) {
721 adamjking 323
 
324
        if (isLearn()) {
325
            midiLearn(message);
326
            setLearn(false);
327
        } else {
328
            if (message instanceof ShortMessage) {
329
 
330
                if (channel == ((ShortMessage) message).getChannel()) {
331
 
332
                    int incomingStatus = ((ShortMessage) message).getCommand();
333
 
334
                    if ((incomingStatus == NOTE_OFF || incomingStatus == NOTE_ON)
335
                            && (status == NOTE_OFF || status == NOTE_ON)) {
336
                        if (number == ((ShortMessage) message).getData1()) {
337
                            setMidiValue(incomingStatus == NOTE_OFF ? 0
338
                                    : ((ShortMessage) message).getData2(),
339
                                    false);
340
                        }
341
                    } else if ((incomingStatus == AFTERTOUCH)
342
                            && (status == AFTERTOUCH)) {
343
                        if (number == ((ShortMessage) message).getData1()) {
344
                            setMidiValue(incomingStatus == NOTE_OFF ? 0
345
                                    : ((ShortMessage) message).getData2(),
346
                                    false);
347
                        }
348
                    } else if (incomingStatus == CONTROL_CHANGE
349
                            && status == CONTROL_CHANGE) {
350
 
351
                        int incomingNumber = ((ShortMessage) message)
352
                                .getData1();
353
                        int incomingValue = ((ShortMessage) message).getData2();
354
 
355
                        if (highResolution
356
                                && ((number < 64) || (number < 102 && number > 97))) {
357
 
358
                            if (number < 64) {
359
                                if (number < 32) {
360
                                    if (incomingNumber == number) {
361
                                        int newValue = value & 0x007F;
362
                                        newValue = newValue
363
                                                | incomingValue << 7;
364
                                        setMidiValue(newValue, false);
365
                                    } else if (incomingNumber == number + 32) {
366
                                        int newValue = value & 0x3F80;
367
                                        newValue = newValue | incomingValue;
368
                                        setMidiValue(newValue, false);
369
                                    }
370
                                } else {
371
                                    if (incomingNumber == number) {
372
                                        int newValue = value & 0x3F80;
373
                                        newValue = newValue | incomingValue;
374
                                        setMidiValue(newValue, false);
375
                                    } else if (incomingNumber == number - 32) {
376
                                        int newValue = value & 0x007F;
377
                                        newValue = newValue
378
                                                | incomingValue << 7;
379
                                        setMidiValue(newValue, false);
380
                                    }
381
                                }
382
                            } else {
383
                                if (number % 2 == 0) {
384
                                    if (incomingNumber == number + 1) {
385
                                        int newValue = value & 0x007F;
386
                                        newValue = newValue
387
                                                | incomingValue << 7;
388
                                        setMidiValue(newValue, false);
389
                                    } else if (incomingNumber == number) {
390
                                        int newValue = value & 0x3F80;
391
                                        newValue = newValue | incomingValue;
392
                                        setMidiValue(newValue, false);
393
                                    }
394
                                } else {
395
                                    if (incomingNumber == number - 1) {
396
                                        int newValue = value & 0x3F80;
397
                                        newValue = newValue | incomingValue;
398
                                        setMidiValue(newValue, false);
399
                                    } else if (incomingNumber == number) {
400
                                        int newValue = value & 0x007F;
401
                                        newValue = newValue
402
                                                | incomingValue << 7;
403
                                        setMidiValue(newValue, false);
404
                                    }
405
                                }
406
                            }
407
                        } else {
408
                            if (number == incomingNumber) {
409
                                setMidiValue(incomingValue, false);
410
                            }
411
                        }
412
                    } else if (incomingStatus == PROGRAM_CHANGE
413
                            && status == PROGRAM_CHANGE) {
414
                        setMidiValue(((ShortMessage) message).getData1(), false);
415
                    } else if (incomingStatus == CHANNEL_PRESSURE
416
                            && status == CHANNEL_PRESSURE) {
417
                        setMidiValue(((ShortMessage) message).getData1(), false);
418
                    } else if (incomingStatus == PITCH_BEND
419
                            && status == PITCH_BEND) {
420
                        setMidiValue(((ShortMessage) message).getData1() & 0x7F
421
                                | (((ShortMessage) message).getData2() << 7),
422
                                false);
423
                    }
424
                }
425
            }
628 adamjking 426
        }
427
    }
428
}