[Alsaplayer-devel]ac3play patch
Yuqing Deng
deng@tinker.chem.brown.edu
Thu, 7 Jun 2001 18:22:46 -0700 (EDT)
Hi,
I made ac3play work with alsa 0.9.
The patch is included. Run automake and autoconf before configure.
Yuqing
diff -Ncr ac3play-0.3.0/Makefile.am /home/deng/ac3play-0.3.0/Makefile.am
*** ac3play-0.3.0/Makefile.am Mon Jun 5 14:49:13 2000
--- /home/deng/ac3play-0.3.0/Makefile.am Wed Jan 24 20:44:36 2001
***************
*** 4,8 ****
CFLAGS = @CFLAGS@ -I$(top_srcdir)/libac3
bin_PROGRAMS = ac3play
! ac3play_SOURCES = ac3play.c ac3_pack.c ac3_pack.h
ac3play_LDADD = $(top_builddir)/libac3/libac3.a
--- 4,8 ----
CFLAGS = @CFLAGS@ -I$(top_srcdir)/libac3
bin_PROGRAMS = ac3play
! ac3play_SOURCES = ac3play.c ac3burst.c ac3burst.h
ac3play_LDADD = $(top_builddir)/libac3/libac3.a
diff -Ncr ac3play-0.3.0/ac3_pack.c /home/deng/ac3play-0.3.0/ac3_pack.c
*** ac3play-0.3.0/ac3_pack.c Tue Jun 6 03:59:22 2000
--- /home/deng/ac3play-0.3.0/ac3_pack.c Wed Dec 31 19:00:00 1969
***************
*** 1,309 ****
- /*
- * ac3_pack.c
- *
- * Copyright (C) 2000 by Yuqing Deng
- *
- * Based on Andy Lo A Foe's orginal ac3play 0.2.0
- *
- * ac3_pack.c is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * play_ac3 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * Tue Jun 6 09:56:34 CEST 2000, andy
- * -----------------------------------
- * Updated ALSA API calls
- *
- *
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/asoundlib.h>
- #include "ac3.h"
- #include "ac3_internal.h"
- #include "parse.h"
-
- #define BLOCK_SIZE 6144
- static char buf[BLOCK_SIZE];
- static uint_32 sbuffer_size = 0;
-
- static syncinfo_t syncinfo;
- static char *sbuffer = &buf[10];
-
- static int pcm_mode = SND_PCM_MODE_FRAGMENT;
- static FILE *bla2;
- static snd_pcm_t *handle;
- static snd_pcm_stream_status_t status;
- static snd_pcm_stream_setup_t setup;
- static stream = SND_PCM_STREAM_PLAYBACK;
-
- uint_32
- buffer_syncframe(syncinfo_t *syncinfo, uint_8 **start, uint_8 *end)
- {
- uint_8 *cur = *start;
- uint_16 syncword = syncinfo->syncword;
- uint_32 ret = 0;
-
- //
- // Find an ac3 sync frame.
- //
- while(syncword != 0x0b77)
- {
- if(cur >= end)
- goto done;
- syncword = (syncword << 8) + *cur++;
- }
-
- //need the next 3 bytes to decide how big the frame is
- while(sbuffer_size < 3)
- {
- if(cur >= end)
- goto done;
-
- sbuffer[sbuffer_size++] = *cur++;
- }
-
- parse_syncinfo(syncinfo,sbuffer);
- //stats_print_syncinfo(syncinfo);
-
- while(sbuffer_size < syncinfo->frame_size * 2 - 2)
- {
- if(cur >= end)
- goto done;
-
- sbuffer[sbuffer_size++] = *cur++;
- }
-
- // Check the crc over the entire frame
- crc_init();
- crc_process_frame(sbuffer,syncinfo->frame_size * 2 - 2);
-
- if(!crc_validate())
- {
- //error_flag = 1;
- fprintf(stderr,"** CRC failed - skipping frame **\n");
- goto done;
- }
- //
- //if we got to this point, we found a valid ac3 frame to decode
- //
-
- //bitstream_init(buffer);
- //get rid of the syncinfo struct as we already parsed it
- //bitstream_get(24);
-
- //reset the syncword for next time
- syncword = 0xffff;
- sbuffer_size = 0;
- ret = 1;
-
- done:
- syncinfo->syncword = syncword;
- *start = cur;
- return ret;
- }
-
- void
- output_spdif_pack(uint_8 *data_start, uint_8 *data_end)
- {
- unsigned short *sbuf = (unsigned short *)buf;
- int err = 0;
-
- while(buffer_syncframe(&syncinfo, &data_start, data_end))
- {
- sbuf[0] = 0xf872; //spdif syncword
- sbuf[1] = 0x4e1f; // .............
- sbuf[2] = 0x0001; // AC3 data
- sbuf[3] = syncinfo.frame_size * 16;
- sbuf[4] = 0x0b77; // AC3 syncwork
-
- // extract_ac3 seems to write swabbed data
- swab(&buf[10], &buf[10], syncinfo.frame_size * 2 - 2);
- #ifdef DEBUG
- if (bla2)
- fwrite(buf, BLOCK_SIZE, 1, bla2);
- #endif
-
- // Write out the frame to S/PDIF
- #ifdef DEBUG
- do {
- if ((err=snd_pcm_stream_status(handle, &status)) < 0) {
- fprintf(stderr, "cannot get stream status: %s\n", snd_strerror(err));
- }
-
- switch (status.status) {
- case SND_PCM_STATUS_NOTREADY:
- fprintf(stderr, "status: NOTREADY\n");
- break;
- case SND_PCM_STATUS_READY:
- fprintf(stderr, "status: READY\n");
- break;
- case SND_PCM_STATUS_PREPARED:
- fprintf(stderr, "status: PREPARED\n");
- break;
- case SND_PCM_STATUS_RUNNING:
- fprintf(stderr, "status: RUNNING\n");
- break;
- case SND_PCM_STATUS_XRUN:
- fprintf(stderr, "status: XRUN\n");
- break;
- case SND_PCM_STATUS_PAUSED:
- fprintf(stderr, "status: PAUSED\n");
- break;
- }
- fprintf(stderr, "bytes available: %d\n",
- status.avail);
- } while (status.bytes_free < BLOCK_SIZE);
- #endif
-
- snd_pcm_write(handle, buf, BLOCK_SIZE);
- memset(&status, 0, sizeof(status));
- snd_pcm_stream_status(handle, &status);
- if (status.xruns) {
- fprintf(stderr, "underrun, resetting stream\n");
- snd_pcm_stream_flush(handle, stream);
- snd_pcm_stream_prepare(handle, stream);
- snd_pcm_write(handle, buf, BLOCK_SIZE);
- snd_pcm_stream_status(handle, &status);
- if (status.xruns) {
- fprintf(stderr, "still underrun, give up\n");
- return;
- }
- }
- }
- }
-
- uint_32
- spdif_init(int acard, int adevice)
- {
- snd_pcm_stream_info_t info;
- snd_pcm_digital_t digital;
- snd_pcm_stream_params_t params;
- int err, c;
-
- if ((err = snd_pcm_open(&handle, acard, adevice, SND_PCM_OPEN_PLAYBACK)) < 0)
- {
- fprintf(stderr, "open: %s\n", snd_strerror(err));
- return 1;
- }
- memset(&info, 0, sizeof(info));
- if ((err = snd_pcm_stream_info(handle, &info)) < 0) {
- fprintf(stderr, "info: %s\n", snd_strerror(err));
- snd_pcm_close(handle);
- return 1;
- }
- #ifdef DEBUG
- bla2 = fopen("/tmp/ac3dump", "w");
-
- printf("%s\n", info.subname);
- printf("stream = %d\n", info.stream);
- printf("formats = %d\n", info.formats);
- printf("flags = %d\n", info.flags);
- printf("samplerate = %d - %d\n", info.min_rate, info.max_rate);
- // printf("mode = %d\n", info.mode);
- printf("fifo_size = %d\n", info.fifo_size);
- printf("buffer_size = %d\n", info.buffer_size);
- #endif
- memset(&setup, 0, sizeof(setup));
- memset(¶ms, 0, sizeof(params));
- params.mode = pcm_mode;
- params.stream = stream;
- params.start_mode = SND_PCM_START_FULL;
- params.xrun_mode = SND_PCM_XRUN_FLUSH;
- params.frag_size = BLOCK_SIZE;
- params.buffer_size = BLOCK_SIZE * 6;
- #if 1
- params.digital.valid = 1;
- params.digital.dig.aes.status[0] = SND_PCM_AES0_NONAUDIO;
- params.digital.dig.aes.status[3] = SND_PCM_AES3_CON_FS_48000;
- #endif
- params.format.format = SND_PCM_SFMT_S16_LE;
- params.format.rate = 48000;
- params.format.interleave = 1;
- params.format.channels = 2;
- snd_pcm_stream_flush(handle, stream);
-
- if ((err = snd_pcm_stream_params(handle, ¶ms)) < 0) {
- fprintf(stderr, "params: %s\n", snd_strerror(err));
- snd_pcm_close(handle);
- return 3;
- }
- #if 0
- setup.digital.valid = 1;
- setup.digital.dig.aes.status[0] = SND_PCM_DIG0_NONAUDIO;
- setup.digital.dig.aes.status[3] = SND_PCM_DIG3_CON_FS_48000;
- #endif
- setup.mode = pcm_mode;
- setup.stream = stream;
- if ((err = snd_pcm_stream_prepare(handle, stream)) < 0) {
- fprintf(stderr, "prepare: %s\n", snd_strerror(err));
- return 2;
- }
- if ((err = snd_pcm_stream_setup(handle, &setup)) < 0) {
- fprintf(stderr, "setup: %s\n", snd_strerror(err));
- snd_pcm_close(handle);
- return 2;
- }
-
- memset(buf, 0, sizeof(buf));
-
- // Send some trailing zeros to avoid misdetecting the
- // first frame as PCM (works for DTT2500 at least)
- for (c=0; c < 0; c++) {
- if ((snd_pcm_write(handle, buf, BLOCK_SIZE)) < 0) {
- fprintf(stderr, "error in initial write\n");
- exit(2);
- }
- if ((err=snd_pcm_stream_status(handle, &status)) < 0) {
- fprintf(stderr, "cannot get stream status: %s\n", snd_strerror(err));
- }
- //snd_pcm_stream_prepare(handle, SND_PCM_CHANNEL_PLAYBACK);
-
- switch (status.status) {
- case SND_PCM_STATUS_NOTREADY:
- fprintf(stderr, "status: NOTREADY\n");
- break;
- case SND_PCM_STATUS_READY:
- fprintf(stderr, "status: READY\n");
- break;
- case SND_PCM_STATUS_PREPARED:
- snd_pcm_playback_go(handle);
- fprintf(stderr, "status: PREPARED\n");
- break;
- case SND_PCM_STATUS_RUNNING:
- fprintf(stderr, "status: RUNNING\n");
- break;
- case SND_PCM_STATUS_XRUN:
- fprintf(stderr, "status: XRUN\n");
- break;
- case SND_PCM_STATUS_PAUSED:
- fprintf(stderr, "status: PAUSED\n");
- break;
- }
- fprintf(stderr, "bytes available: %d\n",
- status.bytes_avail);
- }
- return 0;
- }
-
- void spdif_close()
- {
- // Cleanup
- snd_pcm_close(handle);
- #ifdef DEBUG
- if (bla2)
- fclose(bla2);
- #endif
- }
--- 0 ----
diff -Ncr ac3play-0.3.0/ac3_pack.h /home/deng/ac3play-0.3.0/ac3_pack.h
*** ac3play-0.3.0/ac3_pack.h Mon Jun 5 01:14:45 2000
--- /home/deng/ac3play-0.3.0/ac3_pack.h Wed Dec 31 19:00:00 1969
***************
*** 1,4 ****
- uint_32 buffer_syncframe(syncinfo_t*, uint_8 **, uint_8 *);
- void output_spdif_pack(uint_8 *, uint_8 *);
- uint_32 spdif_init(int acard, int adevice);
- void spdif_close(void);
--- 0 ----
diff -Ncr ac3play-0.3.0/ac3burst.c /home/deng/ac3play-0.3.0/ac3burst.c
*** ac3play-0.3.0/ac3burst.c Wed Dec 31 19:00:00 1969
--- /home/deng/ac3play-0.3.0/ac3burst.c Sat Jun 2 10:13:03 2001
***************
*** 0 ****
--- 1,362 ----
+ /*
+ * ac3burst.c
+ *
+ * Copyright (C) 2000 by Yuqing Deng
+ *
+ * Based on Andy Lo A Foe's orginal ac3play 0.2.0
+ *
+ * ac3_pack.c is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * play_ac3 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Tue Jun 6 09:56:34 CEST 2000, andy
+ * -----------------------------------
+ * Updated ALSA API calls
+ *
+ *
+ */
+
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <sys/asoundlib.h>
+ #include <sys/uio.h>
+ #include <errno.h>
+ #include <sys/poll.h>
+ #include "ac3.h"
+ #include "ac3_internal.h"
+ #include "crc.h"
+ #include "parse.h"
+
+ extern void swab (__const void *__restrict __from, void *__restrict __to,
+ ssize_t __n);
+
+ #define BURST_SIZE 6144
+ static u_char buf[BURST_SIZE];
+ static uint_32 sbuffer_size = 0;
+
+ static syncinfo_t syncinfo;
+ static char *sbuffer = &buf[10];
+
+ #ifdef DEBUG
+ static FILE *bla2;
+ #endif
+
+ static snd_pcm_t *handle;
+ static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
+ static snd_output_t *log;
+ //static snd_pcm_uframes_t buffer_size = BURST_SIZE / 4 * 6;
+
+ uint_32
+ buffer_syncframe(syncinfo_t *syncinfo, uint_8 **start, uint_8 *end)
+ {
+ uint_8 *cur = *start;
+ uint_16 syncword = syncinfo->syncword;
+ uint_32 ret = 0;
+
+ //
+ // Find an ac3 sync frame.
+ //
+ resync:
+ while(syncword != 0x0b77)
+ {
+ if(cur >= end)
+ goto done;
+ syncword = (syncword << 8) + *cur++;
+ }
+
+ //need the next 3 bytes to decide how big the frame is
+ while(sbuffer_size < 3)
+ {
+ if(cur >= end)
+ goto done;
+
+ sbuffer[sbuffer_size++] = *cur++;
+ }
+
+ parse_syncinfo(syncinfo,sbuffer);
+ //stats_print_syncinfo(syncinfo);
+
+ while(sbuffer_size < syncinfo->frame_size * 2 - 2)
+ {
+ if(cur >= end)
+ goto done;
+
+ sbuffer[sbuffer_size++] = *cur++;
+ }
+
+ // Check the crc over the entire frame
+ crc_init();
+ crc_process_frame(sbuffer,syncinfo->frame_size * 2 - 2);
+
+ if(!crc_validate())
+ {
+ //error_flag = 1;
+ fprintf(stderr,"** CRC failed - skipping frame **\n");
+ syncword = 0xffff;
+ sbuffer_size = 0;
+ goto resync;
+ }
+ //
+ //if we got to this point, we found a valid ac3 frame to decode
+ //
+
+ //bitstream_init(buffer);
+ //get rid of the syncinfo struct as we already parsed it
+ //bitstream_get(24);
+
+ //reset the syncword for next time
+ syncword = 0xffff;
+ sbuffer_size = 0;
+ ret = 1;
+
+ done:
+ syncinfo->syncword = syncword;
+ *start = cur;
+ return ret;
+ }
+ void xrun(void)
+ {
+ snd_pcm_status_t *status;
+ int res;
+
+ snd_pcm_status_alloca(&status);
+ if ((res = snd_pcm_status(handle, status))<0) {
+ printf("status error: %s", snd_strerror(res));
+ return;
+ }
+ if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) {
+ struct timeval now, diff, tstamp;
+ gettimeofday(&now, 0);
+ snd_pcm_status_get_trigger_tstamp(status, &tstamp);
+ timersub(&now, &tstamp, &diff);
+ fprintf(stderr, "xrun!!! (at least %.3f ms long)\n", diff.tv_sec * 1000 + diff.tv_usec / 1000.0);
+ if ((res = snd_pcm_prepare(handle))<0) {
+ printf("xrun: prepare error: %s", snd_strerror(res));
+ return;
+ }
+ return; /* ok, data should be accepted again */
+ }
+ }
+ void write_burst(u_char *data, size_t count)
+ {
+ ssize_t r;
+ while(count > 0) {
+ r = snd_pcm_writei(handle, data, count);
+ if (r == -EAGAIN || (r >=0 && r < count)) {
+ snd_pcm_wait(handle, 1000);
+ } else if (r == -EPIPE) {
+ xrun();
+ }
+ if (r > 0) {
+ count -= r;
+ data += r * 4;
+ }
+ }
+ }
+
+ void write_pause_burst(int error)
+ {
+ 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, BURST_SIZE - 96);
+
+ write_burst((u_char *)sbuf, BURST_SIZE / 4);
+ }
+
+ void
+ output_spdif_burst(uint_8 *data_start, uint_8 *data_end)
+ {
+ unsigned short *sbuf = (unsigned short *)buf;
+
+ while(buffer_syncframe(&syncinfo, &data_start, data_end))
+ {
+ sbuf[0] = 0xf872; //spdif syncword
+ sbuf[1] = 0x4e1f; // .............
+ sbuf[2] = 0x0001; // AC3 data
+ sbuf[3] = syncinfo.frame_size * 16;
+ sbuf[4] = 0x0b77; // AC3 syncword
+
+ // extract_ac3 seems to write swabbed data
+ swab(&buf[10], &buf[10], syncinfo.frame_size * 2 - 2);
+ #ifdef DEBUG
+ if (bla2)
+ fwrite(buf, BURST_SIZE, 1, bla2);
+ #endif
+
+ // Write out the frame to S/PDIF
+ write_burst(buf, BURST_SIZE / 4);
+
+
+ }
+ }
+
+ uint_32
+ spdif_init(int acard, int adevice)
+ {
+ //char *pcm_name = "hw:0,2"; /* first card second device */
+ char pcm_name[255];
+ static snd_aes_iec958_t spdif;
+ snd_pcm_info_t *info;
+ snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
+ unsigned int channels = 2;
+ unsigned int rate = 48000;
+ int err, c;
+
+ if (err = snprintf(&pcm_name[0], 11, "hw:%1d,%1d", acard, adevice) <= 0)
+ {
+ return 1;
+ }
+
+ if ((err = snd_pcm_open(&handle, pcm_name, stream, 0)) < 0)
+ {
+ fprintf(stderr, "open: %s\n", snd_strerror(err));
+ return 1;
+ }
+
+ snd_pcm_info_alloca(&info);
+
+ if ((err = snd_pcm_info(handle, info)) < 0) {
+ fprintf(stderr, "info: %s\n", snd_strerror(err));
+ snd_pcm_close(handle);
+ return 1;
+ }
+ printf("device: %d, subdevice: %d\n", snd_pcm_info_get_device(info),
+ snd_pcm_info_get_subdevice(info));
+ {
+ snd_ctl_elem_value_t *ctl;
+ snd_ctl_t *ctl_handle;
+ char ctl_name[12];
+ int ctl_card;
+
+ spdif.status[0] = IEC958_AES0_NONAUDIO |
+ IEC958_AES0_CON_EMPHASIS_NONE;
+ spdif.status[1] = IEC958_AES1_CON_ORIGINAL |
+ IEC958_AES1_CON_PCM_CODER;
+ spdif.status[2] = 0;
+ spdif.status[3] = IEC958_AES3_CON_FS_48000;
+
+ snd_ctl_elem_value_alloca(&ctl);
+ snd_ctl_elem_value_set_interface(ctl, SND_CTL_ELEM_IFACE_PCM);
+ snd_ctl_elem_value_set_device(ctl, snd_pcm_info_get_device(info));
+ snd_ctl_elem_value_set_subdevice(ctl, snd_pcm_info_get_subdevice(info));
+ snd_ctl_elem_value_set_name(ctl, SND_CTL_NAME_IEC958("", PLAYBACK,PCM_STREAM));
+ snd_ctl_elem_value_set_iec958(ctl, &spdif);
+ ctl_card = snd_pcm_info_get_card(info);
+ if (ctl_card < 0) {
+ fprintf(stderr, "Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card");
+ goto __diga_end;
+ }
+ sprintf(ctl_name, "hw:%d", ctl_card);
+ printf("hw:%d\n", ctl_card);
+ if ((err = snd_ctl_open(&ctl_handle, ctl_name, 0)) < 0) {
+ fprintf(stderr, "Unable to open the control interface '%s': %s", ctl_name, snd_strerror(err));
+ goto __diga_end;
+ }
+ if ((err = snd_ctl_elem_write(ctl_handle, ctl)) < 0) {
+ fprintf(stderr, "Unable to update the IEC958 control: %s", snd_strerror(err));
+ goto __diga_end;
+ }
+ snd_ctl_close(ctl_handle);
+ __diga_end:
+
+ }
+ #ifdef DEBUG
+ bla2 = fopen("/tmp/ac3dump", "w");
+ #endif
+
+ {
+ snd_pcm_hw_params_t *params;
+ snd_pcm_sw_params_t *swparams;
+
+ snd_pcm_hw_params_alloca(¶ms);
+ snd_pcm_sw_params_alloca(&swparams);
+
+ err = snd_pcm_hw_params_any(handle, params);
+ if (err < 0) {
+ fprintf(stderr, "Broken configuration for this PCM: no configurations available");
+ return 2;
+ }
+ err = snd_pcm_hw_params_set_access(handle, params,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+ if (err < 0) {
+ fprintf(stderr, "Access tyep not available");
+ return 2;
+ }
+ err = snd_pcm_hw_params_set_format(handle, params, format);
+
+ if (err < 0) {
+ fprintf(stderr, "Sample format non available");
+ return 2;
+ }
+
+ err = snd_pcm_hw_params_set_channels(handle, params, channels);
+
+ if (err < 0) {
+ fprintf(stderr, "Channels count non avaible");
+ return 2;
+ }
+
+ err = snd_pcm_hw_params_set_rate_near(handle, params, rate, 0); assert(err >= 0);
+
+ //err = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size);
+
+ snd_output_stdio_attach(&log, stderr, 0);
+
+ err = snd_pcm_hw_params(handle, params);
+
+ if (err < 0) {
+ fprintf(stderr, "Cannot set buffer size\n");
+ snd_pcm_hw_params_dump(params, log);
+ return 2;
+ }
+ snd_pcm_sw_params_current(handle, swparams);
+ #ifdef DEBUG
+ snd_pcm_sw_params_dump(swparams, log);
+ snd_pcm_dump(handle, log);
+ #endif
+ }
+ memset(buf, 0, sizeof(buf));
+
+ // Send some trailing zeros to avoid misdetecting the
+ // first frame as PCM (works for DTT2500 at least)
+ for (c=0; c < 0; c++) {
+ write_pause_burst(0);
+ }
+ return 0;
+ }
+
+ void spdif_close()
+ {
+ // Cleanup
+ snd_pcm_close(handle);
+ #ifdef DEBUG
+ if (bla2)
+ fclose(bla2);
+ #endif
+ }
diff -Ncr ac3play-0.3.0/ac3burst.h /home/deng/ac3play-0.3.0/ac3burst.h
*** ac3play-0.3.0/ac3burst.h Wed Dec 31 19:00:00 1969
--- /home/deng/ac3play-0.3.0/ac3burst.h Wed Jan 24 20:44:36 2001
***************
*** 0 ****
--- 1,5 ----
+ uint_32 buffer_syncframe(syncinfo_t*, uint_8 **, uint_8 *);
+ void output_spdif_burst(uint_8 *, uint_8 *);
+ void write_paust_burst(int);
+ uint_32 spdif_init(int acard, int adevice);
+ void spdif_close(void);
diff -Ncr ac3play-0.3.0/ac3play.c /home/deng/ac3play-0.3.0/ac3play.c
*** ac3play-0.3.0/ac3play.c Mon Jun 5 01:54:36 2000
--- /home/deng/ac3play-0.3.0/ac3play.c Wed Jan 24 20:44:36 2001
***************
*** 21,31 ****
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ac3.h>
#include <ac3_internal.h>
! #include "ac3_pack.h"
#define AC3_BLOCK_SIZE 2048
static char inbuf[AC3_BLOCK_SIZE];
--- 21,34 ----
*/
#include <stdio.h>
+ #include <fcntl.h>
#include <string.h>
+ #include <errno.h>
+ #include <unistd.h>
#include <stdlib.h>
#include <ac3.h>
#include <ac3_internal.h>
! #include "ac3burst.h"
#define AC3_BLOCK_SIZE 2048
static char inbuf[AC3_BLOCK_SIZE];
***************
*** 33,39 ****
int main(int argc, char *argv[])
{
! FILE *bla;
int val,need_swab = 1;
int old_rate = -1;
int arg_file = 1; // Default location of filename
--- 36,42 ----
int main(int argc, char *argv[])
{
! FILE* bla;
int val,need_swab = 1;
int old_rate = -1;
int arg_file = 1; // Default location of filename
***************
*** 67,86 ****
bla = stdin;
} else
bla = fopen(argv[arg_file], "r");
! if (!bla) {
fprintf(stderr, "Invalid file\n");
return 1;
}
! if (spdif_init(acard, adevice) != 0)
fprintf(stderr, "error openning digital output\n");
// Read the whole file
while((bytes_read = fread(inbuf, 1, AC3_BLOCK_SIZE, bla)) == AC3_BLOCK_SIZE)
{
! output_spdif_pack(inbuf, inbuf + AC3_BLOCK_SIZE);
!
}
// cleanup
--- 70,90 ----
bla = stdin;
} else
bla = fopen(argv[arg_file], "r");
! if (bla < 0) {
fprintf(stderr, "Invalid file\n");
return 1;
}
! if (spdif_init(acard, adevice) != 0) {
fprintf(stderr, "error openning digital output\n");
+ return 1;
+ }
// Read the whole file
while((bytes_read = fread(inbuf, 1, AC3_BLOCK_SIZE, bla)) == AC3_BLOCK_SIZE)
{
! output_spdif_burst(inbuf, inbuf + AC3_BLOCK_SIZE);
}
// cleanup