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