*** empty log message ***
[chuck-blob.git] / v2 / skiniio_skini.cpp
blobf013cd8b0e965f7b304b92d9e520ca84dce9907e
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: skiniio_skini.cpp
27 // desc: skini io
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 //-----------------------------------------------------------------------------
32 #include <stdlib.h>
33 #include <vector>
34 #include "skiniio_skini.h"
35 #include "chuck_errmsg.h"
40 //-----------------------------------------------------------------------------
41 // global variables
42 //-----------------------------------------------------------------------------
43 //#define BUFFER_SIZE 8192
45 //std::vector<RtMidiIn *> MidiInManager::the_mins;
46 //std::vector<CBuffer *> MidiInManager::the_bufs;
47 //std::vector<RtMidiOut *> MidiOutManager::the_mouts;
51 //-----------------------------------------------------------------------------
52 // name: SkiniOut()
53 // desc: constructor
54 //-----------------------------------------------------------------------------
55 SkiniOut::SkiniOut()
57 skout = new Skini;
58 m_filename = NULL;
59 m_valid = FALSE;
65 //-----------------------------------------------------------------------------
66 // name: ~SkiniOut()
67 // desc: destructor
68 //-----------------------------------------------------------------------------
69 SkiniOut::~SkiniOut()
71 if( skout ) this->close();
72 SAFE_DELETE( skout );
78 //-----------------------------------------------------------------------------
79 // name: send()
80 // desc: send skini message
81 //-----------------------------------------------------------------------------
82 t_CKUINT SkiniOut::send( const SkiniMsg * msg )
84 if( !m_valid ) return 0;
86 // write message in file
87 skout->write_message( msg->type, msg->time, msg->channel, msg->data1, msg->data2 );
89 return 3;
95 //-----------------------------------------------------------------------------
96 // name: open
97 // desc: open skini output
98 //-----------------------------------------------------------------------------
99 t_CKBOOL SkiniOut::open( const char * filename )
101 // close if already opened
102 if( m_valid )
103 this->close();
105 m_valid = skout->setFile( filename );
106 //if( m_valid ) strcpy( m_filename, filename );
108 return m_valid;
114 //-----------------------------------------------------------------------------
115 // name: close( )
116 // desc: close skini output
117 //-----------------------------------------------------------------------------
118 t_CKBOOL SkiniOut::close( )
120 if( !m_valid )
121 return FALSE;
123 // close
124 //MidiOutManager::close( this );
126 m_valid = FALSE;
127 m_filename = NULL;
129 skout->close_file();
131 return TRUE;
137 //-----------------------------------------------------------------------------
138 // name: noteon()
139 // desc: note on message
140 //-----------------------------------------------------------------------------
141 t_CKUINT MidiOut::noteon( t_CKUINT channel, t_CKUINT note, t_CKUINT velocity )
142 { return this->send( (t_CKBYTE)(MIDI_NOTEON + channel), note, velocity ); }
147 //-----------------------------------------------------------------------------
148 // name: noteoff()
149 // desc: note off message
150 //-----------------------------------------------------------------------------
151 t_CKUINT MidiOut::noteoff( t_CKUINT channel, t_CKUINT note, t_CKUINT velocity )
152 { return this->send( (t_CKBYTE)(MIDI_NOTEOFF + channel), note, velocity ); }
157 //-----------------------------------------------------------------------------
158 // name: polypress()
159 // desc: polypress message
160 //-----------------------------------------------------------------------------
161 t_CKUINT MidiOut::polypress( t_CKUINT channel, t_CKUINT note, t_CKUINT pressure )
162 { return this->send( (t_CKBYTE)(MIDI_POLYPRESS + channel), note, pressure ); }
167 //-----------------------------------------------------------------------------
168 // name: ctrlchange()
169 // desc: ctrl change message
170 //-----------------------------------------------------------------------------
171 t_CKUINT MidiOut::ctrlchange( t_CKUINT channel, t_CKUINT ctrl_num, t_CKUINT ctrl_val )
172 { return this->send( (t_CKBYTE)(MIDI_CTRLCHANGE + channel), ctrl_num, ctrl_val ); }
177 //-----------------------------------------------------------------------------
178 // name: progchange()
179 // desc: prog change message
180 //-----------------------------------------------------------------------------
181 t_CKUINT MidiOut::progchange( t_CKUINT channel, t_CKUINT patch )
182 { return this->send( (t_CKBYTE)(MIDI_PROGCHANGE + channel), patch, 0 ); }
187 //-----------------------------------------------------------------------------
188 // name: chanpress()
189 // desc: chan press
190 //-----------------------------------------------------------------------------
191 t_CKUINT MidiOut::chanpress( t_CKUINT channel, t_CKUINT pressure )
192 { return this->send( (t_CKBYTE)(MIDI_CHANPRESS + channel), pressure, 0 ); }
197 //-----------------------------------------------------------------------------
198 // name: pitchbend()
199 // desc: pitch bend
200 //-----------------------------------------------------------------------------
201 t_CKUINT MidiOut::pitchbend( t_CKUINT channel, t_CKUINT bend_val )
203 assert( FALSE );
204 return 0;
205 // return this->send( (t_CKBYTE)(MIDI_PITCHBEND + channel),
206 // (t_CKBYTE)(HIBYTE( bend_val << 1 )),
207 // (t_CKBYTE)(LOBYTE( bend_val & 0x7f )) );
213 //-----------------------------------------------------------------------------
214 // name: allnotesoff()
215 // desc: allnotesoff
216 //-----------------------------------------------------------------------------
217 t_CKUINT MidiOut::allnotesoff( t_CKUINT channel )
219 return this->send( (t_CKBYTE)(MIDI_CTRLCHANGE + channel),
220 (t_CKBYTE)(MIDI_ALLNOTESOFF), 0 );
226 //-----------------------------------------------------------------------------
227 // name: MidiIn()
228 // desc: constructor
229 //-----------------------------------------------------------------------------
230 SkiniIn::SkiniIn()
232 m_filename = NULL;
233 m_valid = FALSE;
234 //m_read_index = 0;
235 //m_buffer = NULL;
236 //SELF = NULL;
242 //-----------------------------------------------------------------------------
243 // name: ~SkiniIn()
244 // desc: destructor
245 //-----------------------------------------------------------------------------
246 SkiniIn::~SkiniIn( )
248 this->close();
249 // SAFE_DELETE( min );
255 //-----------------------------------------------------------------------------
256 // name: open()
257 // desc: open
258 //-----------------------------------------------------------------------------
259 t_CKBOOL SkiniIn::open( const char * filename )
261 // close if already opened
262 if( m_valid )
263 this->close();
265 // open
266 m_valid = skin->setFile( filename );
267 //if( m_valid ) strcpy( m_filename, filename );
268 return m_valid;
274 MidiInManager::MidiInManager()
276 the_mins.resize( 1024 );
277 the_bufs.resize( 1024 );
281 MidiInManager::~MidiInManager()
283 // yeah right
287 t_CKBOOL MidiInManager::open( MidiIn * min, t_CKINT device_num )
289 // see if port not already open
290 if( device_num >= the_mins.capacity() || !the_mins[device_num] )
293 // allocate the buffer
294 CBuffer * cbuf = new CBuffer;
295 if( !cbuf->initialize( BUFFER_SIZE, sizeof(MidiMsg) ) )
297 EM_error2( 0, "MidiIn: couldn't allocate CBuffer for port %i...", device_num );
298 delete cbuf;
299 return FALSE;
302 // allocate
303 RtMidiIn * rtmin = new RtMidiIn;
304 try {
305 rtmin->openPort( device_num );
306 rtmin->setCallback( cb_midi_input, cbuf );
307 } catch( RtError & err ) {
308 // print it
309 EM_error2( 0, "MidiIn: couldn't open MIDI port %i...", device_num );
310 EM_error2( 0, "...(%s)", err.getMessage().c_str() );
311 delete cbuf;
312 return FALSE;
315 // resize?
316 if( device_num >= the_mins.capacity() )
318 t_CKINT size = the_mins.capacity() * 2;
319 if( device_num >= size ) size = device_num + 1;
320 the_mins.resize( size );
321 the_bufs.resize( size );
324 // put cbuf and rtmin in vector for future generations
325 the_mins[device_num] = rtmin;
326 the_bufs[device_num] = cbuf;
329 // found
330 min->m_buffer = the_bufs[device_num];
331 // get an index into your (you are min here) own buffer,
332 // and a free ticket to your own workshop
333 min->m_read_index = min->m_buffer->join( (Chuck_Event *)min->SELF );
334 min->m_device_num = (t_CKUINT)device_num;
336 // done
337 return TRUE;
342 //-----------------------------------------------------------------------------
343 // name: close()
344 // desc: close
345 //-----------------------------------------------------------------------------
346 t_CKBOOL SkiniIn::close()
348 if( !m_valid )
349 return FALSE;
351 // close
352 // MidiInManager::close( this );
354 m_valid = FALSE;
355 m_filename = NULL;
356 skin->close_file();
358 return TRUE;
362 //-----------------------------------------------------------------------------
363 // name: get()
364 // desc: get message
365 //-----------------------------------------------------------------------------
366 t_CKUINT SkiniIn::recv( SkiniMsg * msg )
368 if( !m_valid ) return FALSE;
369 //return m_buffer->get( msg, 1, m_read_index );
371 Skini::Message mess;
372 msg->type = skin->nextMessage( mess ); // what????
373 msg->time = mess.time;
374 msg->channel = mess.channel;
375 if( mess.floatValues.size() > 0 )
376 msg->data1 = mess.floatValues[0];
377 if( mess.floatValues.size() > 1 )
378 msg->data2 = mess.floatValues[1];
380 return 0;