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

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

unix.superglobalmegacorp.com

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