4 char *__slPendingError = NULL ;
6 slScheduler *slScheduler::current = NULL ;
8 void slScheduler::init ()
14 fprintf ( stderr, "slScheduler: soundcard init failed.\n" ) ;
21 fprintf ( stderr, "slScheduler: Needs a sound card that supports 8 bits per sample.\n" ) ;
28 fprintf ( stderr, "slScheduler: Needs a sound card that supports monophonic replay.\n" ) ;
33 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
34 samplePlayer [ i ] = NULL ;
38 num_pending_callbacks = 0 ;
44 spare_buffer0 = NULL ;
45 spare_buffer1 = NULL ;
46 spare_buffer2 = NULL ;
51 void slScheduler::initBuffers ()
57 delete spare_buffer0 ;
58 delete spare_buffer1 ;
59 delete spare_buffer2 ;
61 mixer_buffer_size = getDriverBufferSize () ;
63 mixer_buffer = new Uchar [ mixer_buffer_size ] ;
64 memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
66 spare_buffer0 = new Uchar [ mixer_buffer_size ] ;
67 spare_buffer1 = new Uchar [ mixer_buffer_size ] ;
68 spare_buffer2 = new Uchar [ mixer_buffer_size ] ;
71 slScheduler::~slScheduler ()
73 if ( current == this )
78 delete spare_buffer0 ;
79 delete spare_buffer1 ;
80 delete spare_buffer2 ;
87 void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb )
89 register int l = mixer_buffer_size ;
90 register Uchar *d = mixer_buffer ;
92 register Uchar *a = spare_buffer0 ;
93 register Uchar *b = spare_buffer1 ;
95 spa -> read ( l, a ) ;
96 spb -> read ( l, b ) ;
98 while ( l-- ) *d++ = mix ( *a++, *b++ ) ;
103 void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb,
104 slSamplePlayer *spc )
106 register int l = mixer_buffer_size ;
107 register Uchar *d = mixer_buffer ;
109 register Uchar *a = spare_buffer0 ;
110 register Uchar *b = spare_buffer1 ;
111 register Uchar *c = spare_buffer2 ;
113 spa -> read ( l, a ) ;
114 spb -> read ( l, b ) ;
115 spc -> read ( l, c ) ;
117 while ( l-- ) *d++ = mix ( *a++, *b++, *c++ ) ;
121 void slScheduler::realUpdate ( int dump_first )
123 if ( not_working () )
126 if ( __slPendingError != NULL )
128 fprintf ( stderr, "%s", __slPendingError ) ;
134 while ( secondsUsed() <= safety_margin )
136 slSamplePlayer *psp [ 3 ] ;
139 pri [ 0 ] = pri [ 1 ] = pri [ 2 ] = -1 ;
141 for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
143 if ( samplePlayer [ i ] == NULL )
146 /* Clean up dead sample players */
148 if ( samplePlayer [ i ] -> isDone () )
150 delete samplePlayer [ i ] ;
151 samplePlayer [ i ] = NULL ;
155 if ( samplePlayer [ i ] -> isPaused () )
158 int lowest = ( pri [0] <= pri [2] ) ?
159 (( pri [0] <= pri [1] ) ? 0 : 1 ) :
160 (( pri [1] <= pri [2] ) ? 1 : 2 ) ;
162 if ( samplePlayer[i]->getPriority() > pri[lowest] )
164 psp[lowest] = samplePlayer[i] ;
165 pri[lowest] = samplePlayer[i]->getPriority() ;
169 for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
171 if ( samplePlayer [ i ] == NULL )
174 if ( ! samplePlayer [ i ] -> isPaused () &&
175 samplePlayer [ i ] != psp[0] &&
176 samplePlayer [ i ] != psp[1] &&
177 samplePlayer [ i ] != psp[2] )
179 samplePlayer [ i ] -> preempt ( mixer_buffer_size ) ;
185 memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
190 psp[0] -> read ( mixer_buffer_size, mixer_buffer ) ;
193 mixBuffer ( psp[0], psp[1] ) ;
195 mixBuffer ( psp[0], psp[1], psp[2] ) ;
200 dump_first = SL_FALSE ;
203 play ( mixer_buffer, mixer_buffer_size ) ;
205 now += mixer_buffer_size ;
211 void slScheduler::addCallBack ( slCallBack c, slSample *s, slEvent e, int m )
213 if ( not_working () )
216 if ( num_pending_callbacks >= SL_MAX_CALLBACKS )
218 fprintf ( stderr, "slScheduler: Too many pending callback events!\n" ) ;
222 slPendingCallBack *p = & ( pending_callback [ num_pending_callbacks++ ] ) ;
230 void slScheduler::flushCallBacks ()
232 if ( not_working () )
236 Execute all the callbacks that we accumulated
239 This is done at the end of 'update' to reduce the risk
240 of nasty side-effects caused by 'unusual' activities
241 in the application's callback function.
244 while ( num_pending_callbacks > 0 )
246 slPendingCallBack *p = & ( pending_callback [ --num_pending_callbacks ] ) ;
249 (*(p->callback))( p->sample, p->event, p->magic ) ;