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

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

unix.superglobalmegacorp.com

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