static int ALSA_Init_internal(void) { snd_pcm_format_t pformat; unsigned int btime = 250000; /* 250ms */ unsigned int ptime = 50000; /* 50ms */ snd_pcm_uframes_t psize; snd_pcm_uframes_t bsize; unsigned int rate, channels; snd_pcm_hw_params_t * hwparams; int err; /* setup playback format structure */ pformat = (md_mode&DMODE_FLOAT)? SND_PCM_FORMAT_FLOAT : (md_mode&DMODE_16BITS)? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U8; channels = (md_mode&DMODE_STEREO)?2:1; rate = md_mixfreq; #define MIKMOD_ALSA_DEVICE "default" if ((err = alsa_pcm_open(&pcm_h, MIKMOD_ALSA_DEVICE, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { _mm_errno = MMERR_OPENING_AUDIO; goto END; } snd_pcm_hw_params_alloca(&hwparams); err = alsa_pcm_hw_params_any(pcm_h, hwparams); if (err < 0) { _mm_errno = MMERR_ALSA_NOCONFIG; goto END; } err = alsa_pcm_hw_params_set_access(pcm_h, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (!err) err = alsa_pcm_hw_params_set_format(pcm_h, hwparams, pformat); if (!err) err = alsa_pcm_hw_params_set_rate_near(pcm_h, hwparams, &rate, NULL); if (!err) err = alsa_pcm_hw_params_set_channels_near(pcm_h, hwparams, &channels); if (!err) err = alsa_pcm_hw_params_set_buffer_time_near(pcm_h, hwparams, &btime, NULL); if (!err) err = alsa_pcm_hw_params_set_period_time_near(pcm_h, hwparams, &ptime, NULL); if (!err) err = alsa_pcm_hw_params(pcm_h, hwparams); if (err < 0) { _mm_errno = MMERR_ALSA_SETPARAMS; goto END; } if (rate != md_mixfreq) { _mm_errno = MMERR_ALSA_SETRATE; goto END; } if (!(md_mode&DMODE_STEREO) && channels != 1) { _mm_errno = MMERR_ALSA_SETCHANNELS; goto END; } if ((md_mode&DMODE_STEREO) && channels != 2) { _mm_errno = MMERR_ALSA_SETCHANNELS; goto END; } err = alsa_pcm_hw_params_current(pcm_h, hwparams); if (!err) err = alsa_pcm_hw_params_get_buffer_size(hwparams, &bsize); if (!err) err = alsa_pcm_hw_params_get_period_size(hwparams, &psize, NULL); if (err < 0) { _mm_errno = MMERR_ALSA_BUFFERSIZE; goto END; } period_size = psize; global_frame_size = channels * ((md_mode&DMODE_FLOAT)? 4 : (md_mode&DMODE_16BITS)? 2 : 1); if (!(audiobuffer=(SBYTE*)MikMod_malloc(period_size * global_frame_size))) { _mm_errno = MMERR_OUT_OF_MEMORY; goto END; } /* sound device is ready to work */ if (!VC_Init()) { enabled = 1; return 0; } END: alsa_pcm_close(pcm_h); pcm_h = NULL; return 1; }
static BOOL ALSA_Init_internal(void) { snd_pcm_format_t pformat; #ifdef OLD_ALSA #define channels pformat.channels #define rate pformat.rate int mask,card; #else int rate; int channels; int err; snd_pcm_hw_params_t * hwparams; snd_pcm_sw_params_t * swparams; #endif /* adjust user-configurable settings */ if((getenv("MM_NUMFRAGS"))&&(numfrags==DEFAULT_NUMFRAGS)) { numfrags=atoi(getenv("MM_NUMFRAGS")); if ((numfrags<2)||(numfrags>16)) numfrags=DEFAULT_NUMFRAGS; } #ifdef OLD_ALSA if((getenv("ALSA_CARD"))&&(!cardmin)&&(cardmax==SND_CARDS)) { cardmin=atoi(getenv("ALSA_CARD")); cardmax=cardmin+1; #endif if(getenv("ALSA_PCM")) device=atoi(getenv("ALSA_PCM")); #ifdef OLD_ALSA } #endif /* setup playback format structure */ #define NUM_CHANNELS() ((md_mode&DMODE_STEREO)?2:1) #ifdef OLD_ALSA memset(&pformat,0,sizeof(pformat)); #ifdef SND_LITTLE_ENDIAN pformat.format=(md_mode&DMODE_16BITS)?SND_PCM_SFMT_S16_LE:SND_PCM_SFMT_U8; #else pformat.format=(md_mode&DMODE_16BITS)?SND_PCM_SFMT_S16_BE:SND_PCM_SFMT_U8; #endif #else pformat = (md_mode&DMODE_16BITS)?SND_PCM_FORMAT_S16_LE:SND_PCM_FORMAT_U8; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); #endif channels = NUM_CHANNELS(); rate=md_mixfreq; /* scan for appropriate sound card */ #ifdef OLD_ALSA mask=alsa_cards_mask(); #endif _mm_errno=MMERR_OPENING_AUDIO; #ifdef OLD_ALSA for (card=cardmin;card<cardmax;card++) #endif { #ifdef OLD_ALSA struct snd_ctl_hw_info info; snd_ctl_t *ctl_h; int dev,devmin,devmax; #endif #ifdef OLD_ALSA /* no card here, onto the next */ if (!(mask&(1<<card))) continue; #endif #ifdef OLD_ALSA /* try to open the card in query mode */ if (alsa_ctl_open(&ctl_h,card)<0) continue; #else if ((err = alsa_pcm_open(&pcm_h, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0)) < 0) { printf("snd_pcm_open() call failed: %s\n", alsa_strerror(err)); goto END; } #endif #ifdef OLD_ALSA /* get hardware information */ if(alsa_ctl_hw_info(ctl_h,&info)<0) { alsa_ctl_close(ctl_h); continue; } /* scan subdevices */ if(device==-1) { devmin=0;devmax=info.pcmdevs; } else devmin=devmax=device; #endif #ifdef OLD_ALSA for(dev=devmin;dev<devmax;dev++) #endif { #ifdef OLD_ALSA int size,bps; snd_pcm_info_t pcminfo; snd_pcm_playback_info_t ctlinfo; struct snd_pcm_playback_info pinfo; struct snd_pcm_playback_params pparams; /* get PCM capabilities */ if(alsa_ctl_pcm_info(ctl_h,dev,&pcminfo)<0) continue; /* look for playback capability */ if(!(pcminfo.flags&SND_PCM_INFO_PLAYBACK)) continue; /* get playback information */ #if defined(SND_LIB_VERSION) && (SND_LIB_VERSION >= 0x400) if(alsa_ctl_pcm_playback_info(ctl_h,dev,0,&ctlinfo)<0) continue; #else if(alsa_ctl_pcm_playback_info(ctl_h,dev,&ctlinfo)<0) continue; #endif /* If control goes here, we have found a sound device able to play PCM data. Let's open in in playback mode and see if we have compatible playback settings. */ if (alsa_pcm_open(&pcm_h,card,dev,SND_PCM_OPEN_PLAYBACK)<0) continue; if (alsa_pcm_playback_info(pcm_h,&pinfo)<0) { alsa_pcm_close(pcm_h); pcm_h=NULL; continue; } /* check we have compatible settings */ if((pinfo.min_rate>rate)||(pinfo.max_rate<rate)|| (!(pinfo.formats&(1<<pformat.format)))) { alsa_pcm_close(pcm_h); pcm_h=NULL; continue; } fragmentsize=pinfo.buffer_size/numfrags; #ifdef MIKMOD_DEBUG if ((fragmentsize<512)||(fragmentsize>16777216L)) fprintf(stderr,"\rweird pinfo.buffer_size:%d\n",pinfo.buffer_size); #endif alsa_pcm_flush_playback(pcm_h); /* set new parameters */ if(alsa_pcm_playback_format(pcm_h,&pformat)<0) #else if( alsa_pcm_set_params(pcm_h, pformat, SND_PCM_ACCESS_RW_INTERLEAVED, channels, rate, 1, 500000 /* 0.5sec */ ) < 0) #endif { alsa_pcm_close(pcm_h); pcm_h=NULL; #ifdef OLD_ALSA continue; #else goto END; #endif } global_frame_size = channels*(md_mode&DMODE_16BITS?2:1); #ifdef OLD_ALSA /* compute a fragmentsize hint each fragment should be shorter than, but close to, half a second of playback */ bps=(rate*global_frame_size)>>1; size=fragmentsize;while (size>bps) size>>=1; #endif #ifdef MIKMOD_DEBUG if (size < 16) { fprintf(stderr,"\rweird hint result:%d from %d, bps=%d\n",size,fragmentsize,bps); size=16; } #endif #ifdef OLD_ALSA buffer_size = size; memset(&pparams,0,sizeof(pparams)); pparams.fragment_size=size; pparams.fragments_max=-1; /* choose the best */ pparams.fragments_room=-1; if(alsa_pcm_playback_params(pcm_h,&pparams)<0) { alsa_pcm_close(pcm_h); pcm_h=NULL; continue; } #else /* choose all parameters */ err = alsa_pcm_hw_params_any(pcm_h, hwparams); if (err < 0) { printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err)); goto END; } { snd_pcm_uframes_t temp_u_buffer_size, temp_u_period_size; err = alsa_pcm_get_params(pcm_h, &temp_u_buffer_size, &temp_u_period_size); if (err < 0) { alsa_pcm_close(pcm_h); pcm_h=NULL; printf("Unable to get buffer size for playback: %s\n", alsa_strerror(err)); goto END; } buffer_size_in_frames = 1200; period_size = temp_u_period_size; } /* The set_swparams function was taken from test/pcm.c * in the alsa-lib distribution*/ if ((err = set_swparams(pcm_h, swparams)) < 0) { printf("Setting of swparams failed: %s\n", snd_strerror(err)); goto END; } #endif if (!(audiobuffer=(SBYTE*)MikMod_malloc( #ifdef OLD_ALSA fragmentsize #else buffer_size_in_frames * global_frame_size #endif ))) { #ifdef OLD_ALSA alsa_ctl_close(ctl_h); #else alsa_pcm_close(pcm_h); #endif return 1; } /* sound device is ready to work */ if (VC_Init()) { #ifdef OLD_ALSA alsa_ctl_close(ctl_h); #else alsa_pcm_close(pcm_h); #endif return 1; } else return 0; } #ifdef OLD_ALSA alsa_ctl_close(ctl_h); #else alsa_pcm_close(pcm_h); #endif } END: return 1; }