|
|
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: 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.