/***************************************************************************/ /* This code has been fully inspired from various place */ /* I will give their name later. May they be bless .... It works */ /* */ /* For the moment test it. */ /* */ /* 27-08-00 -- Ze'ev Maor -- fixed recovery from flase syncword detection */ /* */ /* 24-08-00 -- Ze'ev Maor -- Modified for integrtion with DXR3-OMS-plugin */ /***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "output.h" void swab(const void*, void*, size_t); #define BLOCK_SIZE 6144 static unsigned char buf[BLOCK_SIZE]; static uint32_t sbuffer_size; static syncinfo_t syncinfo; static char *sbuffer; static int done_banner; static uint32_t buffer_syncframe(syncinfo_t *syncinfo, uint8_t **start, uint8_t *end) { uint8_t *cur = *start; uint16_t syncword = syncinfo->syncword; uint32_t 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_data(syncinfo,sbuffer); while(sbuffer_size < (uint32_t)syncinfo->frame_size * 2 - 2) { if(cur >= end) goto done; sbuffer[sbuffer_size++] = *cur++; } 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; bzero(buf,BLOCK_SIZE); goto done; } // //if we got to this point, we found a valid ac3 frame to decode // //reset the syncword for next time syncword = 0xffff; sbuffer_size = 0; ret = 1; done: syncinfo->syncword = syncword; *start = cur; return ret; } void init_spdif(void) { sbuffer_size = 0; sbuffer = &buf[10]; done_banner = 0; } int output_spdif_zero(int frames) { int res; buf[0] = 0x72; buf[1] = 0xf8; // spdif syncword buf[2] = 0x1f; buf[3] = 0x4e; // .............. buf[4] = 0x00; // null frame (no data) buf[5] = 7 << 5; // stream = 7 buf[6] = 0x00; buf[7] = 0x00; // frame size memset(&buf[8], 0, BLOCK_SIZE - 8); while (frames-- > 0) { res = output_play((short *)buf, BLOCK_SIZE / 2 / 2); /* 2 channels, 16-bit samples */ if (res < 0) return res; } return 0; } int output_spdif_leadin(void) { memset(buf, 0, 8); return output_play((short *)buf, 8); } int output_spdif(uint8_t *data_start, uint8_t *data_end, int quiet) { int ret = 0, res; while(buffer_syncframe(&syncinfo, &data_start, data_end)) { buf[0] = 0x72; buf[1] = 0xf8; // spdif syncword buf[2] = 0x1f; buf[3] = 0x4e; // .............. buf[4] = 0x01; // AC3 data buf[5] = buf[13] & 7; // bsmod, stream = 0 buf[6] = (syncinfo.frame_size * 16) & 0xff; buf[7] = ((syncinfo.frame_size * 16) >> 8) & 0xff; buf[8] = 0x77; buf[9] = 0x0b; // AC3 syncwork if (!done_banner && !quiet) { fprintf(stdout,"AC3 Stream "); fprintf(stdout,"%2.1f KHz",syncinfo.sampling_rate * 1e-3); fprintf(stdout,"%4d kbps",syncinfo.bit_rate); fprintf(stdout,"\n"); done_banner = 1; } #ifndef _a_b_c_d_e_f /* WORDS_BIGENDIAN */ // extract_ac3 seems to write swabbed data swab(&buf[10], &buf[10], syncinfo.frame_size * 2 - 2); #endif res = output_play((short *)buf, BLOCK_SIZE / 2 / 2); /* 2 channels, 16-bit samples */ ret = ret < 0 ? ret : res; bzero(buf,BLOCK_SIZE); } return ret; }