|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Support for Linux/ALSA sound ! 5: * ! 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: } ! 145: ! 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: } ! 158: ! 159: snd_pcm_hw_params_free (hw_params); ! 160: ! 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; ! 169: ! 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.