1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the License.html file in the root of the source tree.
5 */
6
7 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 //
9 // Information about OpenMG (OMA) files
10 //
11 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12
13 //---------------------------------------------------------------------------
14 // Pre-compilation
15 #include "MediaInfo/PreComp.h"
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19 //---------------------------------------------------------------------------
20
21 //---------------------------------------------------------------------------
22 #include "MediaInfo/Setup.h"
23 //---------------------------------------------------------------------------
24
25 //---------------------------------------------------------------------------
26 #if defined(MEDIAINFO_OPENMG_YES)
27 //---------------------------------------------------------------------------
28
29 //---------------------------------------------------------------------------
30 #include "MediaInfo/Audio/File_OpenMG.h"
31 //---------------------------------------------------------------------------
32
33 namespace MediaInfoLib
34 {
35
36 //***************************************************************************
37 // Info
38 //***************************************************************************
39
40 //---------------------------------------------------------------------------
OpenMG_CodecID_Format(int8u CodecID)41 static const char* OpenMG_CodecID_Format (int8u CodecID)
42 {
43 switch (CodecID)
44 {
45 case 0 :
46 case 1 :
47 return "Atrac3";
48 case 3 : return "MPEG Audio";
49 case 4 : return "PCM";
50 case 5 : return "WMA";
51 default : return "";
52 }
53 }
54
55 //---------------------------------------------------------------------------
OpenMG_CodecID_Encryption(int8u CodecID)56 static const char* OpenMG_CodecID_Encryption (int8u CodecID)
57 {
58 switch (CodecID)
59 {
60 case 1 : return "SDMI";
61 default : return "";
62 }
63 }
64
65 //---------------------------------------------------------------------------
OpenMG_SamplingRate(int8u SamplingRate_Code)66 static int32u OpenMG_SamplingRate (int8u SamplingRate_Code)
67 {
68 switch (SamplingRate_Code)
69 {
70 case 0 : return 32000;
71 case 1 : return 44100;
72 case 2 : return 44800;
73 case 3 : return 88200;
74 case 4 : return 96000;
75 default : return 0;
76 }
77 }
78
79 //---------------------------------------------------------------------------
OpenMG_Channels(int8u Channels_Code)80 static int8u OpenMG_Channels (int8u Channels_Code)
81 {
82 if (Channels_Code<=4)
83 return Channels_Code;
84 else
85 return Channels_Code+1; //+LFE
86 }
87
88 //---------------------------------------------------------------------------
OpenMG_ChannelPositions(int8u Channels_Code)89 static const char* OpenMG_ChannelPositions (int8u Channels_Code)
90 {
91 switch (Channels_Code)
92 {
93 case 1 : return "Front: C";
94 case 2 : return "Front: L R";
95 case 3 : return "Front: L R, Side: C";
96 case 4 : return "Front: L R, Back: L R";
97 case 5 : return "Front: L C R, Side: L R, LFE";
98 case 6 : return "Front: L C R, Side: L R, Back: C, LFE";
99 case 7 : return "Front: L C R, Side: L R, Back: L R, LFE";
100 default : return "";
101 }
102 }
103
104 //---------------------------------------------------------------------------
OpenMG_ChannelLayout(int8u Channels_Code)105 static const char* OpenMG_ChannelLayout (int8u Channels_Code)
106 {
107 switch (Channels_Code)
108 {
109 case 1 : return "C";
110 case 2 : return "L R";
111 case 3 : return "L R S";
112 case 4 : return "L R BL BR";
113 case 5 : return "L R C SL SR LFE";
114 case 6 : return "L R C SL SR BC LFE";
115 case 7 : return "L R C SL SR BL BR LFE";
116 default : return "";
117 }
118 }
119
120 //***************************************************************************
121 // Constructor/Destructor
122 //***************************************************************************
123
124 //---------------------------------------------------------------------------
File_OpenMG()125 File_OpenMG::File_OpenMG()
126 {
127 //File__Tags_Helper
128 Base=this;
129
130 //Config
131 #if MEDIAINFO_TRACE
132 Trace_Layers_Update(8); //Stream
133 #endif //MEDIAINFO_TRACE
134 StreamSource=IsStream;
135 }
136
137 //***************************************************************************
138 // Streams management
139 //***************************************************************************
140
141 //---------------------------------------------------------------------------
Streams_Fill()142 void File_OpenMG::Streams_Fill()
143 {
144 Fill(Stream_General, 0, General_Format, "OpenMG");
145
146 File__Tags_Helper::Stream_Prepare(Stream_Audio);
147
148 File__Tags_Helper::Streams_Fill();
149 }
150
151 //***************************************************************************
152 // Buffer - File header
153 //***************************************************************************
154
155 //---------------------------------------------------------------------------
FileHeader_Begin()156 bool File_OpenMG::FileHeader_Begin()
157 {
158 if (!File__Tags_Helper::FileHeader_Begin())
159 return false;
160
161 //Synchro
162 if (Buffer_Offset+3>Buffer_Size)
163 return false;
164
165 // Testing
166 if (Buffer[Buffer_Offset ]!=0x45 // "EA3"
167 || Buffer[Buffer_Offset+1]!=0x41
168 || Buffer[Buffer_Offset+2]!=0x33)
169 {
170 File__Tags_Helper::Reject();
171 return false;
172 }
173
174 return true;
175 }
176
177 //---------------------------------------------------------------------------
FileHeader_Parse()178 void File_OpenMG::FileHeader_Parse()
179 {
180 //Parsing
181 int16u Size, FrameSize=0;
182 int8u Flags, CodecID, SamplingRate_Code=0, Channels_Code=0;
183 bool JointStereo=false;
184 Skip_C3( "Code");
185 Get_B1 (Flags, "Flags");
186 Get_B2 (Size, "Size");
187 Skip_XX(26, "Unknown");
188 Get_B1 (CodecID, "Coded ID"); Param_Info1(OpenMG_CodecID_Format(CodecID));
189 if (CodecID<=1) //Atrac3
190 {
191 BS_Begin();
192 Skip_S1(7, "Unknown");
193 Get_SB ( JointStereo, "Joint Stereo");
194 Get_S1 (3, SamplingRate_Code, "Sampling Rate"); Param_Info2(OpenMG_SamplingRate(SamplingRate_Code), " Hz");
195 Get_S1 (3, Channels_Code, "Channels"); Param_Info2(OpenMG_Channels(Channels_Code), " channel(s)");
196 Get_S2 (10, FrameSize, "Frame size");
197 BS_End();
198 }
199 Skip_XX(Size-Element_Offset, "Unknown");
200
201 FILLING_BEGIN();
202 if (!Status[IsAccepted])
203 {
204 File__Tags_Helper::Accept();
205
206 Fill(Stream_Audio, 0, Audio_Format, OpenMG_CodecID_Format(CodecID));
207 Fill(Stream_Audio, 0, Audio_Encryption, OpenMG_CodecID_Encryption(CodecID));
208 int64u StreamSize=(int64u)-1;
209 if (File_Size!=(int64u)-1)
210 {
211 StreamSize=File_Size-(Buffer_Offset+Element_Size);
212 Fill(Stream_Audio, 0, Audio_StreamSize, StreamSize);
213 }
214 if (CodecID<=1) // Atrac3
215 {
216 Fill(Stream_Audio, 0, Audio_Channel_s_, OpenMG_Channels(Channels_Code));
217 Fill(Stream_Audio, 0, Audio_ChannelPositions, OpenMG_ChannelPositions(Channels_Code));
218 Fill(Stream_Audio, 0, Audio_ChannelLayout, OpenMG_ChannelLayout(Channels_Code));
219 if (Channels_Code==1 && JointStereo)
220 Fill(Stream_Audio, 0, Audio_Format_Settings_Mode, "Joint Stereo");
221 Fill(Stream_Audio, 0, Audio_SamplingRate, OpenMG_SamplingRate(SamplingRate_Code));
222
223 if (CodecID==1) //Protected
224 FrameSize++; //Not sure
225 FrameSize<<=3; //8-byte blocks
226 int64u BitRate=OpenMG_SamplingRate(SamplingRate_Code)*FrameSize/256;
227 Fill(Stream_Audio, 0, Audio_BitRate, BitRate);
228 if (StreamSize!=(int64u)-1 && BitRate)
229 Fill(Stream_Audio, 0, Audio_Duration, StreamSize*8*1000/BitRate);
230 }
231 }
232 FILLING_END();
233 }
234
235 //***************************************************************************
236 // Buffer - Global
237 //***************************************************************************
238
239 //---------------------------------------------------------------------------
Read_Buffer_Continue()240 void File_OpenMG::Read_Buffer_Continue()
241 {
242 //Parsing
243 Skip_XX(File_Size-Buffer_Offset, "Data");
244
245 File__Analyze::Finish();
246 }
247
248 } //NameSpace
249
250 #endif
251