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

1.1.1.4 ! root        1:  /*
1.1       root        2:   * UAE - The Un*x Amiga Emulator
1.1.1.4 ! root        3:   *
1.1       root        4:   * Support for Linux/USS sound
1.1.1.4 ! root        5:   *
1.1       root        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;
1.1.1.3   root       64:     spec.channels = currprefs.sound_stereo ? 2 : 1;
1.1       root       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;
1.1.1.3   root       90:     spec.channels = currprefs.sound_stereo ? 2 : 1;
1.1       root       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).  */
1.1.1.3   root       96:     size >>= spec.channels - 1;
                     97:     size >>= currprefs.sound_bits == 8 ? 0 : 1;
1.1       root       98:     while (size & (size - 1))
                     99:        size &= size - 1;
                    100:     if (size < 512)
                    101:        size = 512;
                    102:     spec.samples = size;
                    103:     spec.callback = sound_callback;
                    104:     spec.userdata = 0;
                    105: 
                    106:     if (SDL_OpenAudio (&spec, NULL) < 0) {
                    107:        write_log (stderr, "Couldn't open audio: %s\n", SDL_GetError());
                    108:        return 0;
                    109:     }
                    110:     have_sound = 1;
                    111: 
1.1.1.2   root      112:     scaled_sample_evtime = (unsigned long)MAXHPOS_PAL * MAXVPOS_PAL * VBLANK_HZ_PAL * CYCLE_UNIT / spec.freq;
1.1       root      113:     scaled_sample_evtime_ok = 1;
                    114: 
                    115:     if (spec.format == AUDIO_S16) {
                    116:        init_sound_table16 ();
1.1.1.3   root      117:        sample_handler = currprefs.sound_stereo ? sample16s_handler : sample16_handler;
1.1       root      118:     } else {
                    119:        init_sound_table8 ();
1.1.1.3   root      120:        sample_handler = currprefs.sound_stereo ? sample8s_handler : sample8_handler;
1.1       root      121:     }
                    122:     sound_available = 1;
                    123:     write_log ("SDL sound driver found and configured for %d bits at %d Hz, buffer is %d samples\n",
                    124:               currprefs.sound_bits, spec.freq, spec.samples);
                    125:     sndbufpt = sndbuffer;
                    126:     sndbufsize = size * currprefs.sound_bits / 8 * spec.channels;
                    127:     return 1;
                    128: }
                    129: 
                    130: static void *sound_thread (void *dummy)
                    131: {
                    132:     for (;;) {
                    133:        int cmd = read_comm_pipe_int_blocking (&to_sound_pipe);
                    134:        int n;
                    135: 
                    136:        switch (cmd) {
                    137:        case 0:
                    138:            open_sound ();
                    139:            uae_sem_post (&sound_init_sem);
                    140:            break;
                    141:        case 1:
                    142:            uae_sem_post (&sound_init_sem);
                    143:            return 0;
                    144:        }
                    145:     }
                    146: }
                    147: 
                    148: /* We need a thread for this, since communication between finish_sound_buffer
                    149:    and the callback works through semaphores.  In theory, this is unnecessary,
                    150:    since SDL uses a sound thread internally, and the callback runs in its
                    151:    context.  But we don't want to depend on SDL's internals too much.  */
                    152: static void init_sound_thread (void)
                    153: {
                    154:     uae_thread_id tid;
                    155: 
                    156:     init_comm_pipe (&to_sound_pipe, 20, 1);
                    157:     uae_sem_init (&data_available_sem, 0, 0);
                    158:     uae_sem_init (&callback_done_sem, 0, 0);
                    159:     uae_sem_init (&sound_init_sem, 0, 0);
                    160:     uae_start_thread (sound_thread, NULL, &tid);
                    161: }
                    162: 
                    163: void close_sound (void)
                    164: {
                    165:     if (! have_sound)
                    166:        return;
                    167: 
                    168:     SDL_PauseAudio (1);
                    169:     if (in_callback) {
                    170:        closing_sound = 1;
                    171:        uae_sem_post (&data_available_sem);
                    172:     }
                    173:     write_comm_pipe_int (&to_sound_pipe, 1, 1);
                    174:     uae_sem_wait (&sound_init_sem);
                    175:     SDL_CloseAudio ();
                    176:     uae_sem_destroy (&data_available_sem);
                    177:     uae_sem_destroy (&sound_init_sem);
                    178:     uae_sem_destroy (&callback_done_sem);
                    179:     have_sound = 0;
                    180: }
                    181: 
                    182: int init_sound (void)
                    183: {
                    184:     in_callback = 0;
                    185:     closing_sound = 0;
                    186: 
                    187:     init_sound_thread ();
                    188:     write_comm_pipe_int (&to_sound_pipe, 0, 1);
                    189:     uae_sem_wait (&sound_init_sem);
                    190:     SDL_PauseAudio (0);
                    191: 
                    192:     return have_sound;
                    193: }
                    194: 
                    195: void pause_sound (void)
                    196: {
                    197:     SDL_PauseAudio (1);
                    198: }
                    199: 
                    200: void resume_sound (void)
                    201: {
                    202:     SDL_PauseAudio (0);
                    203: }

unix.superglobalmegacorp.com

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