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

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.13  root        9: const char Audio_fileid[] = "Hatari audio.c : " __DATE__ " " __TIME__;
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.1.9   root       16: #include "log.h"
1.1       root       17: #include "sound.h"
                     18: 
                     19: 
1.1.1.14! root       20: int nAudioFrequency = 44100;              /* Sound playback frequency */
        !            21: bool bSoundWorking = false;               /* Is sound OK */
        !            22: volatile bool bPlayingBuffer = false;     /* Is playing buffer? */
1.1.1.5   root       23: int SoundBufferSize = 1024;               /* Size of sound buffer */
                     24: int CompleteSndBufIdx;                    /* Replay-index into MixBuffer */
1.1.1.2   root       25: 
1.1       root       26: 
                     27: 
1.1.1.2   root       28: /*-----------------------------------------------------------------------*/
1.1.1.11  root       29: /**
                     30:  * SDL audio callback function - copy emulation sound to audio system.
                     31:  */
1.1.1.7   root       32: static void Audio_CallBack(void *userdata, Uint8 *stream, int len)
1.1.1.2   root       33: {
1.1.1.12  root       34:        Sint16 *pBuffer;
1.1.1.9   root       35:        int i;
1.1.1.7   root       36: 
1.1.1.12  root       37:        pBuffer = (Sint16 *)stream;
                     38:        len = len / 4;  // Use length in samples (16 bit stereo), not in bytes
1.1.1.9   root       39: 
                     40:        if (nGeneratedSamples >= len)
                     41:        {
1.1.1.10  root       42:                /* Enough samples available: Pass completed buffer to audio system
                     43:                 * by write samples into sound buffer and by converting them from
                     44:                 * 'signed' to 'unsigned' */
                     45:                for (i = 0; i < len; i++)
                     46:                {
1.1.1.12  root       47:                        *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) % MIXBUFFER_SIZE][0];
                     48:                        *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) % MIXBUFFER_SIZE][1];
1.1.1.10  root       49:                }
1.1.1.9   root       50:                CompleteSndBufIdx += len;
                     51:                nGeneratedSamples -= len;
                     52:        }
1.1.1.10  root       53:        else  /* Not enough samples available: */
1.1.1.9   root       54:        {
1.1.1.10  root       55:                for (i = 0; i < nGeneratedSamples; i++)
                     56:                {
1.1.1.12  root       57:                        *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) % MIXBUFFER_SIZE][0];
                     58:                        *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) % MIXBUFFER_SIZE][1];
1.1.1.10  root       59:                }
                     60:                /* If the buffer is filled more than 50%, mirror sample buffer to fake the
                     61:                 * missing samples */
                     62:                if (nGeneratedSamples >= len/2)
                     63:                {
                     64:                        int remaining = len - nGeneratedSamples;
1.1.1.12  root       65:                        memcpy(pBuffer, stream+(nGeneratedSamples-remaining)*4, remaining*4);
1.1.1.10  root       66:                }
1.1.1.9   root       67:                CompleteSndBufIdx += nGeneratedSamples;
                     68:                nGeneratedSamples = 0;
1.1.1.10  root       69:                
1.1.1.9   root       70:        }
1.1.1.10  root       71: 
1.1.1.9   root       72:        CompleteSndBufIdx = CompleteSndBufIdx % MIXBUFFER_SIZE;
1.1.1.2   root       73: }
                     74: 
1.1       root       75: 
1.1.1.2   root       76: /*-----------------------------------------------------------------------*/
1.1.1.11  root       77: /**
1.1.1.14! root       78:  * Initialize the audio subsystem. Return true if all OK.
1.1.1.11  root       79:  * We use direct access to the sound buffer, set to a unsigned 8-bit mono stream.
                     80:  */
1.1.1.2   root       81: void Audio_Init(void)
1.1       root       82: {
1.1.1.9   root       83:        SDL_AudioSpec desiredAudioSpec;    /* We fill in the desired SDL audio options here */
1.1.1.5   root       84: 
1.1.1.9   root       85:        /* Is enabled? */
                     86:        if (!ConfigureParams.Sound.bEnableSound)
                     87:        {
                     88:                /* Stop any sound access */
                     89:                Log_Printf(LOG_DEBUG, "Sound: Disabled\n");
1.1.1.14! root       90:                bSoundWorking = false;
1.1.1.9   root       91:                return;
                     92:        }
                     93: 
                     94:        /* Init the SDL's audio subsystem: */
                     95:        if (SDL_WasInit(SDL_INIT_AUDIO) == 0)
                     96:        {
                     97:                if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
                     98:                {
                     99:                        fprintf(stderr, "Could not init audio: %s\n", SDL_GetError() );
1.1.1.14! root      100:                        bSoundWorking = false;
1.1.1.9   root      101:                        return;
                    102:                }
                    103:        }
                    104: 
                    105:        /* Set up SDL audio: */
1.1.1.14! root      106:        desiredAudioSpec.freq = nAudioFrequency;
1.1.1.12  root      107:        desiredAudioSpec.format = AUDIO_S16SYS;       /* 16-Bit signed */
                    108:        desiredAudioSpec.channels = 2;                /* stereo */
1.1.1.9   root      109:        desiredAudioSpec.samples = 1024;              /* Buffer size */
                    110:        desiredAudioSpec.callback = Audio_CallBack;
                    111:        desiredAudioSpec.userdata = NULL;
                    112: 
                    113:        if (SDL_OpenAudio(&desiredAudioSpec, NULL))   /* Open audio device */
                    114:        {
                    115:                fprintf(stderr, "Can't use audio: %s\n", SDL_GetError());
1.1.1.14! root      116:                bSoundWorking = false;
        !           117:                ConfigureParams.Sound.bEnableSound = false;
1.1.1.9   root      118:                SDL_QuitSubSystem(SDL_INIT_AUDIO);
                    119:                return;
                    120:        }
                    121: 
                    122:        SoundBufferSize = desiredAudioSpec.size;      /* May be different than the requested one! */
                    123:        if (SoundBufferSize > MIXBUFFER_SIZE/2)
                    124:        {
                    125:                fprintf(stderr, "Warning: Soundbuffer size is too big!\n");
                    126:        }
                    127: 
                    128:        /* All OK */
1.1.1.14! root      129:        bSoundWorking = true;
1.1.1.9   root      130:        /* And begin */
1.1.1.14! root      131:        Audio_EnableAudio(true);
1.1       root      132: }
                    133: 
1.1.1.2   root      134: 
                    135: /*-----------------------------------------------------------------------*/
1.1.1.11  root      136: /**
                    137:  * Free audio subsystem
                    138:  */
1.1.1.2   root      139: void Audio_UnInit(void)
1.1       root      140: {
1.1.1.9   root      141:        if (bSoundWorking)
                    142:        {
                    143:                /* Stop */
1.1.1.14! root      144:                Audio_EnableAudio(false);
1.1.1.2   root      145: 
1.1.1.9   root      146:                SDL_CloseAudio();
1.1.1.7   root      147: 
1.1.1.14! root      148:                bSoundWorking = false;
1.1.1.9   root      149:        }
1.1       root      150: }
                    151: 
1.1.1.2   root      152: 
                    153: /*-----------------------------------------------------------------------*/
1.1.1.11  root      154: /**
                    155:  * Lock the audio sub system so that the callback function will not be called.
                    156:  */
1.1.1.5   root      157: void Audio_Lock(void)
1.1       root      158: {
1.1.1.9   root      159:        SDL_LockAudio();
1.1       root      160: }
                    161: 
1.1.1.2   root      162: 
                    163: /*-----------------------------------------------------------------------*/
1.1.1.11  root      164: /**
                    165:  * Unlock the audio sub system so that the callback function will be called again.
                    166:  */
1.1.1.5   root      167: void Audio_Unlock(void)
1.1       root      168: {
1.1.1.9   root      169:        SDL_UnlockAudio();
1.1       root      170: }
                    171: 
1.1.1.2   root      172: 
                    173: /*-----------------------------------------------------------------------*/
1.1.1.11  root      174: /**
                    175:  * Set audio playback frequency variable, pass as PLAYBACK_xxxx
                    176:  */
1.1.1.14! root      177: void Audio_SetOutputAudioFreq(int nNewFrequency)
1.1       root      178: {
1.1.1.9   root      179:        /* Do not reset sound system if nothing has changed! */
1.1.1.14! root      180:        if (nNewFrequency != nAudioFrequency)
1.1.1.9   root      181:        {
1.1.1.14! root      182:                /* Set new frequency */
        !           183:                nAudioFrequency = nNewFrequency;
1.1.1.9   root      184: 
                    185:                /* Re-open SDL audio interface if necessary: */
                    186:                if (bSoundWorking)
                    187:                {
                    188:                        Audio_UnInit();
                    189:                        Audio_Init();
                    190:                }
                    191:        }
1.1       root      192: }
                    193: 
1.1.1.2   root      194: 
                    195: /*-----------------------------------------------------------------------*/
1.1.1.11  root      196: /**
                    197:  * Start/Stop sound buffer
                    198:  */
1.1.1.12  root      199: void Audio_EnableAudio(bool bEnable)
1.1       root      200: {
1.1.1.9   root      201:        if (bEnable && !bPlayingBuffer)
                    202:        {
                    203:                /* Start playing */
1.1.1.14! root      204:                SDL_PauseAudio(false);
        !           205:                bPlayingBuffer = true;
1.1.1.9   root      206:        }
                    207:        else if (!bEnable && bPlayingBuffer)
                    208:        {
                    209:                /* Stop from playing */
1.1.1.14! root      210:                SDL_PauseAudio(true);
        !           211:                bPlayingBuffer = false;
1.1.1.9   root      212:        }
1.1       root      213: }

unix.superglobalmegacorp.com

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