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
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: midiio_alsa.cpp
27 // desc: midi io alsa implementation
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 //-----------------------------------------------------------------------------
32 #include "midiio_alsa.h"
39 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
45 UINT__ m_device_num
= 0;
52 //-----------------------------------------------------------------------------
55 //-----------------------------------------------------------------------------
64 //-----------------------------------------------------------------------------
66 // desc: open a device
67 //-----------------------------------------------------------------------------
68 BOOL__
MidiOut::open( int device_num
)
73 m_device_num
= device_num
;
76 sprintf( buffer
, "hw:0,%d", m_device_num
);
77 err
= snd_rawmidi_open( NULL
, &m_midi_out
, buffer
, 0 );
85 //-----------------------------------------------------------------------------
87 // desc: close the device
88 //-----------------------------------------------------------------------------
89 BOOL__
MidiOut::close( )
91 // send everything in buffer
92 snd_rawmidi_drain( m_midi_out
);
95 snd_rawmidi_close( m_midi_out
);
103 //-----------------------------------------------------------------------------
106 //-----------------------------------------------------------------------------
107 BOOL__
MidiOut::drain()
109 snd_rawmidi_drain( m_midi_out
);
117 //-----------------------------------------------------------------------------
119 // desc: send 1 BYTE__ midi message
120 //-----------------------------------------------------------------------------
121 UINT__
MidiOut::send( BYTE__ status
)
124 snd_rawmidi_write( m_midi_out
, &status
, 1 );
132 //-----------------------------------------------------------------------------
134 // desc: send 2 BYTE__ midi message
135 //-----------------------------------------------------------------------------
136 UINT__
MidiOut::send( BYTE__ status
, BYTE__ data1
)
139 snd_rawmidi_write( m_midi_out
, &status
, 1 );
140 snd_rawmidi_write( m_midi_out
, &data1
, 1 );
148 //-----------------------------------------------------------------------------
150 // desc: send 3 BYTE__ midi message
151 //-----------------------------------------------------------------------------
152 UINT__
MidiOut::send( BYTE__ status
, BYTE__ data1
, BYTE__ data2
)
154 // send the three BYTE__s
155 snd_rawmidi_write( m_midi_out
, &status
, 1 );
156 snd_rawmidi_write( m_midi_out
, &data1
, 1 );
157 snd_rawmidi_write( m_midi_out
, &data2
, 1 );
165 //-----------------------------------------------------------------------------
167 // desc: send midi message
168 //-----------------------------------------------------------------------------
169 UINT__
MidiOut::send( const MidiMsg
* msg
)
171 return this->send( msg
->data
[0], msg
->data
[1], msg
->data
[2] );
177 //-----------------------------------------------------------------------------
180 //-----------------------------------------------------------------------------
185 pthread_mutex_init( &m_mutex
, NULL
);
191 //-----------------------------------------------------------------------------
194 //-----------------------------------------------------------------------------
203 //-----------------------------------------------------------------------------
206 //-----------------------------------------------------------------------------
207 BOOL__
MidiIn::open( int device_num
)
212 m_device_num
= device_num
;
215 sprintf( buffer
, "hw:0,%d", m_device_num
);
216 err
= snd_rawmidi_open( &m_midi_in
, NULL
, buffer
, 0 );
218 // initialize the buffer
219 m_buffer
.initialize( 1024, sizeof( MidiMsg
) );
222 pthread_create( &m_cb_thread_id
, NULL
, midi_in_cb
, this );
230 //-----------------------------------------------------------------------------
233 //-----------------------------------------------------------------------------
234 BOOL__
MidiIn::close()
236 snd_rawmidi_drain( m_midi_in
);
237 snd_rawmidi_close( m_midi_in
);
239 pthread_cancel( m_cb_thread_id
);
240 pthread_mutex_destroy( &m_mutex
);
248 //-----------------------------------------------------------------------------
251 //-----------------------------------------------------------------------------
252 UINT__
MidiIn::recv( MidiMsg
* msg
)
255 //pthread_mutex_lock( &m_mutex );
256 r
= m_buffer
.get( msg
, 1 );
257 //pthread_mutex_unlock( &m_mutex );
265 //-----------------------------------------------------------------------------
266 // name: midi_in_cb()
268 //-----------------------------------------------------------------------------
269 void * MidiIn::midi_in_cb( void * arg
)
271 MidiIn
* min
= (MidiIn
*)arg
;
273 int n
= 0, num_args
= 0, num_left
= 0;
278 // get the next BYTE__
279 n
= snd_rawmidi_read( min
->m_midi_in
, &byte
, 1 );
283 fprintf( stdout
, "error: rawmidi_read...\n" );
289 if( byte
& 0x80 ) // status byte
291 if( (byte
& 0xf0) == 0xf0 ) // system msg
297 if( ( (byte
& 0xf0) == 0xc0 ) || ( (byte
& 0xf0) == 0xd0 ) )
310 if( num_left
== num_args
)
319 if( ((msg
.data
[2] & 0xf0) == 0xc0) || ((msg
.data
[2] & 0xf0) == 0xd0) )
324 //pthread_mutex_lock( &min->m_mutex );
325 min
->m_buffer
.put( &msg
, 1 );
326 //pthread_mutex_unlock( &min->m_mutex );