*** empty log message ***
[chuck-blob.git] / exile / digitalio_win32.h
blob4de9758fae057e6ba17b7d34e95e26e6cef7e802
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 // name: digitalio.h
27 // desc: digitalio
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 //-----------------------------------------------------------------------------
32 #ifndef __DIGITAL_IO_H__
33 #define __DIGITAL_IO_H__
35 #include <windows.h>
36 #include <dsound.h>
41 //-----------------------------------------------------------------------------
42 // define and forward references
43 //-----------------------------------------------------------------------------
44 #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
45 #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
46 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
48 // defaults
49 #define BUFFER_SIZE_OUT_DEFAULT 512
50 #define BUFFER_SIZE_IN_DEFAULT 512
51 #define NUM_OUT_BUFFERS_DEFAULT 4
52 #define NUM_IN_BUFFERS_DEFAULT 4
53 #define NUM_CHANNELS_DEFAULT 2 // number of channels
54 #define SAMPLING_RATE_DEFAULT 44100 // sampling rate
55 #define BITS_PER_SAMPLE_DEFAULT 16 // sample size
56 #define DEVICE_NUM_OUT_DEFAULT 0
57 #define DEVICE_NUM_IN_DEFAULT 0
59 // sample types
60 #define SAMPLE_SHORT short
61 #define SAMPLE_FLOAT float
62 #define SAMPLE_INTERNAL SAMPLE_SHORT
63 #define SAMPLE SAMPLE_FLOAT
64 #define S_MAX 0x7fff // max value for 16 bit
65 #define S_MIN -0x7fff // min value for 16 bit
67 // external to internal sample
68 #define SAMPLE_TO_INTERNAL(s) ( (SAMPLE_INTERNAL)((SAMPLE)S_MAX * s) )
69 #define INTERNAL_TO_SAMPLE(s) ( (SAMPLE)((SAMPLE)s / S_MAX) )
71 // forward
72 class InternalBuffer;
73 class EventOutBuffer;
74 class EventInBuffer;
76 // types
77 #define DWORD__ DWORD
78 #define UINT__ unsigned long
79 #define BOOL__ DWORD__
80 #define FLOAT__ float
81 #define BYTE__ unsigned char
83 #ifndef FALSE
84 #define FALSE 0
85 #endif
86 #ifndef TRUE
87 #define TRUE 1
88 #endif
93 //-----------------------------------------------------------------------------
94 // name: Digitalio
95 // desc: ...
96 //-----------------------------------------------------------------------------
97 class Digitalio
99 public:
100 static BOOL__ initialize( DWORD__ num_channels = NUM_CHANNELS_DEFAULT,
101 DWORD__ sampling_rate = SAMPLING_RATE_DEFAULT,
102 DWORD__ bps = BITS_PER_SAMPLE_DEFAULT );
103 static void shutdown();
105 public:
106 static DWORD__ sampling_rate( ) { return (DWORD__)m_wfx.nSamplesPerSec; }
107 static DWORD__ num_channels( ) { return (DWORD__)m_wfx.nChannels; }
109 public: // data
110 static BOOL__ m_init;
111 static LPDIRECTSOUND m_ds;
112 static LPDIRECTSOUNDBUFFER m_primary;
113 static WAVEFORMATEX m_wfx;
119 //-----------------------------------------------------------------------------
120 // name: TickOut
121 // desc: ...
122 //-----------------------------------------------------------------------------
123 class TickOut
125 public:
126 virtual ~TickOut() {}
128 public:
129 virtual BOOL__ reset() { return TRUE; }
130 virtual BOOL__ tick_out( SAMPLE s ) = 0;
131 virtual BOOL__ tick_out( SAMPLE l, SAMPLE r ) = 0;
132 virtual BOOL__ tick_out( const SAMPLE * out, DWORD__ n ) = 0;
138 //-----------------------------------------------------------------------------
139 // name: TickIn
140 // desc: ...
141 //-----------------------------------------------------------------------------
142 class TickIn
144 public:
145 virtual ~TickIn() { }
147 public:
148 virtual BOOL__ reset() { return TRUE; }
149 virtual BOOL__ tick_in( SAMPLE * in ) = 0;
150 virtual BOOL__ tick_in( SAMPLE * l, SAMPLE * r ) = 0;
151 virtual BOOL__ tick_in( SAMPLE * in, DWORD__ n ) = 0;
153 virtual SAMPLE tick( )
154 { SAMPLE in; return ( tick_in( &in ) ? in : (SAMPLE)0.0f ); }
160 //-----------------------------------------------------------------------------
161 // name: ChannelIO
162 // desc: ...
163 //-----------------------------------------------------------------------------
164 class ChannelIO
166 public:
167 virtual ~ChannelIO() { }
169 public:
170 virtual SAMPLE _( SAMPLE x ) = 0;
176 //-----------------------------------------------------------------------------
177 // name: class DigitalOut
178 // desc: ...
179 //-----------------------------------------------------------------------------
180 class DigitalOut : public TickOut
182 public:
183 DigitalOut();
184 ~DigitalOut();
186 public:
187 BOOL__ initialize( DWORD__ device_num = DEVICE_NUM_OUT_DEFAULT,
188 DWORD__ num_channels = NUM_CHANNELS_DEFAULT,
189 DWORD__ sampling_rate = SAMPLING_RATE_DEFAULT,
190 DWORD__ bps = BITS_PER_SAMPLE_DEFAULT,
191 DWORD__ buffer_size = BUFFER_SIZE_OUT_DEFAULT,
192 DWORD__ num_buffers = NUM_OUT_BUFFERS_DEFAULT );
193 void cleanup();
195 BOOL__ start();
196 BOOL__ stop();
198 public:
199 virtual BOOL__ tick_out( SAMPLE s );
200 virtual BOOL__ tick_out( SAMPLE l, SAMPLE r );
201 virtual BOOL__ tick_out( const SAMPLE * samples, DWORD__ n );
203 public:
204 DWORD__ render();
206 protected:
207 BOOL__ m_init_out;
208 BOOL__ m_render_start;
210 DWORD__ m_out_buffer_size;
211 DWORD__ m_num_out_buffers;
212 InternalBuffer ** m_out_buffers;
213 EventOutBuffer * m_main_out_buffer;
214 DWORD__ m_curr_buffer_out;
215 SAMPLE_INTERNAL * m_data_ptr_out;
216 SAMPLE_INTERNAL * m_data_max_out;
217 DWORD__ m_index;
219 inline BOOL__ prepare_tick_out();
225 //-----------------------------------------------------------------------------
226 // name: class DigitalIn
227 // desc: ...
228 //-----------------------------------------------------------------------------
229 class DigitalIn : public TickIn
231 public:
232 DigitalIn();
233 ~DigitalIn();
235 public: // in
236 BOOL__ initialize( DWORD__ device_number = DEVICE_NUM_IN_DEFAULT,
237 DWORD__ num_channels = NUM_CHANNELS_DEFAULT,
238 DWORD__ sampling_rate = SAMPLING_RATE_DEFAULT,
239 DWORD__ bps = BITS_PER_SAMPLE_DEFAULT,
240 DWORD__ buffer_size = BUFFER_SIZE_IN_DEFAULT,
241 DWORD__ num_buffers = NUM_IN_BUFFERS_DEFAULT );
242 void cleanup();
244 BOOL__ start();
245 BOOL__ stop();
247 public:
248 virtual BOOL__ tick_in( SAMPLE * s );
249 virtual BOOL__ tick_in( SAMPLE * l, SAMPLE * r );
250 virtual BOOL__ tick_in( SAMPLE * samples, DWORD__ n );
252 public:
253 static DWORD__ CALLBACK cb_capture( void * param );
255 protected:
256 BOOL__ m_init_in;
257 BOOL__ m_capture_start;
258 HANDLE m_capture_thread;
260 DWORD__ m_in_buffer_size;
261 DWORD__ m_num_in_buffers;
262 InternalBuffer ** m_in_buffers;
263 EventInBuffer * m_main_in_buffer;
264 DWORD__ m_curr_buffer_in;
265 SAMPLE_INTERNAL * m_data_ptr_in;
266 SAMPLE_INTERNAL * m_data_max_in;
268 inline BOOL__ prepare_tick_in();
274 //-----------------------------------------------------------------------------
275 // name: AudioBuffer
276 // desc: ...
277 //-----------------------------------------------------------------------------
278 class AudioBuffer
280 public:
281 AudioBuffer( DWORD__ size = 0 );
283 public:
284 BOOL__ initialize( DWORD__ size );
285 void cleanup();
286 SAMPLE * data();
287 DWORD__ size();
289 protected:
290 SAMPLE * m_data;
291 DWORD__ m_size;
293 SAMPLE * m_ptr_curr;
294 SAMPLE * m_ptr_end;
300 //-----------------------------------------------------------------------------
301 // name: AudioBufferIn
302 // desc: ...
303 //-----------------------------------------------------------------------------
304 class AudioBufferIn : public TickIn, public AudioBuffer
306 public:
307 AudioBufferIn( DWORD__ size = 0 );
308 virtual ~AudioBufferIn();
310 public:
311 virtual BOOL__ reset();
312 virtual BOOL__ tick_in( SAMPLE * in );
313 virtual BOOL__ tick_in( SAMPLE * l, SAMPLE * r );
314 virtual BOOL__ tick_in( SAMPLE * in, DWORD__ n );
320 //-----------------------------------------------------------------------------
321 // name: AudioBufferOut
322 // desc: ...
323 //-----------------------------------------------------------------------------
324 class AudioBufferOut : public TickOut, public AudioBuffer
326 public:
327 AudioBufferOut( DWORD__ size = 0 );
328 virtual ~AudioBufferOut();
330 public:
331 virtual BOOL__ reset();
332 virtual BOOL__ tick_out( SAMPLE s );
333 virtual BOOL__ tick_out( SAMPLE l, SAMPLE r );
334 virtual BOOL__ tick_out( const SAMPLE * out, DWORD__ n );
340 //-----------------------------------------------------------------------------
341 // name: InternalBuffer
342 // desc: sample buffer
343 //-----------------------------------------------------------------------------
344 class InternalBuffer
346 public:
347 InternalBuffer();
348 ~InternalBuffer();
350 public:
351 BOOL__ initialize( DWORD__ buffer_size );
352 void cleanup();
354 public:
355 BOOL__ clear();
356 void synch();
357 void signal();
358 void reset();
360 public:
361 SAMPLE_INTERNAL * data( DWORD__ channel = 0 );
362 DWORD__ size() const;
364 protected:
365 SAMPLE_INTERNAL * m_data;
366 DWORD__ m_size;
367 HANDLE m_event;
373 //-----------------------------------------------------------------------------
374 // name: class EventOutBuffer
375 // desc: sample buffer with event
376 //-----------------------------------------------------------------------------
377 class EventOutBuffer
379 public:
380 EventOutBuffer( LPDIRECTSOUND ds );
381 ~EventOutBuffer();
383 public:
384 BOOL__ initialize( WAVEFORMATEX * wfx, DWORD__ buffer_size,
385 DWORD__ block_size );
386 void cleanup();
388 public:
389 BOOL__ wait();
390 BOOL__ swap( InternalBuffer * src, DWORD__ offset, DWORD__ size );
391 BOOL__ cswap( InternalBuffer * src );
392 void cswap_reset();
394 public:
395 LPDIRECTSOUNDBUFFER buffer();
397 protected:
398 LPDIRECTSOUNDBUFFER m_buffer;
399 LPDIRECTSOUND m_ds;
400 WAVEFORMATEX m_wfx;
401 DSBUFFERDESC m_desc;
403 DWORD__ m_block_size;
404 DWORD__ m_offset;
410 //-----------------------------------------------------------------------------
411 // name: class EventInBuffer
412 // desc: sample buffer with event
413 //-----------------------------------------------------------------------------
414 class EventInBuffer
416 public:
417 EventInBuffer();
418 ~EventInBuffer();
420 public:
421 BOOL__ initialize( WAVEFORMATEX * wfx, DWORD__ buffer_size,
422 DWORD__ block_size );
423 void cleanup();
425 public:
426 BOOL__ wait();
427 BOOL__ swap( InternalBuffer * src, DWORD__ offset, DWORD__ size );
428 BOOL__ cswap( InternalBuffer * src );
429 void cswap_reset();
431 public:
432 LPDIRECTSOUNDCAPTUREBUFFER buffer();
434 protected:
435 LPDIRECTSOUNDCAPTURE m_dsc;
436 LPDIRECTSOUNDCAPTUREBUFFER m_buffer;
437 WAVEFORMATEX m_wfx;
438 DSCBUFFERDESC m_desc;
440 DWORD__ m_block_size;
441 DWORD__ m_offset;
447 #endif