home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / tracker.4.6.lzh / TRACKER4.6 / Nextstep / audio.c
Text File  |  1994-11-24  |  6KB  |  287 lines

  1. /* Nextstep/audio.c  crufted together by Frank Siegert */
  2. /* derived from the linux source */
  3.  
  4. #include "defs.h"
  5. #ifdef MALLOC_NOT_IN_STDLIB
  6. #include <malloc.h>        /* there is no malloc.h in NS */
  7. #else
  8. #include <stdlib.h>
  9. #endif
  10. #include <stdio.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include "extern.h"
  14.  
  15. /* Start NeXT defines */
  16.  
  17. #include <sound/sound.h>
  18. #include <sys/resource.h>
  19.  
  20. #import <mach/cthreads.h>
  21. #import <mach/mach.h>
  22. #import <mach/message.h>
  23. mutex_t waitMutex;
  24. condition_t waitCondition;
  25.  
  26. #define MAXSOUND 4            /* number of independent  
  27. sound frames */
  28. #define MAXSAMPLE 16*1024        /* size of a frame 16kByte*/
  29. #define MARKEDFREE 0            /* marker for unused frame */
  30. #define MARKEDBUSY 1            /* marker for used frame */
  31.  
  32. SNDSoundStruct *blubber[MAXSOUND];    /* array of sound frames */
  33. char     *fillSound;            /* current fill point */
  34. int    fillCount;            /* fill frame counter */
  35. int    actualSample=0;            /* frame to be filled up */
  36. int     played=0;
  37. int    lastFreed;            /* last sample freed */
  38.  
  39. /* End NeXT defines */
  40. /********************************************************************* 
  41. ********/
  42. /* soundEnd is called by the soundplayer when a sound finished  
  43. playing       */    
  44.  
  45. /********************************************************************* 
  46. ********/
  47. int soundEnd(SNDSoundStruct *s, int tag, int err)
  48. {
  49.     mutex_lock(waitMutex);
  50.     lastFreed=tag-1;
  51.     s->info[0]=MARKEDFREE;
  52.     played--;
  53.     mutex_unlock(waitMutex);
  54.     condition_signal(waitCondition);
  55.     return (0);
  56. }
  57.    
  58.  
  59. /********************************************************************* 
  60. ********/
  61. /* play is called by nextSample to put the current frame to the sound  
  62. queue  */
  63. /********************************************************************* 
  64. ********/
  65.   void play(SNDSoundStruct *theSound, int SoundTag)
  66.  {
  67.          int err;
  68.         theSound ->info[0]=MARKEDBUSY;
  69.         played++;
  70.          err =  
  71. SNDStartPlaying(theSound,SoundTag+1,63,0,0,(SNDNotificationFun)soundEn 
  72. d);
  73.         if (err) {
  74.             exit(0);
  75.         }
  76.        return;
  77. }
  78. /********************************************************************* 
  79. ********/
  80. /* nextSample plays the current Sample and tries to get a unused one,         
  81. */
  82. /* it waits until a frame is avaiable                           
  83. */
  84. /********************************************************************* 
  85. ********/
  86. char *nextSample()
  87.  {
  88.     play(blubber[actualSample],actualSample);    /* play  
  89. current */
  90.  
  91.      actualSample++;                    /* next frame  
  92. */
  93.     if (actualSample>=MAXSOUND) {            /* reached  
  94. end of frames */
  95.         actualSample=0;                /* back to  
  96. the beginning */
  97.     }
  98.  
  99.      mutex_lock(waitMutex);
  100.      while (blubber[actualSample]->info[0]==MARKEDBUSY) {
  101.         condition_wait(waitCondition, waitMutex);
  102.     }
  103.     mutex_unlock(waitMutex);
  104.  
  105.  
  106.     /* wait for free */
  107.      return (char  
  108. *)((int)blubber[actualSample]+sizeof(SNDSoundStruct));
  109. }
  110.  
  111.  
  112. ID("$Id: audio.c,v 4.0 1994/01/11 17:59:57 espie Exp espie $")
  113.  
  114. LOCAL unsigned char *buffer;        /* buffer for ready-to-play  
  115. samples */
  116. LOCAL unsigned short *buffer16;        /* Sure this isn't unsigned  
  117. short ? */
  118. LOCAL int buf_index;               /* index conflicts with  
  119. index(3) */
  120. LOCAL int buf_max;
  121. LOCAL int audio;                   /* /dev/dsp */
  122.  
  123.  
  124. LOCAL int stereo;                    /* are we  
  125. playing stereo or not ? */
  126. /* 256th of primary/secondary source for that side. */
  127. LOCAL int primary=512, secondary=0;
  128. LOCAL int dsp_samplesize = 16; /* must be 8 or 16 */
  129.  
  130. void set_mix(percent)
  131. int percent;
  132.     {
  133.     percent *= 256;                /* NS not used yet */
  134.     percent /= 100;
  135.     primary = percent;
  136.     secondary = 512 - percent;
  137.     }
  138.  
  139. int open_audio(f, s)
  140. int f;
  141. int s;
  142.     {
  143.     int loop;
  144.      waitMutex=mutex_alloc();
  145.     waitCondition=condition_alloc();
  146.  
  147.  /******************************************************************** 
  148. ***/
  149.  /* create some Sound structures in mem big enougth to hold a            
  150. */
  151.  /* a significant amount of sound data                                   
  152. */
  153.  
  154.     for (loop=0;loop<MAXSOUND;loop++) {
  155.      blubber[loop]=(SNDSoundStruct*)  
  156. calloc(sizeof(SNDSoundStruct)+(MAXSAMPLE*2)+16,1);  /* must be more  
  157. than MAXSAMPLE */
  158.     blubber[loop]->magic=SND_MAGIC;
  159.     blubber[loop]->dataLocation=sizeof(SNDSoundStruct);
  160.     blubber[loop]->dataSize=0;
  161.     blubber[loop]->dataFormat=SND_FORMAT_LINEAR_16;        /* 8  
  162. bit linear */
  163.  
  164.     blubber[loop]->samplingRate=SND_RATE_HIGH;                 /* 44  
  165. kHz */
  166.     blubber[loop]->channelCount=2;    
  167.     if (!s) blubber[loop]->channelCount=1;
  168.     blubber[loop]->info[0]=MARKEDFREE;
  169.     }
  170.  
  171.     fillCount=0;
  172.     actualSample=0;
  173.     lastFreed=0;
  174.  
  175.     fillSound=(char  
  176. *)((int)blubber[actualSample]+sizeof(SNDSoundStruct));     /* start of  
  177. data area */
  178.  
  179.     task_priority(task_self(), 18, TRUE);             /*  
  180. set our priority to high */
  181.         
  182.     SNDSetFilter(0);                        /*  
  183. low pass filter ON */
  184.  
  185.     stereo = s;
  186.     dsp_samplesize=16;
  187.     f = 44100;
  188.     buf_max=MAXSAMPLE*2;
  189.     buffer = fillSound;
  190.     buffer16 = (short *)buffer;
  191.     buf_index = 0;
  192.  
  193.     return f;
  194.     }
  195.  
  196. LOCAL void actually_flush_buffer()
  197.     {
  198.     int l,i;
  199.  
  200.     l = sizeof(*buffer) * buf_index;
  201.     if (dsp_samplesize !=8) l *= 2;
  202.     blubber[actualSample]->dataSize=l;
  203.     buffer16=buffer=nextSample();
  204.     buf_index = 0;
  205.     }
  206.  
  207. void output_samples(left, right)
  208. int left, right;
  209.     {
  210.     if (dsp_samplesize != 8)    /* Cool! 16 bits/sample */
  211.     {
  212.  
  213.         if (stereo)
  214.             {
  215.             if (buf_index * 2 >= buf_max - 1) 
  216.  
  217.                actually_flush_buffer();
  218.  
  219.             buffer16[buf_index++] = 
  220.  
  221.                left>>8;            /* YAKK! I have not  
  222. figured
  223.                            out why I need  
  224. this shift
  225.                            Without it sounds  
  226. like a
  227.                            hoard of crazy  
  228. daemons */
  229.             buffer16[buf_index++] = 
  230.  
  231.                right>>8;
  232.             }
  233.         else
  234.             {
  235.             if (buf_index * 2 >= buf_max) 
  236.  
  237.                actually_flush_buffer();
  238.             buffer16[buf_index++] = (left + right)>>8;
  239.             }
  240.     }
  241.     else
  242.     {
  243.         if (stereo)
  244.             {
  245.             if (buf_index >= buf_max - 1) 
  246.  
  247.                 actually_flush_buffer();
  248.             buffer[buf_index++] = 
  249.  
  250.                left>>8;
  251.             buffer[buf_index++] = 
  252.  
  253.                right>>8;
  254.             }
  255.         else
  256.             {
  257.             if (buf_index >= buf_max) 
  258.  
  259.                 actually_flush_buffer();
  260.             buffer[buf_index++] = ((left + right) >> 8);
  261.             }
  262.         }
  263.     }
  264.  
  265. void flush_buffer()
  266.     {    /* Dummy version */
  267.     }
  268.  
  269. void close_audio()
  270.     {
  271.     actually_flush_buffer();
  272.     free(buffer);
  273.     }
  274.  
  275. void set_synchro(s)
  276.     {
  277.     }
  278.  
  279. int update_frequency()
  280.     {
  281.     return 0;
  282.     }
  283.  
  284. void discard_buffer()
  285.     {
  286.     }
  287.