Annotation of hatari/src/audio.c, revision 1.1.1.8

1.1       root        1: /*
1.1.1.5   root        2:   Hatari - audio.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   This file contains the routines which pass the audio data to the SDL library.
1.1       root        8: */
1.1.1.8 ! root        9: char Audio_rcsid[] = "Hatari $Id: audio.c,v 1.20 2004/09/24 11:19:46 thothy Exp $";
1.1       root       10: 
1.1.1.2   root       11: #include <SDL.h>
                     12: 
1.1       root       13: #include "main.h"
                     14: #include "audio.h"
1.1.1.6   root       15: #include "configuration.h"
1.1       root       16: #include "debug.h"
                     17: #include "errlog.h"
                     18: #include "memAlloc.h"
                     19: #include "misc.h"
                     20: #include "sound.h"
                     21: 
                     22: 
                     23: /* 11Khz, 22Khz, 44Khz playback */
1.1.1.5   root       24: int SoundPlayBackFrequencies[] =
                     25: {
1.1       root       26:   11025,  /* PLAYBACK_LOW */
                     27:   22050,  /* PLAYBACK_MEDIUM */
                     28:   44100,  /* PLAYBACK_HIGH */
                     29: };
                     30: 
1.1.1.2   root       31: 
1.1.1.8 ! root       32: BOOL bSoundWorking = FALSE;               /* Is sound OK */
1.1.1.5   root       33: volatile BOOL bPlayingBuffer = FALSE;     /* Is playing buffer? */
                     34: int OutputAudioFreqIndex = FREQ_22Khz;    /* Playback rate (11Khz,22Khz or 44Khz) */
                     35: int SoundBufferSize = 1024;               /* Size of sound buffer */
                     36: int CompleteSndBufIdx;                    /* Replay-index into MixBuffer */
1.1.1.2   root       37: 
1.1       root       38: 
                     39: 
1.1.1.2   root       40: /*-----------------------------------------------------------------------*/
                     41: /*
1.1.1.5   root       42:   SDL audio callback function - copy emulation sound to audio system.
1.1.1.2   root       43: */
1.1.1.7   root       44: static void Audio_CallBack(void *userdata, Uint8 *stream, int len)
1.1.1.2   root       45: {
1.1.1.7   root       46:   Uint8 *pBuffer;
                     47:   int i;
                     48: 
1.1.1.6   root       49:   /* If there are only some samples missing to have a complete buffer,
                     50:    * we generate them here (sounds much better then!). However, if a lot of
                     51:    * samples are missing, then the system is probably too slow, so we don't
                     52:    * generate more samples to not make things worse... */
                     53:   if(nGeneratedSamples < len && len-nGeneratedSamples < 128)
                     54:     Sound_UpdateFromAudioCallBack();
                     55: 
1.1.1.7   root       56:   /* Pass completed buffer to audio system: Write samples into sound buffer
                     57:    * and convert them from 'signed' to 'unsigned' */
                     58:   pBuffer = stream;
                     59:   for(i = 0; i < len; i++)
                     60:   {
                     61:     *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) % MIXBUFFER_SIZE] ^ 128;
                     62:   }
1.1.1.5   root       63: 
                     64:   /* We should now have generated a complete frame of samples.
                     65:    * However, for slow systems we have to check how many generated samples
                     66:    * we may advance... */
                     67:   if(nGeneratedSamples >= len)
                     68:   {
                     69:     CompleteSndBufIdx += len;
                     70:     nGeneratedSamples -= len;
                     71:   }
                     72:   else
                     73:   {
                     74:     CompleteSndBufIdx += nGeneratedSamples;
                     75:     nGeneratedSamples = 0;
                     76:   }
                     77:   CompleteSndBufIdx = CompleteSndBufIdx % MIXBUFFER_SIZE;
1.1.1.2   root       78: }
                     79: 
1.1       root       80: 
1.1.1.2   root       81: /*-----------------------------------------------------------------------*/
1.1       root       82: /*
1.1.1.5   root       83:   Initialize the audio subsystem. Return TRUE if all OK.
                     84:   We use direct access to the sound buffer, set to a unsigned 8-bit mono stream.
1.1       root       85: */
1.1.1.2   root       86: void Audio_Init(void)
1.1       root       87: {
1.1.1.5   root       88:   SDL_AudioSpec desiredAudioSpec;    /* We fill in the desired SDL audio options here */
                     89: 
1.1.1.2   root       90:   /* Is enabled? */
1.1.1.7   root       91:   if (!ConfigureParams.Sound.bEnableSound)
1.1.1.4   root       92:   {
1.1.1.3   root       93:     /* Stop any sound access */
1.1.1.2   root       94:     ErrLog_File("Sound: Disabled\n");
                     95:     bSoundWorking = FALSE;
1.1       root       96:     return;
                     97:   }
                     98: 
1.1.1.4   root       99:   /* Init the SDL's audio subsystem: */
                    100:   if( SDL_WasInit(SDL_INIT_AUDIO)==0 )
                    101:   {
                    102:     if( SDL_InitSubSystem(SDL_INIT_AUDIO)<0 )
                    103:     {
                    104:       fprintf(stderr, "Could not init audio: %s\n", SDL_GetError() );
                    105:       bSoundWorking = FALSE;
                    106:       return;
                    107:     }
                    108:   }
                    109: 
                    110:   /* Set up SDL audio: */
1.1.1.3   root      111:   desiredAudioSpec.freq = SoundPlayBackFrequencies[OutputAudioFreqIndex];
1.1.1.5   root      112:   desiredAudioSpec.format = AUDIO_U8;           /* 8 Bit unsigned */
                    113:   desiredAudioSpec.channels = 1;                /* Mono */
                    114:   desiredAudioSpec.samples = 1024;              /* Buffer size */
1.1.1.3   root      115:   desiredAudioSpec.callback = Audio_CallBack;
                    116:   desiredAudioSpec.userdata = NULL;
1.1.1.5   root      117: 
                    118:   if( SDL_OpenAudio(&desiredAudioSpec, NULL) )  /* Open audio device */
1.1.1.3   root      119:   {
1.1.1.4   root      120:     fprintf(stderr, "Can't use audio: %s\n", SDL_GetError());
1.1.1.2   root      121:     bSoundWorking = FALSE;
1.1.1.3   root      122:     ConfigureParams.Sound.bEnableSound = FALSE;
1.1.1.7   root      123:     SDL_QuitSubSystem(SDL_INIT_AUDIO);
1.1.1.2   root      124:     return;
1.1       root      125:   }
1.1.1.3   root      126: 
1.1.1.5   root      127:   SoundBufferSize = desiredAudioSpec.size;      /* May be different than the requested one! */
                    128:   if(SoundBufferSize > MIXBUFFER_SIZE/2)
                    129:   {
                    130:     fprintf(stderr, "Warning: Soundbuffer size is too big!\n");
                    131:   }
                    132: 
                    133:   /* All OK */
                    134:   bSoundWorking = TRUE;
                    135:   /* And begin */
                    136:   Audio_EnableAudio(TRUE);
1.1       root      137: }
                    138: 
1.1.1.2   root      139: 
                    140: /*-----------------------------------------------------------------------*/
1.1       root      141: /*
1.1.1.5   root      142:   Free audio subsystem
1.1       root      143: */
1.1.1.2   root      144: void Audio_UnInit(void)
1.1       root      145: {
1.1.1.7   root      146:   if (bSoundWorking)
                    147:   {
                    148:     /* Stop */
                    149:     Audio_EnableAudio(FALSE);
1.1.1.2   root      150: 
1.1.1.7   root      151:     SDL_CloseAudio();
                    152: 
                    153:     bSoundWorking = FALSE;
                    154:   }
1.1       root      155: }
                    156: 
1.1.1.2   root      157: 
                    158: /*-----------------------------------------------------------------------*/
1.1       root      159: /*
1.1.1.5   root      160:   Lock the audio sub system so that the callback function will not be called.
1.1       root      161: */
1.1.1.5   root      162: void Audio_Lock(void)
1.1       root      163: {
1.1.1.5   root      164:   SDL_LockAudio();
1.1       root      165: }
                    166: 
1.1.1.2   root      167: 
                    168: /*-----------------------------------------------------------------------*/
1.1       root      169: /*
1.1.1.5   root      170:   Unlock the audio sub system so that the callback function will be called again.
1.1       root      171: */
1.1.1.5   root      172: void Audio_Unlock(void)
1.1       root      173: {
1.1.1.5   root      174:   SDL_UnlockAudio();
1.1       root      175: }
                    176: 
1.1.1.2   root      177: 
                    178: /*-----------------------------------------------------------------------*/
1.1       root      179: /*
1.1.1.3   root      180:   Set audio playback frequency variable, pass as PLAYBACK_xxxx
1.1       root      181: */
1.1.1.2   root      182: void Audio_SetOutputAudioFreq(int Frequency)
1.1       root      183: {
1.1.1.5   root      184:   /* Do not reset sound system if nothing has changed! */
                    185:   if(Frequency != OutputAudioFreqIndex)
                    186:   {
                    187:     /* Set new frequency, index into SoundPlayBackFrequencies[] */
                    188:     OutputAudioFreqIndex = Frequency;
1.1.1.2   root      189: 
1.1.1.7   root      190:     /* Re-open SDL audio interface if necessary: */
                    191:     if (bSoundWorking)
                    192:     {
                    193:       Audio_UnInit();
                    194:       Audio_Init();
                    195:     }
1.1.1.5   root      196:   }
1.1       root      197: }
                    198: 
1.1.1.2   root      199: 
                    200: /*-----------------------------------------------------------------------*/
1.1       root      201: /*
1.1.1.5   root      202:   Start/Stop sound buffer
1.1       root      203: */
1.1.1.5   root      204: void Audio_EnableAudio(BOOL bEnable)
1.1       root      205: {
1.1.1.5   root      206:   if(bEnable && !bPlayingBuffer)
                    207:   {
                    208:     /* Start playing */
                    209:     SDL_PauseAudio(FALSE);
                    210:     bPlayingBuffer = TRUE;
                    211:   }
                    212:   else if(!bEnable && bPlayingBuffer)
                    213:   {
                    214:     /* Stop from playing */
1.1.1.7   root      215:     SDL_PauseAudio(TRUE);
                    216:     bPlayingBuffer = FALSE;
1.1       root      217:   }
                    218: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.