|
|
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: ! 10: #include <alsa/asoundlib.h> ! 11: ! 12: extern int sound_fd; ! 13: extern uae_u16 sndbuffer[]; ! 14: extern uae_u16 *sndbufpt; ! 15: extern int sndbufsize; ! 16: extern snd_pcm_t *alsa_playback_handle; ! 17: extern int alsa_to_frames_divisor; ! 18: ! 19: /* alsa_xrun_recovery() function is copied from ALSA manual. why the hell did ! 20: they make ALSA this hard?! i bet 95% of ALSA programmers would like a ! 21: simpler way to do error handling.. let the 5% use tricky APIs. ! 22: */ ! 23: static int alsa_xrun_recovery(snd_pcm_t *handle, int err) ! 24: { ! 25: if (err == -EPIPE) { ! 26: /* under-run */ ! 27: err = snd_pcm_prepare(handle); ! 28: if (err < 0) ! 29: fprintf(stderr, "uae: no recovery with alsa from underrun, prepare failed: %s\n", snd_strerror(err)); ! 30: return 0; ! 31: } else if (err == -ESTRPIPE) { ! 32: while ((err = snd_pcm_resume(handle)) == -EAGAIN) { ! 33: /* wait until the suspend flag is released */ ! 34: fprintf(stderr, "uae: sleeping for alsa.\n"); ! 35: sleep(1); ! 36: } ! 37: if (err < 0) { ! 38: err = snd_pcm_prepare(handle); ! 39: if (err < 0) ! 40: fprintf(stderr, "uae: no recovery with alsa from suspend, prepare failed: %s\n", snd_strerror(err)); ! 41: } ! 42: return 0; ! 43: } ! 44: return err; ! 45: } ! 46: ! 47: static void check_sound_buffers (void) ! 48: { ! 49: if ((char *)sndbufpt - (char *)sndbuffer >= sndbufsize) { ! 50: int frames = sndbufsize / alsa_to_frames_divisor; ! 51: char *buf = (char *) sndbuffer; ! 52: int ret; ! 53: while (frames > 0) { ! 54: ret = snd_pcm_writei(alsa_playback_handle, buf, frames); ! 55: if (ret < 0) { ! 56: if (ret == -EAGAIN || ret == -EINTR) ! 57: continue; ! 58: if (alsa_xrun_recovery(alsa_playback_handle, ret) < 0) { ! 59: fprintf(stderr, "uae: write error with alsa: %s\n", snd_strerror(ret)); ! 60: exit(-1); ! 61: } ! 62: continue; ! 63: } ! 64: frames -= ret; ! 65: buf += ret * alsa_to_frames_divisor; ! 66: } ! 67: sndbufpt = sndbuffer; ! 68: } ! 69: } ! 70: ! 71: #define PUT_SOUND_BYTE(b) do { *(uae_u8 *)sndbufpt = b; sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 1); } while (0) ! 72: #define PUT_SOUND_WORD(b) do { *(uae_u16 *)sndbufpt = b; sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 2); } while (0) ! 73: #define PUT_SOUND_BYTE_LEFT(b) PUT_SOUND_BYTE(b) ! 74: #define PUT_SOUND_WORD_LEFT(b) PUT_SOUND_WORD(b) ! 75: #define PUT_SOUND_BYTE_RIGHT(b) PUT_SOUND_BYTE(b) ! 76: #define PUT_SOUND_WORD_RIGHT(b) PUT_SOUND_WORD(b) ! 77: #define SOUND16_BASE_VAL 0 ! 78: #define SOUND8_BASE_VAL 128 ! 79: ! 80: #define DEFAULT_SOUND_MAXB 8192 ! 81: #define DEFAULT_SOUND_MINB 8192 ! 82: #define DEFAULT_SOUND_BITS 16 ! 83: #define DEFAULT_SOUND_FREQ 44100 ! 84: #define HAVE_STEREO_SUPPORT
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.