[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/swf/tag_loaders.cpp [release_0_8_1
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/swf/tag_loaders.cpp [release_0_8_1] |
Date: |
Thu, 09 Aug 2007 21:57:29 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Branch: release_0_8_1
Changes by: Sandro Santilli <strk> 07/08/09 21:57:29
Modified files:
. : ChangeLog
server/swf : tag_loaders.cpp
Log message:
* server/swf/tag_loaders.cpp: move all ADPCM-related code in an
ADPCMDecoder class.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&only_with_tag=release_0_8_1&r1=1.3971.2.3&r2=1.3971.2.4
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&only_with_tag=release_0_8_1&r1=1.123.2.1&r2=1.123.2.2
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3971.2.3
retrieving revision 1.3971.2.4
diff -u -b -r1.3971.2.3 -r1.3971.2.4
--- ChangeLog 9 Aug 2007 17:25:52 -0000 1.3971.2.3
+++ ChangeLog 9 Aug 2007 21:57:28 -0000 1.3971.2.4
@@ -1,5 +1,7 @@
2007-08-09 Sandro Santilli <address@hidden>
+ * server/swf/tag_loaders.cpp: move all ADPCM-related code in an
+ ADPCMDecoder class.
* server/button_character_instance.cpp (construct): properly construct
all button child characters. Fixes bug #20729.
* server/swf/tag_loaders.cpp (adpcm_expand): another try at fixing the
Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.123.2.1
retrieving revision 1.123.2.2
diff -u -b -r1.123.2.1 -r1.123.2.2
--- server/swf/tag_loaders.cpp 9 Aug 2007 17:01:58 -0000 1.123.2.1
+++ server/swf/tag_loaders.cpp 9 Aug 2007 21:57:29 -0000 1.123.2.2
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-/* $Id: tag_loaders.cpp,v 1.123.2.1 2007/08/09 17:01:58 strk Exp $ */
+/* $Id: tag_loaders.cpp,v 1.123.2.2 2007/08/09 21:57:29 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -77,13 +77,260 @@
int sample_count, // in stereo, this is number of *pairs* of samples
bool stereo);
-static void adpcm_expand(unsigned char* &data, stream* in,
- int sample_count, // in stereo, this is number of *pairs* of samples
- bool stereo);
-
namespace SWF {
namespace tag_loaders {
+// ----------------------------------------------------------------------------
+// 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 = iclamp(sample, -32768, 32767);
+
+ /* Update our stepsize index. Use a lookup table. */
+ stepsize_index += index_update_table[code_mag];
+ stepsize_index = iclamp(stepsize_index, 0, STEPSIZE_CT - 1);
+ }
+
+ /* Uncompress 4096 mono samples of ADPCM. */
+ static void doMonoBlock(int16_t** out_data, int n_bits, int
sample_count, stream* in, int sample, int stepsize_index)
+ {
+ /* First sample doesn't need to be decompressed. */
+ sample_count--;
+ *(*out_data)++ = (int16_t) sample;
+
+ while (sample_count--)
+ {
+ 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)++ = (int16_t) sample;
+ }
+ }
+
+
+ /* Uncompress 4096 stereo sample pairs of ADPCM. */
+ static void doStereoBlock(
+ int16_t** out_data, // in/out param
+ int n_bits,
+ int sample_count,
+ stream* in,
+ int left_sample,
+ int left_stepsize_index,
+ int right_sample,
+ int right_stepsize_index
+ )
+ {
+ /* First samples don't need to be decompressed. */
+ sample_count--;
+ *(*out_data)++ = (int16_t) left_sample;
+ *(*out_data)++ = (int16_t) right_sample;
+
+ while (sample_count--)
+ {
+ int left_raw_code = in->read_uint(n_bits);
+ doSample(n_bits, left_sample, left_stepsize_index,
left_raw_code);
+ *(*out_data)++ = (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)++ = (int16_t) right_sample;
+ }
+ }
+
+public:
+
+ // Utility function: uncompress ADPCM data from in stream to
+ // out_data[]. The output buffer must have (sample_count*2)
+ // bytes for mono, or (sample_count*4) bytes for stereo.
+ static void adpcm_expand(
+ unsigned char* &data,
+ stream* in,
+ int sample_count, // in stereo, this is number of *pairs*
of samples (TODO: why is this signed at all ??)
+ bool stereo)
+ {
+ int16_t* out_data = new int16_t[stereo ? sample_count*2 :
sample_count];
+ data = reinterpret_cast<unsigned char *>(out_data);
+
+ // Read header.
+ in->ensureBytes(1); // nbits
+ unsigned int n_bits = in->read_uint(2) + 2; // 2 to 5 bits
(TODO: use unsigned...)
+
+
+#ifndef GNASH_TRUST_SWF_INPUT
+
+ // bitsPerCompSample is the number of bits for each comp sample
+ unsigned int bitsPerCompSample = n_bits;
+ if (stereo) bitsPerCompSample *= 2;
+
+ // There's going to be one block every 4096 samples ...
+ unsigned int blocksCount = sample_count/4096;
+
+ // ... or fraction
+ if ( sample_count%4096 ) ++blocksCount;
+
+ // Of the total samples, all but the first sample in a block
are comp
+ unsigned int compSamples = sample_count - blocksCount;
+
+ // From every block, a fixed 22 bits will be read (16 of which
are the uncomp sample)
+ unsigned int fixedBitsPerBlock = 22;
+
+ // Total bits needed from stream
+ unsigned long bitsNeeded = (compSamples*bitsPerCompSample) +
(fixedBitsPerBlock*blocksCount);
+
+ // 2 bits have been read already, so the stream position is now
one byte after the
+ // next 6 bits we're going to read, so we strip those 6 bits
from the count of bits
+ // we still need
+ bitsNeeded -= (8-2);
+
+ // Now, we convert this number to bytes, requiring one more if
any
+ unsigned int excessBits = bitsNeeded%8;
+ unsigned long bytesNeeded = bitsNeeded/8;
+ if ( excessBits ) ++bytesNeeded;
+
+ //log_debug("adpcm_expand, stereo:%d, sample_count:%u,
bitsPerSample:%u, "
+ // "blocksCount:%u, bitsPerBlock:%u, bitsNeeded:%lu,
excessBits:%u, bytesNeeded:%lu",
+ // stereo, sample_count, bitsPerCompSample, blocksCount,
fixedBitsPerBlock, bitsNeeded, excessBits, bytesNeeded);
+
+ in->ensureBytes(bytesNeeded);
+
+#endif // GNASH_TRUST_SWF_INPUT
+
+ while (sample_count)
+ {
+ // 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.
+
+ int samples_this_block = imin(sample_count, 4096);
+ sample_count -= samples_this_block;
+
+ if (stereo == false)
+ {
+#define DO_MONO(n) doMonoBlock(&out_data, n, samples_this_block, in, sample,
stepsize_index)
+
+ switch (n_bits)
+ {
+ default: assert(0); break;
+ case 2: DO_MONO(2); break;
+ case 3: DO_MONO(3); break;
+ case 4: DO_MONO(4); break;
+ case 5: DO_MONO(5); break;
+ }
+ }
+ 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.
+
+#define DO_STEREO(n) \
+ doStereoBlock( \
+ &out_data, n, samples_this_block, \
+ in, sample, stepsize_index, \
+ right_sample, right_stepsize_index)
+
+ switch (n_bits)
+ {
+ default: assert(0); break;
+ case 2: DO_STEREO(2); break;
+ case 3: DO_STEREO(3); break;
+ case 4: DO_STEREO(4); break;
+ case 5: DO_STEREO(5); break;
+ }
+ }
+ }
+
+ }
+
+
+};
+
+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
+// ----------------------------------------------------------------------------
+
+
//
// Some tag implementations
//
@@ -1321,7 +1568,7 @@
//log_debug("ADPCM format");
// Uncompress the ADPCM before handing data to host.
if (sample_count == 0) sample_count = data_bytes / ( stereo ? 4 : 2 );
- adpcm_expand(data, in, sample_count, stereo);
+ ADPCMDecoder::adpcm_expand(data, in, sample_count, stereo);
data_bytes = sample_count * (stereo ? 4 : 2);
format = sound_handler::FORMAT_NATIVE16;
break;
@@ -1599,80 +1846,11 @@
data = (unsigned char *)out_data;
}
-//
-// ADPCM
-//
-
-// Data from Alexis' SWF reference
-static int s_index_update_table_2bits[2] = { -1, 2 };
-static int s_index_update_table_3bits[4] = { -1, -1, 2, 4 };
-static int s_index_update_table_4bits[8] = { -1, -1, -1, -1, 2, 4, 6,
8 };
-static int s_index_update_table_5bits[16] = { -1, -1, -1, -1, -1, -1, -1,
-1, 1, 2, 4, 6, 8, 10, 13, 16 };
-
-static int* s_index_update_tables[4] = {
- s_index_update_table_2bits,
- s_index_update_table_3bits,
- s_index_update_table_4bits,
- s_index_update_table_5bits,
-};
-
-// Data from Jansen. http://homepages.cwi.nl/~jack/
-// Check out his Dutch retro punk songs, heh heh :)
-const int STEPSIZE_CT = 89;
-static int 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
-};
-
-
-// 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 :(
-
// @@ lots of macros here! It seems that VC6 can't correctly
// handle integer template args, although it's happy to
// compile them?!
-// void DO_SAMPLE(int n_bits, int& sample, int& stepsize_index, int
raw_code)
-#define DO_SAMPLE(n_bits, sample, stepsize_index, 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 = iclamp(sample, -32768, 32767);
\
-
\
- /* Update our stepsize index. Use a lookup table. */
\
- stepsize_index += index_update_table[code_mag];
\
- stepsize_index = iclamp(stepsize_index, 0, STEPSIZE_CT - 1);
\
-}
-
class in_stream
{
@@ -1691,162 +1869,4 @@
};
-// void DO_MONO_BLOCK(int16_t** out_data, int n_bits, int sample_count,
stream* in, int sample, int stepsize_index)
-#define DO_MONO_BLOCK(out_data, n_bits, sample_count, in, sample,
stepsize_index) \
-{
\
- /* First sample doesn't need to be decompressed. */
\
- sample_count--;
\
- *(*out_data)++ = (int16_t) sample;
\
-
\
- while (sample_count--)
\
- {
\
- int raw_code = in->read_uint(n_bits);
\
- DO_SAMPLE(n_bits, sample, stepsize_index, raw_code); /*
sample & stepsize_index are in/out params */ \
- *(*out_data)++ = (int16_t) sample;
\
- }
\
-}
-
-
-// void do_stereo_block(
-// int16_t** out_data, // in/out param
-// int n_bits,
-// int sample_count,
-// stream* in,
-// int left_sample,
-// int left_stepsize_index,
-// int right_sample,
-// int right_stepsize_index
-// )
-#define DO_STEREO_BLOCK(out_data, n_bits, sample_count, in, left_sample,
left_stepsize_index, right_sample, right_stepsize_index) \
-/* Uncompress 4096 stereo sample pairs of ADPCM. */
\
-{
\
- /* First samples don't need to be decompressed. */
\
- sample_count--;
\
- *(*out_data)++ = (int16_t) left_sample;
\
- *(*out_data)++ = (int16_t) right_sample;
\
-
\
- while (sample_count--)
\
- {
\
- int left_raw_code = in->read_uint(n_bits);
\
- DO_SAMPLE(n_bits, left_sample, left_stepsize_index,
left_raw_code); \
- *(*out_data)++ = (int16_t) left_sample;
\
-
\
- int right_raw_code = in->read_uint(n_bits);
\
- DO_SAMPLE(n_bits, right_sample, right_stepsize_index,
right_raw_code); \
- *(*out_data)++ = (int16_t) right_sample;
\
- }
\
-}
-
-
-// Utility function: uncompress ADPCM data from in stream to
-// out_data[]. The output buffer must have (sample_count*2)
-// bytes for mono, or (sample_count*4) bytes for stereo.
-static void adpcm_expand(
- unsigned char* &data,
- stream* in,
- int sample_count, // in stereo, this is number of *pairs* of
samples (TODO: why is this signed at all ??)
- bool stereo)
-{
- int16_t* out_data = new int16_t[stereo ? sample_count*2 : sample_count];
- data = reinterpret_cast<unsigned char *>(out_data);
-
- // Read header.
- in->ensureBytes(1); // nbits
- unsigned int n_bits = in->read_uint(2) + 2; // 2 to 5 bits (TODO:
use unsigned...)
-
-
-#ifndef GNASH_TRUST_SWF_INPUT
-
- // bitsPerCompSample is the number of bits for each comp sample
- unsigned int bitsPerCompSample = n_bits;
- if (stereo) bitsPerCompSample *= 2;
-
- // There's going to be one block every 4096 samples ...
- unsigned int blocksCount = sample_count/4096;
-
- // ... or fraction
- if ( sample_count%4096 ) ++blocksCount;
-
- // Of the total samples, all but the first sample in a block are comp
- unsigned int compSamples = sample_count - blocksCount;
-
- // From every block, a fixed 22 bits will be read (16 of which are the
uncomp sample)
- unsigned int fixedBitsPerBlock = 22;
-
- // Total bits needed from stream
- unsigned long bitsNeeded = (compSamples*bitsPerCompSample) +
(fixedBitsPerBlock*blocksCount);
-
- // 2 bits have been read already, so the stream position is now one
byte after the
- // next 6 bits we're going to read, so we strip those 6 bits from the
count of bits
- // we still need
- bitsNeeded -= (8-2);
-
- // Now, we convert this number to bytes, requiring one more if any
- unsigned int excessBits = bitsNeeded%8;
- unsigned long bytesNeeded = bitsNeeded/8;
- if ( excessBits ) ++bytesNeeded;
-
- //log_debug("adpcm_expand, stereo:%d, sample_count:%u,
bitsPerSample:%u, "
- // "blocksCount:%u, bitsPerBlock:%u, bitsNeeded:%lu,
excessBits:%u, bytesNeeded:%lu",
- // stereo, sample_count, bitsPerCompSample, blocksCount,
fixedBitsPerBlock, bitsNeeded, excessBits, bytesNeeded);
-
- in->ensureBytes(bytesNeeded);
-
-#endif // GNASH_TRUST_SWF_INPUT
-
- while (sample_count)
- {
- // 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.
-
- int samples_this_block = imin(sample_count, 4096);
- sample_count -= samples_this_block;
-
- if (stereo == false)
- {
-#define DO_MONO(n) DO_MONO_BLOCK(&out_data, n, samples_this_block, in, sample,
stepsize_index)
-
- switch (n_bits)
- {
- default: assert(0); break;
- case 2: DO_MONO(2); break;
- case 3: DO_MONO(3); break;
- case 4: DO_MONO(4); break;
- case 5: DO_MONO(5); break;
- }
- }
- 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.
-
-#define DO_STEREO(n) \
- DO_STEREO_BLOCK( \
- &out_data, n, samples_this_block, \
- in, sample, stepsize_index, \
- right_sample, right_stepsize_index)
-
- switch (n_bits)
- {
- default: assert(0); break;
- case 2: DO_STEREO(2); break;
- case 3: DO_STEREO(3); break;
- case 4: DO_STEREO(4); break;
- case 5: DO_STEREO(5); break;
- }
- }
- }
-
-}
-
} // namespace gnash