Annotation of previous_trunk/src/audio.c, revision 1.1.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.