Annotation of previous_trunk/src/audio.c, revision 1.1

1.1     ! root        1: #include "main.h"
        !             2: #include "dialog.h"
        !             3: #include "configuration.h"
        !             4: #include "m68000.h"
        !             5: #include "sysdeps.h"
        !             6: #include "audio.h"
        !             7: #include "dma.h"
        !             8: #include "snd.h"
        !             9: #include "host.h"
        !            10: 
        !            11: #include <SDL.h>
        !            12: 
        !            13: 
        !            14: /* Sound emulation SDL interface */
        !            15: static SDL_AudioDeviceID Audio_Input_Device;
        !            16: static SDL_AudioDeviceID Audio_Output_Device;
        !            17: 
        !            18: static bool          bSoundOutputWorking = false; /* Is sound output OK */
        !            19: static bool          bSoundInputWorking  = false; /* Is sound input OK */
        !            20: static bool          bSoundOutAlertShown = false;
        !            21: static bool          bSoundInAlertShown  = false;
        !            22: static bool          bPlayingBuffer      = false; /* Is playing buffer? */
        !            23: static bool          bRecordingBuffer    = false; /* Is recording buffer? */
        !            24: #define              REC_BUFFER_SZ       16  /* Recording buffer size in power of two */
        !            25: static const  Uint32 REC_BUFFER_MASK     = (1<<REC_BUFFER_SZ) - 1;
        !            26: static Uint8         recBuffer[1<<REC_BUFFER_SZ];
        !            27: static Uint32        recBufferWr         = 0;
        !            28: static Uint32        recBufferRd         = 0;
        !            29: static lock_t        recBufferLock;
        !            30: 
        !            31: void Audio_Output_Queue(Uint8* data, int len) {
        !            32:     int chunkSize = AUDIO_BUFFER_SAMPLES;
        !            33:     if (bSoundOutputWorking) {
        !            34:         while (len > 0) {
        !            35:             if (len < chunkSize) chunkSize = len;
        !            36:             SDL_QueueAudio(Audio_Output_Device, data, chunkSize);
        !            37:             data += chunkSize;
        !            38:             len  -= chunkSize;
        !            39:         }
        !            40:     }
        !            41: }
        !            42: 
        !            43: Uint32 Audio_Output_Queue_Size() {
        !            44:     if (bSoundOutputWorking) {
        !            45:         return SDL_GetQueuedAudioSize(Audio_Output_Device) / 4;
        !            46:     } else {
        !            47:         return 0;
        !            48:     }
        !            49: }
        !            50: 
        !            51: /*-----------------------------------------------------------------------*/
        !            52: /**
        !            53:  * SDL audio callback functions - move sound between emulation and audio system.
        !            54:  * Note: These functions will run in a separate thread.
        !            55:  */
        !            56: 
        !            57: static void Audio_Input_CallBack(void *userdata, Uint8 *stream, int len) {
        !            58:     Log_Printf(LOG_WARN, "Audio_Input_CallBack %d", len);
        !            59:     if(len == 0) return;
        !            60:     Audio_Input_Lock();
        !            61:     while(len--) {
        !            62:         recBuffer[recBufferWr++&REC_BUFFER_MASK] = *stream++;          
        !            63:        }
        !            64:        recBufferWr &= REC_BUFFER_MASK;
        !            65:        recBufferWr &= ~1; /* Just to be sure */
        !            66:     Audio_Input_Unlock();
        !            67: }
        !            68: 
        !            69: void Audio_Input_Lock() {
        !            70:     host_lock(&recBufferLock);
        !            71: }
        !            72: 
        !            73: /* 
        !            74:  * Initialize recording buffer with silence to compensate for time gap
        !            75:  * between Audio_Input_Enable and first call of Audio_Input_CallBack.
        !            76:  */
        !            77: #define AUDIO_RECBUF_INIT      0 /* 16000 byte = 1 second */
        !            78: 
        !            79: static void Audio_Input_InitBuf(void) {
        !            80:        recBufferRd = 0;
        !            81:        for (recBufferWr = 0; recBufferWr < AUDIO_RECBUF_INIT; recBufferWr++) {
        !            82:                recBuffer[recBufferWr] = 0;
        !            83:        }
        !            84: }
        !            85: 
        !            86: int Audio_Input_Read(void) {
        !            87:        Sint16 sample = 0;
        !            88:        
        !            89:     if (bSoundInputWorking) {
        !            90:                if ((recBufferRd&REC_BUFFER_MASK)==(recBufferWr&REC_BUFFER_MASK)) {
        !            91:                        return -1;
        !            92:                } else {
        !            93:                        sample = ((recBuffer[recBufferRd&REC_BUFFER_MASK]<<8)|recBuffer[(recBufferRd&REC_BUFFER_MASK)+1]);
        !            94:                        recBufferRd += 2;
        !            95:                        recBufferRd &= REC_BUFFER_MASK;
        !            96:                        return snd_make_ulaw(sample);
        !            97:                }
        !            98:        } else {
        !            99:         return snd_make_ulaw(0); // silence
        !           100:        }
        !           101: }
        !           102: 
        !           103: void Audio_Input_Unlock() {
        !           104:     host_unlock(&recBufferLock);
        !           105: }
        !           106: 
        !           107: static bool check_audio(int requested, int granted, const char* attribute) {
        !           108:     if(requested != granted)
        !           109:         Log_Printf(LOG_WARN, "[Audio] %s mismatch. Requested:%d, granted:%d", attribute, requested, granted);
        !           110:     return requested == granted;
        !           111: }
        !           112: 
        !           113: /*-----------------------------------------------------------------------*/
        !           114: /**
        !           115:  * Initialize the audio subsystem. Return true if all OK.
        !           116:  */
        !           117: void Audio_Output_Init(void)
        !           118: {
        !           119:     SDL_AudioSpec request;    /* We fill in the desired SDL audio options here */
        !           120:     SDL_AudioSpec granted;
        !           121:     
        !           122:     /* Init the SDL's audio subsystem: */
        !           123:     if (SDL_WasInit(SDL_INIT_AUDIO) == 0) {
        !           124:         if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
        !           125:             Log_Printf(LOG_WARN, "[Audio] Could not init audio output: %s\n", SDL_GetError());
        !           126:             DlgAlert_Notice("Error: Can't open SDL audio subsystem.");
        !           127:             bSoundOutputWorking = false;
        !           128:             return;
        !           129:         }
        !           130:     }
        !           131:     
        !           132:     /* Set up SDL audio: */
        !           133:     request.freq     = AUDIO_OUT_FREQUENCY; /* 44,1 kHz */
        !           134:     request.format   = AUDIO_S16MSB;        /* 16-Bit signed, big endian */
        !           135:     request.channels = 2;                   /* stereo */
        !           136:     request.callback = NULL;
        !           137:     request.userdata = NULL;
        !           138:     request.samples  = AUDIO_BUFFER_SAMPLES; /* buffer size in samples */
        !           139: 
        !           140:     Audio_Output_Device = SDL_OpenAudioDevice(NULL, 0, &request, &granted, 0);
        !           141:     if (Audio_Output_Device==0)        /* Open audio device */ {
        !           142:         Log_Printf(LOG_WARN, "[Audio] Can't use audio: %s\n", SDL_GetError());
        !           143:         if(!bSoundOutAlertShown) {
        !           144:             DlgAlert_Notice("Error: Can't open audio output device. No sound output.");
        !           145:             bSoundOutAlertShown = true;
        !           146:         }
        !           147:         bSoundOutputWorking = false;
        !           148:         return;
        !           149:     }
        !           150:     bSoundOutputWorking = true;
        !           151:     bSoundOutputWorking &= check_audio(request.freq,     granted.freq,     "freq");
        !           152:     bSoundOutputWorking &= check_audio(request.format,   granted.format,   "format");
        !           153:     bSoundOutputWorking &= check_audio(request.channels, granted.channels, "channels");
        !           154:     bSoundOutputWorking &= check_audio(request.samples,  granted.samples,  "samples");
        !           155: 
        !           156:     if(!(bSoundOutputWorking)) {
        !           157:         DlgAlert_Notice("Error: Can't open audio output device. No sound output.");
        !           158:     }
        !           159: }
        !           160: 
        !           161: void Audio_Input_Init(void) {    
        !           162:     SDL_AudioSpec request;    /* We fill in the desired SDL audio options here */
        !           163:     SDL_AudioSpec granted;
        !           164:     
        !           165:     /* Init the SDL's audio subsystem: */
        !           166:     if (SDL_WasInit(SDL_INIT_AUDIO) == 0) {
        !           167:         if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
        !           168:             Log_Printf(LOG_WARN, "Could not init audio input: %s\n", SDL_GetError());
        !           169:             DlgAlert_Notice("Error: Can't open SDL audio subsystem.");
        !           170:             bSoundInputWorking = false;
        !           171:             return;
        !           172:         }
        !           173:     }
        !           174:     
        !           175:     /* Set up SDL audio: */
        !           176:     request.freq     = AUDIO_IN_FREQUENCY; /* 8kHz */
        !           177:     request.format   = AUDIO_S16MSB;      /* 16-Bit signed, big endian */
        !           178:     request.channels = 1;                             /* mono */
        !           179:     request.callback = Audio_Input_CallBack;
        !           180:     request.userdata = NULL;
        !           181:     request.samples  = AUDIO_BUFFER_SAMPLES; /* buffer size in samples */
        !           182:     
        !           183:     Audio_Input_Device = SDL_OpenAudioDevice(NULL, 1, &request, &granted, 0); /* Open audio device */
        !           184:     
        !           185:     if (Audio_Input_Device==0){
        !           186:         Log_Printf(LOG_WARN, "Can't use audio: %s\n", SDL_GetError());
        !           187:         if(!bSoundInAlertShown) {
        !           188:             DlgAlert_Notice("Error: Can't open audio input device. No sound recording (will record silence instead).");
        !           189:             bSoundInAlertShown = true;
        !           190:         }
        !           191:         bSoundInputWorking = false;
        !           192:         return;
        !           193:     }
        !           194:     
        !           195:     bSoundInputWorking = true;
        !           196:     bSoundInputWorking &= check_audio(request.freq,     granted.freq,     "freq");
        !           197:     bSoundInputWorking &= check_audio(request.format,   granted.format,   "format");
        !           198:     bSoundInputWorking &= check_audio(request.channels, granted.channels, "channels");
        !           199:     bSoundInputWorking &= check_audio(request.samples,  granted.samples,  "samples");
        !           200:        
        !           201:        if(!(bSoundInputWorking)) {
        !           202:                DlgAlert_Notice("Error: Can't open audio input device. No sound recording (will record silence instead).");
        !           203:        }
        !           204: }
        !           205: 
        !           206: 
        !           207: /*-----------------------------------------------------------------------*/
        !           208: /**
        !           209:  * Free audio subsystem
        !           210:  */
        !           211: void Audio_Output_UnInit(void) {
        !           212:     if (bSoundOutputWorking) {
        !           213:         /* Stop */
        !           214:         Audio_Output_Enable(false);
        !           215:         
        !           216:         SDL_CloseAudioDevice(Audio_Output_Device);
        !           217:         
        !           218:         bSoundOutputWorking = false;
        !           219:     }
        !           220: }
        !           221: 
        !           222: void Audio_Input_UnInit(void) {
        !           223:     if (bSoundInputWorking) {
        !           224:         /* Stop */
        !           225:         Audio_Input_Enable(false);
        !           226:         
        !           227:         SDL_CloseAudioDevice(Audio_Input_Device);
        !           228:         
        !           229:         bSoundInputWorking = false;
        !           230:     }
        !           231: }
        !           232: 
        !           233: /*-----------------------------------------------------------------------*/
        !           234: /**
        !           235:  * Start/Stop sound buffer
        !           236:  */
        !           237: void Audio_Output_Enable(bool bEnable) {
        !           238:     if (bEnable && !bPlayingBuffer) {
        !           239:         /* Start playing */
        !           240:         SDL_PauseAudioDevice(Audio_Output_Device, false);
        !           241:         bPlayingBuffer = true;
        !           242:     }
        !           243:     else if (!bEnable && bPlayingBuffer) {
        !           244:         /* Stop from playing */
        !           245:         SDL_PauseAudioDevice(Audio_Output_Device, true);
        !           246:         bPlayingBuffer = false;
        !           247:     }
        !           248: }
        !           249: 
        !           250: void Audio_Input_Enable(bool bEnable) {
        !           251:     if (bEnable && !bRecordingBuffer) {
        !           252:         /* Start recording */
        !           253:                Audio_Input_InitBuf();
        !           254:         SDL_PauseAudioDevice(Audio_Input_Device, false);
        !           255:         bRecordingBuffer = true;
        !           256:     }
        !           257:     else if (!bEnable && bRecordingBuffer) {
        !           258:         /* Stop recording */
        !           259:         SDL_PauseAudioDevice(Audio_Input_Device, true);
        !           260:         bRecordingBuffer = false;
        !           261:     }
        !           262: }

unix.superglobalmegacorp.com

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