c5067f7b8176131484a77c11aef6eaa8822ae5be
[platform/upstream/gstreamer.git] / gst / siren / decoder.c
1 /*\r
2  * Siren Encoder/Decoder library\r
3  *\r
4  *   @author: Youness Alaoui <kakaroto@kakaroto.homelinux.net>\r
5  *\r
6  * This library is free software; you can redistribute it and/or\r
7  * modify it under the terms of the GNU Library General Public\r
8  * License as published by the Free Software Foundation; either\r
9  * version 2 of the License, or (at your option) any later version.\r
10  *\r
11  * This library is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
14  * Library General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU Library General Public\r
17  * License along with this library; if not, write to the\r
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
19  * Boston, MA 02111-1307, USA.\r
20  */\r
21 \r
22 \r
23 #include "siren7.h"\r
24 \r
25 SirenDecoder Siren7_NewDecoder(int sample_rate) {\r
26   SirenDecoder decoder = (SirenDecoder) malloc(sizeof(struct stSirenDecoder));\r
27   decoder->sample_rate = sample_rate;\r
28 \r
29   decoder->WavHeader.riff.RiffId = ME_TO_LE32(RIFF_ID);\r
30   decoder->WavHeader.riff.RiffSize = sizeof(PCMWavHeader) - 2*sizeof(int);\r
31   decoder->WavHeader.riff.RiffSize = ME_TO_LE32(decoder->WavHeader.riff.RiffSize);\r
32   decoder->WavHeader.WaveId = ME_TO_LE32(WAVE_ID);\r
33 \r
34   decoder->WavHeader.FmtId = ME_TO_LE32(FMT__ID);\r
35   decoder->WavHeader.FmtSize = ME_TO_LE32(sizeof(FmtChunk));\r
36 \r
37   decoder->WavHeader.fmt.Format = ME_TO_LE16(0x01);\r
38   decoder->WavHeader.fmt.Channels = ME_TO_LE16(1);\r
39   decoder->WavHeader.fmt.SampleRate = ME_TO_LE32(16000);\r
40   decoder->WavHeader.fmt.ByteRate = ME_TO_LE32(32000);\r
41   decoder->WavHeader.fmt.BlockAlign = ME_TO_LE16(2);\r
42   decoder->WavHeader.fmt.BitsPerSample = ME_TO_LE16(16);\r
43 \r
44   decoder->WavHeader.FactId = ME_TO_LE32(FACT_ID);\r
45   decoder->WavHeader.FactSize = ME_TO_LE32(sizeof(int));\r
46   decoder->WavHeader.Samples = ME_TO_LE32(0);\r
47 \r
48   decoder->WavHeader.DataId = ME_TO_LE32(DATA_ID);\r
49   decoder->WavHeader.DataSize = ME_TO_LE32(0);\r
50 \r
51   memset(decoder->context, 0, sizeof(decoder->context));\r
52   memset(decoder->backup_frame, 0, sizeof(decoder->backup_frame));\r
53 \r
54   decoder->dw1 = 1;\r
55   decoder->dw2 = 1;\r
56   decoder->dw3 = 1;\r
57   decoder->dw4 = 1;\r
58 \r
59   siren_init();\r
60   return decoder;\r
61 }\r
62 \r
63 void Siren7_CloseDecoder(SirenDecoder decoder) {\r
64   free(decoder);\r
65 }\r
66 \r
67 int Siren7_DecodeFrame(SirenDecoder decoder, unsigned char *DataIn, unsigned char *DataOut) {\r
68   int number_of_coefs,\r
69       sample_rate_bits,\r
70       rate_control_bits,\r
71       rate_control_possibilities,\r
72       checksum_bits,\r
73       esf_adjustment,\r
74       scale_factor,\r
75       number_of_regions,\r
76       sample_rate_code,\r
77       bits_per_frame;\r
78   int decoded_sample_rate_code;\r
79 \r
80   static int absolute_region_power_index[28] = {0};\r
81   static float decoder_standard_deviation[28] = {0};\r
82   static int power_categories[28] = {0};\r
83   static int category_balance[28] = {0};\r
84   int ChecksumTable[4] = {0x7F80, 0x7878, 0x6666, 0x5555};\r
85   int i, j;\r
86 \r
87   int dwRes = 0;\r
88   int envelope_bits = 0;\r
89   int rate_control = 0;\r
90   int number_of_available_bits;\r
91   int number_of_valid_coefs;\r
92   int frame_error = 0;\r
93 \r
94   int In[20];\r
95   float coefs[320];\r
96   float BufferOut[320];\r
97   int sum;\r
98   int checksum;\r
99   int calculated_checksum;\r
100   int idx;\r
101   int temp1;\r
102   int temp2;\r
103 \r
104   for (i = 0; i < 20; i++)\r
105 #ifdef __BIG_ENDIAN__\r
106     In[i] = ((short *) DataIn)[i];\r
107 #else\r
108   In[i] = ((((short *) DataIn)[i] << 8) & 0xFF00) | ((((short *) DataIn)[i] >> 8) & 0x00FF);\r
109 #endif\r
110 \r
111   dwRes = GetSirenCodecInfo(1, decoder->sample_rate, &number_of_coefs, &sample_rate_bits, &rate_control_bits, &rate_control_possibilities, &checksum_bits, &esf_adjustment, &scale_factor,  &number_of_regions, &sample_rate_code, &bits_per_frame );\r
112 \r
113   if (dwRes != 0)\r
114     return dwRes;\r
115 \r
116 \r
117   set_bitstream(In);\r
118 \r
119   decoded_sample_rate_code = 0;\r
120   for (i = 0; i < sample_rate_bits; i++) {\r
121     decoded_sample_rate_code <<= 1;\r
122     decoded_sample_rate_code |= next_bit();\r
123   }\r
124 \r
125 \r
126   if (decoded_sample_rate_code != sample_rate_code)\r
127     return 7;\r
128 \r
129   number_of_valid_coefs = region_size * number_of_regions;\r
130   number_of_available_bits = bits_per_frame - sample_rate_bits  - checksum_bits ;\r
131 \r
132 \r
133   envelope_bits = decode_envelope(number_of_regions, decoder_standard_deviation, absolute_region_power_index, esf_adjustment);\r
134 \r
135   number_of_available_bits -= envelope_bits;\r
136 \r
137   for (i = 0; i < rate_control_bits; i++) {\r
138     rate_control <<= 1;\r
139     rate_control |= next_bit();\r
140   }\r
141 \r
142   number_of_available_bits -= rate_control_bits;\r
143 \r
144   categorize_regions(number_of_regions, number_of_available_bits, absolute_region_power_index, power_categories, category_balance);\r
145 \r
146   for (i = 0; i < rate_control; i++) {\r
147     power_categories[category_balance[i]]++;\r
148   }\r
149 \r
150   number_of_available_bits = decode_vector(decoder, number_of_regions, number_of_available_bits, decoder_standard_deviation, power_categories, coefs, scale_factor);\r
151 \r
152 \r
153   frame_error = 0;\r
154   if (number_of_available_bits > 0) {\r
155     for (i = 0; i < number_of_available_bits; i++) {\r
156       if (next_bit() == 0)\r
157         frame_error = 1;\r
158     }\r
159   } else if (number_of_available_bits < 0 && rate_control + 1 < rate_control_possibilities) {\r
160     frame_error |= 2;\r
161   }\r
162 \r
163   for (i = 0; i < number_of_regions; i++) {\r
164     if (absolute_region_power_index[i] > 33 || absolute_region_power_index[i] < -31)\r
165       frame_error |= 4;\r
166   }\r
167 \r
168   if (checksum_bits > 0) {\r
169     bits_per_frame >>= 4;\r
170     checksum = In[bits_per_frame - 1] & ((1 << checksum_bits)  - 1);\r
171     In[bits_per_frame - 1] &= ~checksum;\r
172     sum = 0;\r
173     idx = 0;\r
174     do {\r
175       sum ^= (In[idx] & 0xFFFF) << (idx % 15);\r
176     } while (++idx < bits_per_frame);\r
177 \r
178     sum = (sum >> 15) ^ (sum & 0x7FFF);\r
179     calculated_checksum = 0;\r
180     for (i = 0; i < 4; i++) {\r
181       temp1 = ChecksumTable[i] & sum;\r
182       for (j = 8; j > 0; j >>= 1) {\r
183         temp2 = temp1 >> j;\r
184         temp1 ^= temp2;\r
185       }\r
186       calculated_checksum <<= 1;\r
187       calculated_checksum |= temp1 & 1;\r
188     }\r
189 \r
190     if (checksum != calculated_checksum)\r
191       frame_error |= 8;\r
192   }\r
193 \r
194   if (frame_error  != 0) {\r
195     for (i = 0; i < number_of_valid_coefs; i++) {\r
196       coefs[i] = decoder->backup_frame[i];\r
197       decoder->backup_frame[i] = 0;\r
198     }\r
199   } else {\r
200     for (i = 0; i < number_of_valid_coefs; i++)\r
201       decoder->backup_frame[i] = coefs[i];\r
202   }\r
203 \r
204 \r
205   for (i = number_of_valid_coefs; i < number_of_coefs; i++)\r
206     coefs[i] = 0;\r
207 \r
208 \r
209   dwRes = siren_rmlt_decode_samples(coefs, decoder->context, 320, BufferOut);\r
210 \r
211 \r
212   for (i = 0; i < 320; i++) {\r
213     if (BufferOut[i] > 32767.0)\r
214       ((short *)DataOut)[i] =  (short) ME_TO_LE16((short) 32767);\r
215     else if (BufferOut[i] <= -32768.0)\r
216       ((short *)DataOut)[i] =  (short) ME_TO_LE16((short) 32768);\r
217     else\r
218       ((short *)DataOut)[i] = (short) ME_TO_LE16((short) BufferOut[i]);\r
219   }\r
220 \r
221   decoder->WavHeader.Samples = ME_FROM_LE32(decoder->WavHeader.Samples);\r
222   decoder->WavHeader.Samples += 320;\r
223   decoder->WavHeader.Samples = ME_TO_LE32(decoder->WavHeader.Samples);\r
224   decoder->WavHeader.DataSize = ME_FROM_LE32(decoder->WavHeader.DataSize);\r
225   decoder->WavHeader.DataSize += 640;\r
226   decoder->WavHeader.DataSize = ME_TO_LE32(decoder->WavHeader.DataSize);\r
227   decoder->WavHeader.riff.RiffSize = ME_FROM_LE32(decoder->WavHeader.riff.RiffSize);\r
228   decoder->WavHeader.riff.RiffSize += 640;\r
229   decoder->WavHeader.riff.RiffSize = ME_TO_LE32(decoder->WavHeader.riff.RiffSize);\r
230 \r
231 \r
232   return 0;\r
233 }\r
234 \r