// AudioDecoderSimple.cpp: Audio decoding using "simple" internal decoders. // // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 // Free Software Foundation, Inc. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include "AudioDecoderSimple.h" #include "AudioResampler.h" #include "BitsReader.h" #include "SoundInfo.h" #include "MediaParser.h" // for AudioInfo definition.. #include "GnashNumeric.h" // for clamp #include "log.h" #include // for std::swap namespace gnash { namespace media { // ---------------------------------------------------------------------------- // ADPCMDecoder class // ---------------------------------------------------------------------------- /// ADPCM decoder utilities // /// Algo from http://www.circuitcellar.com/pastissues/articles/richey110/text.htm /// And also Jansen. /// Here's another reference: http://www.geocities.com/SiliconValley/8682/aud3.txt /// Original IMA spec doesn't seem to be on the web :( /// /// TODO: move in it's own file /// class ADPCMDecoder { private: // Data from Alexis' SWF reference static int _index_update_table_2bits[2]; static int _index_update_table_3bits[4]; static int _index_update_table_4bits[8]; static int _index_update_table_5bits[16]; static int* s_index_update_tables[4]; // Data from Jansen. http://homepages.cwi.nl/~jack/ // Check out his Dutch retro punk songs, heh heh :) static const int STEPSIZE_CT = 89; static int s_stepsize[STEPSIZE_CT]; static void doSample(int n_bits, int& sample, int& stepsize_index, int raw_code) { assert(raw_code >= 0 && raw_code < (1 << n_bits)); static const int HI_BIT = (1 << (n_bits - 1)); int* index_update_table = s_index_update_tables[n_bits - 2]; /* Core of ADPCM. */ int code_mag = raw_code & (HI_BIT - 1); bool code_sign_bit = (raw_code & HI_BIT) ? 1 : 0; int mag = (code_mag << 1) + 1; /* shift in LSB (they do this so that pos & neg zero are different)*/ int stepsize = s_stepsize[stepsize_index]; /* Compute the new sample. It's the predicted value */ /* (i.e. the previous value), plus a delta. The delta */ /* comes from the code times the stepsize. going for */ /* something like: delta = stepsize * (code * 2 + 1) >> code_bits */ int delta = (stepsize * mag) >> (n_bits - 1); if (code_sign_bit) delta = -delta; sample += delta; sample = clamp(sample, -32768, 32767); /* Update our stepsize index. Use a lookup table. */ stepsize_index += index_update_table[code_mag]; stepsize_index = clamp(stepsize_index, 0, STEPSIZE_CT - 1); } /* Uncompress 4096 mono samples of ADPCM. */ static std::uint32_t doMonoBlock(std::int16_t** out_data, int n_bits, BitsReader& in, int sample, int stepsize_index) { /* First sample doesn't need to be decompressed. */ std::uint32_t sample_count = 1; *(*out_data)++ = (std::int16_t) sample; while (sample_count < 4096 && in.gotBits(n_bits)) { int raw_code = in.read_uint(n_bits); doSample(n_bits, sample, stepsize_index, raw_code); /* sample & stepsize_index are in/out params */ *(*out_data)++ = (std::int16_t) sample; sample_count++; } return sample_count; } /* Uncompress 4096 stereo sample pairs of ADPCM. */ static int doStereoBlock( std::int16_t** out_data, // in/out param int n_bits, BitsReader& in, int left_sample, int left_stepsize_index, int right_sample, int right_stepsize_index ) { /* First samples don't need to be decompressed. */ std::uint32_t sample_count = 2; *(*out_data)++ = (std::int16_t) left_sample; *(*out_data)++ = (std::int16_t) right_sample; unsigned bitsNeeded = n_bits*2; while (sample_count < 4096 && in.gotBits(bitsNeeded)) { int left_raw_code = in.read_uint(n_bits); doSample(n_bits, left_sample, left_stepsize_index, left_raw_code); *(*out_data)++ = (std::int16_t) left_sample; int right_raw_code = in.read_uint(n_bits); doSample(n_bits, right_sample, right_stepsize_index, right_raw_code); *(*out_data)++ = (std::int16_t) right_sample; sample_count++; } return sample_count; } public: // Utility function: uncompress ADPCM data from in BitReader to // out_data[]. Returns the output samplecount. static std::uint32_t adpcm_expand( unsigned char* &data, BitsReader& in, unsigned int insize, bool stereo) { // Read header. if ( ! in.gotBits(2) ) { IF_VERBOSE_MALFORMED_SWF( log_swferror(_("corrupted ADPCM header")); ); return 0; } unsigned int n_bits = in.read_uint(2) + 2; // 2 to 5 bits // The compression ratio is 4:1, so this should be enough... std::int16_t* out_data = new std::int16_t[insize * 5]; data = reinterpret_cast(out_data); std::uint32_t sample_count = 0; while ( in.gotBits(22) ) { // Read initial sample & index values. int sample = in.read_sint(16); int stepsize_index = in.read_uint(6); assert(STEPSIZE_CT >= (1 << 6)); // ensure we don't need to clamp. if (stereo == false) { if (n_bits == 0) { abort(); } else if (n_bits == 2) { sample_count += doMonoBlock(&out_data, 2, in, sample, stepsize_index); } else if (n_bits == 3) { sample_count += doMonoBlock(&out_data, 3, in, sample, stepsize_index); } else if (n_bits == 4) { sample_count += doMonoBlock(&out_data, 4, in, sample, stepsize_index); } else if (n_bits == 5) { sample_count += doMonoBlock(&out_data, 5, in, sample, stepsize_index); } } else { // Stereo. // Got values for left channel; now get initial sample // & index for right channel. int right_sample = in.read_sint(16); int right_stepsize_index = in.read_uint(6); assert(STEPSIZE_CT >= (1 << 6)); // ensure we don't need to clamp. if (n_bits == 0) { abort(); } else if (n_bits == 2) { sample_count += doStereoBlock(&out_data, 2, in, sample, stepsize_index, right_sample, right_stepsize_index); } else if (n_bits == 3) { sample_count += doStereoBlock(&out_data, 3, in, sample, stepsize_index, right_sample, right_stepsize_index); } else if (n_bits == 4) { sample_count += doStereoBlock(&out_data, 4, in, sample, stepsize_index, right_sample, right_stepsize_index); } else if (n_bits == 5) { sample_count += doStereoBlock(&out_data, 5, in, sample, stepsize_index, right_sample, right_stepsize_index); } } } return sample_count; } }; int ADPCMDecoder::_index_update_table_2bits[2] = { -1, 2 }; int ADPCMDecoder::_index_update_table_3bits[4] = { -1, -1, 2, 4 }; int ADPCMDecoder::_index_update_table_4bits[8] = { -1, -1, -1, -1, 2, 4, 6, 8 }; int ADPCMDecoder::_index_update_table_5bits[16] = { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 }; int* ADPCMDecoder::s_index_update_tables[4] = { ADPCMDecoder::_index_update_table_2bits, ADPCMDecoder::_index_update_table_3bits, ADPCMDecoder::_index_update_table_4bits, ADPCMDecoder::_index_update_table_5bits }; int ADPCMDecoder::s_stepsize[STEPSIZE_CT] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; // ---------------------------------------------------------------------------- // END OF ADPCMDecoder class // ---------------------------------------------------------------------------- // // Unsigned 8-bit expansion (128 is silence) // // u8_expand allocates the memory for its "data" pointer. // static void u8_expand(unsigned char * &data, const unsigned char* input, std::uint32_t input_size) // This is also the number of u8bit samples { std::int16_t *out_data = new std::int16_t[input_size]; // Convert 8-bit to 16 const std::uint8_t *inp = input; std::int16_t *outp = out_data; for (unsigned int i = input_size; i>0; i--) { *outp++ = ((std::int16_t)(*inp++) - 128) * 256; } data = (unsigned char *)out_data; } AudioDecoderSimple::AudioDecoderSimple(const AudioInfo& info) : _sampleRate(0), _sampleCount(0), _stereo(false), _is16bit(true) { setup(info); log_debug(_("AudioDecoderSimple: initialized flash codec %s (%d)"), (int)_codec, _codec); } AudioDecoderSimple::AudioDecoderSimple(const SoundInfo& info) : _sampleRate(0), _sampleCount(0), _stereo(false), _is16bit(true) { setup(info); log_debug(_("AudioDecoderSimple: initialized flash codec %s (%d)"), (int)_codec, _codec); } AudioDecoderSimple::~AudioDecoderSimple() { } void AudioDecoderSimple::setup(const SoundInfo& info) { _codec = info.getFormat(); switch (_codec) { case AUDIO_CODEC_ADPCM: case AUDIO_CODEC_RAW: case AUDIO_CODEC_UNCOMPRESSED: _sampleRate = info.getSampleRate(); _sampleCount = info.getSampleCount(); _stereo = info.isStereo(); _is16bit = info.is16bit(); break; default: boost::format err = boost::format( _("AudioDecoderSimple: unsupported flash codec %d (%s)")) % (int)_codec % _codec; throw MediaException(err.str()); } } void AudioDecoderSimple::setup(const AudioInfo& info) { if (info.type != CODEC_TYPE_FLASH) { boost::format err = boost::format( _("AudioDecoderSimple: unable to intepret custom audio codec id %s")) % info.codec; throw MediaException(err.str()); } _codec = static_cast(info.codec); switch (_codec) { case AUDIO_CODEC_ADPCM: case AUDIO_CODEC_RAW: case AUDIO_CODEC_UNCOMPRESSED: _sampleRate = info.sampleRate; _stereo = info.stereo; _is16bit = (info.sampleSize==2); // check this! if ( info.sampleSize > 2 ) // troubles... log_unimpl("Sample size > 2 in %s sound!", _codec); break; default: boost::format err = boost::format( _("AudioDecoderSimple: unsupported flash codec %d (%s)")) % (int)_codec % _codec; throw MediaException(err.str()); } } std::uint8_t* AudioDecoderSimple::decode(const std::uint8_t* input, std::uint32_t inputSize, std::uint32_t& outputSize, std::uint32_t& decodedBytes) { unsigned char* decodedData = nullptr; std::uint32_t outsize = 0; switch (_codec) { case AUDIO_CODEC_ADPCM: { //std::uint32_t sample_count = inputSize * ( _stereo ? 1 : 2 ); //(_sampleCount == 0 ? inputSize / ( _stereo ? 4 : 2 ) : _sampleCount); BitsReader br(input, inputSize); std::uint32_t sample_count = ADPCMDecoder::adpcm_expand(decodedData, br, inputSize, _stereo); outsize = sample_count * (_stereo ? 4 : 2); } break; case AUDIO_CODEC_RAW: if (_is16bit) { // FORMAT_RAW 16-bit is exactly what we want! decodedData = new unsigned char[inputSize]; memcpy(decodedData, input, inputSize); outsize = inputSize; } else { // Convert 8-bit unsigned to 16-bit signed range // Allocate as many shorts as there are samples u8_expand(decodedData, input, inputSize); outsize = inputSize * 2; } break; case AUDIO_CODEC_UNCOMPRESSED: // 8- or 16-bit mono or stereo little-endian audio // Convert to 16-bit host-endian. if (!_is16bit) { // Convert 8-bit unsigned to 16-bit signed range // Allocate as many shorts as there are 8-bit samples u8_expand(decodedData, input, inputSize); outsize = inputSize * 2; } else { // Allocate a destination buffer // Read 16-bit data into buffer decodedData = new unsigned char[inputSize]; outsize = inputSize; // Convert 16-bit little-endian data to host-endian. // Runtime detection of host endianness costs almost // nothing and is less of a continual maintenance headache // than compile-time detection. union u { std::uint16_t s; struct { std::uint8_t c0; std::uint8_t c1; } c; } u = { 0x0001 }; switch (u.c.c0) { default: // Impossible log_error(_("Host endianness not detected in AudioDecoderSimple")); // Just carry on anyway... case 0x01: // Little-endian host: sample is already native. // If the input data is the output data, then we probably // can't move the data faster than memcpy. memcpy((char *)decodedData, input, inputSize); break; case 0x00: // Big-endian host // Swap sample bytes to get big-endian format. assert((inputSize & 1) == 0); // Cast the buffers to help the compiler understand that we // swapping 16-bit words. This should produce a single-instruction // swap for each 16-bit word. const std::uint16_t* input16 = reinterpret_cast(input); std::uint16_t* decodedData16 = reinterpret_cast(decodedData); unsigned inputSize16 = inputSize / sizeof(std::uint16_t); for ( unsigned i = 0; i < inputSize16; i++ ) { std::uint16_t sample = input16[i]; decodedData16[i] = ((sample << 8) & 0xFF00) | ((sample >> 8) & 0x00FF); } break; } } break; default: break; // ???, this should only decode ADPCM, RAW and UNCOMPRESSED } std::uint8_t* tmp_raw_buffer = decodedData; std::uint32_t tmp_raw_buffer_size = 0; // If we need to convert samplerate or/and from mono to stereo... if (outsize > 0 && (_sampleRate != 44100 || !_stereo)) { std::int16_t* adjusted_data = nullptr; int adjusted_size = 0; int sample_count = outsize / (_stereo ? 4 : 2); // samples are of size 2 // Convert to needed samplerate - this converter only support standard flash samplerates AudioResampler::convert_raw_data(&adjusted_data, &adjusted_size, tmp_raw_buffer, sample_count, 2, // input sample size is 2 ! _sampleRate, _stereo, 44100, true /* stereo */); // Hopefully this wont happen if (!adjusted_data) { log_error(_("Error in sound sample conversion")); delete[] tmp_raw_buffer; outputSize = 0; decodedBytes = 0; return nullptr; } // Move the new data to the sound-struct delete[] tmp_raw_buffer; tmp_raw_buffer = reinterpret_cast(adjusted_data); tmp_raw_buffer_size = adjusted_size; } else { tmp_raw_buffer_size = outsize; } outputSize = tmp_raw_buffer_size; decodedBytes = inputSize; return tmp_raw_buffer; } } // gnash.media namespace } // gnash namespace