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

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

unix.superglobalmegacorp.com

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