5 #include "slPortability.h"
7 #ifdef SL_USING_OSS_AUDIO
8 #define SLDSP_DEFAULT_DEVICE "/dev/dsp"
10 #define SLDSP_DEFAULT_DEVICE "dsp"
11 #elif defined(__OpenBSD__)
12 #define SLDSP_DEFAULT_DEVICE "/dev/audio"
14 #define SLDSP_DEFAULT_DEVICE "dsp" // dummy ...
22 typedef unsigned char Uchar ;
23 typedef unsigned short Ushort ;
25 #define SL_DEFAULT_SAMPLING_RATE 11025
27 /* Set if the next slScheduler::update will die */
28 extern char *__slPendingError ;
31 class slSamplePlayer ;
48 audio_info_t ainfo; // ioctl structure
49 audio_offset_t audio_offset; // offset in audiostream
50 long counter; // counter-written packets
51 #elif defined(SL_USING_OSS_AUDIO)
52 audio_buf_info buff_info ;
54 ALconfig config; // configuration stuff
55 ALport port; // .. we are here
60 int ioctl ( int cmd, int param = 0 )
62 if ( error ) return param ;
64 if ( ::ioctl ( fd, cmd, & param ) == -1 )
66 perror ( "slDSP: ioctl" ) ;
75 HWAVEOUT hWaveOut; // device handle
76 WAVEFORMATEX Format; // open needs this
78 WAVEHDR wavehdr[ 3 ]; // for round robin ..
79 int curr_header; // index of actual wavehdr
80 long counter; // counter-written packets
84 void open ( char *device, int _rate, int _stereo, int _bps ) ;
86 void getBufferInfo () ;
87 void write ( void *buffer, size_t length ) ;
91 void setError () { error = SL_TRUE ; }
92 int getDriverBufferSize () ;
96 slDSP ( int _rate = SL_DEFAULT_SAMPLING_RATE,
97 int _stereo = SL_FALSE, int _bps = 8 )
99 open ( SLDSP_DEFAULT_DEVICE, _rate, _stereo, _bps ) ;
102 slDSP ( char *device, int _rate = SL_DEFAULT_SAMPLING_RATE,
103 int _stereo = SL_FALSE, int _bps = 8 )
105 open ( device, _rate, _stereo, _bps ) ;
108 ~slDSP () { close () ; }
110 float secondsRemaining () ;
111 float secondsUsed () ;
113 void play ( void *buffer, size_t length ) { write ( buffer, length ) ; }
115 int not_working () { return error ; }
117 int getBps () { return bps ; }
118 int getRate () { return rate ; }
119 int getStereo() { return stereo ; }
145 rate = SL_DEFAULT_SAMPLING_RATE ;
152 slSample () { init () ; }
154 slSample ( Uchar *buff, int leng )
157 setBuffer ( buff, leng ) ;
160 slSample ( char *fname, class slDSP *dsp = NULL )
169 if ( ref_count != 0 )
171 if ( __slPendingError == NULL )
173 "slXXXX: FATAL ERROR - Application deleted a sample while it was playing.\n" ;
179 void ref () { ref_count++ ; }
180 void unRef () { ref_count-- ; }
182 int getPlayCount () { return ref_count ; }
184 char *getComment () { return comment ; }
186 void setComment ( char *nc )
189 comment = new char [ strlen ( nc ) + 1 ] ;
190 strcpy ( comment, nc ) ;
193 Uchar *getBuffer () { return buffer ; }
194 int getLength () { return length ; }
196 void autoMatch ( slDSP *dsp ) ;
198 void setBuffer ( Uchar *buff, int leng )
202 buffer = new Uchar [ leng ] ;
205 memcpy ( buffer, buff, leng ) ;
210 /* These routines only set flags - use changeXXX () to convert a sound */
212 void setRate ( int r ) { rate = r ; }
213 void setBps ( int b ) { bps = b ; }
214 void setStereo ( int s ) { stereo = s ; }
216 int getRate () { return rate ; }
217 int getBps () { return bps ; }
218 int getStereo () { return stereo ; }
220 float getDuration () { return (float) getLength() /
221 (float) ( (getStereo()?2.0f:1.0f)*
222 (getBps()/8.0f)*getRate() ) ; }
224 int loadFile ( char *fname ) ;
226 int loadRawFile ( char *fname ) ;
227 int loadAUFile ( char *fname ) ;
228 int loadWavFile ( char *fname ) ;
230 void changeRate ( int r ) ;
231 void changeBps ( int b ) ;
232 void changeStereo ( int s ) ;
233 void changeToUnsigned () ;
235 void adjustVolume ( float vol ) ;
237 void print ( FILE *fd )
239 if ( buffer == NULL )
241 fprintf ( fd, "Empty sample buffer\n" ) ;
245 fprintf ( fd, "\"%s\"\n",(getComment() == NULL ||
246 getComment()[0]=='\0') ? "Sample" : comment ) ;
247 fprintf ( fd, "%s, %d bits per sample.\n",
248 getStereo() ? "Stereo" : "Mono", getBps() ) ;
249 fprintf ( fd, "%gKHz sample rate.\n", (float) getRate() / 1000.0f ) ;
250 fprintf ( fd, "%d bytes of samples == %g seconds duration.\n", getLength(), getDuration() ) ;
258 SL_SAMPLE_WAITING, /* Sound hasn't started playing yet */
259 SL_SAMPLE_RUNNING, /* Sound has started playing */
260 SL_SAMPLE_DONE , /* Sound is complete */
261 SL_SAMPLE_PAUSED /* Sound hasn't started playing yet */
267 SL_SAMPLE_CONTINUE, /* Don't allow yourself to be preempted */
268 SL_SAMPLE_ABORT , /* Abort playing the sound when preempted */
269 SL_SAMPLE_RESTART , /* Restart the sound when load permits */
270 SL_SAMPLE_MUTE , /* Continue silently until load permits */
271 SL_SAMPLE_DELAY /* Pause until load permits */
277 SL_SAMPLE_LOOP, /* Loop sound so that it plays forever */
278 SL_SAMPLE_ONE_SHOT /* Play sound just once */
283 SL_EVENT_COMPLETE, /* Sound finished playing */
284 SL_EVENT_LOOPED, /* Sound looped back to the start */
285 SL_EVENT_PREEMPTED /* Sound was preempted */
288 typedef void (*slCallBack) ( slSample *, slEvent, int ) ;
292 public: /* SJB TESTING! */
299 slReplayMode replay_mode ;
301 int getStepDelta ( float *_time, float *delta ) ;
305 slEnvelope ( int _nsteps, slReplayMode _rm, float *_times, float *_values )
309 time = new float [ nsteps ] ;
310 value = new float [ nsteps ] ;
311 memcpy ( time , _times , sizeof(float) * nsteps ) ;
312 memcpy ( value, _values, sizeof(float) * nsteps ) ;
318 slEnvelope ( int _nsteps = 1, slReplayMode _rm = SL_SAMPLE_ONE_SHOT )
322 time = new float [ nsteps ] ;
323 value = new float [ nsteps ] ;
325 for ( int i = 0 ; i < nsteps ; i++ )
326 time [ i ] = value [ i ] = 0.0 ;
333 if ( ref_count != 0 )
335 if ( __slPendingError == NULL )
337 "slXXXX: FATAL ERROR - Application deleted an envelope while it was playing.\n" ;
344 void ref () { ref_count++ ; }
345 void unRef () { ref_count-- ; }
347 int getPlayCount () { return ref_count ; }
349 void setStep ( int n, float _time, float _value )
351 if ( n >= 0 && n < nsteps )
354 value [ n ] = _value ;
358 float getStepValue ( int s ) { return value [ s ] ; }
359 float getStepTime ( int s ) { return time [ s ] ; }
361 int getNumSteps () { return nsteps ; }
363 float getValue ( float _time ) ;
365 void applyToPitch ( Uchar *dst, slSamplePlayer *src, int nframes, int start, int next_env ) ;
366 void applyToInvPitch ( Uchar *dst, slSamplePlayer *src, int nframes, int start, int next_env ) ;
367 void applyToVolume ( Uchar *dst, Uchar *src, int nframes, int start ) ;
368 void applyToInvVolume ( Uchar *dst, Uchar *src, int nframes, int start ) ;
371 #define SL_MAX_PRIORITY 16
372 #define SL_MAX_SAMPLES 16
373 #define SL_MAX_CALLBACKS (SL_MAX_SAMPLES * 2)
374 #define SL_MAX_ENVELOPES 4
378 SL_PITCH_ENVELOPE , SL_INVERSE_PITCH_ENVELOPE ,
379 SL_VOLUME_ENVELOPE, SL_INVERSE_VOLUME_ENVELOPE,
380 SL_FILTER_ENVELOPE, SL_INVERSE_FILTER_ENVELOPE,
381 SL_PAN_ENVELOPE , SL_INVERSE_PAN_ENVELOPE ,
382 SL_ECHO_ENVELOPE , SL_INVERSE_ECHO_ENVELOPE ,
387 struct slPendingCallBack
389 slCallBack callback ;
397 int lengthRemaining ; /* Sample frames remaining until repeat */
398 Uchar *bufferPos ; /* Sample frame to replay next */
401 slEnvelope *env [ SL_MAX_ENVELOPES ] ;
402 slEnvelopeType env_type [ SL_MAX_ENVELOPES ] ;
403 int env_start_time [ SL_MAX_ENVELOPES ] ;
405 slReplayMode replay_mode ;
406 slPreemptMode preempt_mode ;
407 slSampleStatus status ;
410 slCallBack callback ;
413 void low_read ( int nframes, Uchar *dest ) ;
417 slSamplePlayer ( slSample *s, slReplayMode rp_mode = SL_SAMPLE_ONE_SHOT,
418 int pri = 0, slPreemptMode pr_mode = SL_SAMPLE_DELAY,
419 int _magic = 0, slCallBack cb = NULL )
425 for ( int i = 0 ; i < SL_MAX_ENVELOPES ; i++ )
428 env_type [ i ] = SL_NULL_ENVELOPE ;
431 if ( sample ) sample -> ref () ;
435 replay_mode = rp_mode ;
436 preempt_mode = pr_mode ;
442 slPreemptMode getPreemptMode () { return preempt_mode ; }
446 return ( isRunning() &&
447 preempt_mode == SL_SAMPLE_CONTINUE ) ? (SL_MAX_PRIORITY+1) :
451 int preempt ( int delay ) ;
453 void addEnvelope ( int i, slEnvelope *_env, slEnvelopeType _type ) ;
457 if ( status != SL_SAMPLE_DONE )
458 status = SL_SAMPLE_PAUSED ;
463 if ( status == SL_SAMPLE_PAUSED )
464 status = SL_SAMPLE_RUNNING ;
469 status = SL_SAMPLE_WAITING ;
470 lengthRemaining = sample->getLength () ;
471 bufferPos = sample->getBuffer () ;
476 status = SL_SAMPLE_RUNNING ;
477 lengthRemaining = sample->getLength () ;
478 bufferPos = sample->getBuffer () ;
483 status = SL_SAMPLE_DONE ;
484 lengthRemaining = 0 ;
488 int getMagic () { return magic ; }
489 slSample *getSample () { return sample ; }
491 int isWaiting () { return status == SL_SAMPLE_WAITING ; }
492 int isPaused () { return status == SL_SAMPLE_PAUSED ; }
493 int isRunning () { return status == SL_SAMPLE_RUNNING ; }
494 int isDone () { return status == SL_SAMPLE_DONE ; }
496 void skip ( int nframes ) ;
497 void read ( int nframes, Uchar *dest, int next_env = 0 ) ;
501 class slScheduler : public slDSP
503 slPendingCallBack pending_callback [ SL_MAX_CALLBACKS ] ;
504 int num_pending_callbacks ;
506 float safety_margin ;
508 int mixer_buffer_size ;
510 Uchar *mixer_buffer ;
511 Uchar *spare_buffer0 ;
512 Uchar *spare_buffer1 ;
513 Uchar *spare_buffer2 ;
518 slSamplePlayer *samplePlayer [ SL_MAX_SAMPLES ] ;
522 void mixBuffer ( slSamplePlayer *a,
523 slSamplePlayer *b ) ;
525 void mixBuffer ( slSamplePlayer *a,
527 slSamplePlayer *c ) ;
529 Uchar mix ( Uchar a, Uchar b )
531 register int r = a + b - 0x80 ;
532 return ( r > 255 ) ? 255 :
536 Uchar mix ( Uchar a, Uchar b, Uchar c )
538 register int r = a + b + c - 0x80 - 0x80 ;
539 return ( r > 255 ) ? 255 :
543 void realUpdate ( int dump_first = SL_FALSE ) ;
545 void initBuffers () ;
549 static slScheduler *current ;
553 slScheduler ( int _rate = SL_DEFAULT_SAMPLING_RATE ) : slDSP ( _rate, SL_FALSE, 8 ) { init () ; }
554 slScheduler ( char *device,
555 int _rate = SL_DEFAULT_SAMPLING_RATE ) : slDSP ( device, _rate, SL_FALSE, 8 ) { init () ; }
558 static slScheduler *getCurrent () { return current ; }
560 int getTimeNow () { return now ; }
561 float getElapsedTime ( int then ) { return (float)(now-then)/(float)getRate() ; }
563 void flushCallBacks () ;
564 void addCallBack ( slCallBack c, slSample *s, slEvent e, int m ) ;
566 void update () { realUpdate ( SL_FALSE ) ; }
567 void dumpUpdate () { realUpdate ( SL_TRUE ) ; }
569 void addSampleEnvelope ( slSample *s = NULL, int magic = 0,
570 int slot = 1, slEnvelope *e = NULL,
571 slEnvelopeType t = SL_VOLUME_ENVELOPE )
573 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
574 if ( samplePlayer [ i ] != NULL &&
575 ( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
576 ( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
577 samplePlayer [ i ] -> addEnvelope ( slot, e, t ) ;
580 void resumeSample ( slSample *s = NULL, int magic = 0 )
582 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
583 if ( samplePlayer [ i ] != NULL &&
584 ( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
585 ( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
586 samplePlayer [ i ] -> resume () ;
589 void pauseSample ( slSample *s = NULL, int magic = 0 )
591 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
592 if ( samplePlayer [ i ] != NULL &&
593 ( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
594 ( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
595 samplePlayer [ i ] -> pause () ;
598 void stopSample ( slSample *s = NULL, int magic = 0 )
600 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
601 if ( samplePlayer [ i ] != NULL &&
602 ( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
603 ( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
604 samplePlayer [ i ] -> stop () ;
607 int loopSample ( slSample *s, int pri = 0, slPreemptMode mode = SL_SAMPLE_MUTE, int magic = 0, slCallBack cb = NULL )
609 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
610 if ( samplePlayer [ i ] == NULL )
612 samplePlayer [ i ] = new slSamplePlayer ( s, SL_SAMPLE_LOOP, pri, mode, magic, cb ) ;
619 int playSample ( slSample *s, int pri = 1, slPreemptMode mode = SL_SAMPLE_ABORT, int magic = 0, slCallBack cb = NULL )
621 for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
622 if ( samplePlayer [ i ] == NULL )
624 samplePlayer [ i ] = new slSamplePlayer ( s, SL_SAMPLE_ONE_SHOT, pri, mode, magic, cb ) ;
631 void setSafetyMargin ( float seconds ) { safety_margin = seconds ; }