|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * UAE - The Un*x Amiga Emulator 1.1.1.2 ! root 3: * 1.1 root 4: * Support for Linux/ALSA sound 1.1.1.2 ! root 5: * 1.1 root 6: * Copyright 1997 Bernd Schmidt 7: * Copyright 2004 Heikki Orsila 8: * 9: * BUGS: certainly 10: * TODO: 11: * - if setup_sound() fails, there may still be hope to get the 12: * sound device, but we totally give up.. see sd-uss. 13: */ 14: 15: #include "sysconfig.h" 16: #include "sysdeps.h" 17: 18: #include "config.h" 19: #include "options.h" 20: #include "memory.h" 21: #include "events.h" 22: #include "custom.h" 23: #include "gensound.h" 24: #include "sounddep/sound.h" 25: 26: #include <alsa/asoundlib.h> 27: 28: int sound_fd; 29: static int have_sound = 0; 30: static unsigned long formats; 31: 32: uae_u16 sndbuffer[44100]; 33: uae_u16 *sndbufpt; 34: int sndbufsize; 35: 36: snd_pcm_t *alsa_playback_handle = 0; 37: int alsa_to_frames_divisor = 4; 38: 39: void close_sound (void) 40: { 41: if (alsa_playback_handle) { 42: snd_pcm_close (alsa_playback_handle); 43: alsa_playback_handle = 0; 44: } 45: } 46: 47: static int open_sound(void) 48: { 49: return snd_pcm_open (&alsa_playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); 50: } 51: 52: /* Try to determine whether sound is available. This is only for GUI purposes. */ 53: int setup_sound (void) 54: { 55: int err; 56: sound_available = 0; 57: if ((err = open_sound()) < 0) { 58: /* TODO: if the pcm was busy, we should the same as sd-uss does. 59: tell the caller that sound is available. in any other 60: condition we should just return 0. */ 61: fprintf (stderr, "cannot open audio device (%s)\n", snd_strerror (err)); 62: return 0; 63: } 64: snd_pcm_close (alsa_playback_handle); 65: alsa_playback_handle = 0; 66: sound_available = 1; 67: return 1; 68: } 69: 70: int init_sound (void) 71: { 72: int tmp; 73: int rate; 74: int dspbits; 75: int alsamode; 76: int channels; 77: int err; 78: snd_pcm_hw_params_t *hw_params; 79: snd_pcm_uframes_t buffer_frames; 80: 81: dspbits = currprefs.sound_bits; 82: channels = currprefs.sound_stereo ? 2 : 1; 83: rate = currprefs.sound_freq; 84: 85: have_sound = 0; 86: alsa_playback_handle = 0; 87: if ((err = open_sound()) < 0) { 88: fprintf (stderr, "cannot open audio device (%s)\n", snd_strerror (err)); 89: goto nosound; 90: } 91: 92: if (currprefs.sound_maxbsiz < 128 || currprefs.sound_maxbsiz > 16384) { 93: fprintf (stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz); 94: currprefs.sound_maxbsiz = 8192; 95: } 96: sndbufsize = currprefs.sound_maxbsiz; 97: 98: if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) { 99: fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", 100: snd_strerror (err)); 101: goto nosound; 102: } 103: 104: if ((err = snd_pcm_hw_params_any (alsa_playback_handle, hw_params)) < 0) { 105: fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", 106: snd_strerror (err)); 107: goto nosound; 108: } 109: 110: if ((err = snd_pcm_hw_params_set_access (alsa_playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { 111: fprintf (stderr, "cannot set access type (%s)\n", 112: snd_strerror (err)); 113: goto nosound; 114: } 115: 116: switch (dspbits) { 117: case 8: 118: alsamode = SND_PCM_FORMAT_U8; 119: break; 120: case 16: 121: alsamode = SND_PCM_FORMAT_S16; 122: break; 123: default: 124: fprintf(stderr, "%d bit samples not supported with uae's alsa\n", dspbits); 125: goto nosound; 126: } 127: 128: if ((err = snd_pcm_hw_params_set_format (alsa_playback_handle, hw_params, alsamode)) < 0) { 129: fprintf (stderr, "cannot set sample format (%s)\n", 130: snd_strerror (err)); 131: goto nosound; 132: } 133: 134: if ((err = snd_pcm_hw_params_set_channels (alsa_playback_handle, hw_params, channels)) < 0) { 135: fprintf (stderr, "cannot set channel count (%s)\n", 136: snd_strerror (err)); 137: goto nosound; 138: } 139: 140: if ((err = snd_pcm_hw_params_set_rate_near (alsa_playback_handle, hw_params, &rate, 0)) < 0) { 141: fprintf (stderr, "cannot set sample rate (%s)\n", 142: snd_strerror (err)); 143: goto nosound; 144: } 1.1.1.2 ! root 145: 1.1 root 146: alsa_to_frames_divisor = channels * dspbits / 8; 147: buffer_frames = sndbufsize / alsa_to_frames_divisor; 148: if ((err = snd_pcm_hw_params_set_period_size_near(alsa_playback_handle, hw_params, &buffer_frames, 0)) < 0) { 149: fprintf (stderr, "cannot set period size near (%s)\n", snd_strerror (err)); 150: goto nosound; 151: } 152: 153: if ((err = snd_pcm_hw_params (alsa_playback_handle, hw_params)) < 0) { 154: fprintf (stderr, "cannot set parameters (%s)\n", 155: snd_strerror (err)); 156: goto nosound; 157: } 1.1.1.2 ! root 158: 1.1 root 159: snd_pcm_hw_params_free (hw_params); 1.1.1.2 ! root 160: 1.1 root 161: if ((err = snd_pcm_prepare (alsa_playback_handle)) < 0) { 162: fprintf (stderr, "cannot prepare audio interface for use (%s)\n", 163: snd_strerror (err)); 164: goto nosound; 165: } 166: 167: scaled_sample_evtime = (unsigned long) MAXHPOS_PAL * MAXVPOS_PAL * VBLANK_HZ_PAL * CYCLE_UNIT / rate; 168: scaled_sample_evtime_ok = 1; 1.1.1.2 ! root 169: 1.1 root 170: if (dspbits == 16) { 171: init_sound_table16 (); 172: sample_handler = currprefs.sound_stereo ? sample16s_handler : sample16_handler; 173: } else { 174: init_sound_table8 (); 175: sample_handler = currprefs.sound_stereo ? sample8s_handler : sample8_handler; 176: } 177: have_sound = 1; 178: sound_available = 1; 179: printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n", dspbits, rate, sndbufsize); 180: 181: sndbufpt = sndbuffer; 182: return 1; 183: 184: nosound: 185: have_sound = 0; 186: close_sound(); 187: return 0; 188: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.