Yattm - unified GTK instant-messaging client logo
   [Generated for version 0.2-17 - Mon Jan 6 19:01:23 GMT+1 2003]

Home - Main Page - Data Structures - File List - Data Fields - Globals

sound.c

Go to the documentation of this file.
00001 /*
00002  * Yattm
00003  * Copyright (C) 1999, Torrey Searle <tsearle@uci.edu>
00004  *
00005  * code orriginally derrived from 
00006  *
00007  * gaim
00008  *
00009  * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  *
00025  */
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #  include <config.h>
00029 #endif
00030 
00031 #include "intl.h"
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <string.h>
00035 #include <sys/time.h>
00036 #include <sys/stat.h>
00037 #include <fcntl.h>
00038 #include <errno.h>
00039 #include <math.h>
00040 
00041 #ifdef __MINGW32__
00042 #include <windows.h>
00043 #else
00044 #include <sys/wait.h>
00045 #include <sys/signal.h>
00046 #endif
00047 
00048 #include "globals.h"
00049 #include "util.h"
00050 #include "dialog.h"
00051 #include "sound.h"
00052 #include "prefs.h"
00053 
00054 #ifdef ESD_SOUND
00055 #include <esd.h>
00056 #endif
00057 
00058 #ifdef ARTS_SOUND
00059 #include <artsc.h>
00060 #include <audiofile.h>
00061 #define BUFFERED_FRAME_COUNT 20000
00062 
00063 /* This is for when arts_init(); arts_free(); arts_init(); does not work
00064  * with GlobalComm=Arts::X11GlobalComm in ~/.mcoprc
00065  * This is KDE bug #34541
00066  * Chris Halls <chris.halls@nikocity.de>
00067  */
00068 #define ARTS_FREE_IS_BROKEN
00069 
00070 #endif
00071 
00072 static int (*play_soundfile)(gchar *soundfile);
00073 static void (*shutdown_sounddrv)();
00074 
00075 static int play_audio(gchar *soundfile)
00076 {
00077     int fd;
00078     struct stat info;   
00079     char * buf;
00080     char * audio_device;
00081     
00082     fd = open(soundfile,O_RDONLY);
00083     if (fd <= 0)
00084     {
00085         eb_debug(DBG_CORE, "Cannot open file %s\n", soundfile);
00086         return FALSE;
00087     }
00088     fstat(fd, &info);
00089     buf = alloca(info.st_size);
00090     read(fd,buf,24);
00091     read(fd,buf,info.st_size-24);
00092     close(fd);
00093     eb_debug(DBG_CORE, "File is %ld bytes\n", info.st_size);
00094 
00095     audio_device = getenv("AUDIODEV");
00096     if (audio_device == NULL) {
00097       /* OK, we're not running on a SunRay */
00098       audio_device = "/dev/audio";
00099     }
00100 
00101     eb_debug(DBG_CORE, "sending to %s\n", audio_device);
00102     
00103     fd = open(audio_device, O_WRONLY | O_EXCL);
00104     if (fd < 0)
00105         return FALSE;
00106     write(fd, buf, info.st_size-24);
00107     close(fd);
00108 
00109     return TRUE;
00110 }
00111 
00112 static int can_play_audio()
00113 {
00114         /* FIXME check for write access and such. */
00115     /* do not change from return 1 for WIN32 */
00116         return 1;
00117 
00118 }
00119 
00120 /*
00121 ** This routine converts from linear to ulaw
00122 **
00123 ** Craig Reese: IDA/Supercomputing Research Center
00124 ** Joe Campbell: Department of Defense
00125 ** 29 September 1989
00126 **
00127 ** References:
00128 ** 1) CCITT Recommendation G.711  (very difficult to follow)
00129 ** 2) "A New Digital Technique for Implementation of Any
00130 **     Continuous PCM Companding Law," Villeret, Michel,
00131 **     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
00132 **     1973, pg. 11.12-11.17
00133 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
00134 **     for Analog-to_Digital Conversion Techniques,"
00135 **     17 February 1987
00136 **
00137 ** Input: Signed 16 bit linear sample
00138 ** Output: 8 bit ulaw sample
00139 */
00140 
00141 #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
00142 #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
00143 #define CLIP 32635
00144 
00145 unsigned char linear2ulaw(int sample)
00146 {
00147   static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00148                              4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00149                              5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00150                              5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00151                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00152                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00153                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00154                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00155                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00156                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00157                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00158                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00159                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00160                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00161                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00162                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
00163   int sign, exponent, mantissa;
00164   unsigned char ulawbyte;
00165 
00166   /* Get the sample into sign-magnitude. */
00167   sign = (sample >> 8) & 0x80;      /* set aside the sign */
00168   if (sign != 0) sample = -sample;      /* get magnitude */
00169   if (sample > CLIP) sample = CLIP;     /* clip the magnitude */
00170 
00171   /* Convert from 16 bit linear to ulaw. */
00172   sample = sample + BIAS;
00173   exponent = exp_lut[(sample >> 7) & 0xFF];
00174   mantissa = (sample >> (exponent + 3)) & 0x0F;
00175   ulawbyte = ~(sign | (exponent << 4) | mantissa);
00176 #ifdef ZEROTRAP
00177   if (ulawbyte == 0) ulawbyte = 0x02;   /* optional CCITT trap */
00178 #endif
00179 
00180   return(ulawbyte);
00181 }
00182 
00183 #if HAVE_LIBAUDIOFILE
00184 
00185 /*
00186 ** This is only a declaration of the _af_ulaw2linear function.
00187 ** It is defined in libaudiofile.
00188 **
00189 ** This routine converts from ulaw to 16 bit linear.
00190 **
00191 ** Craig Reese: IDA/Supercomputing Research Center
00192 ** 29 September 1989
00193 **
00194 ** References:
00195 ** 1) CCITT Recommendation G.711  (very difficult to follow)
00196 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
00197 **     for Analog-to_Digital Conversion Techniques,"
00198 **     17 February 1987
00199 **
00200 ** Input: 8 bit ulaw sample
00201 ** Output: signed 16 bit linear sample
00202 */
00203 int _af_ulaw2linear (unsigned char ulawbyte);
00204 
00205 #else
00206 
00207 /*
00208 ** This routine converts from ulaw to 16 bit linear.
00209 **
00210 ** Craig Reese: IDA/Supercomputing Research Center
00211 ** 29 September 1989
00212 **
00213 ** References:
00214 ** 1) CCITT Recommendation G.711  (very difficult to follow)
00215 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
00216 **     for Analog-to_Digital Conversion Techniques,"
00217 **     17 February 1987
00218 **
00219 ** Input: 8 bit ulaw sample
00220 ** Output: signed 16 bit linear sample
00221 ** Z-note -- this is from libaudiofile.  Thanks guys!
00222 */
00223 int _af_ulaw2linear (unsigned char ulawbyte)
00224 {
00225   static int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764};
00226   int sign, exponent, mantissa, sample;
00227 
00228   ulawbyte = ~ulawbyte;
00229   sign = (ulawbyte & 0x80);
00230   exponent = (ulawbyte >> 4) & 0x07;
00231   mantissa = ulawbyte & 0x0F;
00232   sample = exp_lut[exponent] + (mantissa << (exponent + 3));
00233   if (sign != 0) sample = -sample;
00234   {
00235     return(sample);
00236   }
00237 }
00238 
00239 #endif
00240 
00241 #ifdef ESD_SOUND
00242 
00243 static int can_play_esd()
00244 {
00245     return TRUE;
00246 }
00247 
00248 static int play_esd_file(gchar *soundfile)
00249 {
00250     int esd_stat;
00251     esd_stat = esd_play_file(NULL, soundfile, 1);
00252     if (!esd_stat)
00253     {
00254         if (errno == ENOENT)
00255         {
00256             eb_debug(DBG_CORE, "Yattm: File not found - file = \"%s\"\n", soundfile);
00257         }
00258         else
00259         {
00260             eb_debug(DBG_CORE, "Yattm: Esd play file failed with code %d\n", errno);
00261         }
00262     }
00263     return esd_stat;
00264 }
00265 
00266 #else
00267 
00268 static int can_play_esd()
00269 {
00270     return FALSE;
00271 }
00272 
00273 static int play_esd_file(gchar *soundfile)
00274 {
00275     return FALSE;
00276 }
00277 
00278 #endif
00279 
00280 // *** ARTS Support ***
00281 // Comments/Questions -> sebastian.held@gmx.de
00282 #ifdef ARTS_SOUND
00283 
00284 static int test_arts()
00285 {
00286     int err;
00287     if ((err = arts_init()) != 0)
00288     {
00289     eb_debug(DBG_CORE, "WARNING (NO ERROR!):\ncan_play_arts(): arts_init() failed: %s\nIs artsd running?\n", arts_error_text( err ));
00290     return FALSE;
00291     }
00292     return TRUE;
00293 }
00294 
00295 static int can_play_arts()
00296 {
00297     
00298 #ifndef ARTS_FREE_IS_BROKEN
00299     return test_arts();
00300 #else
00301     pid_t childpid; 
00302     int childstatus;
00303     int ret = -1;
00304 
00305     childpid = fork();
00306 
00307     if(childpid==0)
00308     {
00309     /* Child - do test and exit with result */
00310     exit(test_arts() ? 0 : 1);
00311     }
00312     else if(childpid==-1) 
00313     {
00314     fprintf(stderr,"test_arts(): Failed at fork(), errno=%d\n", errno);
00315     return FALSE;
00316     }
00317     else 
00318     {
00319     if( (ret=waitpid(-1, &childstatus, 0) == -1)) {
00320         fprintf(stderr,"test_arts(): Failed at wait(), errno=%d\n", errno);
00321         perror("waitpid");
00322         return FALSE;
00323     }
00324 
00325     if( WEXITSTATUS(childstatus)==0 ) {
00326         return TRUE;
00327     }
00328     }
00329     return FALSE;   
00330 #endif
00331 }
00332 
00333 static void arts_shutdown()
00334 {
00335     arts_free();
00336 }
00337 
00338 static int play_arts_file(gchar *soundfile)
00339 {
00340     AFfilehandle fd;
00341     AFframecount frameCount, count;
00342     arts_stream_t artsStream;
00343     int frameSize, channelCount, sampleFormat, sampleWidth, err, susperr;
00344     double sampleRate;
00345     char * buf;
00346 
00347 #ifdef ARTS_FREE_IS_BROKEN
00348     /* We have to init every time */
00349     if ((err = arts_init()) != 0)
00350     {
00351     eb_debug(DBG_CORE, "WARNING (NO ERROR!):\ncan_play_arts(): arts_init() failed: %s\nIs artsd running?\n", arts_error_text( err ));
00352     return FALSE;
00353     }
00354 #endif
00355     
00356     fd = afOpenFile( soundfile, "r", NULL );
00357     if (fd == AF_NULL_FILEHANDLE)
00358     {
00359         eb_debug(DBG_CORE, "play_arts_file(): Cannot open file %s\n", soundfile);
00360         return FALSE;
00361     }
00362     frameCount = afGetFrameCount( fd, AF_DEFAULT_TRACK );
00363     frameSize = afGetFrameSize( fd, AF_DEFAULT_TRACK, 1 );
00364     channelCount = afGetChannels( fd, AF_DEFAULT_TRACK );
00365     sampleRate = afGetRate( fd, AF_DEFAULT_TRACK );
00366     afGetSampleFormat( fd, AF_DEFAULT_TRACK, &sampleFormat, &sampleWidth );
00367     eb_debug(DBG_CORE, "play_arts_file(): frameCount: %d\nframeSize: %i\nchannelCount: %i\nsampleRate: %.2f\n", (int) frameCount, frameSize, channelCount, sampleRate );
00368 
00369     artsStream = arts_play_stream( sampleRate, sampleWidth, channelCount, "EVERYBUDDY" );
00370     buf = (char *) malloc( BUFFERED_FRAME_COUNT * frameSize );
00371     count = afReadFrames( fd, AF_DEFAULT_TRACK, buf, BUFFERED_FRAME_COUNT );
00372     do
00373     {
00374         err = arts_write( artsStream, buf, count * frameSize );
00375         eb_debug(DBG_CORE, "count = %d\n", (int) count);
00376         eb_debug(DBG_CORE, "play_arts_file(): written bytes in artsStream: %i\n", err );
00377         if(err < 0)
00378     {
00379         eb_debug(DBG_CORE, "arts_write error: %s\n", arts_error_text( err ) );
00380     }
00381     }
00382     while ((count = afReadFrames( fd, AF_DEFAULT_TRACK, buf, BUFFERED_FRAME_COUNT)) && (err >= 0));
00383     free( buf );
00384     arts_close_stream( artsStream );
00385 
00386     afCloseFile( fd );
00387     susperr = arts_suspend();
00388     if(susperr < 0)
00389     {
00390         eb_debug(DBG_CORE, "arts_suspend error: %s\n", arts_error_text( err ) );
00391     }
00392 
00393     return (err<0?FALSE:TRUE);
00394 }
00395 #else
00396 static int can_play_arts()
00397 {
00398     return FALSE;
00399 }
00400 
00401 static void arts_shutdown()
00402 {
00403 }
00404 
00405 static int play_arts_file(gchar *soundfile)
00406 {
00407     return FALSE;
00408 }
00409 #endif
00410 
00411 char* auscale(char* infile, char*outfile, float scaling)
00412 {
00413 #ifndef __MINGW32__
00414     FILE *fd_in, *fd_out; 
00415     int bytes_read, x;
00416     guint32 header_size;
00417     size_t io_bytes;
00418   
00419     typedef struct
00420     {
00421     /* NOTE: THE GUINT32 VALUES BELOW ARE IN THE FILE AS BIG-ENDIAN
00422      * FORMAT !!!! */
00423     guchar  magic[4];  /* magic number '.snd' */
00424     guint32 dataloc;    /* offset to start of data */
00425     guint32 datasize;   /* num bytes of data */
00426     guint32 dataformat; /* data format code */
00427     guint32 samplerate; /* sampling rate */
00428     guint32 channelcount; /* num of channels */
00429     guchar  info;         /* null terminated id string
00430                    * (variable length) */
00431     } SNDStruct;
00432 
00433     SNDStruct auheader; /* first 28 bytes of .au header */
00434     guchar buf,   buf2[256];
00435     guchar map[256]; /* 8-bit mapping */
00436 
00437     if (scaling == 0.0) return(infile);  /* save time */
00438 
00439     if ((fd_in = fopen(infile, "rb")) == NULL)
00440     {
00441     fprintf(stderr,"Failed opening infile %s, errno=%d\n",infile, errno);
00442     return(infile);
00443     }
00444     /* see if this is .au file, if not then get out */
00445     if ((io_bytes = fread((guchar *)&auheader, sizeof(guchar), sizeof(auheader), fd_in)) != 28)
00446     {
00447     fclose(fd_in);
00448     fprintf(stderr,"Auscale - header read failed\n");
00449     return(infile);
00450     }
00451     if (strncmp(auheader.magic,".snd",4))
00452     {
00453     eb_debug(DBG_CORE, "Not .au file,file type=%X%X%X%X\n",auheader.magic[0],auheader.magic[1],auheader.magic[2],auheader.magic[3]);
00454     fclose(fd_in);
00455     return(infile);
00456     }
00457     x = GUINT32_FROM_BE(auheader.dataformat);
00458     if (x!=1) /* only want ulaw-8 format files */
00459     {
00460     eb_debug(DBG_CORE, "Not .au file,file type=%X%X%X%X\n",auheader.magic[0],auheader.magic[1],auheader.magic[2],auheader.magic[3]);
00461     fclose(fd_in);
00462     return(infile);
00463     }
00464     header_size= GUINT32_FROM_BE(auheader.dataloc); /* get offset to start of
00465                       * data */
00466     /* file is right type, reset to start */
00467     rewind(fd_in);
00468 
00469     if ((fd_out = fopen(outfile, "w+b")) == NULL)
00470     {
00471     fprintf(stderr,"Failed opening outfile %s, errno=%d\n",outfile,
00472         errno);
00473     fclose(fd_in);
00474     return(infile);
00475     }
00476 
00477     eb_debug(DBG_CORE, "Scaling = %f dB\n",scaling);
00478     scaling = pow(10.0,scaling/20.0);
00479 
00480         /* Build mapping */
00481     for (x=0; x<256 ; x++) map[x]=linear2ulaw(scaling*_af_ulaw2linear(x));
00482   
00483     /* Shift the .au header */
00484     /* copy the .au header */
00485     /* Note: There are unusual situations when the 'info' field is VERY
00486      * large and the start of data can therefore be larger than buf2.
00487      * The following 'while' statement takes care of that problem. */
00488     while(header_size >= (guint32)sizeof(buf2))
00489     {
00490     if ((io_bytes = fread(buf2, sizeof(guchar), sizeof(buf2), fd_in)) == sizeof(buf2))
00491     {
00492         if ((io_bytes = fwrite(buf2, sizeof(guchar), sizeof(buf2), fd_out)) !=
00493          sizeof(buf2))
00494         {
00495         eb_debug(DBG_CORE, "error copy au file");
00496         fclose(fd_out);
00497         fclose(fd_in);
00498         return (infile);
00499         }
00500     }
00501     else
00502     {
00503         eb_debug(DBG_CORE, "error copying au file");
00504         fclose(fd_in);
00505         fclose(fd_out);
00506         return (infile);
00507     }
00508     /* calc remaining amount of header */
00509     header_size -= (guint32)sizeof(buf2);
00510     }
00511     /* copy rest of header (or in most cases - all of it) */
00512     if ((io_bytes = fread(buf2, sizeof(guchar), header_size, fd_in)) ==
00513     header_size)
00514     {
00515     if ((io_bytes = fwrite(buf2, sizeof(guchar), header_size, fd_out))
00516         != header_size)
00517     {
00518         eb_debug(DBG_CORE, "error copying au file");
00519         fclose(fd_out);
00520         fclose(fd_in);
00521         return (infile);
00522     }
00523     }
00524     else
00525     {
00526     eb_debug(DBG_CORE, "error copying au file");
00527     fclose(fd_in);
00528     fclose(fd_out);
00529     return(infile);
00530     }
00531 
00532     /* Write the mapped data out */
00533     while((bytes_read = fread( &buf, sizeof(guchar), 1, fd_in)) > 0)
00534     {
00535     fwrite(map+buf, sizeof(guchar), 1, fd_out);
00536     }
00537     fclose(fd_in);
00538     fclose(fd_out);
00539 #endif
00540 
00541     return outfile;
00542 }
00543 
00544 
00545 
00546 /* file_ok 
00547  *
00548  * This routine test to see if file can be found and accessed
00549  * It issues an error message if the file open fails
00550  * Returns:
00551  * FALSE - If file open fails
00552  * TRUE - If file open succeeds
00553  *
00554  * MIZHI 04162001
00555  * I modified this function to use fstat, much cleaner...
00556  */
00557 
00558 gboolean file_ok(gchar *soundfile)
00559 {
00560   gchar message[1024];
00561     
00562   if (access(soundfile, R_OK) == -1) /* use 'access' rather than
00563                       * 'stat', so we also get access
00564                       * results 
00565                       */
00566     {
00567       /* find and report the error */
00568       switch (errno)
00569     {
00570     case ENOENT:
00571       g_snprintf(message, 1024, "Sound file \'%s\', Not Found", soundfile);
00572       break;
00573       
00574     case EACCES:
00575       g_snprintf(message, 1024, "Sound file \'%s\', Access Not Allowed", soundfile);
00576       break;
00577       
00578     default:
00579       g_snprintf(message, 1024, "Error in opening sound file \'%s\', error code = %d", soundfile, errno);
00580       break;
00581     }
00582       
00583       do_error_dialog(message, "Yattm-WARNING");
00584       return FALSE;
00585     }
00586   return TRUE;
00587 }
00588 
00589 
00590 void playsoundfile(gchar *soundfile)
00591 {
00592     
00593 #ifdef _WIN32
00594     if(!play_soundfile)
00595         return;
00596 
00597     if (!file_ok(soundfile)) 
00598         return;
00599 
00600     PlaySound(soundfile,NULL,SND_FILENAME|SND_SYNC);
00601     return;
00602 #endif
00603 #ifndef __MINGW32__
00604     gint pid;
00605 
00606     if(!play_soundfile)
00607         return;
00608 
00609     if (!file_ok(soundfile)) 
00610         return;
00611 
00612     pid = fork();
00613     if (pid < 0)
00614     {
00615         fprintf(stderr, "in playsoundfile(), fork failed!\n");
00616         return;
00617     }
00618     else if (pid == 0)
00619     {
00620         /* we're the child process, play the sound... */
00621         if(fGetLocalPref("SoundVolume") != 0.0)
00622         {
00623         gchar tmp_soundfile[9] = "ebXXXXXX";
00624             
00625             if (mkstemp(tmp_soundfile) == -1) /* create name for auscale */
00626             {
00627                 fprintf(stderr, "in playsoundfile(), mkstemp failed!\n");
00628                 return;
00629             }
00630 
00631             soundfile = auscale(soundfile,tmp_soundfile,fGetLocalPref("SoundVolume"));
00632 
00633             play_soundfile(soundfile);
00634 
00635             if (unlink(tmp_soundfile))
00636                fprintf(stderr,
00637                     "in playsoundfile(), unlink failed!\n");
00638         }
00639         else
00640         {
00641                 play_soundfile(soundfile);
00642         }
00643 
00644         _exit(0);
00645         
00646     }
00647     else
00648     {
00649         /* We're the parent process... */
00650         gtk_timeout_add(100, (GtkFunction)clean_pid, NULL);
00651     }
00652 #endif 
00653     
00654 }
00655 
00656 
00657 
00658 void play_sound(int sound)
00659 {
00660     if (do_no_sound_when_away && is_away)
00661         return;
00662     switch(sound) 
00663     {
00664         case BUDDY_AWAY:
00665         {
00666             playsoundfile(cGetLocalPref("BuddyAwayFilename"));
00667         }
00668         break;
00669         case BUDDY_ARRIVE:
00670         {
00671             playsoundfile(cGetLocalPref("BuddyArriveFilename"));
00672         }
00673         break;
00674         case BUDDY_LEAVE:
00675         {
00676             playsoundfile(cGetLocalPref("BuddyLeaveFilename"));
00677         }
00678         break;
00679         case SEND:
00680         {
00681             playsoundfile(cGetLocalPref("SendFilename"));
00682         }
00683         break;
00684         case RECEIVE:
00685         {
00686             playsoundfile(cGetLocalPref("ReceiveFilename"));
00687             break;
00688         }
00689         case FIRSTMSG:
00690         {
00691             playsoundfile(cGetLocalPref("FirstMsgFilename"));
00692             break;
00693         }
00694         default:
00695             return;
00696     }
00697 }
00698 
00699 void sound_init()
00700 {
00701     /* Determine which sound module will be used to play sounds */
00702 
00703 
00704     if(can_play_arts())
00705     {
00706         eb_debug(DBG_CORE,"Using arts sound\n");
00707         play_soundfile = play_arts_file;
00708         shutdown_sounddrv = arts_shutdown;
00709     }
00710     else if(can_play_esd())
00711     {
00712         eb_debug(DBG_CORE,"Using esd sound\n");
00713         play_soundfile = play_esd_file;
00714         shutdown_sounddrv = NULL;
00715     }
00716     /* handle sound direct to /dev/audio */
00717     else if (can_play_audio())
00718     {
00719         eb_debug(DBG_CORE,"Using raw audio\n");
00720         play_soundfile = play_audio;
00721         shutdown_sounddrv = NULL;
00722     }
00723     else
00724     {
00725        eb_debug(DBG_CORE,"Sound not available\n");
00726        play_soundfile = NULL;
00727        shutdown_sounddrv = NULL;
00728     }
00729 }
00730 
00731 void sound_shutdown()
00732 {
00733     if(shutdown_sounddrv != NULL) {
00734         shutdown_sounddrv();
00735     }
00736 }

Contact: Andy Maloney     [Documentation generated by doxygen]