*** empty log message ***
[chuck-blob.git] / exile / v1 / src / midiio_win32.cpp
blob09623b6c4073eb87c1e94aaf64b3ba0bd37ca524
1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: midiio_win32.cpp
27 // desc: midi io
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 //-----------------------------------------------------------------------------
32 #include <stdlib.h>
33 #include "midiio_win32.h"
38 //-----------------------------------------------------------------------------
39 // global variables
40 //-----------------------------------------------------------------------------
41 UINT g_midi_device;
42 #define BUFFER_SIZE 8192
47 //-----------------------------------------------------------------------------
48 // name: MidiOut()
49 // desc: constructor
50 //-----------------------------------------------------------------------------
51 MidiOut::MidiOut()
53 m_device_num = 0;
54 m_midi_out = NULL;
60 //-----------------------------------------------------------------------------
61 // name: ~MidiOut()
62 // desc: destructor
63 //-----------------------------------------------------------------------------
64 MidiOut::~MidiOut()
66 if( m_midi_out ) this->close();
72 //-----------------------------------------------------------------------------
73 // name: send()
74 // desc: send 1 byte midi message
75 //-----------------------------------------------------------------------------
76 UINT MidiOut::send( BYTE status )
78 return this->send( status, 0, 0 );
84 //-----------------------------------------------------------------------------
85 // name: send()
86 // desc: send 2 byte midi message
87 //-----------------------------------------------------------------------------
88 UINT MidiOut::send( BYTE status, BYTE data1 )
90 return this->send( status, data1, 0 );
96 //-----------------------------------------------------------------------------
97 // name: send()
98 // desc: send 3 byte midi message
99 //-----------------------------------------------------------------------------
100 UINT MidiOut::send( BYTE status, BYTE data1, BYTE data2 )
102 MidiMsg msg;
104 msg.data[0] = status;
105 msg.data[1] = data1;
106 msg.data[2] = data2;
107 msg.data[3] = 0;
109 return midiOutShortMsg( m_midi_out, msg.dw );
115 //-----------------------------------------------------------------------------
116 // name: send()
117 // desc: send
118 //-----------------------------------------------------------------------------
119 UINT MidiOut::send( const MidiMsg * msg )
121 return midiOutShortMsg( m_midi_out, msg->dw );
127 //-----------------------------------------------------------------------------
128 // name: open
129 // desc: open midi output
130 //-----------------------------------------------------------------------------
131 BOOL MidiOut::open( UINT device_num )
133 // close if already opened
134 if( m_midi_out )
135 this->close();
137 // copy
138 m_device_num = device_num;
140 // open the midi out
141 return midiOutOpen( &m_midi_out, m_device_num,
142 (DWORD)cb_midi_output, NULL, CALLBACK_FUNCTION ) == 0;
148 //-----------------------------------------------------------------------------
149 // name: close( )
150 // desc: close midi output
151 //-----------------------------------------------------------------------------
152 BOOL MidiOut::close( )
154 if( !m_midi_out )
155 return FALSE;
157 // turn off everything
158 midiOutReset( m_midi_out );
160 // close
161 midiOutClose( m_midi_out );
163 // set to NULL
164 m_midi_out = NULL;
166 return TRUE;
172 //-----------------------------------------------------------------------------
173 // name: noteon()
174 // desc: note on message
175 //-----------------------------------------------------------------------------
176 UINT MidiOut::noteon( UINT channel, UINT note, UINT velocity )
177 { return this->send( (BYTE)(MIDI_NOTEON + channel), note, velocity ); }
182 //-----------------------------------------------------------------------------
183 // name: noteoff()
184 // desc: note off message
185 //-----------------------------------------------------------------------------
186 UINT MidiOut::noteoff( UINT channel, UINT note, UINT velocity )
187 { return this->send( (BYTE)(MIDI_NOTEOFF + channel), note, velocity ); }
192 //-----------------------------------------------------------------------------
193 // name: polypress()
194 // desc: polypress message
195 //-----------------------------------------------------------------------------
196 UINT MidiOut::polypress( UINT channel, UINT note, UINT pressure )
197 { return this->send( (BYTE)(MIDI_POLYPRESS + channel), note, pressure ); }
202 //-----------------------------------------------------------------------------
203 // name: ctrlchange()
204 // desc: ctrl change message
205 //-----------------------------------------------------------------------------
206 UINT MidiOut::ctrlchange( UINT channel, UINT ctrl_num, UINT ctrl_val )
207 { return this->send( (BYTE)(MIDI_CTRLCHANGE + channel), ctrl_num, ctrl_val ); }
212 //-----------------------------------------------------------------------------
213 // name: progchange()
214 // desc: prog change message
215 //-----------------------------------------------------------------------------
216 UINT MidiOut::progchange( UINT channel, UINT patch )
217 { return this->send( (BYTE)(MIDI_PROGCHANGE + channel), patch, 0 ); }
222 //-----------------------------------------------------------------------------
223 // name: chanpress()
224 // desc: chan press
225 //-----------------------------------------------------------------------------
226 UINT MidiOut::chanpress( UINT channel, UINT pressure )
227 { return this->send( (BYTE)(MIDI_CHANPRESS + channel), pressure, 0 ); }
232 //-----------------------------------------------------------------------------
233 // name: pitchbend()
234 // desc: pitch bend
235 //-----------------------------------------------------------------------------
236 UINT MidiOut::pitchbend( UINT channel, UINT bend_val )
238 return this->send( (BYTE)(MIDI_PITCHBEND + channel),
239 (BYTE)(HIBYTE( bend_val << 1 )),
240 (BYTE)(LOBYTE( bend_val & 0x7f )) );
246 //-----------------------------------------------------------------------------
247 // name: allnotesoff()
248 // desc: allnotesoff
249 //-----------------------------------------------------------------------------
250 UINT MidiOut::allnotesoff( UINT channel )
252 return this->send( (BYTE)(MIDI_CTRLCHANGE + channel),
253 (BYTE)(MIDI_ALLNOTESOFF), 0 );
259 //-----------------------------------------------------------------------------
260 // name: cb_midi_output
261 // desc: call back
262 //-----------------------------------------------------------------------------
263 void CALLBACK MidiOut::cb_midi_output( HMIDIOUT hm_out, UINT msg,
264 DWORD instance, DWORD param1, DWORD param2 )
266 MMRESULT result;
267 MIDIHDR * mhdr = NULL;
269 switch( msg )
271 case MOM_OPEN:
272 break;
273 case MOM_CLOSE:
274 break;
275 case MOM_DONE:
276 mhdr = (MIDIHDR*)param1;
278 result = midiOutUnprepareHeader( hm_out, mhdr, sizeof(MIDIHDR) );
280 if( result != 0 )
282 // TODO: handle the error
283 break;
286 if( mhdr->lpData )
287 free( mhdr->lpData );
289 break;
290 case MOM_POSITIONCB:
291 mhdr = (MIDIHDR*)param2;
292 break;
299 //-----------------------------------------------------------------------------
300 // name: MidiIn()
301 // desc: constructor
302 //-----------------------------------------------------------------------------
303 MidiIn::MidiIn()
305 m_midi_in = NULL;
306 m_device_num = 0;
312 //-----------------------------------------------------------------------------
313 // name: ~MidiIn()
314 // desc: destructor
315 //-----------------------------------------------------------------------------
316 MidiIn::~MidiIn( )
318 this->close();
324 //-----------------------------------------------------------------------------
325 // name: open()
326 // desc: open
327 //-----------------------------------------------------------------------------
328 BOOL MidiIn::open( UINT device_num )
330 MMRESULT result;
331 if( m_midi_in )
332 this->close();
334 m_device_num = device_num;
336 // open the midi
337 result = midiInOpen( &m_midi_in, m_device_num, (DWORD)cb_midi_input,
338 (DWORD)this, CALLBACK_FUNCTION );
340 // check result
341 if( result != 0 )
342 return FALSE;
344 // allocate the buffer
345 if( !m_buffer.initialize( BUFFER_SIZE, sizeof(MidiMsg) ) )
347 this->close();
348 return FALSE;
351 return midiInStart( m_midi_in ) == 0;
357 //-----------------------------------------------------------------------------
358 // name: close()
359 // desc: close
360 //-----------------------------------------------------------------------------
361 BOOL MidiIn::close()
363 if( !m_midi_in )
364 return FALSE;
366 // midi reset
367 midiInReset( m_midi_in );
369 // midi close
370 midiInClose( m_midi_in );
372 // set to NULL
373 m_midi_in = NULL;
375 // deallocate the buffer
376 m_buffer.cleanup();
378 return TRUE;
384 //-----------------------------------------------------------------------------
385 // name: get()
386 // desc: get message
387 //-----------------------------------------------------------------------------
388 UINT MidiIn::recv( MidiMsg * msg )
390 return m_buffer.get( msg, 1 );
396 //-----------------------------------------------------------------------------
397 // name: cb_midi_input()
398 // desc: cb
399 //-----------------------------------------------------------------------------
400 void CALLBACK MidiIn::cb_midi_input( HMIDIIN hm_in, UINT msg, DWORD instance,
401 DWORD param1, DWORD param2 )
403 MidiMsg m, n;
404 MidiIn * midi_in = (MidiIn *)instance;
406 switch( msg )
408 case MIM_OPEN:
409 break;
411 case MIM_CLOSE:
412 break;
414 case MIM_DATA:
415 n.dw = param1;
416 m.data[0] = n.data[2];
417 m.data[1] = n.data[1];
418 m.data[2] = n.data[0];
419 m.data[3] = n.data[3];
421 // put in the buffer, make sure not active sensing
422 if( m.data[2] != 0xfe )
424 midi_in->m_buffer.put( &m, 1 );
426 break;
428 case MIM_ERROR:
429 break;
431 case MIM_LONGDATA:
432 break;
434 case MIM_LONGERROR:
435 break;