]> git.sesse.net Git - vlc/blob - src/ac3_spdif/ac3_iec958.c
* Fixed a few warnings with gcc 3.0.
[vlc] / src / ac3_spdif / ac3_iec958.c
1 /*****************************************************************************
2  * ac3_iec958.c: ac3 to spdif converter
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: ac3_iec958.c,v 1.3 2001/05/06 04:32:02 sam Exp $
6  *
7  * Authors: Stéphane Borel <stef@via.ecp.fr>
8  *          Juha Yrjola <jyrjola@cc.hut.fi>
9  *          German Gomez Garcia <german@piraos.com>
10  *
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.
15  * 
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.
20  *
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  ****************************************************************************/
25
26 /****************************************************************************
27  * Preamble
28  ****************************************************************************/
29 #include "defs.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>                                              /* memset() */
34 #include <fcntl.h>
35 #include <unistd.h>
36
37 #include "config.h"
38 #include "common.h"
39 #include "threads.h"
40 #include "mtime.h"
41
42 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
43
44 #include "stream_control.h"
45 #include "input_ext-dec.h"
46
47 #include "audio_output.h"
48
49 #include "ac3_spdif.h"
50 #include "ac3_iec958.h"
51
52 /****************************************************************************
53  * Local structures and tables
54  ****************************************************************************/
55 typedef struct frame_size_s
56 {
57     u16     i_bit_rate;
58     u16     i_frame_size[3];
59 } frame_size_t;
60                 
61 static const frame_size_t p_frame_size_code[64] =
62 {
63         { 32  ,{64   ,69   ,96   } },
64         { 32  ,{64   ,70   ,96   } },
65         { 40  ,{80   ,87   ,120  } },
66         { 40  ,{80   ,88   ,120  } },
67         { 48  ,{96   ,104  ,144  } },
68         { 48  ,{96   ,105  ,144  } },
69         { 56  ,{112  ,121  ,168  } },
70         { 56  ,{112  ,122  ,168  } },
71         { 64  ,{128  ,139  ,192  } },
72         { 64  ,{128  ,140  ,192  } },
73         { 80  ,{160  ,174  ,240  } },
74         { 80  ,{160  ,175  ,240  } },
75         { 96  ,{192  ,208  ,288  } },
76         { 96  ,{192  ,209  ,288  } },
77         { 112 ,{224  ,243  ,336  } },
78         { 112 ,{224  ,244  ,336  } },
79         { 128 ,{256  ,278  ,384  } },
80         { 128 ,{256  ,279  ,384  } },
81         { 160 ,{320  ,348  ,480  } },
82         { 160 ,{320  ,349  ,480  } },
83         { 192 ,{384  ,417  ,576  } },
84         { 192 ,{384  ,418  ,576  } },
85         { 224 ,{448  ,487  ,672  } },
86         { 224 ,{448  ,488  ,672  } },
87         { 256 ,{512  ,557  ,768  } },
88         { 256 ,{512  ,558  ,768  } },
89         { 320 ,{640  ,696  ,960  } },
90         { 320 ,{640  ,697  ,960  } },
91         { 384 ,{768  ,835  ,1152 } },
92         { 384 ,{768  ,836  ,1152 } },
93         { 448 ,{896  ,975  ,1344 } },
94         { 448 ,{896  ,976  ,1344 } },
95         { 512 ,{1024 ,1114 ,1536 } },
96         { 512 ,{1024 ,1115 ,1536 } },
97         { 576 ,{1152 ,1253 ,1728 } },
98         { 576 ,{1152 ,1254 ,1728 } },
99         { 640 ,{1280 ,1393 ,1920 } },
100         { 640 ,{1280 ,1394 ,1920 } }
101 };
102
103 /****************************************************************************
104  * ac3_iec958_build_burst: builds an iec958/spdif frame based on an ac3 frame
105  ****************************************************************************/
106 void ac3_iec958_build_burst( ac3_spdif_thread_t *p_spdif )
107 {
108     const u8 p_sync[4] = { 0x72, 0xF8, 0x1F, 0x4E };
109     int      i_length  = p_spdif->ac3_info.i_frame_size;
110 #ifndef HAVE_SWAB
111     /* Skip the first byte if i_length is odd */
112     u16 * p_in  = (u16 *)( p_spdif->p_ac3 + ( i_length & 0x1 ) );
113     u16 * p_out = (u16 *)p_spdif->p_iec;
114 #endif
115
116     /* Add the spdif headers */
117     memcpy( p_spdif->p_iec, p_sync, 4 );
118     p_spdif->p_iec[4] = i_length ? 0x01 : 0x00;
119     p_spdif->p_iec[5] = 0x00;
120     p_spdif->p_iec[6] = ( i_length * 8 ) & 0xFF;
121     p_spdif->p_iec[7] = ( ( i_length * 8 ) >> 8 ) & 0xFF;
122
123 #ifdef HAVE_SWAB
124     swab( p_spdif->p_ac3, p_spdif->p_iec + 8, i_length );
125 #else
126     /* i_length should be even */
127     i_length &= ~0x1;
128
129     while( i_length )
130     {
131         *p_out = ( (*p_in & 0x00ff) << 16 ) | ( (*p_in & 0xff00) >> 16 );
132         p_in++;
133         p_out++;
134         i_length -= 2;
135     }
136 #endif
137
138     /* Add zeroes to complete the spdif frame,
139      * they will be ignored by the decoder */
140     memset( p_spdif->p_iec + 8 + i_length, 0, SPDIF_FRAME_SIZE - 8 - i_length );
141 }
142
143 /****************************************************************************
144  * ac3_iec958_parse_syncinfo: parse ac3 sync info
145  ****************************************************************************/
146 int ac3_iec958_parse_syncinfo( ac3_spdif_thread_t *p_spdif )
147 {
148     int             p_sample_rates[4] = { 48000, 44100, 32000, -1 };
149     int             i_frame_rate_code;
150     int             i_frame_size_code;
151     sync_frame_t *  p_sync_frame;
152
153     /* Find sync word */
154     while( ShowBits( &p_spdif->bit_stream, 16 ) != 0xb77 )
155     {
156         RemoveBits( &p_spdif->bit_stream, 8 );
157     }
158
159     /* Read sync frame */
160     GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3, sizeof(sync_frame_t) );
161     p_sync_frame = (sync_frame_t*)p_spdif->p_ac3;
162
163     /* Compute frame rate */
164     i_frame_rate_code = (p_sync_frame->syncinfo.code >> 6) & 0x03;
165     p_spdif->ac3_info.i_sample_rate = p_sample_rates[i_frame_rate_code];
166     if( p_spdif->ac3_info.i_sample_rate == -1 )
167     {
168         return -1;
169     }
170
171     /* Compute frame size */
172     i_frame_size_code = p_sync_frame->syncinfo.code & 0x3f;
173     p_spdif->ac3_info.i_frame_size = 2 *
174         p_frame_size_code[i_frame_size_code].i_frame_size[i_frame_rate_code];
175     p_spdif->ac3_info.i_bit_rate =
176         p_frame_size_code[i_frame_size_code].i_bit_rate;
177
178     if( ( ( p_sync_frame->bsi.bsidmod >> 3 ) & 0x1f ) != 0x08 )
179     {
180         return -1;
181     }
182
183     p_spdif->ac3_info.i_bs_mod = p_sync_frame->bsi.bsidmod & 0x7;
184
185     return 0;
186 }
187