Ejemplo n.º 1
0
static void ALSA_Exit_internal(void)
{
	VC_Exit();
	if (pcm_h) {
		alsa_pcm_drain_playback(pcm_h);
		alsa_pcm_close(pcm_h);
		pcm_h=NULL;
	}
	MikMod_free(audiobuffer);
}
Ejemplo n.º 2
0
static void ALSA_Exit_internal(void)
{
	enabled = 0;
	VC_Exit();
	if (pcm_h) {
		alsa_pcm_drain(pcm_h);
		alsa_pcm_close(pcm_h);
		pcm_h = NULL;
	}
	MikMod_free(audiobuffer);
	audiobuffer = NULL;
}
Ejemplo n.º 3
0
static void ALSA_Exit_internal(void)
{
	VC_Exit();
	if (pcm_h) {
#ifdef OLD_ALSA
		alsa_pcm_drain_playback(pcm_h);
#else
		alsa_pcm_drain(pcm_h);
#endif
		alsa_pcm_close(pcm_h);
		pcm_h=NULL;
	}
	MikMod_free(audiobuffer);
}
Ejemplo n.º 4
0
static BOOL ALSA_Init_internal(void)
{
	snd_pcm_format_t pformat;
	int mask,card;

	/* adjust user-configurable settings */
	if((getenv("MM_NUMFRAGS"))&&(numfrags==DEFAULT_NUMFRAGS)) {
		numfrags=atoi(getenv("MM_NUMFRAGS"));
		if ((numfrags<2)||(numfrags>16)) numfrags=DEFAULT_NUMFRAGS;
	}
	if((getenv("ALSA_CARD"))&&(!cardmin)&&(cardmax==SND_CARDS)) {
		cardmin=atoi(getenv("ALSA_CARD"));
		cardmax=cardmin+1;
		if(getenv("ALSA_PCM"))
			device=atoi(getenv("ALSA_PCM"));
	}

	/* setup playback format structure */
	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
	pformat.channels=(md_mode&DMODE_STEREO)?2:1;
	pformat.rate=md_mixfreq;

	/* scan for appropriate sound card */
	mask=alsa_cards_mask();
	_mm_errno=MMERR_OPENING_AUDIO;
	for (card=cardmin;card<cardmax;card++) {
		struct snd_ctl_hw_info info;
		snd_ctl_t *ctl_h;
		int dev,devmin,devmax;

		/* no card here, onto the next */
		if (!(mask&(1<<card))) continue;

		/* try to open the card in query mode */
		if(alsa_ctl_open(&ctl_h,card)<0)
			continue;

		/* 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;
		for(dev=devmin;dev<devmax;dev++) {
			snd_pcm_info_t pcminfo;
			snd_pcm_playback_info_t ctlinfo;
			struct snd_pcm_playback_info pinfo;
			struct snd_pcm_playback_params pparams;
			int size,bps;

			/* 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>pformat.rate)||(pinfo.max_rate<pformat.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) {
				alsa_pcm_close(pcm_h);
				pcm_h=NULL;
				continue;
			}

			/* compute a fragmentsize hint
			   each fragment should be shorter than, but close to, half a
			   second of playback */
			bps=(pformat.rate*pformat.channels*(md_mode&DMODE_16BITS?2:1))>>1;
			size=fragmentsize;while (size>bps) size>>=1;
#ifdef MIKMOD_DEBUG
			if (size < 16) {
				fprintf(stderr,"\rweird hint result:%d from %d, bps=%d\n",size,fragmentsize,bps);
				size=16;
			}
#endif

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

			if (!(audiobuffer=(SBYTE*)MikMod_malloc(fragmentsize))) {
				alsa_ctl_close(ctl_h);
				return 1;
			}

			/* sound device is ready to work */
			if (VC_Init()) {
				alsa_ctl_close(ctl_h);
				return 1;
			} else
			  return 0;
		}

		alsa_ctl_close(ctl_h);
	}
	return 0;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}