esound r523 - trunk
- From: jmouette svn gnome org
- To: svn-commits-list gnome org
- Subject: esound r523 - trunk
- Date: Tue, 18 Nov 2008 20:30:54 +0000 (UTC)
Author: jmouette
Date: Tue Nov 18 20:30:54 2008
New Revision: 523
URL: http://svn.gnome.org/viewvc/esound?rev=523&view=rev
Log:
* audio.c: (esd_audio_write), (esd_audio_flush),
(esound_getblksize):
* audio_oss.c: (esd_audio_open):
* esd-server.h:
* esd.c: (main):
* esd.h:
* proto.c: (esd_proto_get_latency):
Rewrite generic esd_audio_write to attempt to use select if the
driver seems to support it, and to write in a blocksize that
can be changed by audio open functions.
Modified:
trunk/ChangeLog
trunk/audio.c
trunk/audio_oss.c
trunk/esd-server.h
trunk/esd.c
trunk/esd.h
trunk/proto.c
Modified: trunk/audio.c
==============================================================================
--- trunk/audio.c (original)
+++ trunk/audio.c Tue Nov 18 20:30:54 2008
@@ -7,6 +7,8 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <math.h>
+#include <errno.h>
+#include <sys/select.h>
/*******************************************************************/
/* globals */
@@ -16,6 +18,8 @@
/* the audio device, /dev/dsp, file descriptor */
static int esd_audio_fd = -1;
+static int select_works = 0;
+static int esd_write_size = ESD_BUF_SIZE;
/*******************************************************************/
/* returns audio_fd for use by main prog - platform dependent */
@@ -84,7 +88,44 @@
/* dump a buffer to the sound device */
int esd_audio_write( void *buffer, int buf_size )
{
- return write( esd_audio_fd, buffer, buf_size );
+ ssize_t nwrite=0, pos=0;
+ int write_size = esd_write_size;
+
+ while (buf_size-pos > 0) {
+ if (buf_size-pos < write_size)
+ write_size = buf_size-pos;
+
+ if (select_works) {
+ fd_set set;
+ struct timeval tv;
+ int ret;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 10000;
+ FD_ZERO(&set);
+ FD_SET(esd_audio_fd, &set);
+ if ((ret = select(esd_audio_fd+1, NULL, &set, NULL, &tv)) == 0) {
+ continue;
+ } else if (ret < 0) {
+ return pos > 0 ? pos : -1;
+ }
+ }
+
+ if ((nwrite = write( esd_audio_fd, buffer+pos, write_size )) <= 0 ) {
+ if ( nwrite == -1 ) {
+ if ( errno == EAGAIN || errno == EINTR ) {
+ if (!select_works)
+ usleep(1000);
+ continue;
+ } else {
+ perror("esound: esd_audio_write: write");
+ return pos > 0 ? pos : -1;
+ }
+ }
+ }
+ pos += nwrite;
+ }
+ return pos;
}
#endif
@@ -102,7 +143,14 @@
/* flush the audio buffer */
void esd_audio_flush()
{
- fsync( esd_audio_fd );
return;
}
#endif
+
+/*
+ * For the daemon's use only -- what size to make the buffer
+ */
+int esound_getblksize(void)
+{
+ return esd_write_size;
+}
Modified: trunk/audio_oss.c
==============================================================================
--- trunk/audio_oss.c (original)
+++ trunk/audio_oss.c Tue Nov 18 20:30:54 2008
@@ -23,6 +23,7 @@
return "/dev/dsp, /dev/dsp2, etc.";
}
+#define NFRAGS 32
#define ARCH_esd_audio_open
int esd_audio_open()
@@ -31,6 +32,22 @@
int afd = -1, value = 0, test = 0;
int mode = O_WRONLY;
+ int rate;
+ int fragsize;
+ int frag;
+ struct timeval tv;
+ fd_set set;
+
+ rate = esd_audio_rate *
+ ( ( ( esd_audio_format & ESD_MASK_CHAN) == ESD_STEREO ) ? 2 : 1 ) *
+ ( ( ( esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 ) ? 2 : 1 );
+
+ for ( fragsize = 0; 1L << fragsize < rate / 25; fragsize++ )
+ ;
+
+ fragsize--;
+
+ frag = (NFRAGS << 16) | fragsize;
/* if recording, set for full duplex mode */
if ( (esd_audio_format & ESD_MASK_FUNC) == ESD_RECORD )
@@ -51,6 +68,10 @@
mode &= ~O_NONBLOCK;
fcntl(afd, F_SETFL, mode);
+#if defined(SNDCTL_DSP_SETFRAGMENT)
+ ioctl(afd, SNDCTL_DSP_SETFRAGMENT, &frag);
+#endif
+
/* TODO: check that this is allowable */
/* set for full duplex operation, if recording */
#if defined(SNDCTL_DSP_SETDUPLEX)
@@ -59,26 +80,6 @@
}
#endif
- /* set the sound driver fragment size and number */
-#if !defined(__powerpc__) /* does not exist on powerpc */
- /* fragment = max_buffers << 16 + log2(buffer_size), (256 16) */
- value = test = ( 0x0100 << 16 ) + 0x0008;
- if (ioctl(afd, SNDCTL_DSP_SETFRAGMENT, &test) == -1)
- { /* Fatal error */
- perror( "SNDCTL_DSP_SETFRAGMENT" );
- close( afd );
- esd_audio_fd = -1;
- return( -1 );
- }
- if ( 0 /* value != test */ ) /* TODO: determine the real test */
- { /* The device doesn't support the requested audio format. */
- fprintf( stderr, "unsupported fragment size: %d\n", value );
- close( afd );
- esd_audio_fd = -1;
- return( -1 );
- }
-#endif /* #if !defined(__powerpc__) */
-
/* set the sound driver audio format for playback */
value = test = ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 )
@@ -131,8 +132,31 @@
return( -1 );
}
+ if ( ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &test) == -1)
+ { /* Fatal error */
+ perror("SNDCTL_DSP_GETBLKSIZE");
+ close( afd );
+ esd_audio_fd = -1;
+ return( -1 );
+ }
+ esd_write_size = test > ESD_MAX_WRITE_SIZE ? ESD_MAX_WRITE_SIZE : test;
+
/* value = test = buf_size; */
esd_audio_fd = afd;
+ /*
+ * From XMMS:
+ * Stupid hack to find out if the driver supports select; some
+ * drivers won't work properly without a select and some won't
+ * work with a select :/
+ */
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 10;
+ FD_ZERO(&set);
+ FD_SET(afd, &set);
+ test = select(afd + 1, NULL, &set, NULL, &tv);
+ if (test > 0)
+ select_works = 1;
return afd;
}
Modified: trunk/esd-server.h
==============================================================================
--- trunk/esd-server.h (original)
+++ trunk/esd-server.h Tue Nov 18 20:30:54 2008
@@ -209,6 +209,9 @@
int esd_set_socket_buffers( int sock, int src_format,
int src_rate, int base_rate );
+/* audio.c */
+int esound_getblksize(void);
+
/*******************************************************************/
/* evil evil macros */
Modified: trunk/esd.c
==============================================================================
--- trunk/esd.c (original)
+++ trunk/esd.c Tue Nov 18 20:30:54 2008
@@ -640,7 +640,7 @@
/* begin test scaffolding parameters */
/* int format = AFMT_U8; AFMT_S16_LE; */
/* int stereo = 0; */ /* 0=mono, 1=stereo */
- int default_rate = ESD_DEFAULT_RATE, default_buf_size = ESD_BUF_SIZE;
+ int default_rate = ESD_DEFAULT_RATE;
int i, j, freq=440;
int magl, magr;
@@ -848,11 +848,6 @@
exit( 1 );
}
-#define ESD_AUDIO_STUFF \
- esd_sample_size = ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 ) \
- ? sizeof(signed short) : sizeof(unsigned char); \
- esd_buf_size_samples = default_buf_size / 2; \
- esd_buf_size_octets = esd_buf_size_samples * esd_sample_size;
/* start the initializatin process */
/* printf( "ESound daemon initializing...\n" );*/
@@ -860,7 +855,6 @@
/* set the data size parameters */
esd_audio_format = default_format;
esd_audio_rate = default_rate;
- ESD_AUDIO_STUFF;
/* open and initialize the audio device, /dev/dsp */
itmp = esd_audio_open();
@@ -885,7 +879,6 @@
/* cant do defaults ... try 44.1 kkz 8bit stereo */
esd_audio_format = ESD_BITS8 | ESD_STEREO;
esd_audio_rate = 44100;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 44.1Khz, stereo, 8bit failed\n"
@@ -893,56 +886,48 @@
/* cant do defaults ... try 48 kkz 16bit stereo */
esd_audio_format = ESD_BITS16 | ESD_STEREO;
esd_audio_rate = 48000;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 48Khz, stereo,16bit failed\n"
"Trying 22.05Khz, 8bit stereo.\n");
/* cant do defaults ... try 22.05 kkz 8bit stereo */
esd_audio_format = ESD_BITS8 | ESD_STEREO;
esd_audio_rate = 22050;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 22.05Khz, stereo, 8bit failed\n"
"Trying 44.1Khz, 16bit mono.\n");
/* cant do defaults ... try 44.1Khz kkz 16bit mono */
esd_audio_format = ESD_BITS16;
esd_audio_rate = 44100;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 44.1Khz, mono, 8bit failed\n"
"Trying 22.05Khz, 8bit mono.\n");
/* cant do defaults ... try 22.05 kkz 8bit mono */
esd_audio_format = ESD_BITS8;
esd_audio_rate = 22050;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 22.05Khz, mono, 8bit failed\n"
"Trying 11.025Khz, 8bit stereo.\n");
/* cant to defaults ... try 11.025 kkz 8bit stereo */
esd_audio_format = ESD_BITS8 | ESD_STEREO;
esd_audio_rate = 11025;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 11.025Khz, stereo, 8bit failed\n"
"Trying 11.025Khz, 8bit mono.\n");
/* cant to defaults ... try 11.025 kkz 8bit mono */
esd_audio_format = ESD_BITS8;
esd_audio_rate = 11025;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 11.025Khz, mono, 8bit failed\n"
"Trying 8.192Khz, 8bit mono.\n");
/* cant to defaults ... try 8.192 kkz 8bit mono */
esd_audio_format = ESD_BITS8;
esd_audio_rate = 8192;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Audio device open for 8.192Khz, mono, 8bit failed\n"
"Trying 8Khz, 8bit mono.\n");
/* cant to defaults ... try 8 kkz 8bit mono */
esd_audio_format = ESD_BITS8;
esd_audio_rate = 8000;
- ESD_AUDIO_STUFF;
if ( esd_audio_open() < 0 ) {
fprintf(stderr, "Sound device inadequate for Esound. Fatal.\n");
if (!esd_use_tcpip)
@@ -969,6 +954,11 @@
}
}
}
+ esd_sample_size = ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 )
+ ? sizeof(signed short) : sizeof(unsigned char);
+ esd_buf_size_samples = esound_getblksize() / esd_sample_size;
+ esd_buf_size_octets = esound_getblksize();
+
/* allocate and zero out buffer */
output_buffer = (void *) malloc( esd_buf_size_octets );
Modified: trunk/esd.h
==============================================================================
--- trunk/esd.h (original)
+++ trunk/esd.h Tue Nov 18 20:30:54 2008
@@ -12,6 +12,8 @@
/* size of the audio buffer */
#define ESD_BUF_SIZE (4 * 1024)
+/* maximum size we can write(). Otherwise we might overflow */
+#define ESD_MAX_WRITE_SIZE (21 * 4096)
/* length of the authorization key, octets */
#define ESD_KEY_LEN (16)
Modified: trunk/proto.c
==============================================================================
--- trunk/proto.c (original)
+++ trunk/proto.c Tue Nov 18 20:30:54 2008
@@ -89,22 +89,23 @@
int esd_proto_get_latency( esd_client_t *client )
{
int lag, amount, actual;
+ int buf_size = esound_getblksize();
ESDBG_TRACE( printf( "(%02d) proto: get latency\n", client->fd ); );
if (esd_audio_format & ESD_STEREO)
{
if (esd_audio_format & ESD_BITS16)
- amount = (44100 * (ESD_BUF_SIZE + 64)) / esd_audio_rate;
+ amount = (44100 * (buf_size + 64)) / esd_audio_rate;
else
- amount = (44100 * (ESD_BUF_SIZE + 128)) / esd_audio_rate;
+ amount = (44100 * (buf_size + 128)) / esd_audio_rate;
}
else
{
if (esd_audio_format & ESD_BITS16)
- amount = (2 * 44100 * (ESD_BUF_SIZE + 128)) / esd_audio_rate;
+ amount = (2 * 44100 * (buf_size + 128)) / esd_audio_rate;
else
- amount = (2 * 44100 * (ESD_BUF_SIZE + 256)) / esd_audio_rate;
+ amount = (2 * 44100 * (buf_size + 256)) / esd_audio_rate;
}
lag = maybe_swap_32( client->swap_byte_order, amount );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]