Annotation of uae/src/sd-sdl/sound.c, revision 1.1.1.1

1.1       root        1:  /* 
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * Support for Linux/USS sound
                      5:   * 
                      6:   * Copyright 1997 Bernd Schmidt
                      7:   */
                      8: 
                      9: #include "sysconfig.h"
                     10: #include "sysdeps.h"
                     11: 
                     12: #include "config.h"
                     13: #include "options.h"
                     14: #include "memory.h"
                     15: #include "events.h"
                     16: #include "custom.h"
                     17: #include "gensound.h"
                     18: #include "sounddep/sound.h"
                     19: #include "threaddep/thread.h"
                     20: #include "SDL_audio.h"
                     21: 
                     22: int sound_fd;
                     23: static int have_sound = 0;
                     24: static unsigned long formats;
                     25: 
                     26: uae_u16 sndbuffer[44100];
                     27: uae_u16 *sndbufpt;
                     28: int sndbufsize;
                     29: static SDL_AudioSpec spec;
                     30: 
                     31: static smp_comm_pipe to_sound_pipe;
                     32: static uae_sem_t data_available_sem, callback_done_sem, sound_init_sem;
                     33: 
                     34: static int in_callback, closing_sound;
                     35: 
                     36: static void sound_callback (void *userdata, Uint8 *stream, int len)
                     37: {
                     38:     if (closing_sound)
                     39:        return;
                     40:     in_callback = 1;
                     41:     /* Wait for data to finish.  */
                     42:     uae_sem_wait (&data_available_sem);
                     43:     if (! closing_sound) {
                     44:        memcpy (stream, sndbuffer, sndbufsize);
                     45:        /* Notify writer that we're done.  */
                     46:        uae_sem_post (&callback_done_sem);
                     47:     }
                     48:     in_callback = 0;
                     49: }
                     50: 
                     51: void finish_sound_buffer (void)
                     52: {
                     53:     uae_sem_post (&data_available_sem);
                     54:     uae_sem_wait (&callback_done_sem);
                     55: }
                     56: 
                     57: /* Try to determine whether sound is available.  This is only for GUI purposes.  */
                     58: int setup_sound (void)
                     59: {
                     60:     int size = currprefs.sound_maxbsiz;
                     61: 
                     62:     spec.freq = currprefs.sound_freq;
                     63:     spec.format = AUDIO_S16;
                     64:     spec.channels = currprefs.stereo ? 2 : 1;
                     65:     size >>= spec.channels - 1;
                     66:     size >>= 1;
                     67:     while (size & (size - 1))
                     68:        size &= size - 1;
                     69:     if (size < 512)
                     70:        size = 512;
                     71:     spec.samples = size;
                     72:     spec.callback = sound_callback;
                     73:     spec.userdata = 0;
                     74: 
                     75:     if (SDL_OpenAudio (&spec, NULL) < 0) {
                     76:        write_log (stderr, "Couldn't open audio: %s\n", SDL_GetError());
                     77:        return 0;
                     78:     }
                     79:     sound_available = 1;
                     80:     SDL_CloseAudio ();
                     81:     return 1;
                     82: }
                     83: 
                     84: static int open_sound (void)
                     85: {
                     86:     int size = currprefs.sound_maxbsiz;
                     87: 
                     88:     spec.freq = currprefs.sound_freq;
                     89:     spec.format = currprefs.sound_bits == 8 ? AUDIO_U8 : AUDIO_S16;
                     90:     spec.channels = currprefs.stereo ? 2 : 1;
                     91:     /* Always interpret buffer size as number of samples, not as actual
                     92:        buffer size.  Of course, since 8192 is the default, we'll have to
                     93:        scale that to a sane value (assuming that otherwise 16 bits and
                     94:        stereo would have been enabled and we'd have done the shift by
                     95:        two anyway).  */
                     96:     size >>= 2;
                     97:     while (size & (size - 1))
                     98:        size &= size - 1;
                     99:     if (size < 512)
                    100:        size = 512;
                    101:     spec.samples = size;
                    102:     spec.callback = sound_callback;
                    103:     spec.userdata = 0;
                    104: 
                    105:     if (SDL_OpenAudio (&spec, NULL) < 0) {
                    106:        write_log (stderr, "Couldn't open audio: %s\n", SDL_GetError());
                    107:        return 0;
                    108:     }
                    109:     have_sound = 1;
                    110: 
                    111:     scaled_sample_evtime = (unsigned long)maxhpos * maxvpos * vblank_hz * CYCLE_UNIT / spec.freq;
                    112:     scaled_sample_evtime_ok = 1;
                    113: 
                    114:     if (spec.format == AUDIO_S16) {
                    115:        init_sound_table16 ();
                    116:        sample_handler = currprefs.stereo ? sample16s_handler : sample16_handler;
                    117:     } else {
                    118:        init_sound_table8 ();
                    119:        sample_handler = currprefs.stereo ? sample8s_handler : sample8_handler;
                    120:     }
                    121:     sound_available = 1;
                    122:     write_log ("SDL sound driver found and configured for %d bits at %d Hz, buffer is %d samples\n",
                    123:               currprefs.sound_bits, spec.freq, spec.samples);
                    124:     sndbufpt = sndbuffer;
                    125:     sndbufsize = size * currprefs.sound_bits / 8 * spec.channels;
                    126:     return 1;
                    127: }
                    128: 
                    129: static void *sound_thread (void *dummy)
                    130: {
                    131:     for (;;) {
                    132:        int cmd = read_comm_pipe_int_blocking (&to_sound_pipe);
                    133:        int n;
                    134: 
                    135:        switch (cmd) {
                    136:        case 0:
                    137:            open_sound ();
                    138:            uae_sem_post (&sound_init_sem);
                    139:            break;
                    140:        case 1:
                    141:            uae_sem_post (&sound_init_sem);
                    142:            return 0;
                    143:        }
                    144:     }
                    145: }
                    146: 
                    147: /* We need a thread for this, since communication between finish_sound_buffer
                    148:    and the callback works through semaphores.  In theory, this is unnecessary,
                    149:    since SDL uses a sound thread internally, and the callback runs in its
                    150:    context.  But we don't want to depend on SDL's internals too much.  */
                    151: static void init_sound_thread (void)
                    152: {
                    153:     uae_thread_id tid;
                    154: 
                    155:     init_comm_pipe (&to_sound_pipe, 20, 1);
                    156:     uae_sem_init (&data_available_sem, 0, 0);
                    157:     uae_sem_init (&callback_done_sem, 0, 0);
                    158:     uae_sem_init (&sound_init_sem, 0, 0);
                    159:     uae_start_thread (sound_thread, NULL, &tid);
                    160: }
                    161: 
                    162: void close_sound (void)
                    163: {
                    164:     if (! have_sound)
                    165:        return;
                    166: 
                    167:     SDL_PauseAudio (1);
                    168:     if (in_callback) {
                    169:        closing_sound = 1;
                    170:        uae_sem_post (&data_available_sem);
                    171:     }
                    172:     write_comm_pipe_int (&to_sound_pipe, 1, 1);
                    173:     uae_sem_wait (&sound_init_sem);
                    174:     SDL_CloseAudio ();
                    175:     uae_sem_destroy (&data_available_sem);
                    176:     uae_sem_destroy (&sound_init_sem);
                    177:     uae_sem_destroy (&callback_done_sem);
                    178:     have_sound = 0;
                    179: }
                    180: 
                    181: int init_sound (void)
                    182: {
                    183:     in_callback = 0;
                    184:     closing_sound = 0;
                    185: 
                    186:     init_sound_thread ();
                    187:     write_comm_pipe_int (&to_sound_pipe, 0, 1);
                    188:     uae_sem_wait (&sound_init_sem);
                    189:     SDL_PauseAudio (0);
                    190: 
                    191:     return have_sound;
                    192: }
                    193: 
                    194: void pause_sound (void)
                    195: {
                    196:     SDL_PauseAudio (1);
                    197: }
                    198: 
                    199: void resume_sound (void)
                    200: {
                    201:     SDL_PauseAudio (0);
                    202: }

unix.superglobalmegacorp.com

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