source: abuse/tags/pd/imlib/port/sgi/sound.c @ 604

Last change on this file since 604 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 6.7 KB
Line 
1/*************************************
2  Threaded sound driver system
3**************************************/
4
5// comminicates with sound sub-system via shared memory
6
7#include "macs.hpp"
8#include "sound.hpp"
9#include "readwav.hpp"
10#include "dprint.hpp"
11#include "jmalloc.hpp"
12#include <sys/types.h>
13#include <sys/ipc.h>
14#include <sys/shm.h>
15#include "timing.hpp"
16#include <sys/ipc.h>
17#include <sys/shm.h>
18#include <signal.h>
19#include <unistd.h>
20
21enum { SFXCMD_QUIT,
22       SFXCMD_REGISTER,
23       SFXCMD_UNREGISTER,
24       SFXCMD_PLAY
25     };
26
27#define DIN_NAME  "/tmp/sfxdrv.signal"
28#define DOUT_NAME "/tmp/sfxdrv.command"
29
30class sfx_handle
31{
32  public :
33  int shm_id;
34  sound_effect *me;
35  sfx_handle   *next; 
36  void         *user_data_pointer;
37  void         *shm_data_pointer;
38  sfx_handle(sound_effect *Me, sfx_handle *Next, void  *UData, void  *SData, int Shm_id)
39  { me=Me;
40    next=Next;
41    shm_id=Shm_id;
42    user_data_pointer=UData;
43    shm_data_pointer=SData;
44  }
45} ;
46
47static sfx_handle *sfx_list=NULL;
48static ushort last_allocated_sfx_id=0;
49static int sfx_driver_out_fd=-1,sfx_driver_in_fd=-1;
50static int sdriver_pid=0;
51
52
53static void kill_sound_driver()
54{
55  if (sfx_driver_out_fd>=0)
56  {
57    uchar cmd=SFXCMD_QUIT;        // failed, tell the driver good-bye
58    write(sfx_driver_out_fd,&cmd,1);
59    close(sfx_driver_out_fd);
60    close(sfx_driver_in_fd);
61    sfx_driver_out_fd=-1;
62
63    milli_wait(10);
64    kill(sdriver_pid,SIGUSR1);
65    unlink(DIN_NAME);
66    unlink(DOUT_NAME);
67  }
68}
69
70
71
72#ifdef __sgi
73static void sfx_clean_up(...)
74#else
75static void sfx_clean_up(int why)      // on exit unattach all shared memory links
76#endif
77
78  while (sfx_list)
79  {
80    if (sfx_driver_out_fd>=0)
81    {
82      int fail=0;
83      uchar cmd=SFXCMD_UNREGISTER;
84      if (write(sfx_driver_out_fd,&cmd,1)!=1)
85        fail=1;
86      else if (write(sfx_driver_out_fd,&sfx_list->shm_id,
87                     sizeof(sfx_list->shm_id))!=sizeof(sfx_list->shm_id))
88        fail=1;
89      if (fail)
90      { kill_sound_driver(); }
91    }
92
93    shmdt((char *)sfx_list->shm_data_pointer);  // detach the shared memory from us
94
95    sfx_handle *last=sfx_list;
96    sfx_list=sfx_list->next;
97    jfree(last);
98  }
99}
100
101
102
103#define TOTAL_SIGS 29
104
105int sigs[TOTAL_SIGS]={SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGTRAP,
106                      SIGABRT,SIGIOT,SIGBUS,SIGFPE,SIGKILL,
107                      SIGUSR1,SIGSEGV,SIGUSR2,SIGPIPE,SIGALRM,
108                      SIGTERM,SIGCHLD,SIGCONT,SIGSTOP,
109                      SIGTSTP,SIGTTIN,SIGTTOU,SIGIO,
110                      SIGURG,SIGXCPU,SIGXFSZ,SIGVTALRM,SIGPROF,
111                      SIGWINCH};
112
113#include <errno.h>
114
115sound_effect::sound_effect(char *filename)
116{
117  if (sfx_driver_out_fd>=0)
118  {
119    long sample_speed;
120    void *dat=read_wav(filename,sample_speed,size);
121
122    int id=shmget(IPC_PRIVATE,size,IPC_CREAT | 0777);
123    if (id==-1)
124    {
125      dprintf("Unable to allocate a shared memory id, please clean up\n");
126      jfree(dat);
127      data=NULL;
128    } else
129    {
130      void *shm_addr=shmat(id,NULL,0);  // attach as read/write
131      if ((long)shm_addr==-1)                   // if not able to attach
132      {
133        dprintf("shmat failed, too many shared memory segements or permission denied\n");
134        if (shmctl(id,IPC_RMID,NULL)!=0)
135          dprintf("shmctl failed, why?\n");
136        jfree(dat);
137        data=NULL;
138      } else
139      {
140        memcpy(shm_addr,dat,size);
141        jfree(dat);
142
143        int fail=0;
144        uchar cmd=SFXCMD_REGISTER;
145        if (write(sfx_driver_out_fd,&cmd,1)==0)
146          fail=1;
147        else if (write(sfx_driver_out_fd,&id,sizeof(id))!=sizeof(id))
148          fail=1;
149        else if (write(sfx_driver_out_fd,&size,sizeof(size))!=sizeof(size))
150          fail=1;
151        else if (read(sfx_driver_in_fd,&cmd,1)!=1)
152          fail=1;
153        else if (cmd!=1)    // did we get an 'OK' back so when can delete the shm ID?
154          fail=1;
155
156        if (shmctl(id,IPC_RMID,NULL)!=0)
157          dprintf("shmctl failed, why?\n");
158
159        if (fail)
160        {
161          kill_sound_driver();
162          shmdt((char *)shm_addr);
163          data=NULL;
164        } else
165        {
166          sfx_list=new sfx_handle(this,sfx_list,dat,shm_addr,id);       
167          data=(void *)sfx_list;
168        }
169      }     
170    }
171  }
172}
173
174
175sound_effect::~sound_effect()
176{
177  if (sfx_driver_out_fd>=0 && data)
178  {
179    sfx_handle *h=(sfx_handle *)data;
180    uchar cmd=SFXCMD_UNREGISTER;
181    int fail=0;
182    if (write(sfx_driver_out_fd,&cmd,1)!=1)
183      fail=1;
184    else if (write(sfx_driver_out_fd,&h->shm_id,sizeof(h->shm_id))!=sizeof(h->shm_id))
185      fail=1;
186
187    if (fail)
188    { kill_sound_driver(); }
189
190    shmdt((char *)h->shm_data_pointer);
191     
192  }
193}
194
195
196void sound_effect::play(int volume, int pitch, int panpot)
197{
198  if (sfx_driver_out_fd>=0 && data)
199  {   
200    sfx_handle *h=(sfx_handle *)data;
201    uchar cmd=SFXCMD_PLAY;
202    int fail=0;
203    if (write(sfx_driver_out_fd,&cmd,1)!=1)
204      fail=1;
205    else if (write(sfx_driver_out_fd,&h->shm_id,sizeof(h->shm_id))!=sizeof(h->shm_id))
206      fail=1;
207    else if (write(sfx_driver_out_fd,&volume,sizeof(volume))!=sizeof(volume))
208       fail=1;
209
210    if (fail)
211       kill_sound_driver();
212  }
213}
214
215
216int sound_init(int argc, char **argv)
217{
218  int i;
219  for (i=1;i<argc;i++)
220  {
221    if (!strcmp(argv[i],"-nosound"))
222    {
223      dprintf("sound : disabled with (-nosound)\n");
224      sfx_driver_out_fd=-1;
225      return 0;
226    }
227  }
228
229#ifdef __linux__
230  FILE *sfx_driver_fp=popen("lnx_sdrv","r");
231#else
232  FILE *sfx_driver_fp=popen("sgi_sdrv","r");
233#endif
234
235  if (!sfx_driver_fp)
236  {
237    dprintf("Error starting sound effect, could not run sgisfx_driver\n"
238            "make sure it is in your path and you execute permission\n");
239    sfx_driver_out_fd=-1;
240    return 0;
241  }
242
243  char str[100];
244  if (!fgets(str,100,sfx_driver_fp) || !sscanf(str,"%d",&sdriver_pid) || sdriver_pid<0)
245  {
246    pclose(sfx_driver_fp);
247    dprintf("sound effects driver returned failure, sound effects disabled\n");
248    sfx_driver_out_fd=-1;
249    return 0;
250  } else
251  {
252    pclose(sfx_driver_fp);
253
254    do
255    { milli_wait(50);
256    } while (access(DIN_NAME,R_OK));
257    sfx_driver_in_fd=open(DIN_NAME,O_RDWR);
258
259    do
260    { milli_wait(50);
261    } while (access(DOUT_NAME,W_OK));
262    fprintf(stderr,"opening %s for writing\n",DOUT_NAME);
263    sfx_driver_out_fd=open(DOUT_NAME,O_RDWR);
264
265    for (int i=0;i<TOTAL_SIGS;i++)
266       signal(sigs[i],sfx_clean_up);
267
268    atexit(sound_uninit);
269  }
270 
271  return SFX_INITIALIZED;
272}
273
274
275void sound_uninit()
276{
277  if (sfx_driver_out_fd>=0)
278  {
279    if (sfx_list)
280    {
281#ifdef __sgi
282      sfx_clean_up();
283#else
284      sfx_clean_up(1);
285#endif
286    }
287   
288    uchar cmd;
289    cmd=SFXCMD_QUIT;
290    write(sfx_driver_out_fd,&cmd,1);   // send quit commmand to the driver
291    close(sfx_driver_out_fd);          // close connection
292    close(sfx_driver_in_fd);          // close connection
293    sfx_driver_out_fd=-1;
294    sfx_driver_in_fd=-1;
295  }
296}
297
298
299
300
301
302
303song::song(char *filename) { ; }
304
305void song::play(unsigned char volume) { ; }
306int song::playing() { return 0; }
307void song::set_volume(int vol)  { ; }
308void song::stop(long fadeout_time) { ;  }
309int playing() { return 0; }
310song::~song() { ; }
311
312
313
Note: See TracBrowser for help on using the repository browser.