Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Mar 2000 03:48:59 +0200 (IST)
From:      Roman Shterenzon <roman@xpert.com>
To:        freebsd-questions@freebsd.org
Subject:   Re: xmms port (fwd)
Message-ID:  <Pine.LNX.4.10.10003040345380.22653-101000@devnull.xpert.com>

index | next in thread | raw e-mail

[-- Attachment #1 --]
Hi all,
I've received this mail from the package maintanier, unfortunately it
didn't work for me, but your milleage may vary.
I wanted to note that I'm using XFree86 3.3.6 which I downloaded from
ftp.freebsd.org.
I don't think that I've did cvsup of stable which has broken it.
I *think* that I had 1.0.1 work on my machine, but I'm not sure anymore.
I'm using VoxWare driver for sb16.

--Roman Shterenzon, UNIX System Administrator and Consultant
[ Xpert UNIX Systems Ltd., Herzlia, Israel. Tel: +972-9-9522361 ]

---------- Forwarded message ----------
Date: Fri,  3 Mar 2000 19:47:50 +0100 (MET)
From: Espen Skoglund <esk@ira.uka.de>
To: Roman Shterenzon <roman@xpert.com>
Subject: Re: xmms port

[Roman Shterenzon]
> I'm using mpg123 for now..  I don't know how to aproach this
> problem, perhaps, you have an idea?

I sort of managed to reproduce a similar problem on my FreeBSD
4.0-CURRENT today.  The patch which is attached below does the work
for me.  If you could put it in patches/patch-ca (or something) and
give it another try, I would be interested to hear if this also fixes
the problems with 3.4-STABLE.

	eSk



[-- Attachment #2 --]
*** Output/OSS/audio.c.org	2000/01/28 11:15:35	1.14
--- Output/OSS/audio.c	1999/11/04 20:16:52	1.7
***************
*** 21,31 ****
  
  #define NFRAGS		32
  
  static gint fd = 0;
  static gpointer buffer;
  static gboolean going = FALSE, prebuffer, paused = FALSE, unpause = FALSE,
           do_pause = FALSE, remove_prebuffer = FALSE;
! static gint device_buffer_used, buffer_size, prebuffer_size, blk_size;
  static gint rd_index = 0, wr_index = 0;
  static gint output_time_offset = 0;
  static guint64 written = 0, output_bytes = 0;
--- 21,33 ----
  
  #define NFRAGS		32
  
+ #define min(x,y) ((x)<(y)?(x):(y))
+ 
  static gint fd = 0;
  static gpointer buffer;
  static gboolean going = FALSE, prebuffer, paused = FALSE, unpause = FALSE,
           do_pause = FALSE, remove_prebuffer = FALSE;
! static gint buffer_size, prebuffer_size, blk_size;
  static gint rd_index = 0, wr_index = 0;
  static gint output_time_offset = 0;
  static guint64 written = 0, output_bytes = 0;
***************
*** 35,54 ****
  static gint input_bps, input_format, input_frequency, input_channels;
  static gchar *device_name;
  static pthread_t buffer_thread;
! static gboolean realtime = FALSE, select_works = TRUE;
! 
! static void oss_calc_device_buffer_used(void)
! {
! 	audio_buf_info buf_info;
! 	if(paused)
! 		device_buffer_used = 0;
! 	else if (!ioctl(fd, SNDCTL_DSP_GETOSPACE, &buf_info))
! 		device_buffer_used = (buf_info.fragstotal * buf_info.fragsize) - buf_info.bytes;
! }
! 
  
- gint oss_downsample(gpointer ob, guint length, guint speed, guint espeed);
- 
  static void oss_setup_format(AFormat fmt,gint rate, gint nch)
  {
  	format = fmt;
--- 37,44 ----
  static gint input_bps, input_format, input_frequency, input_channels;
  static gchar *device_name;
  static pthread_t buffer_thread;
! static gboolean realtime = FALSE;
  
  static void oss_setup_format(AFormat fmt,gint rate, gint nch)
  {
  	format = fmt;
***************
*** 119,134 ****
  
  gint oss_get_output_time(void)
  {
! 	
  	guint64 bytes;
  
  	if (!fd || !going)
  		return 0;
  
! 	if(realtime)
! 		oss_calc_device_buffer_used();
! 	bytes = output_bytes - device_buffer_used;
  
  	return output_time_offset + (gint) ((bytes  * 1000) / ebps);
  }
  
--- 109,132 ----
  
  gint oss_get_output_time(void)
  {
! 	audio_buf_info buf_info;
  	guint64 bytes;
  
  	if (!fd || !going)
  		return 0;
  
! 	if (!paused)
! 	{
! 		if (!ioctl(fd, SNDCTL_DSP_GETOSPACE, &buf_info))
! 			bytes = output_bytes - ((buf_info.fragstotal - buf_info.fragments) * buf_info.fragsize);
! 		else
! 			bytes = output_bytes;
! 	}
! 	else
! 		bytes = output_bytes;
  
+ 	if (bytes < 0)
+ 		bytes = 0;
  	return output_time_offset + (gint) ((bytes  * 1000) / ebps);
  }
  
***************
*** 146,156 ****
  
  gint oss_playing(void)
  {
! 	if(!going)
! 		return 0;
! 	if(realtime)
! 		oss_calc_device_buffer_used();
! 	if (!oss_used() && (device_buffer_used - (3 * blk_size)) <= 0)
  		return FALSE;
  
  	return TRUE;
--- 144,158 ----
  
  gint oss_playing(void)
  {
! 	audio_buf_info buf_info;
! 	int bytes;
! 
! 	if (!ioctl(fd, SNDCTL_DSP_GETOSPACE, &buf_info))
! 		bytes = ((buf_info.fragstotal - buf_info.fragments - 3) * buf_info.fragsize);
! 	else
! 		bytes = 0;
! 
! 	if (!oss_used() && bytes <= 0)
  		return FALSE;
  
  	return TRUE;
***************
*** 181,190 ****
  
  static void oss_write_audio(gpointer data,gint length)
  {
- 	audio_buf_info abuf_info;
  	AFormat new_format;
  	gint new_frequency,new_channels;
  	EffectPlugin *ep;
  	
  	new_format = input_format;
  	new_frequency = input_frequency;
--- 183,192 ----
  
  static void oss_write_audio(gpointer data,gint length)
  {
  	AFormat new_format;
  	gint new_frequency,new_channels;
  	EffectPlugin *ep;
+ 	audio_buf_info abuf_info;
  	
  	new_format = input_format;
  	new_frequency = input_frequency;
***************
*** 209,215 ****
  	}
  	if(effects_enabled() && ep && ep->mod_samples)
  		length = ep->mod_samples(&data,length, input_format, input_frequency, input_channels);
! 	if(realtime && !ioctl(fd,SNDCTL_DSP_GETOSPACE,&abuf_info))
  	{
  		while(abuf_info.bytes < length)
  		{
--- 211,217 ----
  	}
  	if(effects_enabled() && ep && ep->mod_samples)
  		length = ep->mod_samples(&data,length, input_format, input_frequency, input_channels);
! 	if(!ioctl(fd,SNDCTL_DSP_GETOSPACE,&abuf_info))
  	{
  		while(abuf_info.bytes < length)
  		{
***************
*** 224,351 ****
  		output_bytes += oss_downsample(data,length,frequency,efrequency);
  }
  
! static void swap_words(guint16 *buffer, gint length)
  {
! 	guint16 *ptr = buffer;
! 	gint i;
! 	for(i = 0; i < length; i++, ptr++)
! 		*ptr = ((*ptr & 0x00FF) << 8) | (*ptr >> 8);
! }
! 
! 
! #define RESAMPLE_STEREO(sample_type, shift) \
! { \
!         gint i, x1, in_samples, out_samples; \
! 	sample_type *inptr = (sample_type *)ob, *outptr;\
! 	gint x, frac, delta;\
! 	nlen = (((length >> shift) * espeed) / speed) << shift;\
! 	if(big_endian && (oss_format == AFMT_S16_LE || oss_format == AFMT_U16_LE)) \
! 		swap_words(ob, length >> 1);\
! 	else if(!big_endian && (oss_format == AFMT_S16_BE || oss_format == AFMT_U16_BE)) \
! 		swap_words(ob, length >> 1);\
! 	if(nlen > nbuffer_size)\
! 	{\
! 		nbuffer = g_realloc(nbuffer, nlen);\
! 		nbuffer_size = nlen;\
! 	}\
! 	outptr = (sample_type *)nbuffer; \
!         in_samples = length >> shift; \
!         out_samples = nlen >> shift; \
! 	delta = (in_samples << 12) / out_samples;\
! 	for (x = 0, i = 0; i < out_samples; i++)\
! 	{\
! 		x1 = (x >> 12) << 12;\
! 		frac = x - x1;\
! 		*outptr++ = (sample_type) ((inptr[(x1 >> 12) << 1] * ((1<<12) - frac) + inptr[((x1 >> 12) + 1) << 1] * frac) >> 12);\
! 		*outptr++ = (sample_type) ((inptr[((x1 >> 12) << 1) + 1] * ((1<<12) - frac) + inptr[(((x1 >> 12) + 1) << 1) + 1] * frac) >> 12);\
! 		x += delta;\
! 	}\
! 	if(big_endian && (oss_format == AFMT_S16_LE || oss_format == AFMT_U16_LE)) \
! 		swap_words(nbuffer, nlen >> 1);\
! 	else if(!big_endian && (oss_format == AFMT_S16_BE || oss_format == AFMT_U16_BE)) \
! 		swap_words(nbuffer, nlen >> 1);\
! 	w = write(fd, nbuffer, nlen);		  \
! }
! 
! #define RESAMPLE_MONO(sample_type, shift) \
! { \
!         gint i, x1, in_samples, out_samples; \
! 	sample_type *inptr = (sample_type *)ob, *outptr;\
! 	gint x, frac, delta;\
! 	nlen = (((length >> shift) * espeed) / speed) << shift;\
! 	if(big_endian && (oss_format == AFMT_S16_LE || oss_format == AFMT_U16_LE)) \
! 		swap_words(ob, length >> 1);\
! 	else if(!big_endian && (oss_format == AFMT_S16_BE || oss_format == AFMT_U16_BE)) \
! 		swap_words(ob, length >> 1);\
! 	if(nlen > nbuffer_size)\
! 	{\
! 		nbuffer = g_realloc(nbuffer, nlen);\
! 		nbuffer_size = nlen;\
! 	}\
! 	outptr = (sample_type *)nbuffer; \
!         in_samples = length >> shift; \
!         out_samples = nlen >> shift; \
! 	delta = (in_samples << 12) / out_samples;\
! 	for (x = 0, i = 0; i < out_samples; i++)\
! 	{\
! 		x1 = (x >> 12) << 12;\
! 		frac = x - x1;\
! 		*outptr++ = (sample_type) ((inptr[x1 >> 12] * ((1<<12) - frac) + inptr[(x1 >> 12) + 1] * frac) >> 12);\
! 		x += delta;\
! 	}\
! 	if(big_endian && (oss_format == AFMT_S16_LE || oss_format == AFMT_U16_LE)) \
! 		swap_words(nbuffer, nlen >> 1);\
! 	else if(!big_endian && (oss_format == AFMT_S16_BE || oss_format == AFMT_U16_BE)) \
! 		swap_words(nbuffer, nlen >> 1);\
! 	w = write(fd, nbuffer, nlen);		  \
! }
! 
! 
! gint oss_downsample(gpointer ob, guint length, guint speed, guint espeed)
! {
! 	guint nlen, w;
! 	static gpointer nbuffer = NULL;
! 	static gint nbuffer_size = 0;
! #ifdef WORDS_BIGENDIAN
! 	gboolean big_endian = TRUE;
! #else
! 	gboolean big_endian = FALSE;
! #endif
  
! 	if (oss_format == AFMT_S16_BE || oss_format == AFMT_S16_LE)
  	{
! 		if(channels == 2)
! 			RESAMPLE_STEREO(gint16, 2)
! 		else
! 			RESAMPLE_MONO(gint16, 1)
! 	}
! 	else if (oss_format == AFMT_U16_BE || oss_format == AFMT_U16_LE)
! 	{
! 		if(channels == 2)
! 			RESAMPLE_STEREO(guint16, 2)
! 		else
! 			RESAMPLE_MONO(guint16, 1)
  	}
! 	else if (oss_format == AFMT_S8)
  	{
! 		if(channels == 2)
! 			RESAMPLE_STEREO(gint8, 1)
! 		else
! 			RESAMPLE_MONO(gint8, 0)
  	}
! 	else if (oss_format == AFMT_U8)
  	{
! 		if(channels == 2)
! 			RESAMPLE_STEREO(guint8, 1)
! 		else
! 			RESAMPLE_MONO(guint8, 0)
  	}
  	return w;
  }
  
  void oss_write(gpointer ptr, gint length)
  {
  	gint cnt, off = 0;
  
  	if (!realtime)
  	{
--- 226,300 ----
  		output_bytes += oss_downsample(data,length,frequency,efrequency);
  }
  
! gint oss_downsample(guchar * ob, guint length, guint speed, guint espeed)
  {
! 	guint nlen, i, off, d, w;
  
! 	if ((oss_format == AFMT_U16_BE || oss_format == AFMT_U16_LE || oss_format == AFMT_S16_BE || oss_format == AFMT_S16_LE) && channels == 2)
  	{
! 		gulong *nbuffer, *obuffer, *ptr;
! 
! 		obuffer = (gulong *) ob;
! 		length >>= 2;
! 
! 		nlen = (length * espeed) / speed;
! 		d = (speed << 8) / espeed;
! 
! 		nbuffer = g_malloc(nlen << 2);
! 		for (i = 0, off = 0, ptr = nbuffer; i < nlen; i++)
! 		{
! 			*ptr++ = obuffer[off >> 8];
! 			off += d;
! 		}
! 		w = write(fd, nbuffer, nlen << 2);
! 		g_free(nbuffer);
  	}
! 	else if (((oss_format == AFMT_U16_BE || oss_format == AFMT_U16_LE || oss_format == AFMT_S16_BE || oss_format == AFMT_S16_LE) && channels == 1)
! 	     || ((oss_format == AFMT_U8 || oss_format == AFMT_S8) && channels == 2))
  	{
! 		gushort *nbuffer, *obuffer, *ptr;
! 
! 		obuffer = (gushort *) ob;
! 		length >>= 1;
! 
! 		nlen = (length * espeed) / speed;
! 		d = (speed << 8) / espeed;
! 
! 		nbuffer = g_malloc(nlen << 1);
! 		for (i = 0, off = 0, ptr = nbuffer; i < nlen; i++)
! 		{
! 			*ptr++ = obuffer[off >> 8];
! 			off += d;
! 		}
! 		w = write(fd, nbuffer, nlen << 1);
! 		g_free(nbuffer);
  	}
! 	else
  	{
! 		guchar *nbuffer, *obuffer, *ptr;
! 
! 		obuffer = ob;
! 
! 		nlen = (length * espeed) / speed;
! 		d = (speed << 8) / espeed;
! 
! 		nbuffer = g_malloc(nlen);
! 		for (i = 0, off = 0, ptr = nbuffer; i < nlen; i++)
! 		{
! 			*ptr++ = obuffer[off >> 8];
! 			off += d;
! 		}
! 		w = write(fd, nbuffer, nlen);
! 		g_free(nbuffer);
  	}
  	return w;
+ 
  }
  
  void oss_write(gpointer ptr, gint length)
  {
  	gint cnt, off = 0;
+ 	audio_buf_info abuf_info;
  
  	if (!realtime)
  	{
***************
*** 354,360 ****
  		written += length;
  		while (length > 0)
  		{
! 			cnt = MIN(length, buffer_size - wr_index);
  			memcpy(buffer + wr_index, ptr + off, cnt);
  			wr_index = (wr_index + cnt) % buffer_size;
  			length -= cnt;
--- 303,309 ----
  		written += length;
  		while (length > 0)
  		{
! 			cnt = min(length, buffer_size - wr_index);
  			memcpy(buffer + wr_index, ptr + off, cnt);
  			wr_index = (wr_index + cnt) % buffer_size;
  			length -= cnt;
***************
*** 424,431 ****
  void *oss_loop(void *arg)
  {
  	gint length, cnt;
! 	fd_set set;
! 	struct timeval tv;
  
  	while (going)
  	{
--- 373,380 ----
  void *oss_loop(void *arg)
  {
  	gint length, cnt;
! 	audio_buf_info abuf_info;
! 	
  
  	while (going)
  	{
***************
*** 433,469 ****
  			prebuffer = FALSE;
  		if (oss_used() > 0 && !paused && !prebuffer)
  		{
! 			tv.tv_sec = 0;
! 			tv.tv_usec = 10000;
! 			FD_ZERO(&set);
! 			FD_SET(fd, &set);
! 			if(!select_works || (select(fd + 1, NULL, &set, NULL, &tv) > 0))
  			{
! 				length = MIN(blk_size, oss_used());
! 				while (length > 0)
! 				{
! 					cnt = MIN(length,buffer_size-rd_index);
! 					oss_write_audio(buffer + rd_index, cnt);
! 					rd_index=(rd_index+cnt)%buffer_size;
! 					length-=cnt;				
! 				}
! 				if (!oss_used())
! 				{
! 					ioctl(fd, SNDCTL_DSP_POST, 0);
! 				}
  			}
  		}
  		else
- 		{
  			xmms_usleep(10000);
- 		}
- 		oss_calc_device_buffer_used();
  		if (do_pause && !paused)
  		{
  			do_pause = FALSE;
  			paused = TRUE;
! 			rd_index -= device_buffer_used;
! 			output_bytes -= device_buffer_used;
  			if (rd_index < 0)
  				rd_index += buffer_size;
  			ioctl(fd, SNDCTL_DSP_RESET, 0);
--- 382,409 ----
  			prebuffer = FALSE;
  		if (oss_used() > 0 && !paused && !prebuffer)
  		{
! 			length = min(blk_size, oss_used());
! 			while (length > 0)
  			{
! 				cnt = min(length,buffer_size-rd_index);
! 				oss_write_audio(buffer + rd_index, cnt);
! 				rd_index=(rd_index+cnt)%buffer_size;
! 				length-=cnt;				
  			}
+ 			if (!oss_used())
+ 				ioctl(fd, SNDCTL_DSP_POST, 0);
  		}
  		else
  			xmms_usleep(10000);
  		if (do_pause && !paused)
  		{
  			do_pause = FALSE;
  			paused = TRUE;
! 			if (!ioctl(fd, SNDCTL_DSP_GETOSPACE, &abuf_info))
! 			{
! 				rd_index -= (abuf_info.fragstotal - abuf_info.fragments) * abuf_info.fragsize;
! 				output_bytes -= (abuf_info.fragstotal - abuf_info.fragments) * abuf_info.fragsize;
! 			}
  			if (rd_index < 0)
  				rd_index += buffer_size;
  			ioctl(fd, SNDCTL_DSP_RESET, 0);
***************
*** 506,515 ****
  
  void oss_set_audio_params(void)
  {
! 	gint frag, stereo, ret;
! 	struct timeval tv;
! 	fd_set set;
! 	
  	ioctl(fd, SNDCTL_DSP_RESET, 0);
  	frag = (NFRAGS << 16) | fragsize;
  	ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
--- 446,453 ----
  
  void oss_set_audio_params(void)
  {
! 	gint frag, stereo;
! 
  	ioctl(fd, SNDCTL_DSP_RESET, 0);
  	frag = (NFRAGS << 16) | fragsize;
  	ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
***************
*** 519,550 ****
  	ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
  	efrequency = frequency;
  	ioctl(fd, SNDCTL_DSP_SPEED, &efrequency);
! 
  	if(ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blk_size) == -1)
  		blk_size = 1L << fragsize;
  
  	ebps = efrequency * channels;
! 	if (oss_format == AFMT_U16_BE || oss_format == AFMT_U16_LE ||
! 	    oss_format == AFMT_S16_BE || oss_format == AFMT_S16_LE)
  		ebps *= 2;
- 
- 	/* Stupid hack to find out if the driver support selects,
- 	   some drivers won't work properly without a select and
- 	   some won't work with a select :/ */
- 	
- 	tv.tv_sec = 0;
- 	tv.tv_usec = 50000;
- 	FD_ZERO(&set);
- 	FD_SET(fd, &set);
- 	ret = select(fd + 1, NULL, &set, NULL, &tv);
- 	if(ret > 0)
- 		select_works = TRUE;
- 	else
- 		select_works = FALSE;
  }
  
  gint oss_open(AFormat fmt, gint rate, gint nch)
  {
  	oss_setup_format(fmt,rate,nch);
  	
  	input_format = format;
--- 457,476 ----
  	ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
  	efrequency = frequency;
  	ioctl(fd, SNDCTL_DSP_SPEED, &efrequency);
! 	if(abs(((efrequency * 100) / frequency) - 100) < 10)
! 		efrequency = frequency;
  	if(ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blk_size) == -1)
  		blk_size = 1L << fragsize;
  
  	ebps = efrequency * channels;
! 	if (oss_format == AFMT_U16_BE || oss_format == AFMT_U16_LE || oss_format == AFMT_S16_BE || oss_format == AFMT_S16_LE)
  		ebps *= 2;
  }
  
  gint oss_open(AFormat fmt, gint rate, gint nch)
  {
+ 	gint fmts, policy;
+ 	
  	oss_setup_format(fmt,rate,nch);
  	
  	input_format = format;
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.LNX.4.10.10003040345380.22653-101000>