gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash server/parser/sound_definition.cpp server...


From: Martin Guy
Subject: [Gnash-commit] gnash server/parser/sound_definition.cpp server...
Date: Sun, 13 May 2007 12:20:37 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Martin Guy <martinwguy> 07/05/13 12:20:37

Modified files:
        server/parser  : sound_definition.cpp 
        server/swf     : tag_loaders.cpp 
        .              : ChangeLog 

Log message:
                * server/parser/sound_definition.cpp: Move ADPCM code elsewhere
                * server/swf/tag_loaders.cpp: Decode all linear formats into 
native 16,
                  move ADPCM code here where it's used.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/sound_definition.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&r1=1.97&r2=1.98
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3175&r2=1.3176

Patches:
Index: server/parser/sound_definition.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/sound_definition.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/parser/sound_definition.cpp  27 Feb 2007 09:54:49 -0000      1.2
+++ server/parser/sound_definition.cpp  13 May 2007 12:20:36 -0000      1.3
@@ -124,213 +124,6 @@
        }
 }
 
-       //
-       // 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
-       {
-       public:
-               const unsigned char*    m_in_data;
-               int     m_current_bits;
-               int     m_unused_bits;
-
-               in_stream(const unsigned char* data)
-                       :
-                       m_in_data(data),
-                       m_current_bits(0),
-                       m_unused_bits(0)
-               {
-               }
-       };
-
-
-//     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.
-       void    sound_handler::adpcm_expand(
-               void* out_data_void,
-               stream* in,
-               int sample_count,       // in stereo, this is number of *pairs* 
of samples
-               bool stereo)
-       {
-               int16_t*        out_data = (int16_t*) out_data_void;
-
-               // Read header.
-               int     n_bits = in->read_uint(2) + 2;  // 2 to 5 bits
-
-               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
 
 

Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -b -r1.97 -r1.98
--- server/swf/tag_loaders.cpp  12 May 2007 06:50:37 -0000      1.97
+++ server/swf/tag_loaders.cpp  13 May 2007 12:20:36 -0000      1.98
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: tag_loaders.cpp,v 1.97 2007/05/12 06:50:37 strk Exp $ */
+/* $Id: tag_loaders.cpp,v 1.98 2007/05/13 12:20:36 martinwguy Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -69,6 +69,17 @@
 }
 
 namespace gnash {
+
+// Forward declaration for functions at end of file
+
+static void u8_expand(void* out_data_void, stream* in,
+       int sample_count,  // in stereo, this is number of *pairs* of samples
+       bool stereo);
+
+static void adpcm_expand(void* out_data_void, stream* in,
+       int sample_count,  // in stereo, this is number of *pairs* of samples
+       bool stereo);
+
 namespace SWF {
 namespace tag_loaders {
 
@@ -1149,6 +1160,9 @@
 // Sound
 //
 
+// Common data
+static int     s_sample_rate_table[] = { 5512, 11025, 22050, 44100 };
+
 // @@ There are two sets of code to decode/expand/byteswap audio here.
 // @@ There should be one (search for ADPCM).
 
@@ -1168,8 +1182,6 @@
        bool    stereo = in->read_uint(1) ? true : false;
        int     sample_count = in->read_u32();
 
-       static int      s_sample_rate_table[] = { 5512, 11025, 22050, 44100 };
-
        IF_VERBOSE_PARSE
        (
            log_parse(_("define sound: ch=%d, format=%d, "
@@ -1182,7 +1194,7 @@
 
        if (handler)
        {
-           int data_bytes = 0;
+           unsigned data_bytes = 0;
            unsigned char*      data = NULL;
 
            if (! (sample_rate >= 0 && sample_rate <= 3))
@@ -1193,57 +1205,99 @@
                return;
            }
 
-           if (format == sound_handler::FORMAT_ADPCM)
-           {
+           switch (format) {
+
+           case sound_handler::FORMAT_ADPCM:
                // Uncompress the ADPCM before handing data to host.
                data_bytes = sample_count * (stereo ? 4 : 2);
                data = new unsigned char[data_bytes];
-               sound_handler::adpcm_expand(data, in, sample_count, stereo);
+               adpcm_expand(data, in, sample_count, stereo);
                format = sound_handler::FORMAT_NATIVE16;
-           }
-           else
-           {
-               // @@ This is pretty awful -- lots of copying, slow reading.
+               break;
+
+           case sound_handler::FORMAT_RAW:
+               // 8- or 16-bit mono or stereo host-endian audio
                data_bytes = in->get_tag_end_position() - in->get_position();
                data = new unsigned char[data_bytes];
-               for (int i = 0; i < data_bytes; i++)
-               {
-                   data[i] = in->read_u8();
+               // Convert to 16-bit host-endian
+               if (sample_16bit) {
+                   // FORMAT_RAW 16-bit is exactly what we want!
+                   in->read((char *)data, data_bytes);
+               } else {
+                   // Convert 8-bit signed to 16-bit range
+                   // Allocate as many shorts as there are samples
+                   int16_t *newdata = new int16_t[data_bytes];
+                   u8_expand(newdata, in, sample_count, stereo);
+
+                   // Keep new data and dispose of old
+                   unsigned char *tmp = data;
+                   data = (unsigned char *) newdata;
+                   delete [] tmp;
                }
+               format = sound_handler::FORMAT_NATIVE16;
+               break;
 
-               // Samples are always little-endian.
-               // Swap bytes on behalf of the host, to make it easier for the 
handler.
-               // @@ I'm assuming this is a good idea?  Most sound handlers 
will prefer native endianness?
-               if (format == sound_handler::FORMAT_UNCOMPRESSED
-                   && sample_16bit)
+           case sound_handler::FORMAT_UNCOMPRESSED:
+               // 8- or 16-bit mono or stereo little-endian audio
+               data_bytes = in->get_tag_end_position() - in->get_position();
+
+               // Convert to 16-bit host-endian.
+               if (!sample_16bit)
                {
+                   // Convert 8-bit signed to 16-bit range
+                   // Allocate as many shorts as there are 8-bit samples
+                   int16_t *newdata = new int16_t[data_bytes];
+                   u8_expand(newdata, in, sample_count, stereo);
+                   data = (unsigned char *) newdata;
+               } else {
+                   // Read 16-bit data into buffer
+                   data = new unsigned char[data_bytes];
+                   in->read((char *)data, data_bytes);
+
+                   // 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 attempting compile-time detection.
+                   // than compile-time detection.
                    union u {
                        uint16_t s;
                        struct {
                            uint8_t c0;
                            uint8_t c1;
                        } c;
-                   } u;
-                   u.s = 0x0001;
+                   } u = { 0x0001 };
+
                    switch (u.c.c0) {
                    case 0x01:  // Little-endian host: sample is already native.
                        break;
                    case 0x00:  // Big-endian host
                        // Swap sample bytes to get big-endian format.
-                       for (int i = 0; i < data_bytes - 1; i += 2)
+                       assert(data_bytes & 1 == 0);
+                       for (unsigned i = 0; i < data_bytes; i+=2)
                        {
                            swap(&data[i], &data[i+1]);
                        }
                        break;
                    default:    // Impossible
-                       log_error(_("Host endianness not detected in 
define-sound_loader"));
-                       assert(0);
+                       log_error(_("Host endianness not detected in 
define_sound_loader"));
+                       // Just carry on anyway...
                    }
-                   format = sound_handler::FORMAT_NATIVE16;
                }
+               format = sound_handler::FORMAT_NATIVE16;
+               break;
+
+           case sound_handler::FORMAT_MP3:
+               // Handled elsewhere
+               break;
+
+           case sound_handler::FORMAT_NELLYMOSER:
+               // One day...
+               break;
+
+           // This is impossible as an input but stops fussy compilers
+           // complaining about unhandled enum values.
+           case sound_handler::FORMAT_NATIVE16:
+               break;
            }
 
            int handler_id = handler->create_sound(
@@ -1338,8 +1392,6 @@
     int sample_count = in->read_u32();
     if (format == 2) garbage = in->read_uint(16);
 
-    static int s_sample_rate_table[] = { 5512, 11025, 22050, 44100 };
-
     IF_VERBOSE_PARSE
     (
        log_parse(_("sound stream head: format=%d, rate=%d, 16=%d, stereo=%d, 
ct=%d"),
@@ -1411,7 +1463,7 @@
        sample_count =  data_bytes / (stereo ? 4 : 2);
        data_bytes = sample_count * (stereo ? 4 : 2);
        data = new unsigned char[data_bytes];
-       sound_handler::adpcm_expand(data, in, sample_count, stereo);
+       adpcm_expand(data, in, sample_count, stereo);
        format = sound_handler::FORMAT_NATIVE16;
     } else if (format == sound_handler::FORMAT_NATIVE16)
     {
@@ -1566,13 +1618,260 @@
 }
 
 
-
-
 } // namespace gnash::SWF::tag_loaders
 } // namespace gnash::SWF
-} // namespace gnash
 
 // Local Variables:
 // mode: C++
 // indent-tabs-mode: t
 // End:
+
+// Expand ADPCM, 8-bit and non-host-endian 16-bit audio to 16-bit host-endian
+//
+// Provides:
+//
+// void        adpcm_expand(void* out_data_void, stream* in,
+//     int sample_count, // in stereo, this is number of *pairs* of samples
+//     bool stereo)
+//
+//     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.
+//
+// This code has wandered round the Gnash source tree and has still not found
+// its proper home yet.
+
+
+//
+// Unsigned 8-bit expansion (128 is silence)
+//
+
+static void u8_expand(
+       void* out_data_void,
+       stream* in,
+       int sample_count,       // in stereo, this is number of *pairs* of 
samples
+       bool stereo)
+{
+       int16_t *out_data = (int16_t*) out_data_void;
+
+       unsigned total_samples = stereo ? sample_count*2 : sample_count;
+       uint8_t *in_data = new uint8_t[total_samples];
+       in->read((char *)in_data, total_samples); // Read 8-bit samples
+
+       // Convert 8-bit to 16
+       uint8_t *inp = in_data;
+       int16_t *outp = out_data;
+       for (unsigned i=total_samples; i>0; i--) {
+               *outp++ = ((int16_t)(*inp++) - 128) * 256;
+       }
+       
+       delete [] in_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
+{
+public:
+       const unsigned char*    m_in_data;
+       int     m_current_bits;
+       int     m_unused_bits;
+
+       in_stream(const unsigned char* data)
+               :
+               m_in_data(data),
+               m_current_bits(0),
+               m_unused_bits(0)
+       {
+       }
+};
+
+
+//     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(
+       void* out_data_void,
+       stream* in,
+       int sample_count,       // in stereo, this is number of *pairs* of 
samples
+       bool stereo)
+{
+       int16_t*        out_data = (int16_t*) out_data_void;
+
+       // Read header.
+       int     n_bits = in->read_uint(2) + 2;  // 2 to 5 bits
+
+       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

Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3175
retrieving revision 1.3176
diff -u -b -r1.3175 -r1.3176
--- ChangeLog   13 May 2007 12:19:05 -0000      1.3175
+++ ChangeLog   13 May 2007 12:20:36 -0000      1.3176
@@ -2,6 +2,9 @@
 
        * server/stream.{h.cpp}: Punch a block-read primitive through the
          stream layer.
+       * server/parser/sound_definition.cpp: Move ADPCM code elsewhere
+       * server/swf/tag_loaders.cpp: Decode all linear formats into native 16,
+         move ADPCM code here where it's used.
 
 2007-05-12 Tomas Groth Christensen <address@hidden>
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]