Annotation of uae/src/sd-alsa/sound.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.