summaryrefslogtreecommitdiff
path: root/src/audio_out/audio_esd_out.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_out/audio_esd_out.c')
-rw-r--r--src/audio_out/audio_esd_out.c256
1 files changed, 71 insertions, 185 deletions
diff --git a/src/audio_out/audio_esd_out.c b/src/audio_out/audio_esd_out.c
index 4669c5b32..8434e91c8 100644
--- a/src/audio_out/audio_esd_out.c
+++ b/src/audio_out/audio_esd_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_esd_out.c,v 1.6 2001/08/14 01:38:17 guenter Exp $
+ * $Id: audio_esd_out.c,v 1.7 2001/08/24 01:05:30 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -43,17 +43,9 @@
#define AO_OUT_ESD_IFACE_VERSION 1
-#define AUDIO_NUM_FRAGMENTS 15
-#define AUDIO_FRAGMENT_SIZE 8192
+typedef struct esd_driver_s {
-#define GAP_TOLERANCE 15000
-#define MAX_GAP 90000
-
-typedef struct esd_functions_s {
-
- ao_functions_t ao_functions;
-
- metronom_t *metronom;
+ ao_driver_t ao_driver;
int audio_fd;
int capabilities;
@@ -62,52 +54,40 @@ typedef struct esd_functions_s {
int32_t output_sample_rate, input_sample_rate;
double sample_rate_factor;
uint32_t num_channels;
+ uint32_t bytes_per_frame;
- uint32_t bytes_in_buffer; /* number of bytes writen to audio hardware */
-
- int audio_step; /* pts per 32 768 samples (sample = #bytes/2) */
- int32_t bytes_per_kpts; /* bytes per 1024/90000 sec */
-
- uint16_t *sample_buffer;
- int16_t *zero_space;
-
- int audio_started;
- uint32_t last_audio_vpts;
-
- uint32_t latency;
+ int latency, gap_tolerance;
-} esd_functions_t;
+} esd_driver_t;
/*
* connect to esd
*/
-static int ao_open(ao_functions_t *this_gen,
- uint32_t bits, uint32_t rate, int mode)
+static int ao_esd_open(ao_driver_t *this_gen,
+ uint32_t bits, uint32_t rate, int mode)
{
- esd_functions_t *this = (esd_functions_t *) this_gen;
+ esd_driver_t *this = (esd_driver_t *) this_gen;
esd_format_t format;
- printf ("audio_esd_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode);
+ printf ("audio_esd_out: ao_open bits=%d rate=%d, mode=%d\n",
+ bits, rate, mode);
if ( (mode & this->capabilities) == 0 ) {
printf ("audio_esd_out: unsupported mode %08x\n", mode);
- return -1;
+ return 0;
}
if (this->audio_fd>=0) {
if ( (mode == this->mode) && (rate == this->input_sample_rate) )
- return 1;
+ return this->output_sample_rate;
close (this->audio_fd);
}
this->mode = mode;
this->input_sample_rate = rate;
- this->bytes_in_buffer = 0;
- this->audio_started = 0;
- this->last_audio_vpts = 0;
this->output_sample_rate = rate;
/*
@@ -127,6 +107,8 @@ static int ao_open(ao_functions_t *this_gen,
}
printf ("audio_esd_out: %d channels output\n",this->num_channels);
+ this->bytes_per_frame=(bits*this->num_channels)/8;
+
if (this->output_sample_rate > 44100)
this->output_sample_rate = 44100;
@@ -135,176 +117,81 @@ static int ao_open(ao_functions_t *this_gen,
if (this->audio_fd < 0) {
printf("audio_esd_out: connecting to ESD server %s: %s\n",
getenv("ESPEAKER"), strerror(errno));
- return -1;
+ return 0;
}
- this->sample_rate_factor = (double) this->output_sample_rate / (double) this->input_sample_rate;
- this->audio_step = (uint32_t) 90000 * (uint32_t) 32768
- / this->input_sample_rate;
- this->bytes_per_kpts = this->output_sample_rate * this->num_channels * 2 * 1024 / 90000;
-
- printf ("audio_out : audio_step %d pts per 32768 samples\n", this->audio_step);
+ return this->output_sample_rate;
+}
- return 1;
+static int ao_esd_num_channels(ao_driver_t *this_gen)
+{
+ esd_driver_t *this = (esd_driver_t *) this_gen;
+ return this->num_channels;
}
-static void ao_fill_gap (esd_functions_t *this, uint32_t pts_len) {
+static int ao_esd_bytes_per_frame(ao_driver_t *this_gen)
+{
+ esd_driver_t *this = (esd_driver_t *) this_gen;
+ return this->bytes_per_frame;
+}
- int num_bytes ;
- if (pts_len > MAX_GAP)
- pts_len = MAX_GAP;
- num_bytes = pts_len * this->bytes_per_kpts / 1024;
- num_bytes = (num_bytes / (2*this->num_channels)) * (2*this->num_channels);
+static int ao_esd_delay(ao_driver_t *this_gen)
+{
+ esd_driver_t *this = (esd_driver_t *) this_gen;
- printf ("audio_esd_out: inserting %d 0-bytes to fill a gap of %d pts\n",num_bytes, pts_len);
-
- this->bytes_in_buffer += num_bytes;
-
- while (num_bytes>0) {
- if (num_bytes>8192) {
- write(this->audio_fd, this->zero_space, 8192);
- num_bytes -= 8192;
- } else {
- write(this->audio_fd, this->zero_space, num_bytes);
- num_bytes = 0;
- }
- }
+ return this->latency;
}
-static int ao_write_audio_data(ao_functions_t *this_gen,
- int16_t* output_samples, uint32_t num_samples,
- uint32_t pts_)
+static int ao_esd_write(ao_driver_t *this_gen,
+ int16_t* frame_buffer, uint32_t num_frames)
{
- esd_functions_t *this = (esd_functions_t *) this_gen;
- uint32_t vpts, buffer_vpts;
- int32_t gap;
- int bDropPackage;
+ esd_driver_t *this = (esd_driver_t *) this_gen;
if (this->audio_fd<0)
return 1;
- vpts = this->metronom->got_audio_samples (this->metronom, pts_, num_samples);
-
- xprintf (VERBOSE|AUDIO, "audio_esd_out: got %d samples, vpts=%d\n",
- num_samples, vpts);
-
- if (vpts<this->last_audio_vpts) {
- /* reject this */
-
- return 1;
- }
-
- this->last_audio_vpts = vpts;
-
- /*
- * where, in the timeline is the "end" of the audio buffer at the moment?
- */
-
- buffer_vpts = this->metronom->get_current_time (this->metronom);
-
- buffer_vpts += 3000; /* FIXME - esd doesn't have sync capabilities */
-
- /*
- printf ("audio_esd_out: got audio package vpts = %d, buffer_vpts = %d\n",
- vpts, buffer_vpts);
- */
-
- /*
- * calculate gap:
- */
-
- gap = vpts - buffer_vpts;
-
- bDropPackage = 0;
-
- if (gap>GAP_TOLERANCE) {
- ao_fill_gap (this, gap);
-
- /* keep xine responsive */
-
- if (gap>MAX_GAP)
- return 0;
-
- } else if (gap<-GAP_TOLERANCE) {
- bDropPackage = 1;
- }
-
- /*
- * resample and output samples
- */
-
- if (!bDropPackage) {
- int num_output_samples = num_samples * (this->output_sample_rate) / this->input_sample_rate;
-
- switch (this->mode) {
- case AO_CAP_MODE_MONO:
- audio_out_resample_mono (output_samples, num_samples,
- this->sample_buffer, num_output_samples);
- write(this->audio_fd, this->sample_buffer, num_output_samples * 2);
- break;
- case AO_CAP_MODE_STEREO:
- audio_out_resample_stereo (output_samples, num_samples,
- this->sample_buffer, num_output_samples);
- write(this->audio_fd, this->sample_buffer, num_output_samples * 4);
- break;
- }
-
- xprintf (AUDIO|VERBOSE, "audio_esd_out :audio package written\n");
-
- /*
- * step values
- */
-
- this->bytes_in_buffer += num_output_samples * 2 * this->num_channels;
- this->audio_started = 1;
- } else {
- printf ("audio_esd_out: audio package (vpts = %d) dropped\n", vpts);
- }
+ write(this->audio_fd, frame_buffer, num_frames * this->bytes_per_frame);
return 1;
-
}
-static void ao_close(ao_functions_t *this_gen)
+static void ao_esd_close(ao_driver_t *this_gen)
{
- esd_functions_t *this = (esd_functions_t *) this_gen;
+ esd_driver_t *this = (esd_driver_t *) this_gen;
esd_close(this->audio_fd);
this->audio_fd = -1;
}
-static uint32_t ao_get_capabilities (ao_functions_t *this_gen) {
- esd_functions_t *this = (esd_functions_t *) this_gen;
+static uint32_t ao_esd_get_capabilities (ao_driver_t *this_gen) {
+ esd_driver_t *this = (esd_driver_t *) this_gen;
return this->capabilities;
}
-static void ao_connect (ao_functions_t *this_gen, metronom_t *metronom) {
- esd_functions_t *this = (esd_functions_t *) this_gen;
-
- this->metronom = metronom;
+static int ao_esd_get_gap_tolerance (ao_driver_t *this_gen) {
+ esd_driver_t *this = (esd_driver_t *) this_gen;
+ return this->gap_tolerance ;
}
-static void ao_exit(ao_functions_t *this_gen)
+static void ao_esd_exit(ao_driver_t *this_gen)
{
- esd_functions_t *this = (esd_functions_t *) this_gen;
+ esd_driver_t *this = (esd_driver_t *) this_gen;
if (this->audio_fd != -1)
esd_close(this->audio_fd);
- free (this->sample_buffer);
- free (this->zero_space);
free (this);
}
-static int ao_get_property (ao_functions_t *this, int property) {
+static int ao_esd_get_property (ao_driver_t *this, int property) {
/* FIXME: implement some properties
*/
return 0;
}
-static int ao_set_property (ao_functions_t *this, int property, int value) {
+static int ao_esd_set_property (ao_driver_t *this, int property, int value) {
/* FIXME: Implement property support.
*/
@@ -312,10 +199,10 @@ static int ao_set_property (ao_functions_t *this, int property, int value) {
return ~value;
}
-ao_functions_t *init_audio_out_plugin (config_values_t *config) {
+ao_driver_t *init_audio_out_plugin (config_values_t *config) {
- esd_functions_t *this;
- int audio_fd;
+ esd_driver_t *this;
+ int audio_fd;
/*
* open stream to ESD server
@@ -324,11 +211,10 @@ ao_functions_t *init_audio_out_plugin (config_values_t *config) {
xprintf(VERBOSE|AUDIO, "Connecting to ESD server...");
audio_fd = esd_open_sound(NULL);
- if(audio_fd < 0)
- {
+ if(audio_fd < 0) {
char *server = getenv("ESPEAKER");
- // print a message so the user knows why ESD failed
+ /* print a message so the user knows why ESD failed */
printf("audio_esd_out: can't connect to %s ESD server: %s\n",
server ? server : "local", strerror(errno));
@@ -338,30 +224,30 @@ ao_functions_t *init_audio_out_plugin (config_values_t *config) {
esd_close(audio_fd);
- this = (esd_functions_t *) malloc (sizeof (esd_functions_t));
+ this = (esd_driver_t *) malloc (sizeof (esd_driver_t));
this->output_sample_rate = 0;
- this->audio_fd = -1;
- this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO;
-
- this->sample_buffer = malloc (40000);
- memset (this->sample_buffer, 0, 40000);
- this->zero_space = malloc (8192);
- memset (this->zero_space, 0, 8192);
-
- this->ao_functions.get_capabilities = ao_get_capabilities;
- this->ao_functions.get_property = ao_get_property;
- this->ao_functions.set_property = ao_set_property;
- this->ao_functions.connect = ao_connect;
- this->ao_functions.open = ao_open;
- this->ao_functions.write_audio_data = ao_write_audio_data;
- this->ao_functions.close = ao_close;
- this->ao_functions.exit = ao_exit;
-
- return &this->ao_functions;
+ this->audio_fd = -1;
+ this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO;
+ this->latency = config->lookup_int (config, "esd_latency", 30000);
+ this->gap_tolerance = config->lookup_int (config, "esd_gap_tolerance", 15000);
+
+ this->ao_driver.get_capabilities = ao_esd_get_capabilities;
+ this->ao_driver.get_property = ao_esd_get_property;
+ this->ao_driver.set_property = ao_esd_set_property;
+ this->ao_driver.open = ao_esd_open;
+ this->ao_driver.num_channels = ao_esd_num_channels;
+ this->ao_driver.bytes_per_frame = ao_esd_bytes_per_frame;
+ this->ao_driver.get_gap_tolerance = ao_esd_get_gap_tolerance;
+ this->ao_driver.delay = ao_esd_delay;
+ this->ao_driver.write = ao_esd_write;
+ this->ao_driver.close = ao_esd_close;
+ this->ao_driver.exit = ao_esd_exit;
+
+ return &this->ao_driver;
}
static ao_info_t ao_info_esd = {
- AUDIO_OUT_IFACE_VERSION,
+ AO_OUT_ESD_IFACE_VERSION,
"esd",
"xine audio output plugin using esd",
5