| /* | |
| * Siren Encoder/Decoder library | |
| * | |
| * @author: Youness Alaoui <kakaroto@kakaroto.homelinux.net> | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Library General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Library General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Library General Public | |
| * License along with this library; if not, write to the | |
| * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, | |
| * Boston, MA 02110-1301, USA. | |
| */ | |
| #include "siren7.h" | |
| SirenDecoder | |
| Siren7_NewDecoder (int sample_rate) | |
| { | |
| SirenDecoder decoder = (SirenDecoder) malloc (sizeof (struct stSirenDecoder)); | |
| decoder->sample_rate = sample_rate; | |
| decoder->WavHeader.riff.RiffId = ME_TO_LE32 (RIFF_ID); | |
| decoder->WavHeader.riff.RiffSize = sizeof (PCMWavHeader) - 2 * sizeof (int); | |
| decoder->WavHeader.riff.RiffSize = | |
| ME_TO_LE32 (decoder->WavHeader.riff.RiffSize); | |
| decoder->WavHeader.WaveId = ME_TO_LE32 (WAVE_ID); | |
| decoder->WavHeader.FmtId = ME_TO_LE32 (FMT__ID); | |
| decoder->WavHeader.FmtSize = ME_TO_LE32 (sizeof (FmtChunk)); | |
| decoder->WavHeader.fmt.Format = ME_TO_LE16 (0x01); | |
| decoder->WavHeader.fmt.Channels = ME_TO_LE16 (1); | |
| decoder->WavHeader.fmt.SampleRate = ME_TO_LE32 (16000); | |
| decoder->WavHeader.fmt.ByteRate = ME_TO_LE32 (32000); | |
| decoder->WavHeader.fmt.BlockAlign = ME_TO_LE16 (2); | |
| decoder->WavHeader.fmt.BitsPerSample = ME_TO_LE16 (16); | |
| decoder->WavHeader.FactId = ME_TO_LE32 (FACT_ID); | |
| decoder->WavHeader.FactSize = ME_TO_LE32 (sizeof (int)); | |
| decoder->WavHeader.Samples = ME_TO_LE32 (0); | |
| decoder->WavHeader.DataId = ME_TO_LE32 (DATA_ID); | |
| decoder->WavHeader.DataSize = ME_TO_LE32 (0); | |
| memset (decoder->context, 0, sizeof (decoder->context)); | |
| memset (decoder->backup_frame, 0, sizeof (decoder->backup_frame)); | |
| decoder->dw1 = 1; | |
| decoder->dw2 = 1; | |
| decoder->dw3 = 1; | |
| decoder->dw4 = 1; | |
| siren_init (); | |
| return decoder; | |
| } | |
| void | |
| Siren7_CloseDecoder (SirenDecoder decoder) | |
| { | |
| free (decoder); | |
| } | |
| int | |
| Siren7_DecodeFrame (SirenDecoder decoder, unsigned char *DataIn, | |
| unsigned char *DataOut) | |
| { | |
| int 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; | |
| int decoded_sample_rate_code; | |
| int absolute_region_power_index[28] = { 0 }; | |
| float decoder_standard_deviation[28] = { 0 }; | |
| int power_categories[28] = { 0 }; | |
| int category_balance[28] = { 0 }; | |
| int ChecksumTable[4] = { 0x7F80, 0x7878, 0x6666, 0x5555 }; | |
| int i, j; | |
| int dwRes = 0; | |
| int envelope_bits = 0; | |
| int rate_control = 0; | |
| int number_of_available_bits; | |
| int number_of_valid_coefs; | |
| int frame_error = 0; | |
| int In[20]; | |
| float coefs[320]; | |
| float BufferOut[320]; | |
| int sum; | |
| int checksum; | |
| int calculated_checksum; | |
| int idx; | |
| int temp1; | |
| int temp2; | |
| for (i = 0; i < 20; i++) | |
| #ifdef __BIG_ENDIAN__ | |
| In[i] = ((short *) DataIn)[i]; | |
| #else | |
| In[i] = | |
| ((((short *) DataIn)[i] << 8) & 0xFF00) | ((((short *) DataIn)[i] >> 8) | |
| & 0x00FF); | |
| #endif | |
| 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); | |
| if (dwRes != 0) | |
| return dwRes; | |
| set_bitstream (In); | |
| decoded_sample_rate_code = 0; | |
| for (i = 0; i < sample_rate_bits; i++) { | |
| decoded_sample_rate_code <<= 1; | |
| decoded_sample_rate_code |= next_bit (); | |
| } | |
| if (decoded_sample_rate_code != sample_rate_code) | |
| return 7; | |
| number_of_valid_coefs = region_size * number_of_regions; | |
| number_of_available_bits = bits_per_frame - sample_rate_bits - checksum_bits; | |
| envelope_bits = | |
| decode_envelope (number_of_regions, decoder_standard_deviation, | |
| absolute_region_power_index, esf_adjustment); | |
| number_of_available_bits -= envelope_bits; | |
| for (i = 0; i < rate_control_bits; i++) { | |
| rate_control <<= 1; | |
| rate_control |= next_bit (); | |
| } | |
| number_of_available_bits -= rate_control_bits; | |
| categorize_regions (number_of_regions, number_of_available_bits, | |
| absolute_region_power_index, power_categories, category_balance); | |
| for (i = 0; i < rate_control; i++) { | |
| power_categories[category_balance[i]]++; | |
| } | |
| number_of_available_bits = | |
| decode_vector (decoder, number_of_regions, number_of_available_bits, | |
| decoder_standard_deviation, power_categories, coefs, scale_factor); | |
| frame_error = 0; | |
| if (number_of_available_bits > 0) { | |
| for (i = 0; i < number_of_available_bits; i++) { | |
| if (next_bit () == 0) | |
| frame_error = 1; | |
| } | |
| } else if (number_of_available_bits < 0 | |
| && rate_control + 1 < rate_control_possibilities) { | |
| frame_error |= 2; | |
| } | |
| for (i = 0; i < number_of_regions; i++) { | |
| if (absolute_region_power_index[i] > 33 | |
| || absolute_region_power_index[i] < -31) | |
| frame_error |= 4; | |
| } | |
| if (checksum_bits > 0) { | |
| bits_per_frame >>= 4; | |
| checksum = In[bits_per_frame - 1] & ((1 << checksum_bits) - 1); | |
| In[bits_per_frame - 1] &= ~checksum; | |
| sum = 0; | |
| idx = 0; | |
| do { | |
| sum ^= (In[idx] & 0xFFFF) << (idx % 15); | |
| } while (++idx < bits_per_frame); | |
| sum = (sum >> 15) ^ (sum & 0x7FFF); | |
| calculated_checksum = 0; | |
| for (i = 0; i < 4; i++) { | |
| temp1 = ChecksumTable[i] & sum; | |
| for (j = 8; j > 0; j >>= 1) { | |
| temp2 = temp1 >> j; | |
| temp1 ^= temp2; | |
| } | |
| calculated_checksum <<= 1; | |
| calculated_checksum |= temp1 & 1; | |
| } | |
| if (checksum != calculated_checksum) | |
| frame_error |= 8; | |
| } | |
| if (frame_error != 0) { | |
| for (i = 0; i < number_of_valid_coefs; i++) { | |
| coefs[i] = decoder->backup_frame[i]; | |
| decoder->backup_frame[i] = 0; | |
| } | |
| } else { | |
| for (i = 0; i < number_of_valid_coefs; i++) | |
| decoder->backup_frame[i] = coefs[i]; | |
| } | |
| for (i = number_of_valid_coefs; i < number_of_coefs; i++) | |
| coefs[i] = 0; | |
| dwRes = siren_rmlt_decode_samples (coefs, decoder->context, 320, BufferOut); | |
| for (i = 0; i < 320; i++) { | |
| if (BufferOut[i] > 32767.0) | |
| ((short *) DataOut)[i] = (short) ME_TO_LE16 ((short) 32767); | |
| else if (BufferOut[i] <= -32768.0) | |
| ((short *) DataOut)[i] = (short) ME_TO_LE16 ((short) 32768); | |
| else | |
| ((short *) DataOut)[i] = (short) ME_TO_LE16 ((short) BufferOut[i]); | |
| } | |
| decoder->WavHeader.Samples = ME_FROM_LE32 (decoder->WavHeader.Samples); | |
| decoder->WavHeader.Samples += 320; | |
| decoder->WavHeader.Samples = ME_TO_LE32 (decoder->WavHeader.Samples); | |
| decoder->WavHeader.DataSize = ME_FROM_LE32 (decoder->WavHeader.DataSize); | |
| decoder->WavHeader.DataSize += 640; | |
| decoder->WavHeader.DataSize = ME_TO_LE32 (decoder->WavHeader.DataSize); | |
| decoder->WavHeader.riff.RiffSize = | |
| ME_FROM_LE32 (decoder->WavHeader.riff.RiffSize); | |
| decoder->WavHeader.riff.RiffSize += 640; | |
| decoder->WavHeader.riff.RiffSize = | |
| ME_TO_LE32 (decoder->WavHeader.riff.RiffSize); | |
| return 0; | |
| } |