summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/xine-engine/audio_out.c194
1 files changed, 80 insertions, 114 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 57bdba3ac..462890ffc 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.5 2001/08/22 11:03:52 jcdutton Exp $
+ * $Id: audio_out.c,v 1.6 2001/08/22 16:20:13 guenter Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -57,17 +57,6 @@
#include <fcntl.h>
#include <math.h>
#include <unistd.h>
-#if defined(__OpenBSD__)
-#include <soundcard.h>
-#elif defined(__FreeBSD__)
-#include <machine/soundcard.h>
-#else
-#if defined(__linux__)
-#include <linux/config.h> /* Check for DEVFS */
-#endif
-#include <sys/soundcard.h>
-#endif
-#include <sys/ioctl.h>
#include <inttypes.h>
#include "xine_internal.h"
@@ -77,36 +66,12 @@
#include "metronom.h"
#include "utils.h"
-#ifndef AFMT_S16_NE
-# if defined(sparc) || defined(__sparc__) || defined(PPC)
-/* Big endian machines */
-# define AFMT_S16_NE AFMT_S16_BE
-# else
-# define AFMT_S16_NE AFMT_S16_LE
-# endif
-#endif
-
-#ifndef AFMT_AC3
-# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */
-#endif
-
-#define AO_OUT_OSS_IFACE_VERSION 1
-
-#define AUDIO_NUM_FRAGMENTS 15
-#define AUDIO_FRAGMENT_SIZE 8192
-
/* bufsize must be a multiple of 3 and 5 for 5.0 and 5.1 channel playback! */
#define ZERO_BUF_SIZE 15360
#define GAP_TOLERANCE 5000
#define MAX_GAP 90000
-#ifdef CONFIG_DEVFS_FS
-#define DSP_TEMPLATE "/dev/sound/dsp%d"
-#else
-#define DSP_TEMPLATE "/dev/dsp%d"
-#endif
-
struct frmsize_s
{
uint16_t bit_rate;
@@ -163,10 +128,11 @@ static int ao_open(ao_instance_t *self,
uint32_t bits, uint32_t rate, int mode)
{
int result;
- if(result=self->driver->open(self->driver,bits,rate,mode)<0) {
- printf("open failed!\n");
- return -1;
+ if ((result=self->driver->open(self->driver,bits,rate,mode))<0) {
+ printf("open failed!\n");
+ return -1;
};
+
self->mode = mode;
self->input_frame_rate = rate;
self->frames_in_buffer = 0;
@@ -177,7 +143,7 @@ static int ao_open(ao_instance_t *self,
self->output_frame_rate=rate;
self->num_channels = self->driver->num_channels(self->driver);
- self->frame_rate_factor = (double) self->output_frame_rate / (double) self->input_frame_rate; /* Alway produces 1 at the moment */
+ self->frame_rate_factor = (double) self->output_frame_rate / (double) self->input_frame_rate; /* always produces 1 at the moment */
self->audio_step = (uint32_t) 90000 * (uint32_t) 32768
/ self->input_frame_rate;
self->frames_per_kpts = self->output_frame_rate * self->num_channels * 2 * 1024 / 90000;
@@ -225,30 +191,30 @@ static void ao_fill_gap (ao_instance_t *self, uint32_t pts_len) {
void write_pause_burst(ao_instance_t *self, int error)
{
- unsigned char buf[8192];
- unsigned short *sbuf = (unsigned short *)&buf[0];
-
- sbuf[0] = 0xf872;
- sbuf[1] = 0x4e1f;
-
- if (error == 0)
- // Audio ES Channel empty, wait for DD Decoder or pause
- sbuf[2] = 0x0003;
- else
- // user stop, skip or error
- sbuf[2] = 0x0103;
-
- sbuf[3] = 0x0020;
- sbuf[4] = 0x0000;
- sbuf[5] = 0x0000;
-
- memset(&sbuf[6], 0, 6144 - 96);
- self->driver->write(self->driver, sbuf, 6144 / 4);
+ unsigned char buf[8192];
+ unsigned short *sbuf = (unsigned short *)&buf[0];
+
+ sbuf[0] = 0xf872;
+ sbuf[1] = 0x4e1f;
+
+ if (error == 0)
+ /* Audio ES Channel empty, wait for DD Decoder or pause */
+ sbuf[2] = 0x0003;
+ else
+ /* user stop, skip or error */
+ sbuf[2] = 0x0103;
+
+ sbuf[3] = 0x0020;
+ sbuf[4] = 0x0000;
+ sbuf[5] = 0x0000;
+
+ memset(&sbuf[6], 0, 6144 - 96);
+ self->driver->write(self->driver, sbuf, 6144 / 4);
}
static int ao_write(ao_instance_t *self,
- int16_t* output_frames, uint32_t num_frames,
- uint32_t pts_)
+ int16_t* output_frames, uint32_t num_frames,
+ uint32_t pts_)
{
uint32_t vpts, buffer_vpts;
int32_t gap;
@@ -280,47 +246,47 @@ static int ao_write(ao_instance_t *self,
if ( self->audio_has_realtime || !self->audio_started ) {
- /*
- * where, in the timeline is the "end" of the audio buffer at the moment?
- */
-
- buffer_vpts = self->metronom->get_current_time (self->metronom);
-
- if (self->audio_started) {
- pos = self->driver->delay(self->driver);
- } else
- pos = 0;
- if ( (self->mode==AO_CAP_MODE_AC3) && (pos>10) ) pos-=10; /* External AC3 decoder delay correction */
-
- if (pos>self->frames_in_buffer) /* buffer ran dry */
- self->frames_in_buffer = pos;
-
- buffer_vpts += (self->frames_in_buffer - pos) * 1024 / self->frames_per_kpts;
-
- /*
- * calculate gap:
- */
-
- gap = vpts - buffer_vpts;
- xprintf (VERBOSE|AUDIO, "audio_out: buff=%d pos=%d buf_vpts=%d gap=%d\n",
- self->frames_in_buffer, pos,buffer_vpts,gap);
-
- if (gap>GAP_TOLERANCE) {
- ao_fill_gap (self, gap);
-
- /* keep xine responsive */
-
- if (gap>MAX_GAP)
- return 0;
-
- } else if (gap<-GAP_TOLERANCE) {
- bDropPackage = 1;
- xprintf (VERBOSE|AUDIO, "audio_out: audio package (vpts = %d %d)"
- "dropped\n", vpts, gap);
- }
-
+ /*
+ * where, in the timeline is the "end" of the audio buffer at the moment?
+ */
+
+ buffer_vpts = self->metronom->get_current_time (self->metronom);
+
+ if (self->audio_started) {
+ pos = self->driver->delay(self->driver);
+ } else
+ pos = 0;
+ if ( (self->mode==AO_CAP_MODE_AC3) && (pos>10) ) pos-=10; /* External AC3 decoder delay correction */
+
+ if (pos>self->frames_in_buffer) /* buffer ran dry */
+ self->frames_in_buffer = pos;
+
+ buffer_vpts += (self->frames_in_buffer - pos) * 1024 / self->frames_per_kpts;
+
+ /*
+ * calculate gap:
+ */
+
+ gap = vpts - buffer_vpts;
+ xprintf (VERBOSE|AUDIO, "audio_out: buff=%d pos=%d buf_vpts=%d gap=%d\n",
+ self->frames_in_buffer, pos,buffer_vpts,gap);
+
+ if (gap>GAP_TOLERANCE) {
+ ao_fill_gap (self, gap);
+
+ /* keep xine responsive */
+
+ if (gap>MAX_GAP)
+ return 0;
+
+ } else if (gap<-GAP_TOLERANCE) {
+ bDropPackage = 1;
+ xprintf (VERBOSE|AUDIO, "audio_out: audio package (vpts = %d %d)"
+ "dropped\n", vpts, gap);
+ }
+
} /* has realtime */
-
+
/*
* resample and output frames
*/
@@ -361,17 +327,17 @@ static int ao_write(ao_instance_t *self,
break;
case AO_CAP_MODE_AC3:
num_output_frames = (num_frames+8)/4;
- self->frame_buffer[0] = 0xf872; //spdif syncword
- self->frame_buffer[1] = 0x4e1f; // .............
- self->frame_buffer[2] = 0x0001; // AC3 data
+ self->frame_buffer[0] = 0xf872; /* spdif syncword */
+ self->frame_buffer[1] = 0x4e1f; /* ............. */
+ self->frame_buffer[2] = 0x0001; /* AC3 data */
- data = (uint8_t *)&output_frames[1]; // skip AC3 sync
- fscod = (data[2] >> 6) & 0x3;
- frmsizecod = data[2] & 0x3f;
- frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] << 4;
- self->frame_buffer[3] = frame_size;
+ data = (uint8_t *)&output_frames[1]; /* skip AC3 sync */
+ fscod = (data[2] >> 6) & 0x3;
+ frmsizecod = data[2] & 0x3f;
+ frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] << 4;
+ self->frame_buffer[3] = frame_size;
- // ac3 seems to be swabbed data
+ /* ac3 seems to be swabbed data */
swab(output_frames,self->frame_buffer+4, num_frames );
self->driver->write(self->driver, self->zero_space, 2); /* Prevents crackle at start. */
self->driver->write(self->driver, self->frame_buffer, num_output_frames);
@@ -411,6 +377,7 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, metronom_t *metronom) {
ao_instance_t *self;
self = xmalloc (sizeof (ao_instance_t)) ;
+
self->driver = driver;
self->metronom = metronom;
@@ -419,10 +386,9 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, metronom_t *metronom) {
self->close = ao_close;
self->get_capabilities = ao_get_capabilities;
self->audio_loop_running = 0;
- self->frame_buffer = malloc (40000);
- memset (self->frame_buffer, 0, 40000);
- self->zero_space = malloc (ZERO_BUF_SIZE);
- memset (self->zero_space, 0, ZERO_BUF_SIZE);
+ self->frame_buffer = xmalloc (40000);
+ self->zero_space = xmalloc (ZERO_BUF_SIZE);
+
return self;
}