4 slScheduler *slScheduler::current = NULL ;
6 void slScheduler::init ()
12 fprintf ( stderr, "slScheduler: soundcard init failed.\n" ) ;
19 fprintf ( stderr, "slScheduler: Needs a sound card that supports 8 bits per sample.\n" ) ;
26 fprintf ( stderr, "slScheduler: Needs a sound card that supports monophonic replay.\n" ) ;
31 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
32 samplePlayer [ i ] = NULL ;
36 num_pending_callbacks = 0 ;
42 spare_buffer0 = NULL ;
43 spare_buffer1 = NULL ;
44 spare_buffer2 = NULL ;
49 void slScheduler::initBuffers ()
51 if ( not_working () ) return ;
54 delete spare_buffer0 ;
55 delete spare_buffer1 ;
56 delete spare_buffer2 ;
58 mixer_buffer_size = getDriverBufferSize () ;
60 mixer_buffer = new Uchar [ mixer_buffer_size ] ;
61 memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
63 spare_buffer0 = new Uchar [ mixer_buffer_size ] ;
64 spare_buffer1 = new Uchar [ mixer_buffer_size ] ;
65 spare_buffer2 = new Uchar [ mixer_buffer_size ] ;
68 slScheduler::~slScheduler ()
70 if ( current == this )
75 delete spare_buffer0 ;
76 delete spare_buffer1 ;
77 delete spare_buffer2 ;
84 void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb )
86 register int l = mixer_buffer_size ;
87 register Uchar *d = mixer_buffer ;
89 register Uchar *a = spare_buffer0 ;
90 register Uchar *b = spare_buffer1 ;
92 spa -> read ( l, a ) ;
93 spb -> read ( l, b ) ;
95 while ( l-- ) *d++ = mix ( *a++, *b++ ) ;
100 void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb,
101 slSamplePlayer *spc )
103 register int l = mixer_buffer_size ;
104 register Uchar *d = mixer_buffer ;
106 register Uchar *a = spare_buffer0 ;
107 register Uchar *b = spare_buffer1 ;
108 register Uchar *c = spare_buffer2 ;
110 spa -> read ( l, a ) ;
111 spb -> read ( l, b ) ;
112 spc -> read ( l, c ) ;
114 while ( l-- ) *d++ = mix ( *a++, *b++, *c++ ) ;
118 void slScheduler::realUpdate ( int dump_first )
122 if ( not_working () )
125 while ( secondsUsed() <= safety_margin )
127 slSamplePlayer *psp [ 3 ] ;
130 pri [ 0 ] = pri [ 1 ] = pri [ 2 ] = -1 ;
132 for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
134 if ( samplePlayer [ i ] == NULL )
137 /* Clean up dead sample players */
139 if ( samplePlayer [ i ] -> isDone () )
141 delete samplePlayer [ i ] ;
142 samplePlayer [ i ] = NULL ;
146 if ( samplePlayer [ i ] -> isPaused () )
149 int lowest = ( pri [0] <= pri [2] ) ?
150 (( pri [0] <= pri [1] ) ? 0 : 1 ) :
151 (( pri [1] <= pri [2] ) ? 1 : 2 ) ;
153 if ( samplePlayer[i]->getPriority() > pri[lowest] )
155 psp[lowest] = samplePlayer[i] ;
156 pri[lowest] = samplePlayer[i]->getPriority() ;
160 for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
162 if ( samplePlayer [ i ] == NULL )
165 if ( ! samplePlayer [ i ] -> isPaused () &&
166 samplePlayer [ i ] != psp[0] &&
167 samplePlayer [ i ] != psp[1] &&
168 samplePlayer [ i ] != psp[2] )
170 samplePlayer [ i ] -> preempt ( mixer_buffer_size ) ;
176 memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
181 psp[0] -> read ( mixer_buffer_size, mixer_buffer ) ;
184 mixBuffer ( psp[0], psp[1] ) ;
186 mixBuffer ( psp[0], psp[1], psp[2] ) ;
191 dump_first = SL_FALSE ;
194 play ( mixer_buffer, mixer_buffer_size ) ;
196 now += mixer_buffer_size ;
202 void slScheduler::addCallBack ( slCallBack c, slSample *s, slEvent e, int m )
204 if ( num_pending_callbacks >= SL_MAX_CALLBACKS )
206 fprintf ( stderr, "slScheduler: Too many pending callback events!\n" ) ;
210 slPendingCallBack *p = & ( pending_callback [ num_pending_callbacks++ ] ) ;
218 void slScheduler::flushCallBacks ()
221 Execute all the callbacks that we accumulated
224 This is done at the end of 'update' to reduce the risk
225 of nasty side-effects caused by 'unusual' activities
226 in the application's callback function.
229 while ( num_pending_callbacks > 0 )
231 slPendingCallBack *p = & ( pending_callback [ --num_pending_callbacks ] ) ;
234 (*(p->callback))( p->sample, p->event, p->magic ) ;