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

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.5 ! root        9: static char rcsid[] = "Hatari $Id: audio.c,v 1.14 2003/03/12 14:13:23 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"
                     15: #include "debug.h"
                     16: #include "dialog.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.5 ! root       32: BOOL bDisableSound = FALSE;
        !            33: BOOL bSoundWorking = TRUE;                /* Is sound OK */
        !            34: volatile BOOL bPlayingBuffer = FALSE;     /* Is playing buffer? */
        !            35: int OutputAudioFreqIndex = FREQ_22Khz;    /* Playback rate (11Khz,22Khz or 44Khz) */
        !            36: float PlayVolume = 0.0f;
        !            37: int SoundBufferSize = 1024;               /* Size of sound buffer */
        !            38: int CompleteSndBufIdx;                    /* Replay-index into MixBuffer */
1.1.1.2   root       39: 
1.1       root       40: 
                     41: 
1.1.1.2   root       42: /*-----------------------------------------------------------------------*/
                     43: /*
1.1.1.5 ! root       44:   SDL audio callback function - copy emulation sound to audio system.
1.1.1.2   root       45: */
                     46: void Audio_CallBack(void *userdata, Uint8 *stream, int len)
                     47: {
1.1.1.5 ! root       48:   /* Pass completed buffer to audio system: */
        !            49:   Audio_WriteSamplesIntoBuffer(MixBuffer, CompleteSndBufIdx, len,
        !            50:                                (bEmulationActive)?RAMP_UP:RAMP_DOWN, stream);
        !            51: 
        !            52:   /* We should now have generated a complete frame of samples.
        !            53:    * However, for slow systems we have to check how many generated samples
        !            54:    * we may advance... */
        !            55:   if(nGeneratedSamples >= len)
        !            56:   {
        !            57:     CompleteSndBufIdx += len;
        !            58:     nGeneratedSamples -= len;
        !            59:   }
        !            60:   else
        !            61:   {
        !            62:     CompleteSndBufIdx += nGeneratedSamples;
        !            63:     nGeneratedSamples = 0;
        !            64:   }
        !            65:   CompleteSndBufIdx = CompleteSndBufIdx % MIXBUFFER_SIZE;
1.1.1.2   root       66: }
                     67: 
1.1       root       68: 
1.1.1.2   root       69: /*-----------------------------------------------------------------------*/
1.1       root       70: /*
1.1.1.5 ! root       71:   Initialize the audio subsystem. Return TRUE if all OK.
        !            72:   We use direct access to the sound buffer, set to a unsigned 8-bit mono stream.
1.1       root       73: */
1.1.1.2   root       74: void Audio_Init(void)
1.1       root       75: {
1.1.1.5 ! root       76:   SDL_AudioSpec desiredAudioSpec;    /* We fill in the desired SDL audio options here */
        !            77: 
1.1.1.2   root       78:   /* Is enabled? */
1.1.1.4   root       79:   if(bDisableSound)
                     80:   {
1.1.1.3   root       81:     /* Stop any sound access */
1.1.1.2   root       82:     ErrLog_File("Sound: Disabled\n");
                     83:     bSoundWorking = FALSE;
1.1       root       84:     return;
                     85:   }
                     86: 
1.1.1.4   root       87:   /* Init the SDL's audio subsystem: */
                     88:   if( SDL_WasInit(SDL_INIT_AUDIO)==0 )
                     89:   {
                     90:     if( SDL_InitSubSystem(SDL_INIT_AUDIO)<0 )
                     91:     {
                     92:       fprintf(stderr, "Could not init audio: %s\n", SDL_GetError() );
                     93:       bSoundWorking = FALSE;
                     94:       return;
                     95:     }
                     96:   }
                     97: 
                     98:   /* Set up SDL audio: */
1.1.1.3   root       99:   desiredAudioSpec.freq = SoundPlayBackFrequencies[OutputAudioFreqIndex];
1.1.1.5 ! root      100:   desiredAudioSpec.format = AUDIO_U8;           /* 8 Bit unsigned */
        !           101:   desiredAudioSpec.channels = 1;                /* Mono */
        !           102:   desiredAudioSpec.samples = 1024;              /* Buffer size */
1.1.1.3   root      103:   desiredAudioSpec.callback = Audio_CallBack;
                    104:   desiredAudioSpec.userdata = NULL;
1.1.1.5 ! root      105: 
        !           106:   if( SDL_OpenAudio(&desiredAudioSpec, NULL) )  /* Open audio device */
1.1.1.3   root      107:   {
1.1.1.4   root      108:     fprintf(stderr, "Can't use audio: %s\n", SDL_GetError());
1.1.1.2   root      109:     bSoundWorking = FALSE;
1.1.1.3   root      110:     ConfigureParams.Sound.bEnableSound = FALSE;
1.1.1.2   root      111:     return;
1.1       root      112:   }
1.1.1.3   root      113: 
1.1.1.5 ! root      114:   SoundBufferSize = desiredAudioSpec.size;      /* May be different than the requested one! */
        !           115:   if(SoundBufferSize > MIXBUFFER_SIZE/2)
        !           116:   {
        !           117:     fprintf(stderr, "Warning: Soundbuffer size is too big!\n");
        !           118:   }
        !           119: 
        !           120:   /* All OK */
        !           121:   bSoundWorking = TRUE;
        !           122:   /* And begin */
        !           123:   Audio_EnableAudio(TRUE);
1.1       root      124: }
                    125: 
1.1.1.2   root      126: 
                    127: /*-----------------------------------------------------------------------*/
1.1       root      128: /*
1.1.1.5 ! root      129:   Free audio subsystem
1.1       root      130: */
1.1.1.2   root      131: void Audio_UnInit(void)
1.1       root      132: {
1.1.1.5 ! root      133:   /* Stop */
        !           134:   Audio_EnableAudio(FALSE);
1.1.1.2   root      135: 
                    136:   SDL_CloseAudio();
1.1       root      137: }
                    138: 
1.1.1.2   root      139: 
                    140: /*-----------------------------------------------------------------------*/
1.1       root      141: /*
1.1.1.5 ! root      142:   Lock the audio sub system so that the callback function will not be called.
1.1       root      143: */
1.1.1.5 ! root      144: void Audio_Lock(void)
1.1       root      145: {
1.1.1.5 ! root      146:   SDL_LockAudio();
1.1       root      147: }
                    148: 
1.1.1.2   root      149: 
                    150: /*-----------------------------------------------------------------------*/
1.1       root      151: /*
1.1.1.5 ! root      152:   Unlock the audio sub system so that the callback function will be called again.
1.1       root      153: */
1.1.1.5 ! root      154: void Audio_Unlock(void)
1.1       root      155: {
1.1.1.5 ! root      156:   SDL_UnlockAudio();
1.1       root      157: }
                    158: 
1.1.1.2   root      159: 
                    160: /*-----------------------------------------------------------------------*/
1.1       root      161: /*
1.1.1.3   root      162:   Set audio playback frequency variable, pass as PLAYBACK_xxxx
1.1       root      163: */
1.1.1.2   root      164: void Audio_SetOutputAudioFreq(int Frequency)
1.1       root      165: {
1.1.1.5 ! root      166:   /* Do not reset sound system if nothing has changed! */
        !           167:   if(Frequency != OutputAudioFreqIndex)
        !           168:   {
        !           169:     /* Set new frequency, index into SoundPlayBackFrequencies[] */
        !           170:     OutputAudioFreqIndex = Frequency;
1.1.1.2   root      171: 
1.1.1.5 ! root      172:     /* Re-open SDL audio interface... */
        !           173:     Audio_UnInit();
        !           174:     Audio_Init();
        !           175:   }
1.1       root      176: }
                    177: 
1.1.1.2   root      178: 
                    179: /*-----------------------------------------------------------------------*/
1.1       root      180: /*
1.1.1.5 ! root      181:   Start/Stop sound buffer
1.1       root      182: */
1.1.1.5 ! root      183: void Audio_EnableAudio(BOOL bEnable)
1.1       root      184: {
1.1.1.5 ! root      185:   if(bEnable && !bPlayingBuffer)
        !           186:   {
        !           187:     /* Start playing */
        !           188:     SDL_PauseAudio(FALSE);
        !           189:     bPlayingBuffer = TRUE;
        !           190:   }
        !           191:   else if(!bEnable && bPlayingBuffer)
        !           192:   {
        !           193:     /* Stop from playing */
        !           194:     SDL_PauseAudio(!bEnable);
        !           195:     bPlayingBuffer = bEnable;
        !           196:   }
1.1       root      197: }
                    198: 
1.1.1.2   root      199: 
                    200: /*-----------------------------------------------------------------------*/
1.1       root      201: /*
1.1.1.5 ! root      202:   Scale sample value (-128...127) according to 'PlayVolume' setting
1.1       root      203: */
1.1.1.5 ! root      204: Sint8 Audio_ModifyVolume(Sint8 Sample)
1.1       root      205: {
1.1.1.2   root      206:   /* If full volume, just use current value */
1.1       root      207:   if (PlayVolume==1.0f)
                    208:     return(Sample);
                    209: 
1.1.1.2   root      210:   /* Else, scale volume */
1.1.1.5 ! root      211:   Sample = (Sint8)((float)Sample*PlayVolume);
1.1       root      212: 
                    213:   return(Sample);
                    214: }
                    215: 
1.1.1.2   root      216: 
                    217: /*-----------------------------------------------------------------------*/
1.1       root      218: /*
1.1.1.5 ! root      219:   Write samples into sound buffer. Pass pSamples=NULL to write zero's.
1.1       root      220: */
1.1.1.5 ! root      221: void Audio_WriteSamplesIntoBuffer(Sint8 *pSamples, int Index, int Length,
        !           222:                                   int RampSetting, Sint8 *pDestBuffer)
1.1       root      223: {
1.1.1.5 ! root      224:   Sint8 *pBuffer;
1.1.1.2   root      225:   int i;
1.1       root      226: 
1.1.1.2   root      227:   /* Modify ramp volume - ramp down if sound not enabled or not in windows mouse mode */
1.1.1.5 ! root      228:   if( (((RampSetting==RAMP_DOWN) || (!ConfigureParams.Sound.bEnableSound)) && (PlayVolume>0.0f)) )
        !           229:   {
1.1       root      230:     PlayVolume -= RAMP_DOWN_VOLUME_LEVEL;
1.1.1.5 ! root      231:     if(PlayVolume <= 0.0f)
1.1       root      232:       PlayVolume = 0.0f;
                    233:   }
1.1.1.5 ! root      234:   else if((RampSetting==RAMP_UP) && (PlayVolume<1.0f))
        !           235:   {
1.1       root      236:     PlayVolume += RAMP_UP_VOLUME_LEVEL;
1.1.1.5 ! root      237:     if(PlayVolume >= 1.0f)
1.1       root      238:       PlayVolume = 1.0f;
                    239:   }
                    240: 
1.1.1.5 ! root      241:   /* Write section, convert to 'unsigned' and write '128's if passed NULL */
        !           242:   if(Length > 0)
        !           243:   {
        !           244:     if(pSamples)
        !           245:     {
        !           246:       pBuffer = pDestBuffer;
        !           247:       for(i = 0; i < Length; i++)
        !           248:       {
        !           249:         *pBuffer++ = Audio_ModifyVolume(pSamples[Index]) ^ 128;
        !           250:         Index = (Index + 1) % MIXBUFFER_SIZE;
1.1.1.2   root      251:       }
1.1       root      252:     }
1.1.1.5 ! root      253:     else
        !           254:     {
        !           255:       memset(pDestBuffer, 128, Length);
1.1       root      256:     }
                    257:   }
                    258: }
1.1.1.5 ! root      259: 

unix.superglobalmegacorp.com

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