View | Details | Raw Unified
Collapse All | Expand All

(-) src/al_ext.c (+4 lines)
 Lines 993-997    Link Here 
		return ALC_TRUE;
		return ALC_TRUE;
	}
	}
	if(ustrcmp("ALC_CAPTURE_SAMPLES", ename) == 0) {
		return 0x312;
	}
	return 0;
	return 0;
}
}
(-) src/al_main.c (+1 lines)
 Lines 133-138    Link Here 
#ifdef CAPTURE_SUPPORT
#ifdef CAPTURE_SUPPORT
	_alRegisterExtensionGroup( (const ALubyte*) "AL_EXT_capture" );
	_alRegisterExtensionGroup( (const ALubyte*) "AL_EXT_capture" );
	_alRegisterExtensionGroup( (const ALubyte*) "ALC_EXT_capture" );
#endif /* CAPTURE_SUPPORT */
#endif /* CAPTURE_SUPPORT */
#endif /* BUILTIN_EXT_LOKI */
#endif /* BUILTIN_EXT_LOKI */
(-) src/al_queue.c (+5 lines)
 Lines 51-56    Link Here 
		return;
		return;
	}
	}
	_alcDCLockContext();
	SOURCELOCK();
	SOURCELOCK();
	src = _alDCGetSource( sid );
	src = _alDCGetSource( sid );
 Lines 60-65    Link Here 
		_alDebug(ALD_SOURCE, __FILE__, __LINE__,
		_alDebug(ALD_SOURCE, __FILE__, __LINE__,
		      "alSourceQueueBuffers: invalid sid %d\n", sid );
		      "alSourceQueueBuffers: invalid sid %d\n", sid );
		_alcDCUnlockContext();
		SOURCEUNLOCK();
		SOURCEUNLOCK();
		return;
		return;
 Lines 79-84    Link Here 
				_alDCSetError( AL_INVALID_NAME );
				_alDCSetError( AL_INVALID_NAME );
				_alcDCUnlockContext();
				SOURCEUNLOCK();
				SOURCEUNLOCK();
				return;
				return;
 Lines 100-105    Link Here 
	/* we're done */
	/* we're done */
	_alUnlockBuffer();
	_alUnlockBuffer();
	_alcDCUnlockContext();
	SOURCEUNLOCK();
	SOURCEUNLOCK();
	return;
	return;
(-) src/al_source.c (-2 / +2 lines)
 Lines 595-603    Link Here 
			"alSourcefv: %d is an invalid source id", sid );
			"alSourcefv: %d is an invalid source id", sid );
		_alDCSetError( AL_INVALID_NAME );
		_alDCSetError( AL_INVALID_NAME );
		SOURCEUNLOCK();
		SOURCEUNLOCK();
		return;
		return;
	}
	}
 Lines 690-695    Link Here 
		  }
		  }
		  break;
		  break;
		case AL_VELOCITY:
		case AL_VELOCITY:
break;
		  source->velocity.isset = AL_TRUE;
		  source->velocity.isset = AL_TRUE;
		  memcpy( &source->velocity.data, fv1, SIZEOFVECTOR );
		  memcpy( &source->velocity.data, fv1, SIZEOFVECTOR );
 Lines 723-728    Link Here 
		  break;
		  break;
		case AL_PITCH:
		case AL_PITCH:
		  /* only set pitch if it differs from 1.0 */
		  /* only set pitch if it differs from 1.0 */
break;
		  if(fv1[0] == 1.0) {
		  if(fv1[0] == 1.0) {
			source->pitch.isset = AL_FALSE;
			source->pitch.isset = AL_FALSE;
			source->pitch.data  = 1.0;
			source->pitch.data  = 1.0;
(-) src/alc/alc_context.c (+6 lines)
 Lines 1525-1530    Link Here 
	return deviceHandle->cc;
	return deviceHandle->cc;
}
}
ALint __alcGetAvailableSamples(ALvoid);
void alcGetIntegerv( ALCdevice *deviceHandle, ALenum  token,
void alcGetIntegerv( ALCdevice *deviceHandle, ALenum  token,
		     ALsizei  size , ALint *dest )
		     ALsizei  size , ALint *dest )
{
{
 Lines 1546-1551    Link Here 
		     time.
		     time.
		     Check size
		     Check size
		   */
		   */
		case 0x312:  /*ALC_CAPTURE_SAMPLES:*/
          *dest = __alcGetAvailableSamples();
          break;
		case ALC_MAJOR_VERSION:
		case ALC_MAJOR_VERSION:
		  *dest = 1;
		  *dest = 1;
		  break;
		  break;
(-) src/arch/alsa/alsa.c (-79 / +328 lines)
 Lines 46-52    Link Here 
 * get either the default device name or something the
 * get either the default device name or something the
 * user specified
 * user specified
 */
 */
void get_device_name(char *retref, int retsize);
static void get_in_device_name(char *retref, int retsize);
static void get_out_device_name(char *retref, int retsize);
struct alsa_info
struct alsa_info
{
{
 Lines 58-63    Link Here 
	unsigned int periods;
	unsigned int periods;
	snd_pcm_uframes_t bufframesize;
	snd_pcm_uframes_t bufframesize;
	fd_set fd_set;
	fd_set fd_set;
	int setup_read, setup_write;
};
};
void *release_alsa(void *handle)
void *release_alsa(void *handle)
 Lines 76-92    Link Here 
void *grab_read_alsa( void )
void *grab_read_alsa( void )
{
{
	/* no capture support */
	struct alsa_info *retval;
	return NULL;
	snd_pcm_t *handle;
	char card_name[256];
	int err;
	get_in_device_name(card_name, 256);
	err = snd_pcm_open(&handle, card_name, SND_PCM_STREAM_CAPTURE, 0);
	if(err < 0)
	{
		const char *serr = snd_strerror(err);
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"grab_alsa: init failed: %s\n", serr);
		return NULL;
	}
	retval = malloc(sizeof *retval);
	retval->handle      = handle;
	retval->format      = 0;
	retval->channels    = 0;
	retval->speed       = 0;
	retval->framesize   = 0;
	retval->bufframesize= 0;
	retval->periods     = 0;
	retval->setup_read	= 0;
	retval->setup_write	= 0;
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"grab_alsa: init ok, using %s\n", card_name);
	return retval;
}
static void get_out_device_name(char *retref, int retsize)
{
	Rcvar rcv;
	assert(retref);
	if (!(rcv = rc_lookup("alsa-device")))
		rcv = rc_lookup("alsa-out-device");
	if (rcv != NULL)
	{
		if(rc_type(rcv) == ALRC_STRING)
		{
			rc_tostr0(rcv, retref, retsize);
                        return;
		}
	}
	assert((int) strlen(DEFAULT_DEVICE) < retsize);
	strcpy(retref, DEFAULT_DEVICE);
	return;
}
}
void get_device_name(char *retref, int retsize)
static void get_in_device_name(char *retref, int retsize)
{
{
	Rcvar rcv;
	Rcvar rcv;
	assert(retref);
	assert(retref);
	rcv = rc_lookup("alsa-device");
	if (!(rcv = rc_lookup("alsa-in-device")))
		rcv = rc_lookup("alsa-device");
	if(rcv != NULL)
	if(rcv != NULL)
	{
	{
		if(rc_type(rcv) == ALRC_STRING)
		if(rc_type(rcv) == ALRC_STRING)
 Lines 110-118    Link Here 
	char card_name[256];
	char card_name[256];
	int err;
	int err;
	get_device_name(card_name, 256);
	get_out_device_name(card_name, 256);
	err = snd_pcm_open(&handle, card_name, 0, SND_PCM_STREAM_PLAYBACK);
	err = snd_pcm_open(&handle, card_name, SND_PCM_STREAM_PLAYBACK, 0);
	if(err < 0)
	if(err < 0)
	{
	{
		const char *serr = snd_strerror(err);
		const char *serr = snd_strerror(err);
 Lines 130-136    Link Here 
	retval->speed       = 0;
	retval->speed       = 0;
	retval->framesize   = 0;
	retval->framesize   = 0;
	retval->bufframesize= 0;
	retval->bufframesize= 0;
        retval->periods     = 0;
	retval->periods     = 0;
	retval->setup_read	= 0;
	retval->setup_write	= 0;
	_alBlitBuffer = alsa_blitbuffer;
	_alBlitBuffer = alsa_blitbuffer;
 Lines 140-152    Link Here 
	return retval;
	return retval;
}
}
ALboolean set_read_alsa( UNUSED(void *handle),
ALboolean set_read_alsa( void *handle,
			 UNUSED(ALuint *bufsiz),
			 ALuint *bufsiz,
			 UNUSED(ALenum *fmt),
			 ALenum *fmt,
			 UNUSED(ALuint *speed))
			 ALuint *speed)
{
{
	/* no capture support */
	struct alsa_info *ai = handle;
	return AL_FALSE;
	snd_pcm_hw_params_t *setup;
	snd_pcm_uframes_t buffer_size, period_size;
	snd_pcm_t *phandle = 0;
	int err, dir;
	snd_output_t *out;
	if( (ai == NULL) || (ai->handle == NULL) )
		return AL_FALSE;
	if (*fmt == AL_FORMAT_QUAD8_LOKI)
		*fmt = AL_FORMAT_STEREO8;
	if (*fmt == AL_FORMAT_QUAD16_LOKI)
		*fmt = AL_FORMAT_STEREO16;
	ai->channels    = (unsigned int) _al_ALCHANNELS(*fmt);
	ai->format      = (unsigned int) AL2ALSAFMT(*fmt);
	ai->speed       = (unsigned int) *speed;
	ai->framesize   = (unsigned int) FRAMESIZE(ai->format, ai->channels);
	ai->bufframesize= (snd_pcm_uframes_t) *bufsiz / ai->framesize * 4;
	ai->periods     = 2;
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"alsa info (read):\n"\
			" channels: %u\n"\
			" format: %u\n"\
			" speed: %u\n"\
			" framesize: %u\n"\
			" bufframesize: %u\n"\
			" periods: %u",
			ai->channels, ai->format, ai->speed, ai->framesize, ai->bufframesize, ai->periods);
	phandle = ai->handle;
	snd_output_stdio_attach (&out, stderr, 0);
	snd_pcm_hw_params_alloca(&setup);
	err = snd_pcm_hw_params_any(phandle, setup);
	if(err < 0)
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_read_alsa: Could not query parameters: %s",snd_strerror(err));
		return AL_FALSE;
	}
	/* set the interleaved read format */
	err = snd_pcm_hw_params_set_access(phandle, setup, SND_PCM_ACCESS_RW_INTERLEAVED);
	if (err < 0) {
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_read_alsa: Could not set access type: %s",snd_strerror(err));
		return AL_FALSE;
	}
	/* set format */
	err = snd_pcm_hw_params_set_format(phandle, setup, ai->format);
	if(err < 0)
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_read_alsa: could not set format: %s",snd_strerror(err));
		return AL_FALSE;
	}
	/* channels */
	err = snd_pcm_hw_params_set_channels(phandle, setup, ai->channels);
	if(err < 0)
	{
#if (SND_LIB_MAJOR == 0)
		err = snd_pcm_hw_params_get_channels(setup);
#else
		snd_pcm_hw_params_get_channels(setup, &err);
#endif
		if (err != (int) (ai->channels)) {
			_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
					"set_read_alsa: could not set channels: %s",snd_strerror(err));
			return AL_FALSE;
		}
	}
	/* sampling rate */
	err = snd_pcm_hw_params_set_rate_near(phandle, setup, &ai->speed, NULL);
	if(err < 0)
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_read_alsa: could not set speed: %s",snd_strerror(err));
		return AL_FALSE;
	} else if (err > 0) /* err is sampling rate if > 0 */
		ai->speed = (unsigned int) err;
	/* Set number of periods. Periods used to be called fragments. */
	err = snd_pcm_hw_params_set_periods(phandle, setup, ai->periods, 0);
	if (err < 0) {
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_read_alsa: %s\n", snd_strerror(err));
		return AL_FALSE;
	}
	snd_pcm_hw_params_dump (setup, out);
	err = snd_pcm_hw_params_set_buffer_size(phandle, setup, ai->bufframesize);
	snd_pcm_hw_params_dump (setup, out);
	if (err < 0) {
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_read_alsa: %s, size: %d, speed: %d\n",
				snd_strerror(err), ai->bufframesize, ai->speed);
		return AL_FALSE;
	}
#if (SND_LIB_MAJOR == 0)
	buffer_size = snd_pcm_hw_params_get_buffer_size(setup);
	period_size = snd_pcm_hw_params_get_period_size(setup, &dir);
#else
	snd_pcm_hw_params_get_buffer_size(setup, &buffer_size);
	snd_pcm_hw_params_get_period_size(setup, &period_size, &dir);
#endif
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"set_read_alsa (info): Buffersize = %i (%i)",buffer_size, *bufsiz);
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"set_read_alsa (info): Periodsize = %i", period_size);
	err = snd_pcm_hw_params(phandle, setup);
	if(err < 0)
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_read_alsa: %s\n", snd_strerror(err));
		return AL_FALSE;
	}
	err = snd_pcm_prepare(phandle);
	if(err < 0)
	{
		_alDebug(ALD_MAXIMUS,  __FILE__, __LINE__,
				"set_read_alsa %s\n", snd_strerror(err));
		return AL_FALSE;
	}
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"set_read_alsa: handle: %p, phandle: %p\n", handle, phandle);
	snd_output_close (out);
	ai->setup_read = 1;
	return AL_TRUE;
}
}
ALboolean set_write_alsa(void *handle,
ALboolean set_write_alsa(void *handle,
 Lines 159-212    Link Here 
	snd_pcm_uframes_t buffer_size, period_size;
	snd_pcm_uframes_t buffer_size, period_size;
	snd_pcm_t *phandle = 0;
	snd_pcm_t *phandle = 0;
	int err, dir;
	int err, dir;
	snd_output_t *out;
	if( (ai == NULL) || (ai->handle == NULL) )
	if( (ai == NULL) || (ai->handle == NULL) )
	  return AL_FALSE;
		return AL_FALSE;
        ai->channels    = (unsigned int) _al_ALCHANNELS(*fmt);
	ai->channels    = (unsigned int) _al_ALCHANNELS(*fmt);
        ai->format      = (unsigned int) AL2ALSAFMT(*fmt);
	ai->format      = (unsigned int) AL2ALSAFMT(*fmt);
        ai->speed       = (unsigned int) *speed;
	ai->speed       = (unsigned int) *speed;
        ai->framesize   = (unsigned int) FRAMESIZE(ai->format, ai->channels);
	ai->framesize   = (unsigned int) FRAMESIZE(ai->format, ai->channels);
	ai->bufframesize= (snd_pcm_uframes_t) *bufsiz / ai->framesize * 4;
	ai->bufframesize= (snd_pcm_uframes_t) *bufsiz / ai->framesize * 4;
        ai->periods     = 2;
	ai->periods     = 2;
        _alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
	   "alsa info:\n"\
			"alsa info (write):\n"\
	   " channels: %u\n"\
			" channels: %u\n"\
	   " format: %u\n"\
			" format: %u\n"\
	   " speed: %u\n"\
			" speed: %u\n"\
	   " framesize: %u\n"\
			" framesize: %u\n"\
	   " bufframesize: %u\n"\
			" bufframesize: %u\n"\
	   " periods: %u",
			" periods: %u",
	 ai->channels, ai->format, ai->speed, ai->framesize, ai->bufframesize, ai->periods);
			ai->channels, ai->format, ai->speed, ai->framesize, ai->bufframesize, ai->periods);
        phandle = ai->handle;
	phandle = ai->handle;
	snd_output_stdio_attach (&out, stderr, 0);
	snd_pcm_hw_params_alloca(&setup);
	snd_pcm_hw_params_alloca(&setup);
	err = snd_pcm_hw_params_any(phandle, setup);
	err = snd_pcm_hw_params_any(phandle, setup);
	if(err < 0)
	if(err < 0)
	{
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			 "set_write_alsa: Could not query parameters: %s",snd_strerror(err));
				"set_write_alsa: Could not query parameters: %s",snd_strerror(err));
		return AL_FALSE;
		return AL_FALSE;
	}
	}
        /* set the interleaved read format */
	/* set the interleaved write format */
        err = snd_pcm_hw_params_set_access(phandle, setup, SND_PCM_ACCESS_RW_INTERLEAVED);
	err = snd_pcm_hw_params_set_access(phandle, setup, SND_PCM_ACCESS_RW_INTERLEAVED);
        if (err < 0) {
	if (err < 0) {
        	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			 "set_write_alsa: Could not set access type: %s",snd_strerror(err));
				"set_write_alsa: Could not set access type: %s",snd_strerror(err));
                return AL_FALSE;
		return AL_FALSE;
        }
	}
	/* set format */
	/* set format */
	err = snd_pcm_hw_params_set_format(phandle, setup, ai->format);
	err = snd_pcm_hw_params_set_format(phandle, setup, ai->format);
	if(err < 0)
	if(err < 0)
	{
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			 "set_write_alsa: could not set format: %s",snd_strerror(err));
				"set_write_alsa: could not set format: %s",snd_strerror(err));
		return AL_FALSE;
		return AL_FALSE;
	}
	}
 Lines 216-231    Link Here 
	err = snd_pcm_hw_params_set_channels(phandle, setup, ai->channels);
	err = snd_pcm_hw_params_set_channels(phandle, setup, ai->channels);
	if(err < 0)
	if(err < 0)
	{
	{
#if (SND_LIB_MAJOR == 0)
		err = snd_pcm_hw_params_get_channels(setup);
#else
		snd_pcm_hw_params_get_channels(setup, &err);
#endif
		#if (SND_LIB_MAJOR == 0)
		if (err!= (int) (ai->channels)) {
			err = snd_pcm_hw_params_get_channels(setup);
		#else
			snd_pcm_hw_params_get_channels(setup, &err);
		#endif
		if(err!= (int) (ai->channels)) {
			_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				 "set_write_alsa: could not set channels: %s",snd_strerror(err));
					"set_write_alsa: could not set channels: %s",snd_strerror(err));
			return AL_FALSE;
			return AL_FALSE;
		}
		}
 Lines 233-283    Link Here 
	/* sampling rate */
	/* sampling rate */
	err = snd_pcm_hw_params_set_rate_near(phandle, setup, ai->speed, NULL);
	err = snd_pcm_hw_params_set_rate_near(phandle, setup, &ai->speed, NULL);
	if(err < 0)
	if(err < 0)
	{
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			 "set_write_alsa: could not set speed: %s",snd_strerror(err));
				"set_write_alsa: could not set speed: %s",snd_strerror(err));
		return AL_FALSE;
		return AL_FALSE;
	}
	} else if (err > 0) /* err is sampling rate if > 0 */
	/* err is sampling rate if >= 0 */
		ai->speed = (unsigned int) err;
	ai->speed = (unsigned int) err;
        /* Set number of periods. Periods used to be called fragments. */
	/* Set number of periods. Periods used to be called fragments. */
        err = snd_pcm_hw_params_set_periods(phandle, setup, ai->periods, 0);
	err = snd_pcm_hw_params_set_periods(phandle, setup, ai->periods, 0);
        if (err < 0) {
	if (err < 0) {
                _alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"set_write_alsa: %s\n", snd_strerror(err));
				"set_write_alsa: %s\n", snd_strerror(err));
		return AL_FALSE;
		return AL_FALSE;
        }
	}
        err = snd_pcm_hw_params_set_buffer_size(phandle, setup, ai->bufframesize);
	snd_pcm_hw_params_dump (setup, out);
        if (err < 0) {
	err = snd_pcm_hw_params_set_buffer_size(phandle, setup, ai->bufframesize);
                _alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
	snd_pcm_hw_params_dump (setup, out);
			"set_write_alsa: %s\n", snd_strerror(err));
	if (err < 0) {
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
				"set_write_alsa: %s, size: %d, speed: %d\n",
				snd_strerror(err), ai->bufframesize, ai->speed);
		return AL_FALSE;
		return AL_FALSE;
        }
	}
#if (SND_LIB_MAJOR == 0)
	buffer_size = snd_pcm_hw_params_get_buffer_size(setup);
	period_size = snd_pcm_hw_params_get_period_size(setup, &dir);
#else
	snd_pcm_hw_params_get_buffer_size(setup, &buffer_size);
	snd_pcm_hw_params_get_period_size(setup, &period_size, &dir);
#endif
	#if (SND_LIB_MAJOR == 0)
		buffer_size = snd_pcm_hw_params_get_buffer_size(setup);
		period_size = snd_pcm_hw_params_get_period_size(setup, &dir);
	#else
        	snd_pcm_hw_params_get_buffer_size(setup, &buffer_size);
		snd_pcm_hw_params_get_period_size(setup, &period_size, &dir);
	#endif
	
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		"set_write_alsa (info): Buffersize = %i (%i)",buffer_size, *bufsiz);
			"set_write_alsa (info): Buffersize = %i (%i)",buffer_size, *bufsiz);
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		"set_write_alsa (info): Periodsize = %i", period_size);
			"set_write_alsa (info): Periodsize = %i", period_size);
	err = snd_pcm_hw_params(phandle, setup);
	err = snd_pcm_hw_params(phandle, setup);
	if(err < 0)
	if(err < 0)
	{
	{
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
		_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"set_alsa: %s\n", snd_strerror(err));
				"set_alsa: %s\n", snd_strerror(err));
		return AL_FALSE;
		return AL_FALSE;
	}
	}
 Lines 285-294    Link Here 
	if(err < 0)
	if(err < 0)
	{
	{
		_alDebug(ALD_MAXIMUS,  __FILE__, __LINE__,
		_alDebug(ALD_MAXIMUS,  __FILE__, __LINE__,
			"set_alsa %s\n", snd_strerror(err));
				"set_alsa %s\n", snd_strerror(err));
		return AL_FALSE;
		return AL_FALSE;
	}
	}
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"set_write_alsa: handle: %p, phandle: %p\n", handle, phandle);
	snd_output_close (out);
	ai->setup_write = 1;
	return AL_TRUE;
	return AL_TRUE;
}
}
 Lines 300-315    Link Here 
	int data_len = bytes;
	int data_len = bytes;
	int channels = 0;
	int channels = 0;
	int err;
	int err;
        snd_pcm_uframes_t frames;
	snd_pcm_uframes_t frames;
	if((ai == NULL) || (ai->handle == NULL))
	if((ai == NULL) || (ai->handle == NULL) || (!ai->setup_write))
	{
	{
		return;
		return;
	}
	}
	phandle = ai->handle;
	phandle = ai->handle;
        channels= ai->channels;
	channels= ai->channels;
        frames  = (snd_pcm_uframes_t) bytes / ai->framesize;
	frames  = (snd_pcm_uframes_t) bytes / ai->framesize;
	while(data_len > 0)
	while(data_len > 0)
	{
	{
 Lines 347-352    Link Here 
	return;
	return;
}
}
/* capture data from the audio device */
ALsizei capture_alsa(void *handle,
		void *capture_buffer,
		int bufsize)
{
	struct alsa_info *ai = handle;
	snd_pcm_t *phandle = 0;
	char *pdata = capture_buffer;
	int ret;
	snd_pcm_uframes_t frames;
	if ((ai == NULL) || (ai->handle == NULL) || (!ai->setup_read))
		return 0;
	phandle = ai->handle;
	frames = (snd_pcm_uframes_t) bufsize / ai->framesize;
grab:
	_alDebug(ALD_MAXIMUS, __FILE__, __LINE__,
			"set_read_alsa: handle: %p, phandle: %p\n", handle, phandle);
	ret = snd_pcm_readi (phandle, pdata, frames);
	if (ret < 0) {
		fprintf(stderr, "Error, overrun: %d, trying to recover.\n", ret);
		ret = snd_pcm_prepare(phandle);
		if (ret < 0)
			fprintf(stderr, "Unable to recover: %d\n", ret);
		else
			goto grab;
		return 0;
	} else
		return ret * ai->framesize;
}
static int AL2ALSAFMT(ALenum format) {
static int AL2ALSAFMT(ALenum format) {
	switch(format) {
	switch(format) {
(-) src/arch/alsa/alsa.h (+3 lines)
 Lines 17-21    Link Here 
			  ALuint *bufsiz,
			  ALuint *bufsiz,
			  ALenum *fmt,
			  ALenum *fmt,
			  ALuint *speed);
			  ALuint *speed);
ALsizei capture_alsa(void *handle,
		void *capture_buffer,
		int bufsiz);
#endif /* ALSA_H_ */
#endif /* ALSA_H_ */
(-) src/arch/interface/interface_sound.c (+2 lines)
 Lines 413-418    Link Here 
		  bytes = capture_emu10k1(handle, capture_buffer, bufsiz);
		  bytes = capture_emu10k1(handle, capture_buffer, bufsiz);
		  break;
		  break;
		case LA_ALSA:
		case LA_ALSA:
		  bytes = capture_alsa(handle, capture_buffer, bufsiz);
		  break;
		case LA_SDL:
		case LA_SDL:
		case LA_ARTS:
		case LA_ARTS:
		case LA_ESD:
		case LA_ESD:
(-) src/arch/linux/lin_dsp.c (-1 / +4 lines)
 Lines 446-451    Link Here 
	int retval;
	int retval;
	retval = read(read_fd, capture_buffer, bufsiz);
	retval = read(read_fd, capture_buffer, bufsiz);
/*if (retval < 0) printf("%s\n", strerror(errno));*/
	return retval > 0 ? retval : 0;
	return retval > 0 ? retval : 0;
}
}
 Lines 633-639    Link Here 
		 * This is for reading.  Don't really use
		 * This is for reading.  Don't really use
		 * the speed argument.
		 * the speed argument.
		 */
		 */
		*speed = 8000;
		*speed = 16000;
		/* Try to set the speed (ignore value), then read it back */
		/* Try to set the speed (ignore value), then read it back */
                ioctl(dsp_fd, SNDCTL_DSP_SPEED, speed);
                ioctl(dsp_fd, SNDCTL_DSP_SPEED, speed);
(-) src/extensions/al_ext_capture.c (-3 / +234 lines)
 Lines 45-50    Link Here 
	AL_EXT_PAIR(alCaptureStop_EXT),
	AL_EXT_PAIR(alCaptureStop_EXT),
	AL_EXT_PAIR(alCaptureGetData_EXT),
	AL_EXT_PAIR(alCaptureGetData_EXT),
	AL_EXT_PAIR(alCaptureDestroy_EXT),
	AL_EXT_PAIR(alCaptureDestroy_EXT),
	AL_EXT_PAIR(alcCaptureOpenDevice),
	AL_EXT_PAIR(alcCaptureCloseDevice),
	AL_EXT_PAIR(alcCaptureStart),
	AL_EXT_PAIR(alcCaptureStop),
	AL_EXT_PAIR(alcCaptureSamples),
	{ NULL, NULL }
	{ NULL, NULL }
};
};
 Lines 171-184    Link Here 
		                       format, dev->format, samples);
		                       format, dev->format, samples);
		size *= (_al_formatbits(dev->format) / 8);
		size *= (_al_formatbits(dev->format) / 8);
        	if ( n > (ALsizei)size )
       	if ( n > (ALsizei)size )
			temp = malloc( n );
			temp = malloc( n );
		else
		else
			temp = malloc( size );
			temp = malloc( size );
		if ( size > 0 ) {
		if ( size > 0 ) {
			size = _alcDeviceRead(cid, temp, size);
			size = _alcDeviceRead(cid, temp, size);
		}
		if ( size > 0 ) {
			temp = _alBufferCanonizeData(dev->format,
			temp = _alBufferCanonizeData(dev->format,
						     temp,
						     temp,
						     size,
						     size,
 Lines 189-196    Link Here 
						     AL_TRUE);
						     AL_TRUE);
		} else {
		} else {
			/* Hmm, zero size in record.. */
			/* Hmm, zero size in record.. */
			memset(temp, 0, n);
			/*memset(temp, 0, n);*/
			size = n;
			size = 0;
		}
		}
		if(temp == NULL) {
		if(temp == NULL) {
			fprintf(stderr, "could not canonize data\n");
			fprintf(stderr, "could not canonize data\n");
 Lines 203-205    Link Here 
	}
	}
	return size;
	return size;
}
}
/* Hacked in ALC_EXT_capture support.  --ryan. */
/* This doesn't support multiple devices, device enumeration, or capture */
/*  devices seperate from an existing context. How painful. */
/* ring buffer functionality... */
typedef struct
{
    ALubyte *buffer;
    ALsizei size;
    ALsizei write;
    ALsizei read;
    ALsizei used;
} __ALRingBuffer;
static ALboolean __alRingBufferInit(__ALRingBuffer *ring, ALsizei size);
static ALvoid __alRingBufferShutdown(__ALRingBuffer *ring);
static ALsizei __alRingBufferSize(__ALRingBuffer *ring);
static ALvoid __alRingBufferPut(__ALRingBuffer *ring, ALubyte *data, ALsizei size);
static ALsizei __alRingBufferGet(__ALRingBuffer *ring, ALubyte *data, ALsizei size);
static __ALRingBuffer captureRing;
static ALboolean __alRingBufferInit(__ALRingBuffer *ring, ALsizei size)
{
    ALubyte *ptr = (ALubyte *) realloc(ring->buffer, size);
    if (ptr == NULL)
        return(AL_FALSE);
    ring->buffer = ptr;
    ring->size = size;
    ring->write = 0;
    ring->read = 0;
    ring->used = 0;
    return(AL_TRUE);
} /* __alRingBufferInit */
static ALvoid __alRingBufferShutdown(__ALRingBuffer *ring)
{
    free(ring->buffer);
    ring->buffer = NULL;
} /* __alRingBufferShutdown */
static ALsizei __alRingBufferSize(__ALRingBuffer *ring)
{
    return(ring->used);
} /* __alRingBufferSize */
static ALvoid __alRingBufferPut(__ALRingBuffer *ring, ALubyte *data, ALsizei _size)
{
    register ALsizei size = _size;
    register ALsizei cpy;
    register ALsizei avail;
    if (!size)   /* just in case... */
        return;
    /* Putting more data than ring buffer holds in total? Replace it all. */
    if (size > ring->size)
    {
        ring->write = 0;
        ring->read = 0;
        ring->used = ring->size;
        memcpy(ring->buffer, data + (size - ring->size), ring->size);
        return;
    } /* if */
    /* Buffer overflow? Push read pointer to oldest sample not overwritten. */
    avail = ring->size - ring->used;
    if (size > avail)
    {
        ring->read += size - avail;
        if (ring->read > ring->size)
            ring->read -= ring->size;
    } /* if */
    /* Clip to end of buffer and copy first block... */
    cpy = ring->size - ring->write;
    if (size < cpy)
        cpy = size;
    if (cpy) memcpy(ring->buffer + ring->write, data, cpy);
    /* Wrap around to front of ring buffer and copy remaining data... */
    avail = size - cpy;
    if (avail) memcpy(ring->buffer, data + cpy, avail);
    /* Update write pointer... */
    ring->write += size;
    if (ring->write > ring->size)
        ring->write -= ring->size;
    ring->used += size;
    if (ring->used > ring->size)
        ring->used = ring->size;
} /* __alRingBufferPut */
static ALsizei __alRingBufferGet(__ALRingBuffer *ring, ALubyte *data, ALsizei _size)
{
    register ALsizei cpy;
    register ALsizei size = _size;
    register ALsizei avail = ring->used;
    /* Clamp amount to read to available data... */
    if (size > avail)
        size = avail;
    
    /* Clip to end of buffer and copy first block... */
    cpy = ring->size - ring->read;
    if (cpy > size) cpy = size;
    if (cpy) memcpy(data, ring->buffer + ring->read, cpy);
    
    /* Wrap around to front of ring buffer and copy remaining data... */
    avail = size - cpy;
    if (avail) memcpy(data + cpy, ring->buffer, avail);
    /* Update read pointer... */
    ring->read += size;
    if (ring->read > ring->size)
        ring->read -= ring->size;
    ring->used -= size;
    return(size);  /* may have been clamped if there wasn't enough data... */
} /* __alRingBufferGet */
static ALenum captureFmt = AL_NONE;
static ALuint captureFreq = 0;
static ALint captureFmtSize = 0;
ALCdevice *alcCaptureOpenDevice(const ALubyte *deviceName,
                                ALuint freq, ALenum fmt,
                                ALsizei bufsize)
{
    ALCdevice *retval;
	AL_context *cc;
	ALuint cid;
    if (deviceName != NULL)  /* !!! FIXME */
        return NULL;
    switch (fmt)  /* try to keep this sane for now... */
    {
        case AL_FORMAT_MONO8:
        case AL_FORMAT_MONO16:
        case AL_FORMAT_STEREO8:
        case AL_FORMAT_STEREO16:
            break;  /* okay format. */
        default:
            return(NULL);
    }
    captureFmt = fmt;
    captureFreq = freq;
    captureFmtSize = (_al_formatbits(fmt) / 8);
    if ((fmt == AL_FORMAT_STEREO8) || (fmt == AL_FORMAT_STEREO16))
        captureFmtSize *= 2;
    bufsize *= captureFmtSize;
    if (!__alRingBufferInit(&captureRing, bufsize))
        return NULL;
    if (!alCaptureInit_EXT(fmt, freq, bufsize))
        return NULL;
	cid = _alcCCId;
	_alcLockContext( cid );
	cc = _alcGetContext(cid);
    retval = cc->read_device;
	retval->cc = cc;
    _alcUnlockContext( cid );
    fprintf(stderr, "WARNING: ALC_EXT_capture is subject to change!\n");
    return(retval);
}
ALvoid alcCaptureCloseDevice(ALCdevice *dev)
{
    if (dev == NULL)
        return;
    alCaptureDestroy_EXT();
    __alRingBufferShutdown(&captureRing);
}
ALvoid alcCaptureStart(void)
{
    alCaptureStart_EXT();
}
ALvoid alcCaptureStop(void)
{
    alCaptureStop_EXT();
}
/* !!! FIXME: Not ideal; reads samples in ALC_CAPTURE_SAMPLES query */
/* !!! FIXME: should query hardware here and do read in alcCaptureSamples() */
ALint __alcGetAvailableSamples(ALvoid)
{
    static ALubyte buf[1024];
    ALsizei got = alCaptureGetData_EXT(buf, sizeof (buf),
                                       captureFmt, captureFreq);
    if (got > 0)
        __alRingBufferPut(&captureRing, buf, got);
    /*printf("got %d have %d\n", (int) got, (int) (__alRingBufferSize(&captureRing) / captureFmtSize));*/
    return(__alRingBufferSize(&captureRing) / captureFmtSize);
}
ALvoid alcCaptureSamples(ALCdevice *device, ALvoid *buf, ALsizei samps)
{
    if ((__alRingBufferSize(&captureRing) / captureFmtSize) < samps)
        return;  /* !!! FIXME: This is an error condition! */
    __alRingBufferGet(&captureRing, buf, samps * captureFmtSize);
}
(-) src/extensions/al_ext_capture.h (-1 / +16 lines)
 Lines 13-18    Link Here 
#include <AL/alext.h>
#include <AL/alext.h>
ALCdevice *alcCaptureOpenDevice(const ALubyte *deviceName,
                                ALuint freq, ALenum fmt,
                                ALsizei bufsize);
ALvoid alcCaptureCloseDevice(ALCdevice *dev);
ALvoid alcCaptureStart(void);
ALvoid alcCaptureStop(void);
ALint __alcGetAvailableSamples(ALvoid);
ALvoid alcCaptureSamples(ALCdevice *device, ALvoid *buf, ALsizei samps);
/*
/*
 * alInitCapture( void )
 * alInitCapture( void )
 *
 *
 Lines 38-44    Link Here 
	AL_EXT_PAIR(alCaptureStart_EXT),                           \
	AL_EXT_PAIR(alCaptureStart_EXT),                           \
	AL_EXT_PAIR(alCaptureStop_EXT),                            \
	AL_EXT_PAIR(alCaptureStop_EXT),                            \
	AL_EXT_PAIR(alCaptureGetData_EXT),                         \
	AL_EXT_PAIR(alCaptureGetData_EXT),                         \
	AL_EXT_PAIR(alCaptureDestroy_EXT)                         \
	AL_EXT_PAIR(alCaptureDestroy_EXT),                         \
	AL_EXT_PAIR(alcCaptureOpenDevice),                         \
	AL_EXT_PAIR(alcCaptureCloseDevice),                         \
	AL_EXT_PAIR(alcCaptureStart),                         \
	AL_EXT_PAIR(alcCaptureStop),                         \
	AL_EXT_PAIR(alcCaptureSamples)                         \
/* initialization and destruction functions */
/* initialization and destruction functions */