[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash server/swf/tag_loaders.cpp backend/sound_...
From: |
Martin Guy |
Subject: |
[Gnash-commit] gnash server/swf/tag_loaders.cpp backend/sound_... |
Date: |
Fri, 18 May 2007 10:25:44 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Martin Guy <martinwguy> 07/05/18 10:25:44
Modified files:
server/swf : tag_loaders.cpp
backend : sound_handler_sdl.cpp sound_handler_gst.cpp
. : ChangeLog
Log message:
* server/swf/tag_loaders.cpp: Rewrite of sample-reading code to
decode
all linear formats in one place.
* backend/sound_handler_{sdl,gst}.cpp: Remove now unnecessary
attempts
at decoding other linear audio formats.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&r1=1.101&r2=1.102
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.cpp?cvsroot=gnash&r1=1.56&r2=1.57
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_gst.cpp?cvsroot=gnash&r1=1.41&r2=1.42
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3263&r2=1.3264
Patches:
Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.101
retrieving revision 1.102
diff -u -b -r1.101 -r1.102
--- server/swf/tag_loaders.cpp 15 May 2007 14:02:21 -0000 1.101
+++ server/swf/tag_loaders.cpp 18 May 2007 10:25:43 -0000 1.102
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-/* $Id: tag_loaders.cpp,v 1.101 2007/05/15 14:02:21 strk Exp $ */
+/* $Id: tag_loaders.cpp,v 1.102 2007/05/18 10:25:43 martinwguy Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -71,12 +71,14 @@
namespace gnash {
// Forward declaration for functions at end of file
+//
+// Both modify "data" parameter, allocating memory for it.
-static void u8_expand(void* out_data_void, stream* in,
+static void u8_expand(unsigned char* &data, 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,
+static void adpcm_expand(unsigned char* &data, stream* in,
int sample_count, // in stereo, this is number of *pairs* of samples
bool stereo);
@@ -1165,6 +1167,11 @@
// Sound
//
+// Forward declaration
+static void sound_expand(stream *in, sound_handler::format_type &format,
+ bool sample_16bit, bool stereo,
+ unsigned char* &data, unsigned &data_bytes);
+
// Common data
static int s_sample_rate_table[] = { 5512, 11025, 22050, 44100 };
@@ -1199,9 +1206,6 @@
if (handler)
{
- unsigned data_bytes = 0;
- unsigned char* data = NULL;
-
if (! (sample_rate >= 0 && sample_rate <= 3))
{
IF_VERBOSE_MALFORMED_SWF(
@@ -1210,103 +1214,15 @@
return;
}
- 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];
- adpcm_expand(data, in, sample_count, stereo);
- format = sound_handler::FORMAT_NATIVE16;
- 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];
- // 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;
+ unsigned char *data; // Expanded audio data ready for playing
+ unsigned data_bytes; // First it is the amount of data from file,
+ // then the amount allocated at *data (it may grow)
- 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 compile-time detection.
- union u {
- uint16_t s;
- struct {
- uint8_t c0;
- uint8_t c1;
- } c;
- } 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.
- 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"));
- // Just carry on anyway...
- }
- }
- format = sound_handler::FORMAT_NATIVE16;
- break;
-
- case sound_handler::FORMAT_MP3:
- // Decompressed elsewhere
- data_bytes = in->get_tag_end_position() - in->get_position();
- data = new unsigned char[data_bytes];
- in->read((char *)data, data_bytes);
- 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;
- }
+ // sound_expand allocates storage for data[].
+ // and modifies 3 parameters: format, data and data_bytes.
+ sound_expand(in, format, sample_16bit, stereo, data, data_bytes);
int handler_id = handler->create_sound(
data,
@@ -1368,6 +1284,13 @@
}
}
+// There is only one soundstream active per movie, so we cache the extra data
+// we need to be able to decode subsequent soundstreamblocks here.
+//
+static sound_handler::format_type stream_input_format;
+static bool stream_input_is16bit;
+static bool stream_input_stereo;
+
// Load a SoundStreamHead(2) tag.
void
sound_stream_head_loader(stream* in, tag_type tag, movie_definition* m)
@@ -1406,6 +1329,8 @@
int(format), sample_rate, int(sample_16bit), int(stereo),
sample_count);
);
+ // Wot about reading the sample_count samples?
+
// Ask sound_handler it to init this sound.
int data_bytes = 0;
@@ -1418,8 +1343,26 @@
return;
}
- // Since the ADPCM is converted to NATIVE16, the format is set to that...
- if (format == sound_handler::FORMAT_ADPCM) format =
sound_handler::FORMAT_NATIVE16;
+ // Remember settings for decoding of subsequent blocks.
+ // "stereo" is also in the sound object, 16bit no, format get stomped.
+ stream_input_format = format;
+ stream_input_is16bit = sample_16bit;
+ stream_input_stereo = stereo;
+
+ // Tell create_sound what format it will be receiving, in case it cares
+ // at this stage.
+ switch (format) {
+ case sound_handler::FORMAT_ADPCM:
+ case sound_handler::FORMAT_RAW:
+ case sound_handler::FORMAT_UNCOMPRESSED:
+ format = sound_handler::FORMAT_NATIVE16;
+ break;
+ // Shut fussy compilers up...
+ case sound_handler::FORMAT_MP3:
+ case sound_handler::FORMAT_NELLYMOSER:
+ case sound_handler::FORMAT_NATIVE16:
+ break;
+ }
int handler_id = handler->create_sound(
NULL,
@@ -1449,69 +1392,135 @@
int handle_id = m->get_loading_sound_stream_id();
- // store the data with the appropiate sound.
- int data_bytes = 0;
+ unsigned char *data; // Storage is allocated by sound_expand()
+ unsigned data_bytes = in->get_tag_end_position() - in->get_position();
- // @@ This is pretty awful -- lots of copying, slow reading.
- data_bytes = in->get_tag_end_position() - in->get_position();
+ // The format in the input file is in stream_input_*
+ sound_handler::format_type format = stream_input_format;
- if (data_bytes <= 0) return;
- unsigned char *data = new unsigned char[data_bytes];
+ sound_expand(in, format,
+ stream_input_is16bit, stream_input_stereo,
+ data, data_bytes);
+ // "format" now reflects what we hand(ed) to the sound drivers.
+
+ unsigned sample_count = data_bytes;
+ if (stream_input_stereo) sample_count /= 2;
+ if (stream_input_is16bit) sample_count /= 2;
+ // Fill the data on the apropiate sound, and receives the starting point
+ // for later "start playing from this frame" events.
+ long start = handler->fill_stream_data(data, data_bytes, sample_count,
handle_id);
- int format = 0;
- bool stereo = true;
- int sample_count = -1;
+ delete [] data;
- handler->get_info(handle_id, &format, &stereo);
+ start_stream_sound_tag* ssst = new start_stream_sound_tag();
+ ssst->read(m, handle_id, start);
+}
- if (format == sound_handler::FORMAT_ADPCM)
+// sound_expand: Expand audio data to 16-bit host endian.
+//
+// This modifies three of its parameters:
+// On entry, "format" is the format of the original data. If this routine
+// expands that to 16-bit native-endian, it will also modify "format" to
+// FORMAT_NATIVE16. Otherwise it leaves it alone (MP3 and NELLYMOSER).
+//
+// Storage for "data" is allocated here, and the the "data" pointer is
modified.
+//
+// On entry, data_bytes is the amount of sound data to be read from "in";
+// on exit it reflects the number of bytes that "data" now points to.
+static void
+sound_expand(stream *in, sound_handler::format_type &format,
+ bool sample_16bit, bool stereo,
+ unsigned char* &data, unsigned &data_bytes)
+{
+ switch (format) {
+
+ case sound_handler::FORMAT_ADPCM:
{
// Uncompress the ADPCM before handing data to host.
- sample_count = data_bytes / (stereo ? 4 : 2);
- data_bytes = sample_count * (stereo ? 4 : 2);
- data = new unsigned char[data_bytes];
+ unsigned sample_count = data_bytes / (stereo ? 4 : 2);
adpcm_expand(data, in, sample_count, stereo);
format = sound_handler::FORMAT_NATIVE16;
- } else if (format == sound_handler::FORMAT_NATIVE16)
- {
- // Raw data
- sample_count = data_bytes / (stereo ? 4 : 2);
+ break;
+ }
+ case sound_handler::FORMAT_RAW:
+ // 8- or 16-bit mono or stereo host-endian audio
+ // Convert to 16-bit host-endian
+ if (sample_16bit) {
+ // FORMAT_RAW 16-bit is exactly what we want!
+ data = new unsigned char[data_bytes];
in->read((char *)data, data_bytes);
} else {
- in->read((char *)data, data_bytes);
+ // Convert 8-bit signed to 16-bit range
+ // Allocate as many shorts as there are samples
+ unsigned sample_count = data_bytes / (stereo ? 2 : 1);
+ u8_expand(data, in, sample_count, stereo);
+ }
+ format = sound_handler::FORMAT_NATIVE16;
+ break;
- // 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?
- // I dunno why this is commented-out, but if you want to re-enable it,
- // recode it with the same runtime endian order detection as above.
- // Or, better, unify the two routines as there is a lot of duplicated
- // code here.
- /*if (format == sound_handler::FORMAT_UNCOMPRESSED && sample_16bit)
+ case sound_handler::FORMAT_UNCOMPRESSED:
+ // 8- or 16-bit mono or stereo little-endian audio
+ // Convert to 16-bit host-endian.
+ if (!sample_16bit)
{
-#ifndef (?(*!(_TU_LITTLE_ENDIAN_ has gone. Use <boost/detail/endian.hpp>
+ // Convert 8-bit signed to 16-bit range
+ // Allocate as many shorts as there are 8-bit samples
+ unsigned sample_count = data_bytes / (stereo ? 2 : 1);
+ u8_expand(data, in, sample_count, stereo);
+ } 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 compile-time detection.
+ union u {
+ uint16_t s;
+ struct {
+ uint8_t c0;
+ uint8_t c1;
+ } c;
+ } 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]);
}
-#endif // not _TU_LITTLE_ENDIAN_
-
- format = sound_handler::FORMAT_NATIVE16;
- }*/
+ break;
+ default: // Impossible
+ log_error(_("Host endianness not detected in
define_sound_loader"));
+ // Just carry on anyway...
}
+ }
+ format = sound_handler::FORMAT_NATIVE16;
+ break;
+ case sound_handler::FORMAT_MP3:
+ // Decompressed elsewhere
+ data = new unsigned char[data_bytes];
+ in->read((char *)data, data_bytes);
+ break;
- // Fill the data on the apropiate sound, and receives the starting point
- // for later "start playing from this frame" events.
- long start = handler->fill_stream_data(data, data_bytes, sample_count,
handle_id);
-
- delete [] data;
-
- start_stream_sound_tag* ssst = new start_stream_sound_tag();
- ssst->read(m, handle_id, start);
+ case sound_handler::FORMAT_NELLYMOSER:
+ // One day...
+ in->skip_bytes(data_bytes);
+ break;
- // @@ who's going to delete the start_stream_sound_tag ??
+ // This is impossible as an input but stops fussy compilers
+ // complaining about unhandled enum values.
+ case sound_handler::FORMAT_NATIVE16:
+ break;
+ }
}
void
@@ -1632,7 +1641,7 @@
//
// Provides:
//
-// void adpcm_expand(void* out_data_void, stream* in,
+// void adpcm_expand(unsigned char* &data, stream* in,
// int sample_count, // in stereo, this is number of *pairs* of samples
// bool stereo)
//
@@ -1647,17 +1656,19 @@
//
// Unsigned 8-bit expansion (128 is silence)
//
+// u8_expand allocates the memory for its "data" pointer.
+//
static void u8_expand(
- void* out_data_void,
+ unsigned char * &data,
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];
+ int16_t *out_data = new int16_t[total_samples];
+
in->read((char *)in_data, total_samples); // Read 8-bit samples
// Convert 8-bit to 16
@@ -1667,6 +1678,8 @@
*outp++ = ((int16_t)(*inp++) - 128) * 256;
}
+ data = (unsigned char *)out_data;
+
delete [] in_data;
}
@@ -1813,12 +1826,12 @@
// 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,
+ unsigned char* &data,
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;
+ int16_t* out_data = new int16_t[stereo ? sample_count*2 : sample_count];
// Read header.
int n_bits = in->read_uint(2) + 2; // 2 to 5 bits
@@ -1874,6 +1887,8 @@
}
}
}
+
+ data = (unsigned char *)out_data;
}
} // namespace gnash
Index: backend/sound_handler_sdl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.cpp,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -b -r1.56 -r1.57
--- backend/sound_handler_sdl.cpp 15 May 2007 10:47:50 -0000 1.56
+++ backend/sound_handler_sdl.cpp 18 May 2007 10:25:43 -0000 1.57
@@ -18,7 +18,7 @@
// Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003
// which has been donated to the Public Domain.
-// $Id: sound_handler_sdl.cpp,v 1.56 2007/05/15 10:47:50 tgc Exp $
+// $Id: sound_handler_sdl.cpp,v 1.57 2007/05/18 10:25:43 martinwguy Exp $
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -91,19 +91,6 @@
switch (format)
{
- case FORMAT_RAW:
-
- if (data_bytes > 0) {
- convert_raw_data(&adjusted_data, &adjusted_size, data,
sample_count, 1, sample_rate, stereo);
- if (!adjusted_data) {
- gnash::log_error(_("Some kind of error occurred
with raw sound data"));
- return -1;
- }
- sounddata->data_size = adjusted_size;
- sounddata->data = (Uint8*) adjusted_data;
- }
- break;
-
case FORMAT_NATIVE16:
if (data_bytes > 0) {
@@ -130,15 +117,16 @@
return -1;
}
memcpy(sounddata->data, data, data_bytes);
-
break;
+
//case FORMAT_VORBIS:
+ case FORMAT_RAW:
case FORMAT_ADPCM:
case FORMAT_UNCOMPRESSED:
// These should have been converted to FORMAT_NATIVE16
gnash::log_error(_("Sound data format not properly converted"));
- assert(0);
+ return -1;
break;
case FORMAT_NELLYMOSER:
Index: backend/sound_handler_gst.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_gst.cpp,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -b -r1.41 -r1.42
--- backend/sound_handler_gst.cpp 15 May 2007 10:47:50 -0000 1.41
+++ backend/sound_handler_gst.cpp 18 May 2007 10:25:43 -0000 1.42
@@ -20,7 +20,7 @@
// Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003
// which has been donated to the Public Domain.
-/* $Id: sound_handler_gst.cpp,v 1.41 2007/05/15 10:47:50 tgc Exp $ */
+/* $Id: sound_handler_gst.cpp,v 1.42 2007/05/18 10:25:43 martinwguy Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -88,33 +88,7 @@
switch (format)
{
- // TODO: Do we need to do the raw-data-convert? Can't Gstreamer handle
it?
- case FORMAT_RAW:
-/* caps info:
- audio/x-raw-int
- rate: [ 1, 2147483647 ]
- channels: [ 1, 8 ]
- endianness: { 1234, 4321 }
- width: 8
- depth: [ 1, 8 ]
- signed: { true, false }*/
- sounddata->data = new guint8[data_bytes];
- if (!sounddata->data) {
- gnash::log_error(_("Could not allocate space for data
in sound handler"));
- return -1;
- }
- memcpy(sounddata->data, data, data_bytes);
- break;
-
case FORMAT_NATIVE16:
-/* caps info:
- audio/x-raw-int
- rate: [ 1, 2147483647 ]
- channels: [ 1, 8 ]
- endianness: { 1234, 4321 }
- width: 16
- depth: [ 1, 16 ]
- signed: { true, false }*/
sounddata->data = new guint8[data_bytes];
if (!sounddata->data) {
gnash::log_error(_("Could not allocate space for data
in sound handler"));
@@ -134,6 +108,7 @@
break;
+ case FORMAT_RAW:
case FORMAT_ADPCM:
case FORMAT_UNCOMPRESSED:
// These should have been converted to FORMAT_NATIVE16
@@ -600,19 +575,6 @@
gnash::log_unimpl(__PRETTY_FUNCTION__);
}
-void GST_sound_handler::convert_raw_data(
- int16_t** /*adjusted_data*/,
- int* /*adjusted_size*/,
- void* /*data*/,
- int /*sample_count*/,
- int /*sample_size*/,
- int /*sample_rate*/,
- bool /*stereo*/)
-{
- gnash::log_unimpl(__PRETTY_FUNCTION__);
-}
-
-
gnash::sound_handler* gnash::create_sound_handler_gst()
// Factory.
{
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3263
retrieving revision 1.3264
diff -u -b -r1.3263 -r1.3264
--- ChangeLog 18 May 2007 10:14:10 -0000 1.3263
+++ ChangeLog 18 May 2007 10:25:43 -0000 1.3264
@@ -21,6 +21,12 @@
* backend/sound_handler.h: Remove old adpcm_expand() decl
* macros/x11.m4: Two typoes "if x${a} != xfoo"
* utilities/parser.cpp: Shut compiler up
+ * backend/sound_handler_gst.cpp, testsuite/sound_handler_test.cpp:
+ Remove never-implemented stub declaration.
+ * server/swf/tag_loaders.cpp: Rewrite of sample-reading code to decode
+ all linear formats in one place.
+ * backend/sound_handler_{sdl,gst}.cpp: Remove now unnecessary attempts
+ at decoding other linear audio formats.
2007-05-17 Rob Savoye <address@hidden>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash server/swf/tag_loaders.cpp backend/sound_...,
Martin Guy <=