1 /*****************************************************************************
2 * ac3_iec958.c: ac3 to spdif converter
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
5 * $Id: ac3_iec958.c,v 1.2 2001/05/01 04:18:18 sam Exp $
7 * Authors: Stéphane Borel <stef@via.ecp.fr>
8 * Juha Yrjola <jyrjola@cc.hut.fi>
9 * German Gomez Garcia <german@piraos.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
24 ****************************************************************************/
26 /****************************************************************************
28 ****************************************************************************/
41 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
43 #include "stream_control.h"
44 #include "input_ext-dec.h"
46 #include "audio_output.h"
48 #include "ac3_spdif.h"
49 #include "ac3_iec958.h"
51 /****************************************************************************
52 * Local structures and tables
53 ****************************************************************************/
54 typedef struct frame_size_s
60 static const frame_size_t p_frame_size_code[64] =
62 { 32 ,{64 ,69 ,96 } },
63 { 32 ,{64 ,70 ,96 } },
64 { 40 ,{80 ,87 ,120 } },
65 { 40 ,{80 ,88 ,120 } },
66 { 48 ,{96 ,104 ,144 } },
67 { 48 ,{96 ,105 ,144 } },
68 { 56 ,{112 ,121 ,168 } },
69 { 56 ,{112 ,122 ,168 } },
70 { 64 ,{128 ,139 ,192 } },
71 { 64 ,{128 ,140 ,192 } },
72 { 80 ,{160 ,174 ,240 } },
73 { 80 ,{160 ,175 ,240 } },
74 { 96 ,{192 ,208 ,288 } },
75 { 96 ,{192 ,209 ,288 } },
76 { 112 ,{224 ,243 ,336 } },
77 { 112 ,{224 ,244 ,336 } },
78 { 128 ,{256 ,278 ,384 } },
79 { 128 ,{256 ,279 ,384 } },
80 { 160 ,{320 ,348 ,480 } },
81 { 160 ,{320 ,349 ,480 } },
82 { 192 ,{384 ,417 ,576 } },
83 { 192 ,{384 ,418 ,576 } },
84 { 224 ,{448 ,487 ,672 } },
85 { 224 ,{448 ,488 ,672 } },
86 { 256 ,{512 ,557 ,768 } },
87 { 256 ,{512 ,558 ,768 } },
88 { 320 ,{640 ,696 ,960 } },
89 { 320 ,{640 ,697 ,960 } },
90 { 384 ,{768 ,835 ,1152 } },
91 { 384 ,{768 ,836 ,1152 } },
92 { 448 ,{896 ,975 ,1344 } },
93 { 448 ,{896 ,976 ,1344 } },
94 { 512 ,{1024 ,1114 ,1536 } },
95 { 512 ,{1024 ,1115 ,1536 } },
96 { 576 ,{1152 ,1253 ,1728 } },
97 { 576 ,{1152 ,1254 ,1728 } },
98 { 640 ,{1280 ,1393 ,1920 } },
99 { 640 ,{1280 ,1394 ,1920 } }
102 /****************************************************************************
103 * ac3_iec958_build_burst: builds an iec958/spdif frame based on an ac3 frame
104 ****************************************************************************/
105 void ac3_iec958_build_burst( ac3_spdif_thread_t *p_spdif )
107 const u8 p_sync[4] = { 0x72, 0xF8, 0x1F, 0x4E };
108 int i_length = p_spdif->ac3_info.i_frame_size;
110 /* Skip the first byte if i_length is odd */
111 u16 * p_in = (u16 *)( p_spdif->p_ac3 + ( i_length & 0x1 ) );
112 u16 * p_out = (u16 *)p_spdif->p_iec;
115 /* Add the spdif headers */
116 memcpy( p_spdif->p_iec, p_sync, 4 );
117 p_spdif->p_iec[4] = i_length ? 0x01 : 0x00;
118 p_spdif->p_iec[5] = 0x00;
119 p_spdif->p_iec[6] = ( i_length * 8 ) & 0xFF;
120 p_spdif->p_iec[7] = ( ( i_length * 8 ) >> 8 ) & 0xFF;
123 swab( p_spdif->p_ac3, p_spdif->p_iec + 8, i_length );
125 /* i_length should be even */
130 *p_out = ( (*p_in & 0x00ff) << 16 ) | ( (*p_in & 0xff00) >> 16 );
137 /* Add zeroes to complete the spdif frame,
138 * they will be ignored by the decoder */
139 memset( p_spdif->p_iec + 8 + i_length, 0, SPDIF_FRAME_SIZE - 8 - i_length );
142 /****************************************************************************
143 * ac3_iec958_parse_syncinfo: parse ac3 sync info
144 ****************************************************************************/
145 int ac3_iec958_parse_syncinfo( ac3_spdif_thread_t *p_spdif )
147 int p_sample_rates[4] = { 48000, 44100, 32000, -1 };
148 int i_frame_rate_code;
149 int i_frame_size_code;
150 sync_frame_t * p_sync_frame;
153 while( ShowBits( &p_spdif->bit_stream, 16 ) != 0xb77 )
155 RemoveBits( &p_spdif->bit_stream, 8 );
158 /* Read sync frame */
159 GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3, sizeof(sync_frame_t) );
160 p_sync_frame = (sync_frame_t*)p_spdif->p_ac3;
162 /* Compute frame rate */
163 i_frame_rate_code = (p_sync_frame->syncinfo.code >> 6) & 0x03;
164 p_spdif->ac3_info.i_sample_rate = p_sample_rates[i_frame_rate_code];
165 if( p_spdif->ac3_info.i_sample_rate == -1 )
170 /* Compute frame size */
171 i_frame_size_code = p_sync_frame->syncinfo.code & 0x3f;
172 p_spdif->ac3_info.i_frame_size = 2 *
173 p_frame_size_code[i_frame_size_code].i_frame_size[i_frame_rate_code];
174 p_spdif->ac3_info.i_bit_rate =
175 p_frame_size_code[i_frame_size_code].i_bit_rate;
177 if( ( ( p_sync_frame->bsi.bsidmod >> 3 ) & 0x1f ) != 0x08 )
182 p_spdif->ac3_info.i_bs_mod = p_sync_frame->bsi.bsidmod & 0x7;