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: digiio_rtaudio.cpp
27 // desc: digitalio over rtaudio (from Gary Scavone)
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 //-----------------------------------------------------------------------------
32 #include "digiio_rtaudio.h"
34 #include "chuck_errmsg.h"
35 #include "chuck_globals.h"
38 // #include <signal.h>
39 #if (defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)) && !defined(__WINDOWS_PTHREAD__)
41 #include <sys/timeb.h>
47 // extern "C" void signal_int( int );
50 BOOL__
Digitalio::m_init
= FALSE
;
51 DWORD__
Digitalio::m_start
= 0;
52 DWORD__
Digitalio::m_tick_count
= 0;
53 DWORD__
Digitalio::m_num_channels_out
= NUM_CHANNELS_DEFAULT
;
54 DWORD__
Digitalio::m_num_channels_in
= NUM_CHANNELS_DEFAULT
;
55 DWORD__
Digitalio::m_sampling_rate
= SAMPLING_RATE_DEFAULT
;
56 DWORD__
Digitalio::m_bps
= BITS_PER_SAMPLE_DEFAULT
;
57 DWORD__
Digitalio::m_buffer_size
= BUFFER_SIZE_DEFAULT
;
58 DWORD__
Digitalio::m_num_buffers
= NUM_BUFFERS_DEFAULT
;
59 RtAudio
* Digitalio::m_rtaudio
= NULL
;
60 SAMPLE
* Digitalio::m_buffer_out
= NULL
;
61 SAMPLE
* Digitalio::m_buffer_in
= NULL
;
62 SAMPLE
** Digitalio::m_write_ptr
= NULL
;
63 SAMPLE
** Digitalio::m_read_ptr
= NULL
;
64 SAMPLE
* Digitalio::m_extern_in
= NULL
;
65 SAMPLE
* Digitalio::m_extern_out
= NULL
;
66 BOOL__
Digitalio::m_out_ready
= FALSE
;
67 BOOL__
Digitalio::m_in_ready
= FALSE
;
68 BOOL__
Digitalio::m_use_cb
= USE_CB_DEFAULT
;
69 DWORD__
Digitalio::m_go
= 0;
70 DWORD__
Digitalio::m_dac_n
= 0;
71 DWORD__
Digitalio::m_adc_n
= 0;
72 DWORD__
Digitalio::m_end
= 0;
73 DWORD__
Digitalio::m_block
= TRUE
;
74 DWORD__
Digitalio::m_xrun
= 0;
78 #if defined(CK_S_DOUBLE)
79 #define CK_RTAUDIO_FORMAT RTAUDIO_FLOAT64
81 #define CK_RTAUDIO_FORMAT RTAUDIO_FLOAT32
87 //-----------------------------------------------------------------------------
90 //-----------------------------------------------------------------------------
91 void print( const RtAudioDeviceInfo
& info
)
93 EM_error2b( 0, "device name = \"%s\"", info
.name
.c_str() );
94 if (info
.probed
== false)
95 EM_error2b( 0, "probe [failed] ..." );
98 EM_error2b( 0, "probe [success] ..." );
99 EM_error2b( 0, "# output channels = %d", info
.outputChannels
);
100 EM_error2b( 0, "# input channels = %d", info
.inputChannels
);
101 EM_error2b( 0, "# duplex Channels = %d", info
.duplexChannels
);
102 if( info
.isDefault
) EM_error2b( 0, "default device = YES" );
103 else EM_error2b( 0, "default device = NO" );
104 if( info
.nativeFormats
== 0 ) EM_error2b( 0, "no natively supported data formats(?)!" );
107 EM_error2b( 0, "natively supported data formats:" );
108 if( info
.nativeFormats
& RTAUDIO_SINT8
) EM_error2b( 0, " 8-bit int" );
109 if( info
.nativeFormats
& RTAUDIO_SINT16
) EM_error2b( 0, " 16-bit int" );
110 if( info
.nativeFormats
& RTAUDIO_SINT24
) EM_error2b( 0, " 24-bit int" );
111 if( info
.nativeFormats
& RTAUDIO_SINT32
) EM_error2b( 0, " 32-bit int" );
112 if( info
.nativeFormats
& RTAUDIO_FLOAT32
) EM_error2b( 0, " 32-bit float" );
113 if( info
.nativeFormats
& RTAUDIO_FLOAT64
) EM_error2b( 0, " 64-bit float" );
115 if ( info
.sampleRates
.size() < 1 ) EM_error2b( 0,"no supported sample rates found!" );
118 EM_error2b( 0, "supported sample rates:" );
119 for( unsigned int j
= 0; j
< info
.sampleRates
.size(); j
++ )
120 EM_error2b( 0, " %d Hz", info
.sampleRates
[j
] );
128 //-----------------------------------------------------------------------------
131 //-----------------------------------------------------------------------------
132 void Digitalio::probe()
134 RtAudio
* rta
= NULL
;
135 RtAudioDeviceInfo info
;
138 try { rta
= new RtAudio( ); }
141 // problem finding audio devices, most likely
142 EM_error2b( 0, "%s", err
.getMessageString() );
147 int devices
= rta
->getDeviceCount();
148 EM_error2b( 0, "found %d device(s) ...", devices
);
149 // EM_error2( 0, "--------------------------" );
152 for( int i
= 1; i
<= devices
; i
++ )
154 try { info
= rta
->getDeviceInfo(i
); }
155 catch( RtError
& error
)
157 error
.printMessage();
162 EM_error2b( 0, "------( chuck -- dac%d )---------------", i
);
165 if( i
< devices
) EM_error2( 0, "" );
176 #if !defined(__PLATFORM_WIN32__) || defined(__WINDOWS_PTHREAD__)
177 //-----------------------------------------------------------------------------
178 // name: set_priority()
180 //-----------------------------------------------------------------------------
181 static t_CKBOOL
set_priority( CHUCK_THREAD tid
, t_CKINT priority
)
183 struct sched_param param
;
187 EM_log( CK_LOG_FINE
, "setting thread priority to: %ld...", priority
);
190 if( pthread_getschedparam( tid
, &policy
, ¶m
) )
194 param
.sched_priority
= priority
;
198 if( pthread_setschedparam( tid
, policy
, ¶m
) )
204 //-----------------------------------------------------------------------------
205 // name: set_priority()
207 //-----------------------------------------------------------------------------
208 static t_CKBOOL
set_priority( CHUCK_THREAD tid
, t_CKINT priority
)
210 // if priority is 0 then done
211 if( !priority
) return TRUE
;
214 EM_log( CK_LOG_FINE
, "setting thread priority to: %ld...", priority
);
216 // set the priority the thread
217 if( !SetThreadPriority( tid
, priority
) )
225 //-----------------------------------------------------------------------------
226 // name: get_current_time()
228 //-----------------------------------------------------------------------------
229 static t_CKFLOAT
get_current_time( t_CKBOOL fresh
= TRUE
)
231 #ifdef __PLATFORM_WIN32__
234 return t
.time
+ t
.millitm
/1000.0;
236 static struct timeval t
;
237 if( fresh
) gettimeofday(&t
,NULL
);
238 return t
.tv_sec
+ (t_CKFLOAT
)t
.tv_usec
/1000000;
246 static CHUCK_THREAD g_tid_synthesis
= 0;
247 static XThread
* g_watchdog_thread
= NULL
;
248 static t_CKBOOL g_watchdog_state
= FALSE
;
249 static t_CKFLOAT g_watchdog_time
= 0;
252 //-----------------------------------------------------------------------------
255 //-----------------------------------------------------------------------------
256 #if !defined(__PLATFORM_WIN32__) || defined(__WINDOWS_PTHREAD__)
257 static void * watch_dog( void * )
259 static unsigned int __stdcall
watch_dog( void * )
265 t_CKUINT priority
= Chuck_VM::our_priority
;
268 EM_log( CK_LOG_SEVERE
, "starting real-time watch dog processs..." );
271 EM_log( CK_LOG_INFO
, "watchdog timeout: %f::second", g_watchdog_timeout
);
272 EM_log( CK_LOG_INFO
, "watchdog thread priority: %d", priority
);
273 EM_log( CK_LOG_INFO
, "watchdog countermeasure priority: %d", g_watchdog_countermeasure_priority
);
277 // boost watchdog by same priority
278 if( Chuck_VM::our_priority
!= 0x7fffffff )
279 Chuck_VM::set_priority( priority
, NULL
);
282 while( g_do_watchdog
)
285 time
= get_current_time( TRUE
);
286 // fprintf( stderr, "last: %f now: %f\n", g_watchdog_time, time );
289 if( g_watchdog_state
== FALSE
)
292 // if( Digitalio::m_xrun > 100 )
293 if( time
- g_watchdog_time
> g_watchdog_timeout
)
296 EM_log( CK_LOG_SEVERE
, "real-time watchdog counter-measure activating..." );
298 if( g_tid_synthesis
&& Chuck_VM::our_priority
!= 0x7fffffff )
299 set_priority( g_tid_synthesis
, g_watchdog_countermeasure_priority
);
301 g_watchdog_state
= TRUE
;
307 // if( Digitalio::m_xrun == 0 )
308 if( time
- g_watchdog_time
< g_watchdog_timeout
)
311 EM_log( CK_LOG_SEVERE
, "real-time watchdog resting..." );
313 if( g_tid_synthesis
&& Chuck_VM::our_priority
!= 0x7fffffff )
314 set_priority( g_tid_synthesis
, Chuck_VM::our_priority
);
316 g_watchdog_state
= FALSE
;
325 EM_log( CK_LOG_SEVERE
, "stopping real-time watch dog process..." );
333 //-----------------------------------------------------------------------------
334 // name: watchdog_start()
336 //-----------------------------------------------------------------------------
337 BOOL__
Digitalio::watchdog_start()
340 if( g_watchdog_thread
)
344 g_do_watchdog
= TRUE
;
346 g_watchdog_thread
= new XThread
;
348 g_watchdog_thread
->start( watch_dog
, NULL
);
355 //-----------------------------------------------------------------------------
356 // name: watchdog_stop()
358 //-----------------------------------------------------------------------------
359 BOOL__
Digitalio::watchdog_stop()
362 if( !g_watchdog_thread
)
366 g_do_watchdog
= FALSE
;
369 SAFE_DELETE( g_watchdog_thread
);
377 //-----------------------------------------------------------------------------
378 // name: initialize()
380 //-----------------------------------------------------------------------------
381 BOOL__
Digitalio::initialize( DWORD__ num_dac_channels
,
382 DWORD__ num_adc_channels
,
383 DWORD__ sampling_rate
,
384 DWORD__ bps
, DWORD__ buffer_size
,
385 DWORD__ num_buffers
, DWORD__ block
,
386 Chuck_VM
* vm_ref
, BOOL__ rt_audio
,
387 void * callback
, void * data
)
392 m_num_channels_out
= num_dac_channels
;
393 m_num_channels_in
= num_adc_channels
;
394 m_sampling_rate
= sampling_rate
;
396 m_buffer_size
= buffer_size
;
397 m_num_buffers
= num_buffers
;
404 DWORD__ num_channels
;
405 int bufsize
= m_buffer_size
;
407 // if rt_audio is false, then set block to FALSE to avoid deadlock
408 if( !rt_audio
) m_block
= FALSE
;
410 // if real-time audio
414 try { m_rtaudio
= new RtAudio( ); }
417 // problem finding audio devices, most likely
418 EM_error2( 0, "%s", err
.getMessageString() );
419 return m_init
= FALSE
;
423 EM_log( CK_LOG_FINE
, "initializing RtAudio..." );
430 EM_log( CK_LOG_FINE
, "trying %d input %d output...",
431 m_num_channels_in
, m_num_channels_out
);
433 m_rtaudio
->openStream(
434 m_dac_n
, m_num_channels_out
, m_adc_n
, m_num_channels_in
,
435 CK_RTAUDIO_FORMAT
, sampling_rate
,
436 &bufsize
, num_buffers
);
441 EM_log( CK_LOG_INFO
, "initializing callback..." );
444 if( block
) m_rtaudio
->setStreamCallback( &cb
, vm_ref
);
445 else m_rtaudio
->setStreamCallback( &cb2
, vm_ref
);
449 m_rtaudio
->setStreamCallback( (RtAudioCallback
)callback
, data
);
452 } catch( RtError err
) {
454 EM_log( CK_LOG_INFO
, "exception caught: '%s'...", err
.getMessageString() );
455 EM_log( CK_LOG_INFO
, "trying %d input %d output...", 0, m_num_channels_out
);
457 bufsize
= buffer_size
;
459 m_rtaudio
->openStream(
460 m_dac_n
, m_num_channels_out
, 0, 0,
461 RTAUDIO_FLOAT32
, sampling_rate
,
462 &bufsize
, num_buffers
);
467 EM_log( CK_LOG_INFO
, "initializing callback (again)..." );
470 if( block
) m_rtaudio
->setStreamCallback( &cb
, vm_ref
);
471 else m_rtaudio
->setStreamCallback( &cb2
, vm_ref
);
475 m_rtaudio
->setStreamCallback( (RtAudioCallback
)callback
, data
);
478 } catch( RtError err
) {
479 EM_error2( 0, "%s", err
.getMessageString() );
480 SAFE_DELETE( m_rtaudio
);
481 return m_init
= FALSE
;
486 if( bufsize
!= (int)m_buffer_size
)
488 EM_log( CK_LOG_SEVERE
, "new buffer size: %d -> %i", m_buffer_size
, bufsize
);
489 m_buffer_size
= bufsize
;
498 num_channels
= num_dac_channels
> num_adc_channels
?
499 num_dac_channels
: num_adc_channels
;
501 EM_log( CK_LOG_SEVERE
, "allocating buffers for %d x %d samples...",
502 m_buffer_size
, num_channels
);
504 m_buffer_in
= new SAMPLE
[m_buffer_size
* num_channels
];
505 m_buffer_out
= new SAMPLE
[m_buffer_size
* num_channels
];
506 memset( m_buffer_in
, 0, m_buffer_size
* sizeof(SAMPLE
) * num_channels
);
507 memset( m_buffer_out
, 0, m_buffer_size
* sizeof(SAMPLE
) * num_channels
);
515 return m_init
= TRUE
;
521 //-----------------------------------------------------------------------------
524 //-----------------------------------------------------------------------------
525 int Digitalio::cb( char * buffer
, int buffer_size
, void * user_data
)
527 DWORD__ len
= buffer_size
* sizeof(SAMPLE
) * m_num_channels_out
;
531 // copy input to local buffer
532 if( m_num_channels_in
)
534 memcpy( m_buffer_in
, buffer
, len
);
536 if( m_extern_in
) memcpy( m_extern_in
, buffer
, len
);
540 // out is ready early
541 if( m_go
< start
&& m_go
> 1 && m_out_ready
) m_go
= start
;
542 // copy output into local buffer
545 while( !m_out_ready
&& n
-- ) usleep( 250 );
546 if( m_out_ready
&& g_do_watchdog
)
547 g_watchdog_time
= get_current_time( TRUE
);
548 // copy local buffer to be rendered
549 if( m_out_ready
&& !m_end
) memcpy( buffer
, m_buffer_out
, len
);
550 // set all elements of local buffer to silence
551 else memset( buffer
, 0, len
);
553 else // initial condition
556 if( !m_go
&& Chuck_VM::our_priority
!= 0x7fffffff )
557 Chuck_VM::set_priority( Chuck_VM::our_priority
, NULL
);
559 // signal( SIGINT, signal_int );
562 if( g_do_watchdog
) g_watchdog_time
= get_current_time( TRUE
);
564 memset( buffer
, 0, len
);
572 n
= 8; while( !m_out_ready
&& n
-- ) usleep( 250 );
573 len
/= sizeof(SAMPLE
); DWORD__ i
= 0;
574 SAMPLE
* s
= (SAMPLE
*)buffer
;
575 while( i
< len
) *s
++ *= (SAMPLE
)i
++/len
;
580 if( m_extern_out
) memcpy( m_extern_out
, buffer
, len
);
582 // set pointer to the beginning - if not ready, then too late anyway
583 //*m_write_ptr = (SAMPLE *)m_buffer_out;
584 //*m_read_ptr = (SAMPLE *)m_buffer_in;
593 //-----------------------------------------------------------------------------
596 //-----------------------------------------------------------------------------
597 int Digitalio::cb2( char * buffer
, int buffer_size
, void * user_data
)
599 DWORD__ len
= buffer_size
* sizeof(SAMPLE
) * m_num_channels_out
;
600 Chuck_VM
* vm_ref
= (Chuck_VM
*)user_data
;
603 if( !m_go
&& Chuck_VM::our_priority
!= 0x7fffffff )
605 #if !defined(__PLATFORM_WIN32__) || defined(__WINDOWS_PTHREAD__)
606 g_tid_synthesis
= pthread_self();
608 // must duplicate for handle to be usable by other threads
609 g_tid_synthesis
= NULL
;
617 DUPLICATE_SAME_ACCESS
620 // TODO: close the duplicate handle?
622 Chuck_VM::set_priority( Chuck_VM::our_priority
, NULL
);
623 memset( buffer
, 0, len
);
630 g_watchdog_time
= get_current_time( TRUE
);
635 // let it go the first time
639 // copy input to local buffer
640 if( m_num_channels_in
)
642 memcpy( m_buffer_in
, buffer
, len
);
644 if( m_extern_in
) memcpy( m_extern_in
, buffer
, len
);
651 if( g_do_watchdog
) g_watchdog_time
= get_current_time( TRUE
);
652 // get samples from output
653 vm_ref
->run( buffer_size
);
655 if( m_xrun
) m_xrun
--;
663 // copy local buffer to be rendered
664 if( !m_end
) memcpy( buffer
, m_buffer_out
, len
);
665 // set all elements of local buffer to silence
666 else memset( buffer
, 0, len
);
669 if( m_extern_out
) memcpy( m_extern_out
, buffer
, len
);
678 //-----------------------------------------------------------------------------
681 //-----------------------------------------------------------------------------
682 BOOL__
Digitalio::start( )
685 m_rtaudio
->startStream();
687 } catch( RtError err
){ return FALSE
; }
695 //-----------------------------------------------------------------------------
698 //-----------------------------------------------------------------------------
699 BOOL__
Digitalio::stop( )
702 m_rtaudio
->stopStream();
704 } catch( RtError err
){ return FALSE
; }
712 //-----------------------------------------------------------------------------
715 //-----------------------------------------------------------------------------
716 BOOL__
Digitalio::tick( )
720 if( ++m_tick_count
>= m_start
)
722 m_rtaudio
->tickStream();
729 } catch( RtError err
){ return FALSE
; }
735 //-----------------------------------------------------------------------------
738 //-----------------------------------------------------------------------------
739 void Digitalio::shutdown()
741 if( !m_init
) return;
744 if( m_use_cb
) m_rtaudio
->cancelStreamCallback();
745 m_rtaudio
->stopStream();
748 m_rtaudio
->closeStream();
749 SAFE_DELETE( m_rtaudio
);
760 //-----------------------------------------------------------------------------
761 // name: DigitalOut()
763 //-----------------------------------------------------------------------------
764 DigitalOut::DigitalOut()
766 m_data_ptr_out
= NULL
;
767 m_data_max_out
= NULL
;
773 //-----------------------------------------------------------------------------
774 // name: ~DigitalOut()
776 //-----------------------------------------------------------------------------
777 DigitalOut::~DigitalOut()
785 //-----------------------------------------------------------------------------
786 // name: initialize()
787 // desc: initialize audio out
788 //-----------------------------------------------------------------------------
789 BOOL__
DigitalOut::initialize( )
791 // set pointer to beginning of local buffer
792 m_data_ptr_out
= Digitalio::m_use_cb
? Digitalio::m_buffer_out
793 : (SAMPLE
*)Digitalio::audio()->getStreamBuffer();
794 // calculate the end of the buffer
795 m_data_max_out
= m_data_ptr_out
+
796 Digitalio::buffer_size() * Digitalio::num_channels_out();
797 // set the writer pointer to our write pointer
798 Digitalio::m_write_ptr
= &m_data_ptr_out
;
806 //-----------------------------------------------------------------------------
809 //-----------------------------------------------------------------------------
810 BOOL__
DigitalOut::start()
813 return ( Digitalio::start() != 0 );
819 //-----------------------------------------------------------------------------
822 //-----------------------------------------------------------------------------
823 BOOL__
DigitalOut::stop()
834 //-----------------------------------------------------------------------------
837 //-----------------------------------------------------------------------------
838 void DigitalOut::cleanup()
845 //-----------------------------------------------------------------------------
848 //-----------------------------------------------------------------------------
849 BOOL__
DigitalOut::tick_out( SAMPLE sample
)
851 if( !prepare_tick_out() )
854 *m_data_ptr_out
++ = sample
;
862 //-----------------------------------------------------------------------------
865 //-----------------------------------------------------------------------------
866 BOOL__
DigitalOut::tick_out( SAMPLE sample_l
, SAMPLE sample_r
)
868 if( !prepare_tick_out() )
871 *m_data_ptr_out
++ = sample_l
;
872 *m_data_ptr_out
++ = sample_r
;
880 //-----------------------------------------------------------------------------
882 // desc: all channels
883 //-----------------------------------------------------------------------------
884 BOOL__
DigitalOut::tick_out( const SAMPLE
* samples
, DWORD__ n
)
886 if( !prepare_tick_out() )
889 if( !n
) n
= Digitalio::m_num_channels_out
;
891 *m_data_ptr_out
++ = *samples
++;
899 //-----------------------------------------------------------------------------
900 // name: prepare_tick_out()
902 //-----------------------------------------------------------------------------
903 inline BOOL__
DigitalOut::prepare_tick_out()
905 if( m_data_ptr_out
>= m_data_max_out
)
916 //-----------------------------------------------------------------------------
919 //-----------------------------------------------------------------------------
920 DWORD__
DigitalOut::render()
922 //if( !Digitalio::m_use_cb && !Digitalio::tick() ) return FALSE;
924 if( Digitalio::m_block
)
927 Digitalio::m_out_ready
= TRUE
;
929 while( Digitalio::m_out_ready
)
933 // set pointer to the beginning - if not ready, then too late anyway
934 *Digitalio::m_write_ptr
= (SAMPLE
*)Digitalio::m_buffer_out
;
942 //-----------------------------------------------------------------------------
945 //-----------------------------------------------------------------------------
946 DigitalIn::DigitalIn()
948 m_data_ptr_in
= NULL
;
949 m_data_max_in
= NULL
;
955 //-----------------------------------------------------------------------------
956 // name: ~DigitalIn()
958 //-----------------------------------------------------------------------------
959 DigitalIn::~DigitalIn()
967 //-----------------------------------------------------------------------------
968 // name: initialize()
969 // desc: initialize audio in
970 //-----------------------------------------------------------------------------
971 BOOL__
DigitalIn::initialize( )
973 m_data
= new SAMPLE
[Digitalio::buffer_size() * Digitalio::num_channels_in()];
974 memset( m_data
, 0, Digitalio::buffer_size() * Digitalio::num_channels_in() * sizeof(SAMPLE
) );
975 // set the buffer to the beginning of the local buffer
976 m_data_ptr_in
= Digitalio::m_use_cb
? m_data
977 : (SAMPLE
*)Digitalio::audio()->getStreamBuffer();
978 // calculate past buffer
979 m_data_max_in
= m_data_ptr_in
+
980 Digitalio::buffer_size() * Digitalio::num_channels_in();
981 // set the read pointer to the local pointer
982 Digitalio::m_read_ptr
= &m_data_ptr_in
;
984 m_data_ptr_in
= m_data_max_in
;
992 //-----------------------------------------------------------------------------
995 //-----------------------------------------------------------------------------
996 BOOL__
DigitalIn::start()
998 return ( Digitalio::start() != 0 );
1004 //-----------------------------------------------------------------------------
1005 // name: capture_stop()
1007 //-----------------------------------------------------------------------------
1008 BOOL__
DigitalIn::stop()
1017 //-----------------------------------------------------------------------------
1020 //-----------------------------------------------------------------------------
1021 void DigitalIn::cleanup()
1028 //-----------------------------------------------------------------------------
1031 //-----------------------------------------------------------------------------
1032 BOOL__
DigitalIn::tick_in( SAMPLE
* s
)
1034 if( !prepare_tick_in() )
1036 *s
= *m_data_ptr_in
++;
1044 //-----------------------------------------------------------------------------
1047 //-----------------------------------------------------------------------------
1048 BOOL__
DigitalIn::tick_in( SAMPLE
* l
, SAMPLE
* r
)
1050 if( !prepare_tick_in() )
1053 *l
= *m_data_ptr_in
++;
1054 *r
= *m_data_ptr_in
++;
1062 //-----------------------------------------------------------------------------
1065 //-----------------------------------------------------------------------------
1066 BOOL__
DigitalIn::tick_in( SAMPLE
* sample
, DWORD__ n
)
1068 if( !prepare_tick_in() )
1071 if( !n
) n
= Digitalio::m_num_channels_in
;
1073 *sample
++ = *m_data_ptr_in
++;
1081 //-----------------------------------------------------------------------------
1082 // name: prepare_tick_in()
1083 // desc: data ptr ok
1084 //-----------------------------------------------------------------------------
1085 inline BOOL__
DigitalIn::prepare_tick_in()
1087 if( m_data_ptr_in
>= m_data_max_in
)
1098 //-----------------------------------------------------------------------------
1099 // name: cb_capture()
1101 //-----------------------------------------------------------------------------
1102 DWORD__
DigitalIn::capture( )
1104 // if( !Digitalio::m_use_cb && !Digitalio::tick() ) return FALSE;
1106 if( Digitalio::m_block
)
1109 while( !Digitalio::m_in_ready
&& n
-- )
1114 memcpy( m_data
, Digitalio::m_buffer_in
, Digitalio::buffer_size() *
1115 Digitalio::num_channels_in() * sizeof(SAMPLE
) );
1116 Digitalio::m_in_ready
= FALSE
;
1117 // set pointer to the beginning - if not ready, then too late anyway
1118 *Digitalio::m_read_ptr
= (SAMPLE
*)m_data
;
1126 //-----------------------------------------------------------------------------
1127 // name: AudioBufferX()
1129 //-----------------------------------------------------------------------------
1130 AudioBufferX::AudioBufferX( DWORD__ size
)
1133 this->initialize( size
);
1137 m_data
= m_ptr_curr
= m_ptr_end
= NULL
;
1144 //-----------------------------------------------------------------------------
1145 // name: initialize()
1147 //-----------------------------------------------------------------------------
1148 BOOL__
AudioBufferX::initialize( DWORD__ size
)
1151 m_data
= (SAMPLE
*)malloc( size
* sizeof(SAMPLE
) );
1157 memset( m_data
, 0, size
* sizeof(SAMPLE
) );
1160 m_ptr_curr
= m_data
;
1161 m_ptr_end
= m_data
+ size
;
1169 //-----------------------------------------------------------------------------
1172 //-----------------------------------------------------------------------------
1173 void AudioBufferX::cleanup()
1182 m_ptr_curr
= m_ptr_end
= NULL
;
1188 //-----------------------------------------------------------------------------
1191 //-----------------------------------------------------------------------------
1192 DWORD__
AudioBufferX::size()
1200 //-----------------------------------------------------------------------------
1203 //-----------------------------------------------------------------------------
1204 SAMPLE
* AudioBufferX::data()
1212 //-----------------------------------------------------------------------------
1213 // name: AudioBufferIn()
1215 //-----------------------------------------------------------------------------
1216 AudioBufferIn::AudioBufferIn( DWORD__ size
)
1217 : AudioBufferX( size
)
1223 //-----------------------------------------------------------------------------
1224 // name: ~AudioBufferIn()
1226 //-----------------------------------------------------------------------------
1227 AudioBufferIn::~AudioBufferIn()
1235 //-----------------------------------------------------------------------------
1238 //-----------------------------------------------------------------------------
1239 BOOL__
AudioBufferIn::reset()
1241 m_ptr_curr
= m_data
;
1243 return TickIn::reset();
1249 //-----------------------------------------------------------------------------
1252 //-----------------------------------------------------------------------------
1253 BOOL__
AudioBufferIn::tick_in( SAMPLE
* s
)
1266 //-----------------------------------------------------------------------------
1269 //-----------------------------------------------------------------------------
1270 BOOL__
AudioBufferIn::tick_in( SAMPLE
* l
, SAMPLE
* r
)
1272 if( !m_data
|| m_ptr_curr
+ 2 >= m_ptr_end
)
1284 //-----------------------------------------------------------------------------
1287 //-----------------------------------------------------------------------------
1288 BOOL__
AudioBufferIn::tick_in( SAMPLE
* in
, DWORD__ n
)
1290 if( !m_data
|| m_ptr_curr
+ n
>= m_ptr_end
)
1294 *in
++ = *m_ptr_curr
++;
1302 //-----------------------------------------------------------------------------
1303 // name: AudioBufferOut()
1305 //-----------------------------------------------------------------------------
1306 AudioBufferOut::AudioBufferOut( DWORD__ size
)
1307 : AudioBufferX( size
)
1313 //-----------------------------------------------------------------------------
1314 // name: ~AudioBufferOut()
1316 //-----------------------------------------------------------------------------
1317 AudioBufferOut::~AudioBufferOut()
1325 //-----------------------------------------------------------------------------
1328 //-----------------------------------------------------------------------------
1329 BOOL__
AudioBufferOut::reset()
1331 m_ptr_curr
= m_data
;
1333 return TickOut::reset();
1339 //-----------------------------------------------------------------------------
1342 //-----------------------------------------------------------------------------
1343 BOOL__
AudioBufferOut::tick_out( SAMPLE s
)
1356 //-----------------------------------------------------------------------------
1359 //-----------------------------------------------------------------------------
1360 BOOL__
AudioBufferOut::tick_out( SAMPLE l
, SAMPLE r
)
1362 if( !m_data
|| m_ptr_curr
+ 2 >= m_ptr_end
)
1374 //-----------------------------------------------------------------------------
1377 //-----------------------------------------------------------------------------
1378 BOOL__
AudioBufferOut::tick_out( const SAMPLE
* out
, DWORD__ n
)
1380 if( !m_data
|| m_ptr_curr
+ n
>= m_ptr_end
)
1384 *m_ptr_curr
++ = *out
++;