Annotation of uae/src/sd-sdl/sound.c, revision 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.