4 slScheduler *slScheduler::current = NULL ;
5 char *__slPendingError = NULL ;
7 void slScheduler::init ()
13 fprintf ( stderr, "slScheduler: soundcard init failed.\n" ) ;
20 fprintf ( stderr, "slScheduler: Needs a sound card that supports 8 bits per sample.\n" ) ;
27 fprintf ( stderr, "slScheduler: Needs a sound card that supports monophonic replay.\n" ) ;
32 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
33 samplePlayer [ i ] = NULL ;
37 num_pending_callbacks = 0 ;
43 spare_buffer0 = NULL ;
44 spare_buffer1 = NULL ;
45 spare_buffer2 = NULL ;
50 void slScheduler::initBuffers ()
52 if ( not_working () ) return ;
55 delete spare_buffer0 ;
56 delete spare_buffer1 ;
57 delete spare_buffer2 ;
59 mixer_buffer_size = getDriverBufferSize () ;
61 mixer_buffer = new Uchar [ mixer_buffer_size ] ;
62 memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
64 spare_buffer0 = new Uchar [ mixer_buffer_size ] ;
65 spare_buffer1 = new Uchar [ mixer_buffer_size ] ;
66 spare_buffer2 = new Uchar [ mixer_buffer_size ] ;
69 slScheduler::~slScheduler ()
71 if ( current == this )
76 delete spare_buffer0 ;
77 delete spare_buffer1 ;
78 delete spare_buffer2 ;
85 void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb )
87 register int l = mixer_buffer_size ;
88 register Uchar *d = mixer_buffer ;
90 register Uchar *a = spare_buffer0 ;
91 register Uchar *b = spare_buffer1 ;
93 spa -> read ( l, a ) ;
94 spb -> read ( l, b ) ;
96 while ( l-- ) *d++ = mix ( *a++, *b++ ) ;
101 void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb,
102 slSamplePlayer *spc )
104 register int l = mixer_buffer_size ;
105 register Uchar *d = mixer_buffer ;
107 register Uchar *a = spare_buffer0 ;
108 register Uchar *b = spare_buffer1 ;
109 register Uchar *c = spare_buffer2 ;
111 spa -> read ( l, a ) ;
112 spb -> read ( l, b ) ;
113 spc -> read ( l, c ) ;
115 while ( l-- ) *d++ = mix ( *a++, *b++, *c++ ) ;
119 void slScheduler::realUpdate ( int dump_first )
123 if ( not_working () )
126 if ( __slPendingError != NULL )
128 fprintf ( stderr, __slPendingError ) ;
132 while ( secondsUsed() <= safety_margin )
134 slSamplePlayer *psp [ 3 ] ;
137 pri [ 0 ] = pri [ 1 ] = pri [ 2 ] = -1 ;
139 for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
141 if ( samplePlayer [ i ] == NULL )
144 /* Clean up dead sample players */
146 if ( samplePlayer [ i ] -> isDone () )
148 delete samplePlayer [ i ] ;
149 samplePlayer [ i ] = NULL ;
153 if ( samplePlayer [ i ] -> isPaused () )
156 int lowest = ( pri [0] <= pri [2] ) ?
157 (( pri [0] <= pri [1] ) ? 0 : 1 ) :
158 (( pri [1] <= pri [2] ) ? 1 : 2 ) ;
160 if ( samplePlayer[i]->getPriority() > pri[lowest] )
162 psp[lowest] = samplePlayer[i] ;
163 pri[lowest] = samplePlayer[i]->getPriority() ;
167 for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
169 if ( samplePlayer [ i ] == NULL )
172 if ( ! samplePlayer [ i ] -> isPaused () &&
173 samplePlayer [ i ] != psp[0] &&
174 samplePlayer [ i ] != psp[1] &&
175 samplePlayer [ i ] != psp[2] )
177 samplePlayer [ i ] -> preempt ( mixer_buffer_size ) ;
183 memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
188 psp[0] -> read ( mixer_buffer_size, mixer_buffer ) ;
191 mixBuffer ( psp[0], psp[1] ) ;
193 mixBuffer ( psp[0], psp[1], psp[2] ) ;
198 dump_first = SL_FALSE ;
201 play ( mixer_buffer, mixer_buffer_size ) ;
203 now += mixer_buffer_size ;
209 void slScheduler::addCallBack ( slCallBack c, slSample *s, slEvent e, int m )
211 if ( num_pending_callbacks >= SL_MAX_CALLBACKS )
213 fprintf ( stderr, "slScheduler: Too many pending callback events!\n" ) ;
217 slPendingCallBack *p = & ( pending_callback [ num_pending_callbacks++ ] ) ;
225 void slScheduler::flushCallBacks ()
228 Execute all the callbacks that we accumulated
231 This is done at the end of 'update' to reduce the risk
232 of nasty side-effects caused by 'unusual' activities
233 in the application's callback function.
236 while ( num_pending_callbacks > 0 )
238 slPendingCallBack *p = & ( pending_callback [ --num_pending_callbacks ] ) ;
241 (*(p->callback))( p->sample, p->event, p->magic ) ;