home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 February / PCO_0299.ISO / filesbbs / linux / mikmod-3.000 / mikmod-3 / mikmod-3.1.2 / drivers / drv_esd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-07  |  4.9 KB  |  218 lines

  1. /*    MikMod sound library
  2.     (c) 1998 Miodrag Vallat and others - see file AUTHORS for complete list
  3.  
  4.     This library is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU Library General Public License as
  6.     published by the Free Software Foundation; either version 2 of
  7.     the License, or (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU Library General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU Library General Public
  15.     License along with this library; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. /*==============================================================================
  20.  
  21.   $Id: drv_esd.c,v 1.16 1998/12/07 06:01:52 miod Exp $
  22.  
  23.   Mikmod driver for the Enlightened sound daemon (EsounD)
  24.  
  25. ==============================================================================*/
  26.  
  27. /*
  28.  
  29.     You should set the hostname of the machine running esd in the environment
  30.     variable 'ESPEAKER'. If this variable is not set, localhost is used.
  31.  
  32. */
  33.  
  34. #ifdef HAVE_CONFIG_H
  35. #include "config.h"
  36. #endif
  37.  
  38. #ifdef HAVE_UNISTD_H
  39. #include <unistd.h>
  40. #endif
  41. #include <errno.h>
  42. #ifdef HAVE_FCNTL_H
  43. #include <fcntl.h>
  44. #endif
  45. #include <stdlib.h>
  46. #include <signal.h>
  47. #include <time.h>
  48.  
  49. #include <esd.h>
  50.  
  51. #include <mikmod_internals.h>
  52.  
  53. static    int sndfd=-1;
  54. static    esd_format_t format;
  55. static    SBYTE *audiobuffer=NULL;
  56.  
  57. #ifndef HAVE_ESD_CLOSE
  58. #define esd_close(x) close(x)
  59. #endif
  60.  
  61. #ifndef ESD_DEFAULT_RATE
  62. #define ESD_DEFAULT_RATE (44100)
  63. #endif
  64.  
  65. /* I hope to have this function integrated into libesd someday...*/
  66. static ssize_t esd_writebuf(int fd,const void *buffer,size_t count)
  67. {
  68.     ssize_t start=0;
  69.  
  70.     while(start<count) {
  71.         ssize_t res;
  72.  
  73.         res=write(fd,(char*)buffer+start,count-start);
  74.         if(res<0) {
  75.             /* connection lost */
  76.             if(errno==EPIPE)
  77.                 return -1-start;
  78.         } else
  79.             start+=res;
  80.     }
  81.     return start;
  82. }
  83.  
  84. static BOOL ESD_IsThere(void)
  85. {
  86.     int fd;
  87.  
  88.     /* Try to esablish a connection with default esd settings */
  89.     if((fd=esd_play_stream(ESD_BITS16|ESD_STEREO|ESD_STREAM|ESD_PLAY,
  90.                            ESD_DEFAULT_RATE,NULL,"MikMod"))<0)
  91.         return 0;
  92.  
  93.     esd_close(fd);
  94.     return 1;
  95. }
  96.  
  97. static BOOL ESD_Init(void)
  98. {
  99.     format=(md_mode&DMODE_16BITS?ESD_BITS16:ESD_BITS8)|
  100.            (md_mode&DMODE_STEREO?ESD_STEREO:ESD_MONO)|ESD_STREAM|ESD_PLAY;
  101.  
  102.     /* make sure we can open an esd stream with our parameters */
  103.     if((sndfd=esd_play_stream(format,md_mixfreq,NULL,"MikMod"))<0) {
  104.         _mm_errno=MMERR_OPENING_AUDIO;
  105.         return 1;
  106.     }
  107.  
  108.     if(!(audiobuffer=(SBYTE*)_mm_malloc(ESD_BUF_SIZE*sizeof(char))))
  109.         return 1;
  110.  
  111.     return VC_Init();
  112. }
  113.  
  114. static void ESD_Exit(void)
  115. {
  116.     VC_Exit();
  117.     if (audiobuffer) {
  118.         free(audiobuffer);
  119.         audiobuffer=NULL;
  120.     }
  121.     if (sndfd>=0) {
  122.         esd_close(sndfd);
  123.         sndfd=-1;
  124.     }
  125. }
  126.  
  127. static void ESD_Update(void)
  128. {
  129.     int count=VC_WriteBytes(audiobuffer,ESD_BUF_SIZE);
  130.     static time_t losttime;
  131.  
  132.     if(sndfd>=0) {
  133.         if(esd_writebuf(sndfd,audiobuffer,count)<0) {
  134.             /* if we lost our connection with esd, clean up and work as the
  135.                nosound driver until we can reconnect */
  136.             esd_close(sndfd);
  137.             sndfd=-1;
  138.             losttime=time(NULL);
  139.         }
  140.     } else {
  141.         /* an alarm would be better, but then the library user could not use
  142.            alarm(2) himself... */
  143.         if (time(NULL)-losttime>=5) {
  144.             losttime=time(NULL);
  145.             /* Attempt to reconnect every 5 seconds */
  146.             if((sndfd=esd_play_stream(format,md_mixfreq,NULL,"MikMod"))>=0) {
  147.                 VC_SilenceBytes(audiobuffer,ESD_BUF_SIZE);
  148.                 esd_writebuf(sndfd,audiobuffer,ESD_BUF_SIZE);
  149.             }
  150.         }
  151.     }
  152. }
  153.  
  154. static BOOL ESD_PlayStart(void)
  155. {
  156.     if(sndfd<0)
  157.         if((sndfd=esd_play_stream(format,md_mixfreq,NULL,"MikMod"))<0) {
  158.             _mm_errno=MMERR_OPENING_AUDIO;
  159.             return 1;
  160.         }
  161.     /* since the default behaviour of SIGPIPE on most Unices is to kill the
  162.        program, we'll prefer handle EPIPE ourselves should the esd die */
  163.     signal(SIGPIPE,SIG_IGN);
  164.  
  165.     /* silence buffers */
  166.     VC_SilenceBytes(audiobuffer,ESD_BUF_SIZE);
  167.     esd_writebuf(sndfd,audiobuffer,ESD_BUF_SIZE);
  168.  
  169.     return VC_PlayStart();
  170. }
  171.  
  172. static void ESD_PlayStop(void)
  173. {
  174.     if (sndfd>=0) {
  175.         /* silence buffers */
  176.         VC_SilenceBytes(audiobuffer,ESD_BUF_SIZE);
  177.         esd_writebuf(sndfd,audiobuffer,ESD_BUF_SIZE);
  178.  
  179.         signal(SIGPIPE,SIG_DFL);
  180.     }
  181.  
  182.     VC_PlayStop();
  183. }
  184.  
  185. static BOOL ESD_Reset(void)
  186. {
  187.     ESD_Exit();
  188.     return ESD_Init();
  189. }
  190.  
  191. MDRIVER drv_esd={
  192.     NULL,
  193.     "Enlightened sound daemon",
  194.     /* use the same version number as the EsounD release it works with */
  195.     "Enlightened sound daemon (EsounD) driver v0.2.6",
  196.     0,255,
  197.     ESD_IsThere,
  198.     VC_SampleLoad,
  199.     VC_SampleUnload,
  200.     VC_SampleSpace,
  201.     VC_SampleLength,
  202.     ESD_Init,
  203.     ESD_Exit,
  204.     ESD_Reset,
  205.     VC_SetNumVoices,
  206.     ESD_PlayStart,
  207.     ESD_PlayStop,
  208.     ESD_Update,
  209.     VC_VoiceSetVolume,
  210.     VC_VoiceSetFrequency,
  211.     VC_VoiceSetPanning,
  212.     VC_VoicePlay,
  213.     VC_VoiceStop,
  214.     VC_VoiceStopped,
  215.     VC_VoiceGetPosition,
  216.     VC_VoiceRealVolume
  217. };
  218.