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 //-----------------------------------------------------------------------------
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__
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; } }
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
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) )
78 #define UINT__ unsigned long
79 #define BOOL__ DWORD__
81 #define BYTE__ unsigned char
93 //-----------------------------------------------------------------------------
96 //-----------------------------------------------------------------------------
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();
106 static DWORD__
sampling_rate( ) { return (DWORD__
)m_wfx
.nSamplesPerSec
; }
107 static DWORD__
num_channels( ) { return (DWORD__
)m_wfx
.nChannels
; }
110 static BOOL__ m_init
;
111 static LPDIRECTSOUND m_ds
;
112 static LPDIRECTSOUNDBUFFER m_primary
;
113 static WAVEFORMATEX m_wfx
;
119 //-----------------------------------------------------------------------------
122 //-----------------------------------------------------------------------------
126 virtual ~TickOut() {}
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 //-----------------------------------------------------------------------------
141 //-----------------------------------------------------------------------------
145 virtual ~TickIn() { }
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 //-----------------------------------------------------------------------------
163 //-----------------------------------------------------------------------------
167 virtual ~ChannelIO() { }
170 virtual SAMPLE
_( SAMPLE x
) = 0;
176 //-----------------------------------------------------------------------------
177 // name: class DigitalOut
179 //-----------------------------------------------------------------------------
180 class DigitalOut
: public TickOut
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
);
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
);
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
;
219 inline BOOL__
prepare_tick_out();
225 //-----------------------------------------------------------------------------
226 // name: class DigitalIn
228 //-----------------------------------------------------------------------------
229 class DigitalIn
: public TickIn
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
);
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
);
253 static DWORD__ CALLBACK
cb_capture( void * param
);
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 //-----------------------------------------------------------------------------
277 //-----------------------------------------------------------------------------
281 AudioBuffer( DWORD__ size
= 0 );
284 BOOL__
initialize( DWORD__ size
);
300 //-----------------------------------------------------------------------------
301 // name: AudioBufferIn
303 //-----------------------------------------------------------------------------
304 class AudioBufferIn
: public TickIn
, public AudioBuffer
307 AudioBufferIn( DWORD__ size
= 0 );
308 virtual ~AudioBufferIn();
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
323 //-----------------------------------------------------------------------------
324 class AudioBufferOut
: public TickOut
, public AudioBuffer
327 AudioBufferOut( DWORD__ size
= 0 );
328 virtual ~AudioBufferOut();
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 //-----------------------------------------------------------------------------
351 BOOL__
initialize( DWORD__ buffer_size
);
361 SAMPLE_INTERNAL
* data( DWORD__ channel
= 0 );
362 DWORD__
size() const;
365 SAMPLE_INTERNAL
* m_data
;
373 //-----------------------------------------------------------------------------
374 // name: class EventOutBuffer
375 // desc: sample buffer with event
376 //-----------------------------------------------------------------------------
380 EventOutBuffer( LPDIRECTSOUND ds
);
384 BOOL__
initialize( WAVEFORMATEX
* wfx
, DWORD__ buffer_size
,
385 DWORD__ block_size
);
390 BOOL__
swap( InternalBuffer
* src
, DWORD__ offset
, DWORD__ size
);
391 BOOL__
cswap( InternalBuffer
* src
);
395 LPDIRECTSOUNDBUFFER
buffer();
398 LPDIRECTSOUNDBUFFER m_buffer
;
403 DWORD__ m_block_size
;
410 //-----------------------------------------------------------------------------
411 // name: class EventInBuffer
412 // desc: sample buffer with event
413 //-----------------------------------------------------------------------------
421 BOOL__
initialize( WAVEFORMATEX
* wfx
, DWORD__ buffer_size
,
422 DWORD__ block_size
);
427 BOOL__
swap( InternalBuffer
* src
, DWORD__ offset
, DWORD__ size
);
428 BOOL__
cswap( InternalBuffer
* src
);
432 LPDIRECTSOUNDCAPTUREBUFFER
buffer();
435 LPDIRECTSOUNDCAPTURE m_dsc
;
436 LPDIRECTSOUNDCAPTUREBUFFER m_buffer
;
438 DSCBUFFERDESC m_desc
;
440 DWORD__ m_block_size
;