Advertisement
Guest User

Untitled

a guest
Jun 27th, 2017
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.76 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <SDL/SDL.h>
  3. #include <math.h>
  4. #include "s3m_header.h"
  5. #include "helpers.h"
  6.  
  7. typedef struct
  8. {
  9.     const signed short *src;
  10.  
  11.     unsigned int pos;
  12.  
  13.     float frac;
  14.     float rate;
  15.  
  16.     unsigned int length;
  17.     unsigned int loopEnd;
  18.     unsigned int loopLength;
  19.  
  20.     unsigned int vol;
  21.  
  22.     float volL, volR;
  23. } MIXERCHANNEL;
  24.  
  25. MIXERCHANNEL mixerChn[NUM_MIX_CHANNELS];
  26.  
  27. static signed int mixBufL[SOUND_BUFFER_SIZE], mixBufR[SOUND_BUFFER_SIZE];
  28.  
  29. int generateFrame(int numSamples);
  30.  
  31. int audioRunning = 0;
  32.  
  33. void mixerClrChn(int ch)
  34. {
  35.     memset(&mixerChn[ch], 0, sizeof (MIXERCHANNEL));
  36.  
  37.     return;
  38. }
  39.  
  40. void mixerClrAllChn(void)
  41. {
  42.     memset(mixerChn, 0, NUM_MIX_CHANNELS * sizeof (MIXERCHANNEL));
  43.  
  44.     return;
  45. }
  46.  
  47. void mixerSetChnSrc(int ch, const signed short *src, unsigned int length, unsigned int loopLength, unsigned int loopEnd)
  48. {
  49.     mixerChn[ch].src = src;
  50.     mixerChn[ch].frac = 0.0f;
  51.     mixerChn[ch].pos = 0;
  52.  
  53.     mixerChn[ch].length = length;
  54.     mixerChn[ch].loopEnd = loopEnd;
  55.     mixerChn[ch].loopLength = loopLength;
  56.  
  57.     return;
  58. }
  59.  
  60. void mixerSetChnPos(int ch, unsigned int pos)
  61. {
  62.     if (pos <= mixerChn[ch].length)
  63.     {
  64.         if (mixerChn[ch].loopLength > 0)
  65.         {
  66.             if (pos > mixerChn[ch].loopEnd)
  67.             {
  68.                 pos -= mixerChn[ch].loopLength;
  69.             }
  70.         }
  71.  
  72.         mixerChn[ch].frac = 0.0f;
  73.         mixerChn[ch].pos = pos;
  74.     }
  75.  
  76.     return;
  77. }
  78.  
  79. void mixerSetChn(int ch, float vol, int pan)
  80. {
  81.     mixerChn[ch].volL = vol * (float)(0xFF - pan);
  82.     mixerChn[ch].volR = vol * (float)(       pan);
  83.    
  84.     return;
  85. }
  86.  
  87. void mixerSetChnRate(int ch, float rate)
  88. {
  89.     mixerChn[ch].rate = 1.0f / ((float)SOUND_FREQUENCY / rate);
  90.     mixerChn[ch].frac = 0.0f;
  91.  
  92.     return;
  93. }
  94.  
  95. void mixAudio(signed short *target, int numSamples)
  96. {
  97.     memset(mixBufL, 0, numSamples * sizeof (int));
  98.     memset(mixBufR, 0, numSamples * sizeof (int));
  99.  
  100.     {
  101.         int ch;
  102.         for (ch = 0; ch < NUM_MIX_CHANNELS; ch++)
  103.         {
  104.             int s;
  105.             for (s = 0; s < numSamples; s++)
  106.             {
  107.                 if (mixerChn[ch].src != NULL)
  108.                 {
  109.                     mixBufL[s] += (signed int)((float)mixerChn[ch].src[mixerChn[ch].pos] * mixerChn[ch].volL);
  110.                     mixBufR[s] += (signed int)((float)mixerChn[ch].src[mixerChn[ch].pos] * mixerChn[ch].volR);
  111.  
  112.                     mixerChn[ch].frac += mixerChn[ch].rate;
  113.  
  114.                     if (mixerChn[ch].frac >= 1.0f)
  115.                     {
  116.                         mixerChn[ch].pos  += (int)mixerChn[ch].frac;
  117.                         mixerChn[ch].frac -= (int)mixerChn[ch].frac;
  118.                     }
  119.  
  120.                     if (mixerChn[ch].loopLength > 0)
  121.                     {
  122.                         if (mixerChn[ch].pos >= mixerChn[ch].loopEnd)
  123.                         {
  124.                             mixerChn[ch].pos -= mixerChn[ch].loopLength;
  125.                         }
  126.                     }
  127.                     else if (mixerChn[ch].pos >= mixerChn[ch].length)
  128.                     {
  129.                         mixerChn[ch].src = NULL;
  130.  
  131.                         break;
  132.                     }
  133.                 }
  134.             }
  135.         }
  136.     }
  137.  
  138.     {
  139.         signed short *out = target;
  140.  
  141.         int s;
  142.         for (s = 0; s < numSamples; s++)
  143.         {
  144.             *out++ = (signed short)clamp((signed int)(mixBufL[s] / 0x8000), -0x8000, 0x7FFF);
  145.             *out++ = (signed short)clamp((signed int)(mixBufR[s] / 0x8000), -0x8000, 0x7FFF);
  146.         }
  147.     }
  148.  
  149.     return;
  150. }
  151.  
  152. static void SDLMixAudioCallback(void *userdata, unsigned char *stream, int len)
  153. {
  154.     signed short *out = (signed short *)stream;
  155.     int numSamples = len / 4;
  156.  
  157.     while (numSamples)
  158.     {
  159.         int gen = generateFrame(numSamples);
  160.         mixAudio(out, gen);
  161.  
  162.         out += (gen * 2);
  163.         numSamples -= gen;
  164.     }
  165.  
  166.     return;
  167. }
  168.  
  169. int openMixer(void)
  170. {
  171.     SDL_AudioSpec fmt;
  172.  
  173.     mixerClrAllChn();
  174.  
  175.     fmt.freq = SOUND_FREQUENCY;
  176.     fmt.format = AUDIO_S16SYS;
  177.     fmt.channels = 2;
  178.     fmt.samples = SOUND_BUFFER_SIZE;
  179.     fmt.callback = SDLMixAudioCallback;
  180.     fmt.userdata = NULL;
  181.  
  182.     if (SDL_OpenAudio(&fmt, NULL) < 0)
  183.     {
  184.         printf("Unable to open audio: %s\n", SDL_GetError());
  185.  
  186.         return 0;
  187.     }
  188.  
  189.     SDL_PauseAudio(0);
  190.  
  191.     audioRunning = 1;
  192.  
  193.     return 1;
  194. }
  195.  
  196. void closeMixer(void)
  197. {
  198.     mixerClrAllChn();
  199.  
  200.     SDL_PauseAudio(1);
  201.     SDL_CloseAudio();
  202.  
  203.     return;
  204. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement