From 6740e86779eae01c7b4f211be5fd8a9f2b0b92e9 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Fri, 16 Nov 2001 20:24:56 +0000 Subject: DTS Audio should work via the SPDIF Digital out. Added DTS syncinfo check and header parsing. CVS patchset: 1051 CVS date: 2001/11/16 20:24:56 --- src/libdts/xine_decoder.c | 27 +++++++++++++++++++---- src/xine-engine/audio_out.c | 54 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/libdts/xine_decoder.c b/src/libdts/xine_decoder.c index 52bf21fd7..9b94c9f0a 100644 --- a/src/libdts/xine_decoder.c +++ b/src/libdts/xine_decoder.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: xine_decoder.c,v 1.3 2001/11/13 21:47:58 heikos Exp $ + * $Id: xine_decoder.c,v 1.4 2001/11/16 20:24:56 jcdutton Exp $ * * 04-09-2001 DTS passtrough (C) Joachim Koenig * @@ -71,13 +71,31 @@ void dts_init (audio_decoder_t *this_gen, ao_instance_t *audio_out) { void dts_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { dts_decoder_t *this = (dts_decoder_t *) this_gen; - int16_t *sample_buffer=(int16_t *)buf->content; + uint8_t *data=(uint8_t *)buf->content; audio_buffer_t *audio_buffer; + uint32_t ac5_type; + uint32_t ac5_length; + int i; if ((this->audio_caps & AO_CAP_MODE_AC5) == 0) { return; } - + if ((data[0] != 0x7f) || + (data[1] != 0xfe) || + (data[2] != 0x80) || + (data[3] != 0x01)) { + printf("DTS Sync bad\n"); + return; + } + ac5_type=((data[4] & 0x01) << 6) | ((data[5] >>2) & 0x3f); + ac5_length=((data[5] & 0x03) << 12) | ((data[6] & 0xff) << 4) | ((data[7] & 0xf0) >> 4); +/* printf("DTS AC5 length=%d\n",ac5_length); */ + if (ac5_length > 8191) { + printf("ac5_length too long\n"); + return; + } + + if (!this->output_open) { this->output_open = (this->audio_out->open (this->audio_out, this->bits_per_sample, this->rate, @@ -87,10 +105,11 @@ void dts_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { return; audio_buffer = this->audio_out->get_buffer (this->audio_out); + memcpy (audio_buffer->mem, data, ac5_length); audio_buffer->vpts = buf->PTS; audio_buffer->scr = buf->SCR; - audio_buffer->num_frames = 1536; + audio_buffer->num_frames = ac5_length / 2; this->audio_out->put_buffer (this->audio_out, audio_buffer); diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 7f59f1ea8..9919d4197 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.26 2001/11/15 00:32:36 miguelfreitas Exp $ + * $Id: audio_out.c,v 1.27 2001/11/16 20:24:56 jcdutton Exp $ * * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. * (c) 2001 Andy Lo A Foe @@ -290,6 +290,9 @@ static void *ao_loop (void *this_gen) { uint8_t *data; uint32_t cur_time; int num_output_frames ; + uint32_t ac5_type; + uint32_t ac5_length; + uint32_t i; this->audio_loop_running = 1; @@ -420,6 +423,55 @@ static void *ao_loop (void *this_gen) { break; case AO_CAP_MODE_AC5: + memset(this->frame_buffer,0x00,6144); + this->frame_buffer[0] = 0xf872; /* spdif syncword */ + this->frame_buffer[1] = 0x4e1f; /* ............. */ + data = (uint8_t *)&buf->mem[0]; + + if ((data[0] != 0x7f) || + (data[1] != 0xfe) || + (data[2] != 0x80) || + (data[3] != 0x01)) { + continue; + } + ac5_type=((data[4] & 0x01) << 6) | ((data[5] >>2) & 0x3f); + /* printf("AC5 type=%d\n",ac5_type); */ + switch(ac5_type) { + case 0x0f: + this->frame_buffer[2] = 0x000b; /* DTS */ + break; + case 0x1f: + this->frame_buffer[2] = 0x000c; /* DTS */ + break; + case 0x3f: + this->frame_buffer[2] = 0x000d; /* DTS */ + break; + default: + this->frame_buffer[2] = 0x0000; /* DTS */ + break; + } + + ac5_length=((data[5] & 0x03) << 12) | + ((data[6] & 0xff) << 4) | + ((data[7] & 0xf0) >> 4); + /* printf("AC5 length=%d\n",ac5_length); */ + if (ac5_length > 8191) { + break; + } + ac5_length = ac5_length << 3; /* Convert bytes to bits */ + this->frame_buffer[3] = ac5_length; + + /* ac3 seems to be swabbed data */ + swab(buf->mem,this->frame_buffer+4, ac5_length ); + + this->driver->write(this->driver, this->frame_buffer, (ac5_length / 2) + 4); + + break; + + + + + memset(this->frame_buffer,0xff,6144); this->frame_buffer[0] = 0xf872; /* spdif syncword */ this->frame_buffer[1] = 0x4e1f; /* ............. */ -- cgit v1.2.3