summaryrefslogtreecommitdiff
path: root/src/audio_out
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_out')
-rw-r--r--src/audio_out/audio_alsa05_out.c58
-rw-r--r--src/audio_out/audio_alsa_out.c31
-rw-r--r--src/audio_out/audio_oss_out.c39
-rw-r--r--src/audio_out/audio_sun_out.c30
4 files changed, 128 insertions, 30 deletions
diff --git a/src/audio_out/audio_alsa05_out.c b/src/audio_out/audio_alsa05_out.c
index 88e2f17b0..9e3fd121f 100644
--- a/src/audio_out/audio_alsa05_out.c
+++ b/src/audio_out/audio_alsa05_out.c
@@ -24,7 +24,7 @@
* for the SPDIF AC3 sync part
* (c) 2000 Andy Lo A Foe <andy@alsaplayer.org>
*
- * $Id: audio_alsa05_out.c,v 1.2 2001/06/06 19:34:23 f1rmb Exp $
+ * $Id: audio_alsa05_out.c,v 1.3 2001/06/23 19:45:47 guenter Exp $
*/
/* required for swab() */
@@ -57,6 +57,7 @@
#define GAP_TOLERANCE 15000
#define MAX_MASTER_CLOCK_DIV 5000
+#define MAX_GAP 90000
extern uint32_t xine_debug;
@@ -77,6 +78,8 @@ typedef struct _audio_alsa_globals {
int audio_step; /* pts per 32 768 samples (sample = #bytes/2) */
int32_t bytes_per_kpts; /* bytes per 1024/90000 sec */
+ uint32_t last_audio_vpts;
+
int16_t *zero_space;
int audio_started;
@@ -100,8 +103,11 @@ typedef struct _audio_alsa_globals {
} audio_alsa_globals_t;
+/* FIXME : global variables are not allowed in plugins */
+
static audio_alsa_globals_t gAudioALSA;
+
/* ------------------------------------------------------------------------- */
/*
*
@@ -203,13 +209,13 @@ static int ao_open(ao_functions_t *this,uint32_t bits, uint32_t rate, int ao_mod
if(!rate)
return 0;
- if(gAudioALSA.front_handle != NULL) {
+ if(gAudioALSA.front_handle != NULL) {
if(rate == gAudioALSA.input_sample_rate)
return 1;
-
+
snd_pcm_close(gAudioALSA.front_handle);
- }
+ }
gAudioALSA.input_sample_rate = rate;
gAudioALSA.bytes_in_buffer = 0;
@@ -218,6 +224,7 @@ static int ao_open(ao_functions_t *this,uint32_t bits, uint32_t rate, int ao_mod
gAudioALSA.sync_bytes_in_buffer = 0;
gAudioALSA.audio_started = 0;
gAudioALSA.direction = SND_PCM_CHANNEL_PLAYBACK;
+ gAudioALSA.last_audio_vpts = 0;
if (ao_mode == AO_CAP_MODE_AC3) {
gAudioALSA.pcm_default_device = 2;
@@ -233,7 +240,7 @@ static int ao_open(ao_functions_t *this,uint32_t bits, uint32_t rate, int ao_mod
gAudioALSA.pcm_default_card,
gAudioALSA.pcm_default_device,
subdevice, direction
-// | SND_PCM_OPEN_NONBLOCK)) < 0) {
+ /* | SND_PCM_OPEN_NONBLOCK)) < 0) { */
)) < 0) {
perr("snd_pcm_open_subdevice() failed: %s\n", snd_strerror(err));
return 0;
@@ -310,8 +317,10 @@ static int ao_open(ao_functions_t *this,uint32_t bits, uint32_t rate, int ao_mod
pcm_chan_params.channel = gAudioALSA.direction;
pcm_chan_params.start_mode = SND_PCM_START_FULL;
- //pcm_chan_params.start_mode = SND_PCM_START_DATA;
- //pcm_chan_params.stop_mode = SND_PCM_STOP_STOP;
+ /*
+ pcm_chan_params.start_mode = SND_PCM_START_DATA;
+ pcm_chan_params.stop_mode = SND_PCM_STOP_STOP;
+ */
pcm_chan_params.stop_mode = SND_PCM_STOP_ROLLOVER;
gAudioALSA.start_mode = pcm_chan_params.start_mode;
@@ -360,8 +369,12 @@ static int ao_open(ao_functions_t *this,uint32_t bits, uint32_t rate, int ao_mod
*
*/
static void ao_fill_gap (uint32_t pts_len) {
- int num_bytes = pts_len * gAudioALSA.bytes_per_kpts / 1024;
-
+ int num_bytes;
+
+ if (pts_len > MAX_GAP)
+ pts_len = MAX_GAP;
+
+ num_bytes = pts_len * gAudioALSA.bytes_per_kpts / 1024;
num_bytes = (num_bytes / 4) * 4;
gAudioALSA.bytes_in_buffer += num_bytes;
@@ -464,8 +477,8 @@ return;
/*
*
*/
-static void ao_put_samples(ao_functions_t *this,int16_t* output_samples,
- uint32_t num_samples, uint32_t pts_) {
+static int ao_put_samples(ao_functions_t *this,int16_t* output_samples,
+ uint32_t num_samples, uint32_t pts_) {
uint32_t vpts;
uint32_t audio_vpts;
uint32_t master_vpts;
@@ -480,7 +493,7 @@ static void ao_put_samples(ao_functions_t *this,int16_t* output_samples,
num_samples, pts_, gAudioALSA.bytes_in_buffer);
if (gAudioALSA.front_handle == NULL)
- return;
+ return 1;
// if(gAudioALSA.frag_size != num_samples) {
// alsa_set_frag(num_samples, 6);
@@ -488,6 +501,14 @@ static void ao_put_samples(ao_functions_t *this,int16_t* output_samples,
vpts = gAudioALSA.metronom->got_audio_samples (gAudioALSA.metronom,pts_, num_samples);
+ if (vpts<gAudioALSA.last_audio_vpts) {
+ /* reject this */
+
+ return 1;
+ }
+
+ gAudioALSA.last_audio_vpts = vpts;
+
/*
* check if these samples "fit" in the audio output buffer
* or do we have an audio "gap" here?
@@ -499,7 +520,16 @@ static void ao_put_samples(ao_functions_t *this,int16_t* output_samples,
"last_vpts=%d\n", num_samples, vpts, gAudioALSA.last_vpts);
if (gap > GAP_TOLERANCE) {
- // ao_fill_gap (gap);
+
+ /* FIXME : sync wont work without this
+ ao_fill_gap (gap);
+ */
+ /* keep xine responsive */
+ /*
+ if (gap>MAX_GAP)
+ return 0;
+ */
+
}
else if (gap < -GAP_TOLERANCE) {
bDropPackage = 1;
@@ -636,6 +666,8 @@ static void ao_put_samples(ao_functions_t *this,int16_t* output_samples,
gAudioALSA.last_vpts =
vpts + num_samples * 90000 / gAudioALSA.input_sample_rate ;
+
+ return 1;
}
/* ------------------------------------------------------------------------- */
diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c
index 9ec9b8d43..fca95f20d 100644
--- a/src/audio_out/audio_alsa_out.c
+++ b/src/audio_out/audio_alsa_out.c
@@ -24,7 +24,7 @@
* (c) 2001 James Courtier-Dutton <James@superbug.demon.co.uk>
*
*
- * $Id: audio_alsa_out.c,v 1.9 2001/06/11 19:37:53 joachim_koenig Exp $
+ * $Id: audio_alsa_out.c,v 1.10 2001/06/23 19:45:47 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -79,6 +79,7 @@
#define GAP_TOLERANCE 15000
#define MAX_MASTER_CLOCK_DIV 5000
+#define MAX_GAP 90000
typedef struct alsa_functions_s {
@@ -357,7 +358,12 @@ static uint32_t ao_get_current_vpts (alsa_functions_t *this)
static void ao_fill_gap (alsa_functions_t *this, uint32_t pts_len)
{
snd_pcm_sframes_t res;
- int num_frames = (double)pts_len * (double)this->input_sample_rate / (double)this->pts_per_second;
+ int num_frames;
+
+ if (pts_len > MAX_GAP)
+ pts_len = MAX_GAP;
+
+ num_frames = (double)pts_len * (double)this->input_sample_rate / (double)this->pts_per_second;
num_frames = (num_frames / 4) * 4;
this->frames_in_buffer += num_frames;
while (num_frames>0) {
@@ -445,9 +451,9 @@ void write_pause_burst(alsa_functions_t *this,int error)
-static void ao_write_audio_data(ao_functions_t *this_gen,
- int16_t* output_samples, uint32_t num_samples,
- uint32_t pts_)
+static int ao_write_audio_data(ao_functions_t *this_gen,
+ int16_t* output_samples, uint32_t num_samples,
+ uint32_t pts_)
{
alsa_functions_t *this = (alsa_functions_t *) this_gen;
@@ -466,6 +472,13 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
}
vpts = this->metronom->got_audio_samples (this->metronom, pts_, num_samples);
+
+ if (vpts<this->last_audio_vpts) {
+ /* reject this */
+
+ return 1;
+ }
+
/*
* check if these samples "fit" in the audio output buffer
* or do we have an audio "gap" here?
@@ -475,6 +488,12 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
#if 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;
}
@@ -567,6 +586,8 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
}
this->last_vpts = vpts + num_samples * this->pts_per_second / this->input_sample_rate ;
+
+ return 1;
}
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c
index 4a38f51af..19c76e066 100644
--- a/src/audio_out/audio_oss_out.c
+++ b/src/audio_out/audio_oss_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_oss_out.c,v 1.14 2001/06/16 19:58:31 guenter Exp $
+ * $Id: audio_oss_out.c,v 1.15 2001/06/23 19:45:47 guenter Exp $
*/
/* required for swab() */
@@ -75,6 +75,7 @@
#define AUDIO_FRAGMENT_SIZE 8192
#define GAP_TOLERANCE 5000
+#define MAX_GAP 90000
#ifdef CONFIG_DEVFS_FS
#define DSP_TEMPLATE "/dev/sound/dsp%d"
@@ -105,7 +106,7 @@ typedef struct oss_functions_s {
int16_t *zero_space;
int audio_started;
-
+ uint32_t last_audio_vpts;
} oss_functions_t;
/*
@@ -136,6 +137,7 @@ static int ao_open(ao_functions_t *this_gen,
this->input_sample_rate = rate;
this->bytes_in_buffer = 0;
this->audio_started = 0;
+ this->last_audio_vpts = 0;
/*
* open audio device
@@ -239,9 +241,15 @@ static int ao_open(ao_functions_t *this_gen,
static void ao_fill_gap (oss_functions_t *this, uint32_t pts_len) {
- int num_bytes = pts_len * this->bytes_per_kpts / 1024;
+ 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);
- if(this->mode == AO_CAP_MODE_AC3) return;
+
+ if(this->mode == AO_CAP_MODE_AC3) return; /* FIXME */
+
printf ("audio_oss_out: inserting %d 0-bytes to fill a gap of %d pts\n",num_bytes, pts_len);
this->bytes_in_buffer += num_bytes;
@@ -257,9 +265,9 @@ static void ao_fill_gap (oss_functions_t *this, uint32_t pts_len) {
}
}
-static void ao_write_audio_data(ao_functions_t *this_gen,
- int16_t* output_samples, uint32_t num_samples,
- uint32_t pts_)
+static int ao_write_audio_data(ao_functions_t *this_gen,
+ int16_t* output_samples, uint32_t num_samples,
+ uint32_t pts_)
{
oss_functions_t *this = (oss_functions_t *) this_gen;
@@ -278,6 +286,14 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
xprintf (VERBOSE|AUDIO, "audio_oss_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?
*/
@@ -310,6 +326,12 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
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;
}
@@ -370,6 +392,9 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
} else {
printf ("audio_oss_out: audio package (vpts = %d) dropped\n", vpts);
}
+
+ return 1;
+
}
diff --git a/src/audio_out/audio_sun_out.c b/src/audio_out/audio_sun_out.c
index 832ceb41f..b52a4d7af 100644
--- a/src/audio_out/audio_sun_out.c
+++ b/src/audio_out/audio_sun_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_sun_out.c,v 1.2 2001/06/22 10:45:03 jkeil Exp $
+ * $Id: audio_sun_out.c,v 1.3 2001/06/23 19:45:47 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -53,6 +53,7 @@
#endif
#define GAP_TOLERANCE 5000
+#define MAX_GAP 90000
typedef struct sun_functions_s {
@@ -163,7 +164,12 @@ static int ao_open(ao_functions_t *this_gen,
static void ao_fill_gap (sun_functions_t *this, uint32_t pts_len) {
- int num_bytes = pts_len * this->bytes_per_kpts / 1024;
+ 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);
if(this->mode == AO_CAP_MODE_AC3) return;
printf ("audio_sun_out: inserting %d 0-bytes to fill a gap of %d pts\n",num_bytes, pts_len);
@@ -181,9 +187,9 @@ static void ao_fill_gap (sun_functions_t *this, uint32_t pts_len) {
}
}
-static void ao_write_audio_data(ao_functions_t *this_gen,
- int16_t* output_samples, uint32_t num_samples,
- uint32_t pts_)
+static int ao_write_audio_data(ao_functions_t *this_gen,
+ int16_t* output_samples, uint32_t num_samples,
+ uint32_t pts_)
{
sun_functions_t *this = (sun_functions_t *) this_gen;
@@ -199,6 +205,12 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
vpts = this->metronom->got_audio_samples (this->metronom, pts_, num_samples);
+ if (vpts<this->last_audio_vpts) {
+ /* reject this */
+
+ return 1;
+ }
+
xprintf (VERBOSE|AUDIO, "audio_sun_out: got %d samples, vpts=%d\n",
num_samples, vpts);
@@ -234,6 +246,12 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
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;
}
@@ -302,6 +320,8 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
} else {
printf ("audio_sun_out: audio package (vpts = %d) dropped\n", vpts);
}
+
+ return 1;
}