gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-


From: Benjamin Wolsey
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-438-ga08f72e
Date: Thu, 07 Jul 2011 07:23:55 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  a08f72e6ccdbcdb4eb5fe987826bfddd4a8be4c8 (commit)
       via  c25645741f2563d733e61559bcde4422e4b889b1 (commit)
       via  6b0804f2dfec81693ebbceebd097a1a1462b2af5 (commit)
       via  058fa846835f0b4e7a833cc6eeecef09d1613de2 (commit)
       via  460010e81bf2cd440b4dd79581f4342ee919e7cd (commit)
       via  8935ebba89735bc5fbeb8ad0676d629a2e0738e6 (commit)
       via  4db44d279cf06fa968bf4086e60353ef5c152584 (commit)
       via  d6c7780e5b241f583f22e7d65d072b6b92797962 (commit)
       via  6d587482809ba62e513ae36e0e28878cf164bf2d (commit)
       via  d413158d3dabed675665cae6d3457c0b5a770964 (commit)
       via  9530ec36d8ff994b71817bb5903db2d6d67d8aea (commit)
       via  99435cfa9150b5290c7c086da3b46b8da540923b (commit)
       via  4ef48a3b9e73254099e71cd35d3e3485b2f4a432 (commit)
       via  25e003a49a40a92fc1c75a59d40113f1327d5859 (commit)
       via  55dc9ba1f6de105f8b0616a7af839cd16e6abb34 (commit)
       via  47b72a81908e8f77534e3493ec90c704fe4e39fc (commit)
       via  8f659a54c78f8e0f072de027d1a9fd2320f3e867 (commit)
       via  ff6a7aabad29872a16d73393f0dd81d0aeb69584 (commit)
       via  59603b1b726579cd9538f24f82218e03ac3b5478 (commit)
       via  516bba3ab56e9e673295a5fe2af5ad5700bc1643 (commit)
       via  b3f5274f0f2f342eba296a4586120986c9f51766 (commit)
       via  0d6ee955540b788243abbd46a50beb34a5687265 (commit)
       via  a7c6bcd0770d57315d0208f855e5dc5abbc507a9 (commit)
       via  8c07bb0c532dc604cec068ef93ab515dd252339b (commit)
       via  3329c1197538d551e8d58241ec7643177f1838b1 (commit)
       via  88c2bfa52125639346f3c064c9058ebad3ce84b5 (commit)
       via  42ef363d57ac03c77a7d6d4b0c497b9c318d38e2 (commit)
       via  f5e7e38569e50b9cb376fe7fa927f278222b26dc (commit)
       via  4f02ec270fe77b2c4c5af7ebaa71af60b657e1d5 (commit)
       via  558fc598e39d5e9911a64352c5580389c1d05208 (commit)
       via  e9ac16f78a66ad46b797c6511415e0d28aac9b98 (commit)
       via  fb6606bd9d4ee4254d6816018923109bff9bd920 (commit)
       via  289ea1475b5a21d3a66e66940fa16e75525fea45 (commit)
       via  4afcf00239dfbc9c199bbe8843540ab851df9626 (commit)
       via  e18bd688b8fe1a4e7685f68507ad59b8484a39fa (commit)
       via  537f39dcc3fb6e90a422256c3ef006eefb0e04fb (commit)
       via  7a6bea85cbfe3b02e205d6bf72d70117bb8e1b74 (commit)
       via  8bb5b40f347e5f23350b89a47838c708fd4c055b (commit)
       via  85c638107b0688c104f629e22e5bd621e63165cd (commit)
       via  3c2a7c1b8e834d8ef98e22ec43f017c673b09f77 (commit)
      from  55108cb4ea747223a4dd1f8c17c0240743d9d0d8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=a08f72e6ccdbcdb4eb5fe987826bfddd4a8be4c8


commit a08f72e6ccdbcdb4eb5fe987826bfddd4a8be4c8
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jul 7 09:16:01 2011 +0200

    Update test totals.
    
    We're not faking the id3 data now.

diff --git a/testsuite/actionscript.all/Sound.as 
b/testsuite/actionscript.all/Sound.as
index 1db5745..d65ac73 100644
--- a/testsuite/actionscript.all/Sound.as
+++ b/testsuite/actionscript.all/Sound.as
@@ -28,7 +28,7 @@ rcsid="Sound.as";
 endOfTest = function()
 {
 #if OUTPUT_VERSION > 5
-    check_totals(113);
+    check_totals(111);
 #else
     check_totals(94);
 #endif

http://git.savannah.gnu.org/cgit//commit/?id=c25645741f2563d733e61559bcde4422e4b889b1


commit c25645741f2563d733e61559bcde4422e4b889b1
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jul 7 08:03:05 2011 +0200

    Use a separate function for id3.
    
    Drop fake id3 info for debugging.

diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index 3ddef05..982b7cc 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -24,6 +24,7 @@
 #include <boost/scoped_array.hpp>
 #include <boost/thread/mutex.hpp>
 #include <boost/cstdint.hpp>
+#include <boost/optional.hpp>
 
 #include "RunResources.h"
 #include "log.h"
@@ -70,6 +71,9 @@ namespace {
     as_value sound_stop(const fn_call& fn);
     as_value checkPolicyFile_getset(const fn_call& fn);
     void attachSoundInterface(as_object& o);
+
+    /// If there is Id3 data, create an id3 member and call the onID3 function.
+    void handleId3Data(boost::optional<media::Id3Info> id3, as_object& sound);
 }
 
 /// A Sound object in ActionScript can control and play sound
@@ -365,19 +369,6 @@ Sound_as::probeAudio()
 #endif
         if (_mediaParser->parsingCompleted()) {
 
-            boost::optional<media::Id3Info> id3 = _mediaParser->getId3Info();
-            if (id3) {
-                VM& vm = getVM(owner());
-
-                as_object* o = new as_object(getGlobal(owner()));
-                if (id3->album) o->set_member(getURI(vm, "album"), 
*id3->album);
-
-                const ObjectURI& id3 = getURI(vm, "id3");
-                owner().set_member(id3, o);
-
-                const ObjectURI& onID3 = getURI(vm, "onID3");
-                callMethod(&owner(), onID3);
-            }
             _soundLoaded = true;
 
             if (!isStreaming) {
@@ -385,6 +376,9 @@ Sound_as::probeAudio()
             }
             bool success = _mediaParser->getAudioInfo() != 0;
             callMethod(&owner(), NSV::PROP_ON_LOAD, success);
+
+            // TODO: check if this should be called anyway.
+            if (success) handleId3Data(_mediaParser->getId3Info(), owner());
         }
         return; 
     }
@@ -1268,6 +1262,27 @@ sound_areSoundsInaccessible(const fn_call& /*fn*/)
     return as_value();
 }
 
+void
+handleId3Data(boost::optional<media::Id3Info> id3, as_object& sound)
+{
+    if (!id3) return;
+    VM& vm = getVM(sound);
+
+    as_object* o = new as_object(getGlobal(sound));
+
+    // TODO: others.
+    if (id3->album) o->set_member(getURI(vm, "album"), *id3->album);
+    if (id3->year) o->set_member(getURI(vm, "year"), *id3->year);
+
+    // Add Sound.id3 member
+    const ObjectURI& id3prop = getURI(vm, "id3");
+    sound.set_member(id3prop, o);
+
+    // Notify onID3 function.
+    const ObjectURI& onID3 = getURI(vm, "onID3");
+    callMethod(&sound, onID3);
+}
+
 } // anonymous namespace 
 } // gnash namespace
 
diff --git a/libmedia/ffmpeg/MediaParserFfmpeg.cpp 
b/libmedia/ffmpeg/MediaParserFfmpeg.cpp
index 06a8088..95c009a 100644
--- a/libmedia/ffmpeg/MediaParserFfmpeg.cpp
+++ b/libmedia/ffmpeg/MediaParserFfmpeg.cpp
@@ -401,8 +401,6 @@ MediaParserFfmpeg::initializeParser()
         }
     }
 
-    setId3Info(&Id3Info::album, std::string("album"), _id3Object);
-
     log_debug("Parsing FFMPEG media file: format:%s; nstreams:%d",
         _inputFmt->name, _formatCtx->nb_streams);
     

http://git.savannah.gnu.org/cgit//commit/?id=6b0804f2dfec81693ebbceebd097a1a1462b2af5


commit 6b0804f2dfec81693ebbceebd097a1a1462b2af5
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Jul 6 14:38:45 2011 +0200

    Start ID3 implementation.
    
    The design works except that libavformat doesn't set the metadata where
    it should; this needs fixing! Gstreamer also doesn't collect metadata.

diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index cdc11e4..3ddef05 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -42,6 +42,7 @@
 #include "StreamProvider.h"
 #include "ObjectURI.h"
 #include "Relay.h"
+#include "Id3Info.h"
 
 //#define GNASH_DEBUG_SOUND_AS 1
 
@@ -362,11 +363,24 @@ Sound_as::probeAudio()
 #ifdef GNASH_DEBUG_SOUND_AS
         log_debug("Probing audio for load");
 #endif
-        if ( _mediaParser->parsingCompleted() )
-        {
+        if (_mediaParser->parsingCompleted()) {
+
+            boost::optional<media::Id3Info> id3 = _mediaParser->getId3Info();
+            if (id3) {
+                VM& vm = getVM(owner());
+
+                as_object* o = new as_object(getGlobal(owner()));
+                if (id3->album) o->set_member(getURI(vm, "album"), 
*id3->album);
+
+                const ObjectURI& id3 = getURI(vm, "id3");
+                owner().set_member(id3, o);
+
+                const ObjectURI& onID3 = getURI(vm, "onID3");
+                callMethod(&owner(), onID3);
+            }
             _soundLoaded = true;
-            if ( ! isStreaming )
-            {
+
+            if (!isStreaming) {
                 stopProbeTimer(); // will be re-started on Sound.start()
             }
             bool success = _mediaParser->getAudioInfo() != 0;
@@ -537,18 +551,17 @@ Sound_as::getVolume(int& volume)
 void
 Sound_as::loadSound(const std::string& file, bool streaming)
 {
-    if ( ! _mediaHandler || ! _soundHandler ) {
+    if (!_mediaHandler || !_soundHandler) {
         log_debug("No media or sound handlers, won't load any sound");
         return;
     }
 
     /// If we are already streaming stop doing so as we'll replace
     /// the media parser
-    if ( _inputStream ) {
+    if (_inputStream) {
         _soundHandler->unplugInputStream(_inputStream);
         _inputStream = 0;
     }
-
     
     /// Mark sound as not being loaded
     // TODO: should we check for _soundLoaded == true?
@@ -559,7 +572,7 @@ Sound_as::loadSound(const std::string& file, bool streaming)
 
     /// Start at offset 0, in case a previous ::start() call
     /// changed that.
-    _startTime=0;
+    _startTime = 0;
 
     const RunResources& rr = getRunResources(owner());
     URL url(file, rr.streamProvider().baseURL());
@@ -569,7 +582,8 @@ Sound_as::loadSound(const std::string& file, bool streaming)
     const StreamProvider& streamProvider = rr.streamProvider();
     std::auto_ptr<IOChannel> inputStream(streamProvider.getStream(url,
                 rcfile.saveStreamingMedia()));
-    if ( ! inputStream.get() ) {
+
+    if (!inputStream.get()) {
         log_error( _("Gnash could not open this url: %s"), url );
         // dispatch onLoad (false)
         callMethod(&owner(), NSV::PROP_ON_LOAD, false);
@@ -580,7 +594,7 @@ Sound_as::loadSound(const std::string& file, bool streaming)
     isStreaming = streaming;
 
     
_mediaParser.reset(_mediaHandler->createMediaParser(inputStream).release());
-    if ( ! _mediaParser ) {
+    if (!_mediaParser) {
         log_error(_("Unable to create parser for Sound at %s"), url);
         // not necessarely correct, the stream might have been found...
         // dispatch onLoad (false)
diff --git a/libmedia/Id3Info.h b/libmedia/Id3Info.h
new file mode 100644
index 0000000..8ce7507
--- /dev/null
+++ b/libmedia/Id3Info.h
@@ -0,0 +1,57 @@
+// Id3Info.h: Container for Id3Info data
+// 
+//   Copyright (C) 2007, 2008, 2009, 2010, 2011 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
+
+#ifndef GNASH_MEDIA_ID3INFO_H
+#define GNASH_MEDIA_ID3INFO_H
+
+#include <boost/optional.hpp>
+#include <string>
+
+namespace gnash {
+namespace media {
+
+/// Contains ID3 data.
+//
+/// Not all fields must be set.
+struct Id3Info
+{
+    boost::optional<std::string> name;
+    boost::optional<std::string> album;
+    boost::optional<int> year;
+};
+
+/// Set a field of the optional Id3Info.
+//
+/// The object is created if it doesn't already exist.
+///
+/// @param member   The member to set, e.g. &Id3Info::name
+/// @param val      The value for the member.
+/// @param          An Id3Info object.
+template<typename T>
+inline void
+setId3Info(boost::optional<T> Id3Info::*member, T const& val,
+        boost::optional<Id3Info>& obj)
+{
+    if (!obj) obj = Id3Info();
+    ((*obj).*member) = val;
+}
+
+}
+}
+
+#endif
diff --git a/libmedia/Makefile.am b/libmedia/Makefile.am
index a814631..f81015d 100644
--- a/libmedia/Makefile.am
+++ b/libmedia/Makefile.am
@@ -23,6 +23,7 @@ AM_CXXFLAGS = -DREGISTER_MEDIA_HANDLERS
 pkglib_LTLIBRARIES = libgnashmedia.la
 
 libgnashmedia_la_SOURCES = \
+       Id3Info.h \
        AudioDecoder.h \
        AudioDecoderSimple.cpp \
        AudioDecoderSimple.h \
diff --git a/libmedia/MediaParser.cpp b/libmedia/MediaParser.cpp
index cb1ff69..94804fa 100644
--- a/libmedia/MediaParser.cpp
+++ b/libmedia/MediaParser.cpp
@@ -19,11 +19,13 @@
 
 
 #include "MediaParser.h"
-#include "log.h"
-#include "GnashSleep.h" // for usleep.
 
 #include <boost/bind.hpp>
 
+#include "log.h"
+#include "GnashSleep.h" // for usleep.
+#include "Id3Info.h"
+
 // Define this to get debugging output from MediaParser
 //#define GNASH_DEBUG_MEDIAPARSER
 
@@ -74,6 +76,12 @@ MediaParser::isBufferEmpty() const
        return _videoFrames.empty() && _audioFrames.empty();
 }
 
+boost::optional<Id3Info>
+MediaParser::getId3Info() const
+{
+    log_error("No ID3 support implemented in this MediaParser");
+    return boost::optional<Id3Info>();
+}
 
 boost::uint64_t
 MediaParser::getBufferLengthNoLock() const
diff --git a/libmedia/MediaParser.h b/libmedia/MediaParser.h
index 05d5e1b..5a32431 100644
--- a/libmedia/MediaParser.h
+++ b/libmedia/MediaParser.h
@@ -19,9 +19,6 @@
 #ifndef GNASH_MEDIAPARSER_H
 #define GNASH_MEDIAPARSER_H
 
-#include "IOChannel.h" // for inlines
-#include "dsodefs.h" // DSOEXPORT
-
 #include <boost/scoped_array.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/thread/thread.hpp>
@@ -32,12 +29,19 @@
 #include <map>
 #include <vector>
 #include <iosfwd> // for output operator forward declarations
+#include <boost/optional.hpp>
+
+#include "IOChannel.h" // for inlines
+#include "dsodefs.h" // DSOEXPORT
 
 // Undefine this to load/parse media files in main thread
 #define LOAD_MEDIA_IN_A_SEPARATE_THREAD 1
 
 namespace gnash {
     class SimpleBuffer;
+    namespace media {
+        struct Id3Info;
+    }
 }
 
 namespace gnash {
@@ -603,6 +607,11 @@ public:
     /// is a no-op.
     virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
 
+    /// Get ID3 data from the parsed stream if it exists.
+    //
+    /// It's best to do this only when parsingComplete is true.
+    virtual boost::optional<Id3Info> getId3Info() const;
+
 protected:
 
        /// Subclasses *must* set the following variables: @{ 
@@ -694,7 +703,6 @@ protected:
        /// mutex protecting access to the a/v encoded frames queues
        mutable boost::mutex _qMutex;
 
-
        /// Mutex protecting _bytesLoaded (read by main, set by parser)
        mutable boost::mutex _bytesLoadedMutex;
 
diff --git a/libmedia/ffmpeg/MediaParserFfmpeg.cpp 
b/libmedia/ffmpeg/MediaParserFfmpeg.cpp
index 19c8136..06a8088 100644
--- a/libmedia/ffmpeg/MediaParserFfmpeg.cpp
+++ b/libmedia/ffmpeg/MediaParserFfmpeg.cpp
@@ -36,17 +36,17 @@ namespace ffmpeg {
 
 namespace { 
 
-       // Used to calculate a decimal value from a ffmpeg fraction
-       inline double as_double(AVRational time)
-       {
-               return time.num / static_cast<double>(time.den);
-       }
+// Used to calculate a decimal value from a ffmpeg fraction
+inline double as_double(AVRational time) {
+    return time.num / static_cast<double>(time.den);
+}
 
 } // anonymous namespace
 
 
 int
-MediaParserFfmpeg::readPacketWrapper(void* opaque, boost::uint8_t* buf, int 
buf_size)
+MediaParserFfmpeg::readPacketWrapper(void* opaque, boost::uint8_t* buf,
+        int buf_size)
 {
        MediaParserFfmpeg* p = static_cast<MediaParserFfmpeg*>(opaque);
        return p->readPacket(buf, buf_size);
@@ -62,7 +62,7 @@ MediaParserFfmpeg::seekMediaWrapper(void *opaque, 
boost::int64_t offset, int whe
 AVInputFormat*
 MediaParserFfmpeg::probeStream()
 {
-    const size_t probeSize = 2048;
+    const size_t probeSize = 4096;
     const size_t bufSize = probeSize + FF_INPUT_BUFFER_PADDING_SIZE;
 
        boost::scoped_array<boost::uint8_t> buffer(new boost::uint8_t[bufSize]);
@@ -75,8 +75,7 @@ MediaParserFfmpeg::probeStream()
 
        _stream->seek(0);
 
-       if (actuallyRead < 1)
-       {
+       if (actuallyRead < 1) {
                throw IOException(_("MediaParserFfmpeg could not read probe 
data "
                     "from input"));
        }
@@ -310,14 +309,13 @@ MediaParserFfmpeg::parseNextFrame()
 bool
 MediaParserFfmpeg::parseNextChunk()
 {
-       if ( ! parseNextFrame() ) return false;
+       if (!parseNextFrame()) return false;
        return true;
 }
 
 boost::uint64_t
 MediaParserFfmpeg::getBytesLoaded() const
 {
-       //log_unimpl("%s", __PRETTY_FUNCTION__);
        return _lastParsedPosition;
 }
 
@@ -348,33 +346,25 @@ MediaParserFfmpeg::initializeParser()
     _byteIOCxt.buffer = NULL;
     
     _inputFmt = probeStream();
+
 #ifdef GNASH_ALLOW_VCODEC_ENV  
-    if ( ! _inputFmt ) {
-       char* defcodec = getenv("GNASH_DEFAULT_VCODEC");
-       if (defcodec && strlen(defcodec))
-           _inputFmt = av_find_input_format(defcodec); 
-       
+    if (!_inputFmt) {
+        char* defcodec = getenv("GNASH_DEFAULT_VCODEC");
+        if (defcodec && strlen(defcodec)) {
+            _inputFmt = av_find_input_format(defcodec);        
+        }
     }
 #endif 
-    if ( ! _inputFmt ) {
-       throw MediaException("MediaParserFfmpeg couldn't figure out input "
-                            "format");
+    if (! _inputFmt) {
+        throw MediaException("MediaParserFfmpeg couldn't figure out input "
+                     "format");
     }
     
-// av_alloc_format_context was deprecated on
-// 2009-02-08 (r17047) in favor of avformat_alloc_context() 
-#if !defined (LIBAVCODEC_VERSION_MAJOR) || LIBAVCODEC_VERSION_MAJOR < 52
-    _formatCtx = av_alloc_format_context();
-#else
-    _formatCtx = avformat_alloc_context();
-#endif
-
-    assert(_formatCtx);
-    
     // Setup the filereader/seeker mechanism.
     // 7th argument (NULL) is the writer function,
     // which isn't needed.
-    _byteIOBuffer.reset( new unsigned char[byteIOBufferSize] );
+    _byteIOBuffer.reset(new unsigned char[byteIOBufferSize]);
+
     init_put_byte(&_byteIOCxt,
                  _byteIOBuffer.get(), // buffer
                  byteIOBufferSize, // buffer size
@@ -386,64 +376,73 @@ MediaParserFfmpeg::initializeParser()
                  );
     
     _byteIOCxt.is_streamed = 1;
-    
-    // Open the stream. the 4th argument is the filename, which we ignore.
-    if(av_open_input_stream(&_formatCtx, &_byteIOCxt, "", _inputFmt, NULL) < 0)
+ 
+    _formatCtx = avformat_alloc_context();
+    assert(_formatCtx);
+
+    // Otherwise av_open_input_stream will reallocate the context.
+    AVFormatParameters ap;
+    std::memset(&ap, 0, sizeof ap);
+    ap.prealloced_context = 1;
+
+    if (av_open_input_stream(&_formatCtx, &_byteIOCxt, "", _inputFmt, &ap) < 0)
     {
         throw IOException("MediaParserFfmpeg couldn't open input stream");
     }
-    
+
+    // Note: metadata doesn't work here; haven't worked out why.
+    AVMetadata* md = _formatCtx->metadata;
+    if (md) {
+        AVMetadataTag* tag = av_metadata_get(md, "album", 0,
+                AV_METADATA_MATCH_CASE);
+        if (tag && tag->value) {
+            setId3Info(&Id3Info::album, std::string(tag->value),
+                    _id3Object);
+        }
+    }
+
+    setId3Info(&Id3Info::album, std::string("album"), _id3Object);
+
     log_debug("Parsing FFMPEG media file: format:%s; nstreams:%d",
         _inputFmt->name, _formatCtx->nb_streams);
     
-    if ( _formatCtx->title[0] )
-        log_debug(_("  Title:'%s'"), _formatCtx->title);
-    if ( _formatCtx->author[0] )
-        log_debug(_("  Author:'%s'"), _formatCtx->author);
-    if ( _formatCtx->copyright[0] )
-        log_debug(_("  Copyright:'%s'"), _formatCtx->copyright);
-    if ( _formatCtx->comment[0] )
-        log_debug(_("  Comment:'%s'"), _formatCtx->comment);
-    if ( _formatCtx->album[0] )
-        log_debug(_("  Album:'%s'"), _formatCtx->album);
-    
     // Find first audio and video stream
-    for (unsigned int i = 0; i < static_cast<unsigned 
int>(_formatCtx->nb_streams); i++)
-       {
+    for (size_t i = 0; i < static_cast<size_t>(_formatCtx->nb_streams); ++i) {
+
            AVStream* stream = _formatCtx->streams[i];
-           if ( ! stream ) {
-               log_debug("Stream %d of FFMPEG media file is null ?", i);
-               continue;
+           if (! stream) {
+            log_debug("Stream %d of FFMPEG media file is null ?", i);
+            continue;
            }
            
            AVCodecContext* enc = stream->codec; 
-           if ( ! enc ) {
-               log_debug("Stream %d of FFMPEG media file has no codec info", 
i);
-               continue;
+           if (!enc) {
+            log_debug("Stream %d of FFMPEG media file has no codec info", i);
+            continue;
            }
            
            switch (enc->codec_type) {
-           case CODEC_TYPE_AUDIO:
-               if (_audioStreamIndex < 0) {
-                   _audioStreamIndex = i;
-                   _audioStream = _formatCtx->streams[i];
-                   log_debug(_("  Using stream %d for audio: codec id %d"),
-                             i, _audioStream->codec->codec_id);
-                   // codec_name will only be filled by avcodec_find_decoder 
(later);
-               }
-               break;
+            case CODEC_TYPE_AUDIO:
+                if (_audioStreamIndex < 0) {
+                    _audioStreamIndex = i;
+                    _audioStream = _formatCtx->streams[i];
+                    // codec_name will only be filled by avcodec_find_decoder
+                    // (later);
+                    log_debug(_("  Using stream %d for audio: codec id %d"),
+                          i, _audioStream->codec->codec_id);
+                }
+                break;
                
-           case CODEC_TYPE_VIDEO:
-               if (_videoStreamIndex < 0) {
-                   _videoStreamIndex = i;
-                   _videoStream = _formatCtx->streams[i];
-                   log_debug(_("  Using stream %d for video: codec id %d"),
-                             i, _videoStream->codec->codec_id);
-                   // codec_name will only be filled by avcodec_find_decoder 
(later);
-               }
-               break;
-           default:
-               break;
+            case CODEC_TYPE_VIDEO:
+                if (_videoStreamIndex < 0) {
+                    _videoStreamIndex = i;
+                    _videoStream = _formatCtx->streams[i];
+                    log_debug(_("  Using stream %d for video: codec id %d"),
+                          i, _videoStream->codec->codec_id);
+                }
+                break;
+            default:
+                break;
            }
        }
     
@@ -452,7 +451,8 @@ MediaParserFfmpeg::initializeParser()
         const int codec = static_cast<int>(_videoStream->codec->codec_id); 
         boost::uint16_t width = _videoStream->codec->width;
         boost::uint16_t height = _videoStream->codec->height;
-        boost::uint16_t frameRate = 
static_cast<boost::uint16_t>(as_double(_videoStream->r_frame_rate));
+        boost::uint16_t frameRate = static_cast<boost::uint16_t>(
+                as_double(_videoStream->r_frame_rate));
 #if !defined(HAVE_LIBAVFORMAT_AVFORMAT_H) && !defined(HAVE_FFMPEG_AVCODEC_H)
         boost::uint64_t duration = _videoStream->codec_info_duration;
 #else
@@ -476,7 +476,8 @@ MediaParserFfmpeg::initializeParser()
     }
     
     // Create AudioInfo
-    if ( _audioStream) {
+    if (_audioStream) {
+
         const int codec = static_cast<int>(_audioStream->codec->codec_id); 
         boost::uint16_t sampleRate = _audioStream->codec->sample_rate;
         boost::uint16_t sampleSize = 
SampleFormatToSampleSize(_audioStream->codec->sample_fmt);
@@ -543,6 +544,12 @@ MediaParserFfmpeg::readPacket(boost::uint8_t* buf, int 
buf_size)
 
 }
 
+boost::optional<Id3Info>
+MediaParserFfmpeg::getId3Info() const
+{
+    return _id3Object;
+}
+
 // NOTE: as this function is used as a callback from FFMPEG, it should not
 // throw any exceptions, because:
 // a) The behaviour of C++ exceptions passed into C code is undefined.
diff --git a/libmedia/ffmpeg/MediaParserFfmpeg.h 
b/libmedia/ffmpeg/MediaParserFfmpeg.h
index 7848733..a13cc30 100644
--- a/libmedia/ffmpeg/MediaParserFfmpeg.h
+++ b/libmedia/ffmpeg/MediaParserFfmpeg.h
@@ -19,11 +19,13 @@
 #ifndef GNASH_MEDIAPARSER_FFMPEG_H
 #define GNASH_MEDIAPARSER_FFMPEG_H
 
-#include "MediaParser.h" // for inheritance
-#include "ffmpegHeaders.h"
-
 #include <boost/scoped_array.hpp>
 #include <memory>
+#include <boost/optional.hpp>
+
+#include "MediaParser.h" // for inheritance
+#include "ffmpegHeaders.h"
+#include "Id3Info.h"
 
 // Forward declaration
 namespace gnash {
@@ -90,6 +92,8 @@ public:
        // See dox in MediaParser.h
        virtual boost::uint64_t getBytesLoaded() const;
 
+    virtual boost::optional<Id3Info> getId3Info() const;
+
 private:
 
        /// Initialize parser, figuring format and 
@@ -175,6 +179,8 @@ private:
 
        /// Make an EncodedAudioFrame from an AVPacket and push to buffer
        bool parseAudioFrame(AVPacket& packet);
+
+    boost::optional<Id3Info> _id3Object;
 };
 
 
diff --git a/libmedia/gst/MediaParserGst.cpp b/libmedia/gst/MediaParserGst.cpp
index d3ff2ce..ab0aaad 100644
--- a/libmedia/gst/MediaParserGst.cpp
+++ b/libmedia/gst/MediaParserGst.cpp
@@ -131,6 +131,11 @@ MediaParserGst::seek(boost::uint32_t& milliseconds)
                             GST_MSECOND * milliseconds);
 }
 
+boost::optional<Id3Info>
+MediaParserGst::getId3Info() const
+{
+    return boost::optional<Id3Info>();
+}
 
 bool
 MediaParserGst::parseNextChunk()
diff --git a/libmedia/gst/MediaParserGst.h b/libmedia/gst/MediaParserGst.h
index 668e182..4a4a1ac 100644
--- a/libmedia/gst/MediaParserGst.h
+++ b/libmedia/gst/MediaParserGst.h
@@ -19,16 +19,16 @@
 #ifndef GNASH_MEDIAPARSER_GST_H
 #define GNASH_MEDIAPARSER_GST_H
 
-#include "MediaParser.h" // for inheritance
-
 #include <deque>
 #include <boost/scoped_array.hpp>
 #include <memory>
 #include <queue>
-
 #include <gst/gst.h>
-#include "ClockTime.h"
+#include <boost/optional.hpp>
 
+#include "MediaParser.h" // for inheritance
+#include "ClockTime.h"
+#include "Id3Info.h"
 
 // Forward declaration
 namespace gnash {
@@ -119,7 +119,9 @@ public:
     bool parseNextChunk();
 
     // See dox in MediaParser.h
-    boost::uint64_t getBytesLoaded() const;
+    virtual boost::uint64_t getBytesLoaded() const;
+
+    virtual boost::optional<Id3Info> getId3Info() const;
 
     void rememberAudioFrame(EncodedAudioFrame* frame);
     void rememberVideoFrame(EncodedVideoFrame* frame);
diff --git a/testsuite/actionscript.all/Sound.as 
b/testsuite/actionscript.all/Sound.as
index 5f514ae..1db5745 100644
--- a/testsuite/actionscript.all/Sound.as
+++ b/testsuite/actionscript.all/Sound.as
@@ -28,7 +28,7 @@ rcsid="Sound.as";
 endOfTest = function()
 {
 #if OUTPUT_VERSION > 5
-    check_totals(111);
+    check_totals(113);
 #else
     check_totals(94);
 #endif
@@ -117,6 +117,48 @@ check_equals(typeof(s1.duration), 'undefined');
 check_equals(typeof(s1.ID3), 'undefined');
 check_equals(typeof(s1.position), 'undefined');
 
+#if OUTPUT_VERSION > 5
+
+// We hope that this is loaded in before the test finishes.
+
+#if 0
+
+click = new Sound();
+click.onLoad = function() {
+    note("onLoad");
+    // Is called after onID3
+    check_equals(typeof(click.id3), "object");
+};
+
+click.onID3 = function() {
+    note("onID3");
+    xcheck_equals(typeof(click.id3), "object");
+    xcheck_equals(click.id3.album, "Gnash");
+    xcheck_equals(click.id3.songname, "Clicky");
+    xcheck_equals(click.id3.artist, "Benjamin Wolsey");
+    xcheck_equals(click.id3.comment, "Gnash can read this.");
+    xcheck_equals(click.id3.year, "2011");
+    xcheck_equals(click.id3.genre, "42");
+};
+
+click.loadSound(MEDIA(click.mp3), false);
+
+#endif
+
+wav = new Sound();
+wav.onID3 = function() {
+    fail("Should not be called for wave sounds!");
+};
+wav.loadSound(MEDIA(brokenchord.wav), false);
+
+mp3 = new Sound();
+mp3.onID3 = function() {
+    fail("Should not be called where no tag is present.");
+};
+mp3.loadSound(MEDIA(stereo8.mp3), false);
+
+#endif
+
 
 //
 // Use constructor taking a movieclip and check return of all inspectors

http://git.savannah.gnu.org/cgit//commit/?id=058fa846835f0b4e7a833cc6eeecef09d1613de2


commit 058fa846835f0b4e7a833cc6eeecef09d1613de2
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Jul 6 10:15:24 2011 +0200

    Add an mp3 click track with ID3 data.

diff --git a/testsuite/media/README b/testsuite/media/README
index 0e7254e..f34045f 100644
--- a/testsuite/media/README
+++ b/testsuite/media/README
@@ -57,6 +57,24 @@ sound1.mp3
        Sample Encoding: MPEG audio (layer I, II or III)
        Channels       : 1
        Sample Rate    : 22050
+    No ID3 data.
+
+stereo8.mp3
+
+    TODO
+
+click.mp3
+
+       Sample Size    : 16-bits
+       Sample Encoding: MPEG audio (layer I, II or III)
+       Channels       : 2
+       Sample Rate    : 44100
+
+Note: this contains 2 sets of ID3 data: one set written by audacity, and one
+set added using mp3info. The pp uses the set added by mp3info. If it encounters
+only data written by audacity, the onID3 function is called, but the id3 object
+contains no data.
+
 
 square.flv
 
diff --git a/testsuite/media/click.mp3 b/testsuite/media/click.mp3
new file mode 100644
index 0000000..a43054e
Binary files /dev/null and b/testsuite/media/click.mp3 differ

http://git.savannah.gnu.org/cgit//commit/?id=460010e81bf2cd440b4dd79581f4342ee919e7cd


commit 460010e81bf2cd440b4dd79581f4342ee919e7cd
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Jul 6 09:22:22 2011 +0200

    Don't assign false again.
    
    We've just asserted that it's false.

diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index b4101d7..cdc11e4 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -348,8 +348,7 @@ Sound_as::probeAudio()
         // Only probe for sound complete
         assert(_soundHandler);
         assert(!_soundCompleted);
-        if ( ! _soundHandler->isSoundPlaying(soundId) ) {
-            _soundCompleted = false;
+        if (!_soundHandler->isSoundPlaying(soundId)) {
             stopProbeTimer();
             // dispatch onSoundComplete 
             callMethod(&owner(), NSV::PROP_ON_SOUND_COMPLETE);

http://git.savannah.gnu.org/cgit//commit/?id=8935ebba89735bc5fbeb8ad0676d629a2e0738e6


commit 8935ebba89735bc5fbeb8ad0676d629a2e0738e6
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Jul 6 09:12:17 2011 +0200

    Drop unnecessary headers.

diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 9a51a05..2fb50e4 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -26,8 +26,6 @@
 #include <string>
 #include <vector>
 #include <memory>
-#include <cassert>
-#include <cstring>
 #include <limits>
 #include <set>
 #include <boost/scoped_ptr.hpp>

http://git.savannah.gnu.org/cgit//commit/?id=4db44d279cf06fa968bf4086e60353ef5c152584


commit 4db44d279cf06fa968bf4086e60353ef5c152584
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Jul 6 08:31:00 2011 +0200

    Don't waste space.

diff --git a/gui/gui.cpp b/gui/gui.cpp
index db89013..72707f9 100644
--- a/gui/gui.cpp
+++ b/gui/gui.cpp
@@ -948,8 +948,6 @@ Gui::start()
 bool
 Gui::advanceMovie(bool doDisplay)
 {
-
-
     if (isStopped()) {
         return false;
     }
@@ -1006,8 +1004,9 @@ Gui::advanceMovie(bool doDisplay)
        if (doDisplay && visible()) display(m);
 
        if (!loops()) {
-               size_t curframe = m->getRootMovie().get_current_frame(); // can 
be 0 on malformed SWF
-               const gnash::MovieClip& si = m->getRootMovie();
+        // can be 0 on malformed SWF
+               const size_t curframe = m->getRootMovie().get_current_frame(); 
+               const MovieClip& si = m->getRootMovie();
                if (curframe + 1 >= si.get_frame_count()) {
                        quit(); 
                }

http://git.savannah.gnu.org/cgit//commit/?id=d6c7780e5b241f583f22e7d65d072b6b92797962


commit d6c7780e5b241f583f22e7d65d072b6b92797962
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Jul 6 08:17:04 2011 +0200

    Don't parse raw sound.

diff --git a/libsound/LiveSound.h b/libsound/LiveSound.h
index 8d3d8b1..caa0576 100644
--- a/libsound/LiveSound.h
+++ b/libsound/LiveSound.h
@@ -153,7 +153,8 @@ private:
 inline bool
 requiresParsing(const media::SoundInfo& info)
 {
-    return info.getFormat() != media::AUDIO_CODEC_ADPCM;
+    return info.getFormat() != media::AUDIO_CODEC_ADPCM &&
+        info.getFormat() != media::AUDIO_CODEC_RAW;
 }
 
 
diff --git a/libsound/StreamingSoundData.cpp b/libsound/StreamingSoundData.cpp
index 3c68dc2..77db7e7 100644
--- a/libsound/StreamingSoundData.cpp
+++ b/libsound/StreamingSoundData.cpp
@@ -129,7 +129,8 @@ void
 StreamingSoundData::getPlayingInstances(std::vector<InputStream*>& to) const
 {
     boost::mutex::scoped_lock lock(_soundInstancesMutex);
-    for (Instances::const_iterator i=_soundInstances.begin(), 
e=_soundInstances.end();
+    for (Instances::const_iterator i=_soundInstances.begin(),
+            e=_soundInstances.end();
             i!=e; ++i)
     {
         to.push_back(*i);

http://git.savannah.gnu.org/cgit//commit/?id=6d587482809ba62e513ae36e0e28878cf164bf2d


commit 6d587482809ba62e513ae36e0e28878cf164bf2d
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Jul 5 10:52:06 2011 +0200

    Implement seeksamples.
    
    Not sure if it's correct, but at least the data is used.

diff --git a/libcore/swf/StreamSoundBlockTag.cpp 
b/libcore/swf/StreamSoundBlockTag.cpp
index 6c30688..f2e4607 100644
--- a/libcore/swf/StreamSoundBlockTag.cpp
+++ b/libcore/swf/StreamSoundBlockTag.cpp
@@ -79,21 +79,16 @@ StreamSoundBlockTag::loader(SWFStream& in, TagType tag, 
movie_definition& m,
     media::audioCodecType format = sinfo->getFormat();
 
     boost::uint16_t sampleCount;
+    boost::int16_t seekSamples = 0;
 
     // MP3 format blocks have additional info
     if (format == media::AUDIO_CODEC_MP3) {
         in.ensureBytes(4);
-
         // MP3 blocks have restrictions on the number of samples they can
         // contain (due to the codec), so have a variable number of samples
         // per block.
         sampleCount = in.read_u16();
-        const boost::uint16_t seekSamples = in.read_u16();
-
-        if (seekSamples) {
-            LOG_ONCE(log_unimpl(_("MP3 soundblock seek samples (%s)"),
-                        seekSamples));
-        }
+        seekSamples = in.read_u16();
     }
     else sampleCount = sinfo->getSampleCount();
 
@@ -119,14 +114,14 @@ StreamSoundBlockTag::loader(SWFStream& in, TagType tag, 
movie_definition& m,
         throw ParserException(_("Tag boundary reported past end of stream!"));
     }
 
-    // Fill the data on the apropiate sound, and receives the starting point
+    // Fill the data on the appropiate sound, and receives the starting point
     // for later "start playing from this frame" events.
     //
     // TODO: the amount of sound data used should depend on the sampleCount,
     // not on the size of the data. Currently the sound_handler ignores
     // sampleCount completely.
     sound::sound_handler::StreamBlockId blockId =
-        handler->addSoundBlock(buf, sampleCount, sId);
+        handler->addSoundBlock(buf, sampleCount, seekSamples, sId);
 
     boost::intrusive_ptr<ControlTag> s(new StreamSoundBlockTag(sId, blockId));
 
diff --git a/libsound/LiveSound.cpp b/libsound/LiveSound.cpp
index b475cf7..bca4f2b 100644
--- a/libsound/LiveSound.cpp
+++ b/libsound/LiveSound.cpp
@@ -37,7 +37,6 @@ LiveSound::LiveSound(media::MediaHandler& mh, const 
media::SoundInfo& info,
     _playbackPosition(_inPoint),
     _samplesFetched(0)
 {
-    log_debug("in point: %s, playback pos: %s", _inPoint, _playbackPosition);
     createDecoder(mh, info);
 }
 
diff --git a/libsound/SoundUtils.h b/libsound/SoundUtils.h
index fd4e725..2afa91c 100644
--- a/libsound/SoundUtils.h
+++ b/libsound/SoundUtils.h
@@ -24,10 +24,11 @@
 #include <boost/bind.hpp>
 #include <boost/cstdint.hpp>
 
+#include "SoundInfo.h"
+
 namespace gnash {
 namespace sound {
 
-
 /// Volume adjustment
 //
 /// @param start        The beginning of the range to adjust volume for
@@ -41,6 +42,30 @@ adjustVolume(T* start, T* end, float volume)
             boost::bind(std::multiplies<float>(), volume, _1));
 }
 
+/// Convert SWF-specified number of samples to output number of samples
+//
+/// SWF-specified number of samples are: delaySeek in DEFINESOUND,
+/// latency in STREAMSOUNDHEAD and seekSamples in STREAMSOUNDBLOCK.
+/// These refer to samples at the sampleRate of input.
+///
+/// As gnash will resample the sounds to match expected output
+/// (44100 Hz, stereo 16bit) this function is handy to convert
+/// for simpler use later.
+inline size_t
+swfToOutSamples(const media::SoundInfo& sinfo, size_t swfSamples,
+        const size_t outRate = 44100)
+{
+    // NOTE: this was tested with inputs:
+    //     - isStereo?0 is16bit()?1 sampleRate?11025
+    //     - isStereo?0 is16bit()?1 sampleRate?22050
+    //     - isStereo?1 is16bit()?1 sampleRate?22050
+    //     - isStereo?0 is16bit()?1 sampleRate?44100
+    //     - isStereo?1 is16bit()?1 sampleRate?44100
+    //
+    // TODO: test with other sample sizes !
+    return swfSamples * (outRate / sinfo.getSampleRate());
+}
+
 } // namespace sound
 } // namespace gnash
 
diff --git a/libsound/StreamingSound.cpp b/libsound/StreamingSound.cpp
index aa317c5..e50c81d 100644
--- a/libsound/StreamingSound.cpp
+++ b/libsound/StreamingSound.cpp
@@ -29,17 +29,31 @@
 namespace gnash {
 namespace sound {
 
+namespace {
+
+int
+getInPoint(StreamingSoundData& data, size_t block)
+{
+    if (block >= data.blockCount()) return 0;
+    const int latency = data.soundinfo.getDelaySeek();
+
+    // For the first block just return the latency.
+    if (block == 0) return latency;
+
+    // For subsequent blocks add latency to seekSamples. This is documented
+    // but not verified.
+    return swfToOutSamples(data.soundinfo,
+            latency + data.getSeekSamples(block));
+}
+
+}
+
 StreamingSound::StreamingSound(StreamingSoundData& sd,
-            media::MediaHandler& mh, sound_handler::StreamBlockId block,
-            unsigned int inPoint)
+            media::MediaHandler& mh, sound_handler::StreamBlockId block)
         :
-        LiveSound(mh, sd.soundinfo, inPoint),
+        LiveSound(mh, sd.soundinfo, getInPoint(sd, block)),
         _currentBlock(block),
         _positionInBlock(0),
-        // parameter is in stereo samples (44100 per second)
-        // we double to take 2 channels into account
-        // and double again to use bytes
-        _inPoint(inPoint * 4),
         _soundDef(sd)
 {
 }
diff --git a/libsound/StreamingSound.h b/libsound/StreamingSound.h
index f68578a..df534a5 100644
--- a/libsound/StreamingSound.h
+++ b/libsound/StreamingSound.h
@@ -58,12 +58,8 @@ public:
     /// @param mh       The MediaHandler to use for on-demand decoding
     /// @param blockId  Identifier of the encoded block to start decoding from.
     ///                 @see gnash::swf::StreamSoundBlockTag
-    /// @param inPoint  Offset in output samples this instance should start
-    ///                 playing from. These are post-resampling samples (44100 
-    ///                 for one second of samples).
     StreamingSound(StreamingSoundData& def, media::MediaHandler& mh,
-            sound_handler::StreamBlockId blockId,
-            unsigned int inPoint);
+            sound_handler::StreamBlockId blockId);
 
     // See dox in sound_handler.h (InputStream)
     virtual bool eof() const;
@@ -98,10 +94,6 @@ private:
     // The position within the current block.
     size_t _positionInBlock;
 
-    /// Offset in bytes samples from start of the block
-    /// to begin playback from
-    unsigned long _inPoint;
-
     /// The encoded data
     //
     /// It is non-const because we deregister ourselves
diff --git a/libsound/StreamingSoundData.cpp b/libsound/StreamingSoundData.cpp
index be8917b..3c68dc2 100644
--- a/libsound/StreamingSoundData.cpp
+++ b/libsound/StreamingSoundData.cpp
@@ -33,12 +33,15 @@
 namespace gnash {
 namespace sound {
 
+
 size_t
-StreamingSoundData::append(std::auto_ptr<SimpleBuffer> data, size_t 
sampleCount)
+StreamingSoundData::append(std::auto_ptr<SimpleBuffer> data,
+        size_t sampleCount, int seekSamples)
 {
-    UNUSED(sampleCount);
     assert(data.get());
     _buffers.push_back(data);
+    _blockData.push_back(BlockData(sampleCount, seekSamples));
+    assert(_blockData.size() == _buffers.size());
     return _buffers.size() - 1;
 }
 
@@ -65,12 +68,9 @@ StreamingSoundData::eraseActiveSound(Instances::iterator i)
 }
 
 std::auto_ptr<StreamingSound>
-StreamingSoundData::createInstance(media::MediaHandler& mh,
-            unsigned long blockOffset,
-            unsigned int inPoint)
+StreamingSoundData::createInstance(media::MediaHandler& mh, unsigned long 
block)
 {
-    std::auto_ptr<StreamingSound> ret(new StreamingSound(*this, mh,
-                blockOffset, inPoint));
+    std::auto_ptr<StreamingSound> ret(new StreamingSound(*this, mh, block));
 
     boost::mutex::scoped_lock lock(_soundInstancesMutex);
 
diff --git a/libsound/StreamingSoundData.h b/libsound/StreamingSoundData.h
index 1501568..8c39d9b 100644
--- a/libsound/StreamingSoundData.h
+++ b/libsound/StreamingSoundData.h
@@ -69,7 +69,9 @@ public:
     /// @param data          Undecoded sound data. Must be appropriately
     ///                      padded (see MediaHandler::getInputPaddingBytes())
     /// @param sampleCount   The number of samples when decoded.
-    size_t append(std::auto_ptr<SimpleBuffer> data, size_t sampleCount);
+    /// @param seekSamples   Where to start playing from at a particular frame.
+    size_t append(std::auto_ptr<SimpleBuffer> data, size_t sampleCount,
+            int seekSamples);
 
     /// Do we have any data?
     bool empty() const {
@@ -80,6 +82,14 @@ public:
         return _buffers[index];
     }
 
+    size_t getSampleCount(size_t index) const {
+        return _blockData[index].sampleCount;
+    }
+
+    size_t getSeekSamples(size_t index) const {
+        return _blockData[index].seekSamples;
+    }
+
     size_t blockCount() const {
         return _buffers.size();
     }
@@ -114,13 +124,9 @@ public:
     ///                         this instance should start decoding.
     ///                         This refers to a specific StreamSoundBlock.
     ///                         @see gnash::swf::StreamSoundBlockTag
-    /// @param inPoint          Offset in output samples this instance
-    ///                         should start playing from. These are
-    ///                         post-resampling samples from
-    ///                         the start of the specified blockId.
     /// Locks the _soundInstancesMutex when pushing to it
     std::auto_ptr<StreamingSound> createInstance(media::MediaHandler& mh,
-            unsigned long blockOffset, unsigned int inPoint);
+            unsigned long blockOffset);
 
     /// Drop all active sounds
     //
@@ -156,6 +162,18 @@ public:
 
 private:
 
+    struct BlockData
+    {
+        BlockData(size_t count, int seek)
+            :
+            sampleCount(count),
+            seekSamples(seek)
+        {}
+
+        size_t sampleCount;
+        size_t seekSamples;
+    };
+
     /// Playing instances of this sound definition
     //
     /// Multithread access to this member is protected
@@ -166,6 +184,8 @@ private:
     mutable boost::mutex _soundInstancesMutex;
 
     boost::ptr_vector<SimpleBuffer> _buffers;
+
+    std::vector<BlockData> _blockData;
 };
 
 } // gnash.sound namespace 
diff --git a/libsound/sdl/sound_handler_sdl.cpp 
b/libsound/sdl/sound_handler_sdl.cpp
index 126be62..8bd8d86 100644
--- a/libsound/sdl/sound_handler_sdl.cpp
+++ b/libsound/sdl/sound_handler_sdl.cpp
@@ -150,11 +150,11 @@ 
SDL_sound_handler::create_sound(std::auto_ptr<SimpleBuffer> data,
 
 sound_handler::StreamBlockId
 SDL_sound_handler::addSoundBlock(std::auto_ptr<SimpleBuffer> buf,
-        unsigned int nSamples, int streamId)
+        size_t sampleCount, int seekSamples, int handle)
 {
 
     boost::mutex::scoped_lock lock(_mutex);
-    return sound_handler::addSoundBlock(buf, nSamples, streamId);
+    return sound_handler::addSoundBlock(buf, sampleCount, seekSamples, handle);
 }
 
 
diff --git a/libsound/sdl/sound_handler_sdl.h b/libsound/sdl/sound_handler_sdl.h
index cd9995f..ad3b817 100644
--- a/libsound/sdl/sound_handler_sdl.h
+++ b/libsound/sdl/sound_handler_sdl.h
@@ -101,8 +101,7 @@ public:
     // See dox in sound_handler.h
     // overridden to serialize access to the data buffer slot
     virtual StreamBlockId addSoundBlock(std::auto_ptr<SimpleBuffer> buf,
-                                       unsigned int sample_count,
-                                       int streamId);
+           size_t sample_count, int seekSamples, int streamId);
 
     // See dox in sound_handler.h
     virtual void stopEventSound(int sound_handle);
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 161c029..8a3a986 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -77,7 +77,7 @@ ensurePadding(SimpleBuffer& data, media::MediaHandler* m)
 
 sound_handler::StreamBlockId
 sound_handler::addSoundBlock(std::auto_ptr<SimpleBuffer> data,
-        unsigned int sample_count, int handle)
+        size_t sampleCount, int seekSamples, int handle)
 {
     if (!validHandle(_streamingSounds, handle)) {
         log_error("Invalid (%d) handle passed to fill_stream_data, "
@@ -95,8 +95,7 @@ sound_handler::addSoundBlock(std::auto_ptr<SimpleBuffer> data,
     assert(data.get());
     ensurePadding(*data, _mediaHandler);
 
-    // Handling of the sound data
-    return sounddata->append(data, sample_count);
+    return sounddata->append(data, sampleCount, seekSamples);
 }
 
 void
@@ -412,39 +411,6 @@ sound_handler::create_sound(std::auto_ptr<SimpleBuffer> 
data,
 
 }
 
-/*static private*/
-unsigned int
-sound_handler::swfToOutSamples(const media::SoundInfo& sinfo,
-                                      unsigned int swfSamples)
-{
-    // swf samples refers to pre-resampled state so we need to
-    // take that into account.
-
-
-    static const unsigned int outSampleRate = 44100;
-
-    unsigned int outSamples = swfSamples *
-                                (outSampleRate/sinfo.getSampleRate());
-
-    // NOTE: this was tested with inputs:
-    //     - isStereo?0 is16bit()?1 sampleRate?11025
-    //     - isStereo?0 is16bit()?1 sampleRate?22050
-    //     - isStereo?1 is16bit()?1 sampleRate?22050
-    //     - isStereo?0 is16bit()?1 sampleRate?44100
-    //     - isStereo?1 is16bit()?1 sampleRate?44100
-    //
-    // TODO: test with other sample sizes !
-    //
-#if 1
-    log_debug("NOTE: isStereo?%d is16bit()?%d sampleRate?%d",
-              sinfo.isStereo(), sinfo.is16bit(), sinfo.getSampleRate());
-#endif
-
-
-    return outSamples;
-}
-
-/* public */
 bool
 sound_handler::isSoundPlaying(int handle) const
 {
@@ -460,13 +426,10 @@ sound_handler::isSoundPlaying(int handle) const
 void
 sound_handler::playStream(int soundId, StreamBlockId blockId)
 {
-    const unsigned int inPoint = 0;
-
     StreamingSoundData& s = *_streamingSounds[soundId];
     if (s.isPlaying() || s.empty()) return;
 
-    std::auto_ptr<InputStream> is(
-        s.createInstance(*_mediaHandler, blockId, inPoint));
+    std::auto_ptr<InputStream> is(s.createInstance(*_mediaHandler, blockId));
 
     plugInputStream(is);
 }
@@ -596,9 +559,9 @@ sound_handler::unplugAllInputStreams()
 }
 
 void
-sound_handler::fetchSamples (boost::int16_t* to, unsigned int nSamples)
+sound_handler::fetchSamples(boost::int16_t* to, unsigned int nSamples)
 {
-    if ( isPaused() ) return; // should we write wav file anyway ?
+    if (isPaused()) return; // should we write wav file anyway ?
 
     float finalVolumeFact = getFinalVolume()/100.0;
 
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 2b65bae..9a51a05 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -227,13 +227,13 @@ public:
     ///                     MediaHandler::getInputPaddingBytes()), or a
     ///                     reallocation will take place here.
     /// @param sampleCount  Number of samples in the data
+    /// @param seekSamples  Offset of sound to frame data
     /// @param streamId     The soundhandlers id of the sound we want
     ///                     to add data to
     /// @return             a handler for the new block for use in playStream()
     /// @throw              SoundException on error
     virtual StreamBlockId addSoundBlock(std::auto_ptr<SimpleBuffer> data,
-                                       unsigned int sampleCount,
-                                       int streamId);
+               size_t sampleCount, int seekSamples, int streamId);
 
     /// Returns a SoundInfo object for the sound with the given id.
     //
@@ -456,8 +456,6 @@ protected:
         _paused(false),
         _muted(false),
         _volume(100),
-        _sounds(),
-        _inputStreams(),
         _mediaHandler(m)
     {
     }
@@ -517,12 +515,11 @@ private:
     /// Stop all instances of an embedded sound
     void stopEmbedSoundInstances(StreamingSoundData& def);
 
-    typedef std::set< InputStream* > InputStreams;
+    typedef std::set<InputStream*> InputStreams;
 
     /// Sound input streams.
     //
     /// Elements owned by this class.
-    ///
     InputStreams _inputStreams;
 
     media::MediaHandler* _mediaHandler;
@@ -530,24 +527,6 @@ private:
     /// Unplug any completed input stream
     void unplugCompletedInputStreams();
 
-    /// Convert SWF-specified number of samples to output number of samples
-    //
-    /// SWF-specified number of samples are: delaySeek in DEFINESOUND,
-    /// latency in STREAMSOUNDHEAD and seekSamples in STREAMSOUNDBLOCK.
-    /// These refer to samples at the sampleRate of input.
-    ///
-    /// As gnash will resample the sounds to match expected output
-    /// (44100 Hz, stereo 16bit) this function is handy to convert
-    /// for simpler use later.
-    ///
-    /// It is non-static in the event we'll one day allow different
-    /// sound_handler instances to be configured with different output
-    /// sample rate (would need a lot more changes atm but let's keep
-    /// that in mind).
-    ///
-    unsigned int swfToOutSamples(const media::SoundInfo& sinfo,
-                                          unsigned int swfSamples);
-
     boost::scoped_ptr<WAVWriter> _wavWriter;
 
 };

http://git.savannah.gnu.org/cgit//commit/?id=d413158d3dabed675665cae6d3457c0b5a770964


commit d413158d3dabed675665cae6d3457c0b5a770964
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Jul 5 10:16:26 2011 +0200

    Make things private.

diff --git a/libsound/EmbedSound.cpp b/libsound/EmbedSound.cpp
index d477499..9d81673 100644
--- a/libsound/EmbedSound.cpp
+++ b/libsound/EmbedSound.cpp
@@ -35,9 +35,9 @@ namespace sound {
 EmbedSound::EmbedSound(std::auto_ptr<SimpleBuffer> data,
         const media::SoundInfo& info, int nVolume)
     :
-    _buf(data.release()),
     soundinfo(info),
-    volume(nVolume)
+    volume(nVolume),
+    _buf(data.release())
 {
     if (!_buf.get()) _buf.reset(new SimpleBuffer());
 }
diff --git a/libsound/EmbedSound.h b/libsound/EmbedSound.h
index bbdc224..9467543 100644
--- a/libsound/EmbedSound.h
+++ b/libsound/EmbedSound.h
@@ -59,9 +59,9 @@ public:
     //
     /// @param data The encoded sound data.
     /// @param info encoding info
-    /// @param nVolume initial volume (0..100). Optional, defaults to 100.
+    /// @param volume initial volume (0..100). Optional, defaults to 100.
     EmbedSound(std::auto_ptr<SimpleBuffer> data, const media::SoundInfo& info,
-            int nVolume);
+            int volume);
 
     ~EmbedSound();
 
@@ -167,9 +167,6 @@ public:
     ///
     void eraseActiveSound(EmbedSoundInst* inst);
 
-    /// The undecoded data
-    boost::scoped_ptr<SimpleBuffer> _buf;
-
     /// Object holding information about the sound
     media::SoundInfo soundinfo;
 
@@ -179,6 +176,9 @@ public:
 
 private:
 
+    /// The undecoded data
+    boost::scoped_ptr<SimpleBuffer> _buf;
+
     /// Playing instances of this sound definition
     //
     /// Multithread access to this member is protected

http://git.savannah.gnu.org/cgit//commit/?id=9530ec36d8ff994b71817bb5903db2d6d67d8aea


commit 9530ec36d8ff994b71817bb5903db2d6d67d8aea
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Jul 5 10:16:14 2011 +0200

    Make things private.

diff --git a/libsound/StreamingSoundData.h b/libsound/StreamingSoundData.h
index dffa6dd..1501568 100644
--- a/libsound/StreamingSoundData.h
+++ b/libsound/StreamingSoundData.h
@@ -154,13 +154,12 @@ public:
     /// It's the SWF range that is represented here.
     int volume;
 
+private:
+
     /// Playing instances of this sound definition
     //
     /// Multithread access to this member is protected
     /// by the _soundInstancesMutex mutex
-    ///
-    /// @todo make private
-    ///
     Instances _soundInstances;
 
     /// Mutex protecting access to _soundInstances

http://git.savannah.gnu.org/cgit//commit/?id=99435cfa9150b5290c7c086da3b46b8da540923b


commit 99435cfa9150b5290c7c086da3b46b8da540923b
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Jul 5 10:13:28 2011 +0200

    Don't add sound twice to playing instances.

diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 410ca08..161c029 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -457,7 +457,6 @@ sound_handler::isSoundPlaying(int handle) const
     return sounddata.isPlaying();
 }
 
-/*public*/
 void
 sound_handler::playStream(int soundId, StreamBlockId blockId)
 {
@@ -469,8 +468,6 @@ sound_handler::playStream(int soundId, StreamBlockId 
blockId)
     std::auto_ptr<InputStream> is(
         s.createInstance(*_mediaHandler, blockId, inPoint));
 
-    s._soundInstances.push_back(is.get());
-
     plugInputStream(is);
 }
 

http://git.savannah.gnu.org/cgit//commit/?id=4ef48a3b9e73254099e71cd35d3e3485b2f4a432


commit 4ef48a3b9e73254099e71cd35d3e3485b2f4a432
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Jul 5 08:57:53 2011 +0200

    Minor cleanups.

diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index f8e4863..5d543fa 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -50,30 +50,20 @@ public:
 
     /// Create an embedded %sound instance
     //
-    /// @param def
-    ///     The definition of this sound (where immutable data is kept)
-    ///
-    /// @param mh
-    ///     The MediaHandler to use for on-demand decoding
-    ///
-    /// @param inPoint
-    ///     Offset in output samples this instance should start
-    ///     playing from. These are post-resampling samples (44100 
-    ///     for one second of samples).
-    ///
-    /// @param outPoint
-    ///     Offset in output samples this instance should stop
-    ///     playing at. These are post-resampling samples (44100 
-    ///     for one second of samples).
-    ///     Use numeric_limits<unsigned int>::max() for never
-    ///
-    /// @param envelopes
-    ///     SoundEnvelopes to apply to this sound. May be 0 for none.
-    ///
-    /// @param loopCount
-    ///     Number of times this instance should loop over the defined sound.
-    ///     Note that every loop begins and ends at the range given by
-    ///     inPoint and outPoint.
+    /// @param def       The definition of this sound (the immutable data)
+    /// @param mh        The MediaHandler to use for on-demand decoding
+    /// @param inPoint   Offset in output samples this instance should start
+    ///                  playing from. These are post-resampling samples 
(44100 
+    ///                  for one second of samples).
+    /// @param outPoint  Offset in output samples this instance should stop
+    ///                  playing at. These are post-resampling samples (44100 
+    ///                  for one second of samples).
+    ///                  Use numeric_limits<unsigned int>::max() for never
+    /// @param envelopes SoundEnvelopes to apply to this sound. May be 0 for
+    ///                  none.
+    /// @param loopCount Number of times this instance should loop over the
+    ///                  defined sound. Note that every loop begins and ends
+    ///                  at the range given by inPoint and outPoint.
     EmbedSoundInst(EmbedSound& def, media::MediaHandler& mh,
             unsigned int inPoint, unsigned int outPoint,
             const SoundEnvelopes* envelopes, int loopCount);
@@ -88,11 +78,12 @@ public:
 
 private:
 
-    virtual void checkCustomEnd(unsigned& bytesAhead) const {
+    virtual size_t checkEarlierEnd(size_t bytesAhead, size_t pos) const {
         if (_outPoint < std::numeric_limits<unsigned long>::max()) {
-            unsigned toCustomEnd = _outPoint - playbackPosition();
-            bytesAhead = std::min(toCustomEnd, bytesAhead);
+            const size_t toCustomEnd = _outPoint - pos;
+            return std::min(toCustomEnd, bytesAhead);
         }
+        return bytesAhead;
     }
 
     virtual bool moreData();
diff --git a/libsound/LiveSound.h b/libsound/LiveSound.h
index a8a3178..8d3d8b1 100644
--- a/libsound/LiveSound.h
+++ b/libsound/LiveSound.h
@@ -70,14 +70,20 @@ protected:
     /// but decoding is not complete.
     virtual bool moreData() = 0;
 
-    /// True if there is no more data.
+    /// True if there is no more data ever.
+    //
+    /// The InputStream will be disconnected when this is true.
     virtual bool eof() const = 0;
 
+    /// Start from the beginning again.
     void restart() {
         _playbackPosition = _inPoint;
         _samplesFetched = 0;
     }
 
+    /// How many samples have been fetched since the beginning
+    //
+    /// Note that this is reset on each loop.
     unsigned int samplesFetched() const {
         return _samplesFetched;
     }
@@ -95,8 +101,6 @@ protected:
         delete [] data;
     }
 
-    virtual void checkCustomEnd(unsigned&) const {}
-
     /// Return number of already-decoded samples available
     /// from playback position on
     unsigned int decodedSamplesAhead() const {
@@ -104,10 +108,10 @@ protected:
         const unsigned int dds = _decodedData.size();
         if (dds <= _playbackPosition) return 0; 
 
-        unsigned int bytesAhead = dds - _playbackPosition;
-        assert(!(bytesAhead % 2));
+        size_t bytesAhead = dds - _playbackPosition;
+        bytesAhead = checkEarlierEnd(bytesAhead, _playbackPosition);
 
-        checkCustomEnd(bytesAhead);
+        assert(!(bytesAhead % 2));
 
         const unsigned int samplesAhead = bytesAhead / 2;
         return samplesAhead;
@@ -115,6 +119,14 @@ protected:
 
 private:
 
+    /// Check if the sound data ends earlier than expected.
+    //
+    /// This is a way to deal with the outpoint in EmbedSoundInst, but isn't
+    /// very tidy.
+    virtual size_t checkEarlierEnd(size_t left, size_t) const {
+        return left;
+    }
+
     // See dox in sound_handler.h (InputStream)
     unsigned int fetchSamples(boost::int16_t* to, unsigned int nSamples);
 
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 3675eb3..410ca08 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -683,22 +683,20 @@ sound_handler::setAudioDump(const std::string& wavefile)
 void
 sound_handler::unplugCompletedInputStreams()
 {
-    InputStreams::iterator it = _inputStreams.begin();
-    InputStreams::iterator end = _inputStreams.end();
 
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
     log_debug("Scanning %d input streams for completion", 
_inputStreams.size());
 #endif
 
-    while (it != end)
-    {
+    for (InputStreams::iterator it = _inputStreams.begin(),
+            end = _inputStreams.end(); it != end;) {
+
         InputStream* is = *it;
 
         // On EOF, detach
-        if (is->eof())
-        {
+        if (is->eof()) {
             // InputStream EOF, detach
-            InputStreams::iterator it2=it;
+            InputStreams::iterator it2 = it;
             ++it2; // before we erase it
             InputStreams::size_type erased = _inputStreams.erase(is);
             if ( erased != 1 ) {
@@ -707,7 +705,6 @@ sound_handler::unplugCompletedInputStreams()
             }
             it = it2;
 
-            //log_debug("fetchSamples: marking stopped InputStream %p (on 
EOF)", is);
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
             log_debug(" Input stream %p reached EOF, unplugging", is);
 #endif
@@ -724,10 +721,7 @@ sound_handler::unplugCompletedInputStreams()
             // Increment number of sound stop request for the testing framework
             ++_soundsStopped;
         }
-        else
-        {
-            ++it;
-        }
+        else ++it;
     }
 }
 

http://git.savannah.gnu.org/cgit//commit/?id=25e003a49a40a92fc1c75a59d40113f1327d5859


commit 25e003a49a40a92fc1c75a59d40113f1327d5859
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 16:58:46 2011 +0200

    Fix loop count and bug from previous commit.
    
    A loop count of -1 is (accurately) documented to mean 'loop for ever';
    so don't store it as an unsigned value and handle that case gracefully!
    
    Make sure custom end works.

diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index 22a634a..f8e4863 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -88,6 +88,13 @@ public:
 
 private:
 
+    virtual void checkCustomEnd(unsigned& bytesAhead) const {
+        if (_outPoint < std::numeric_limits<unsigned long>::max()) {
+            unsigned toCustomEnd = _outPoint - playbackPosition();
+            bytesAhead = std::min(toCustomEnd, bytesAhead);
+        }
+    }
+
     virtual bool moreData();
 
     /// Apply envelope-volume adjustments
diff --git a/libsound/LiveSound.cpp b/libsound/LiveSound.cpp
index bca4f2b..b475cf7 100644
--- a/libsound/LiveSound.cpp
+++ b/libsound/LiveSound.cpp
@@ -37,6 +37,7 @@ LiveSound::LiveSound(media::MediaHandler& mh, const 
media::SoundInfo& info,
     _playbackPosition(_inPoint),
     _samplesFetched(0)
 {
+    log_debug("in point: %s, playback pos: %s", _inPoint, _playbackPosition);
     createDecoder(mh, info);
 }
 
diff --git a/libsound/LiveSound.h b/libsound/LiveSound.h
index 9747228..a8a3178 100644
--- a/libsound/LiveSound.h
+++ b/libsound/LiveSound.h
@@ -95,6 +95,8 @@ protected:
         delete [] data;
     }
 
+    virtual void checkCustomEnd(unsigned&) const {}
+
     /// Return number of already-decoded samples available
     /// from playback position on
     unsigned int decodedSamplesAhead() const {
@@ -102,9 +104,11 @@ protected:
         const unsigned int dds = _decodedData.size();
         if (dds <= _playbackPosition) return 0; 
 
-        const unsigned int bytesAhead = dds - _playbackPosition;
+        unsigned int bytesAhead = dds - _playbackPosition;
         assert(!(bytesAhead % 2));
 
+        checkCustomEnd(bytesAhead);
+
         const unsigned int samplesAhead = bytesAhead / 2;
         return samplesAhead;
     }

http://git.savannah.gnu.org/cgit//commit/?id=55dc9ba1f6de105f8b0616a7af839cd16e6abb34


commit 55dc9ba1f6de105f8b0616a7af839cd16e6abb34
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 16:58:46 2011 +0200

    Fix loop count.
    
    A loop count of -1 is (accurately) documented to mean 'loop for ever';
    so don't store it as an unsigned value and handle that case gracefully!

diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index 6366022..b2ab058 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -40,7 +40,7 @@ namespace sound {
 EmbedSoundInst::EmbedSoundInst(EmbedSound& soundData,
             media::MediaHandler& mediaHandler,
             unsigned int inPoint, unsigned int outPoint,
-            const SoundEnvelopes* env, unsigned int loopCount)
+            const SoundEnvelopes* env, int loopCount)
         :
         LiveSound(mediaHandler, soundData.soundinfo, inPoint),
         decodingPosition(0),
@@ -71,7 +71,8 @@ EmbedSoundInst::moreData()
     if (decodingCompleted() || reachedCustomEnd()) {
 
         if (loopCount) {
-            --loopCount;
+            // negative count is documented to mean loop forever.
+            if (loopCount > 0) --loopCount;
             restart();
             return true;
         }
diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index c758ab3..22a634a 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -75,10 +75,8 @@ public:
     ///     Note that every loop begins and ends at the range given by
     ///     inPoint and outPoint.
     EmbedSoundInst(EmbedSound& def, media::MediaHandler& mh,
-            unsigned int inPoint,
-            unsigned int outPoint,
-            const SoundEnvelopes* envelopes,
-            unsigned int loopCount);
+            unsigned int inPoint, unsigned int outPoint,
+            const SoundEnvelopes* envelopes, int loopCount);
 
     // See dox in sound_handler.h (InputStream)
     virtual bool eof() const;

http://git.savannah.gnu.org/cgit//commit/?id=47b72a81908e8f77534e3493ec90c704fe4e39fc


commit 47b72a81908e8f77534e3493ec90c704fe4e39fc
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 15:25:27 2011 +0200

    Use LiveSound base class and clean up.

diff --git a/libsound/EmbedSound.cpp b/libsound/EmbedSound.cpp
index 1b2c231..d477499 100644
--- a/libsound/EmbedSound.cpp
+++ b/libsound/EmbedSound.cpp
@@ -57,18 +57,12 @@ EmbedSound::eraseActiveSound(Instances::iterator i)
 }
 
 std::auto_ptr<EmbedSoundInst>
-EmbedSound::createInstance(media::MediaHandler& mh,
-            unsigned int inPoint,
-            unsigned int outPoint,
-            const SoundEnvelopes* envelopes,
-            unsigned int loopCount)
+EmbedSound::createInstance(media::MediaHandler& mh, unsigned int inPoint,
+        unsigned int outPoint, const SoundEnvelopes* envelopes,
+        unsigned int loopCount)
 {
-    std::auto_ptr<EmbedSoundInst> ret(new EmbedSoundInst(
-                                *this,
-                                mh, 
-                                inPoint, outPoint,
-                                envelopes,
-                                loopCount) );
+    std::auto_ptr<EmbedSoundInst> ret(
+        new EmbedSoundInst(*this, mh, inPoint, outPoint, envelopes, 
loopCount));
 
     boost::mutex::scoped_lock lock(_soundInstancesMutex);
 
diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index 753ea96..6366022 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -16,7 +16,6 @@
 // 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 "EmbedSoundInst.h"
 
@@ -25,10 +24,9 @@
 
 #include "SoundInfo.h" // for use
 #include "MediaHandler.h" // for use
-#include "GnashException.h" // for SoundException
 #include "AudioDecoder.h" // for use
 #include "SoundEnvelope.h" // for use
-#include "log.h" // will import boost::format too
+#include "log.h" 
 #include "SoundUtils.h"
 
 // Debug sound decoding
@@ -39,229 +37,73 @@
 namespace gnash {
 namespace sound {
 
-unsigned int
-EmbedSoundInst::samplesFetched() const
-{
-    return _samplesFetched;
-}
-
 EmbedSoundInst::EmbedSoundInst(EmbedSound& soundData,
             media::MediaHandler& mediaHandler,
-            unsigned int inPoint,
-            unsigned int outPoint,
-            const SoundEnvelopes* env,
-            unsigned int loopCount)
+            unsigned int inPoint, unsigned int outPoint,
+            const SoundEnvelopes* env, unsigned int loopCount)
         :
-
+        LiveSound(mediaHandler, soundData.soundinfo, inPoint),
         decodingPosition(0),
-
         loopCount(loopCount),
-
-        // parameter is in stereo samples (44100 per second)
-        // we double to take 2 channels into account
-        // and double again to use bytes
-        _inPoint(inPoint*4),
-
-        // parameter is in stereo samples (44100 per second)
+        // parameters are in stereo samples (44100 per second)
         // we double to take 2 channels into account
         // and double again to use bytes
         _outPoint( outPoint == std::numeric_limits<unsigned int>::max() ?
                    std::numeric_limits<unsigned long>::max()
                    : outPoint * 4),
-
         envelopes(env),
         current_env(0),
-        _samplesFetched(0),
-        _decoder(0),
         _soundDef(soundData)
 {
-    playbackPosition = _inPoint; 
-
-    createDecoder(mediaHandler);
-}
-
-/*private*/
-void
-EmbedSoundInst::createDecoder(media::MediaHandler& mediaHandler)
-{
-    const media::SoundInfo& si = _soundDef.soundinfo;
-
-    media::AudioInfo info(
-        (int)si.getFormat(), // codeci
-        si.getSampleRate(), // sampleRatei
-        si.is16bit() ? 2 : 1, // sampleSizei
-        si.isStereo(), // stereoi
-        0, // duration unknown, does it matter ?
-        media::CODEC_TYPE_FLASH);
-
-    try {
-        _decoder = mediaHandler.createAudioDecoder(info);
-    }
-    catch (const MediaException& e) {
-        log_error("AudioDecoder initialization failed: %s", e.what());
-    }
-}
-
-// Pointer handling and checking functions
-boost::int16_t*
-EmbedSoundInst::getDecodedData(unsigned long int pos)
-{
-    assert(pos < _decodedData.size());
-    return reinterpret_cast<boost::int16_t*>(_decodedData.data() + pos);
 }
 
 bool
 EmbedSoundInst::reachedCustomEnd() const
 {
-    if ( _outPoint == std::numeric_limits<unsigned long>::max() )
-            return false;
-    if ( playbackPosition >= _outPoint ) return true;
+    if (_outPoint == std::numeric_limits<unsigned long>::max()) return false;
+    if (playbackPosition() >= _outPoint) return true;
     return false;
 }
 
-unsigned int 
-EmbedSoundInst::fetchSamples(boost::int16_t* to, unsigned int nSamples)
+bool
+EmbedSoundInst::moreData()
 {
-    // If there exist no decoder, then we can't decode!
-    if (!_decoder.get())
-    {
-        return 0;
-    }
-
-    unsigned int fetchedSamples=0;
-
-    while ( nSamples )
-    {
-        unsigned int availableSamples = decodedSamplesAhead();
-        if ( availableSamples )
-        {
-            boost::int16_t* data = getDecodedData(playbackPosition);
-            if ( availableSamples >= nSamples )
-            {
-                std::copy(data, data+nSamples, to);
-                fetchedSamples += nSamples;
-
-                // Update playback position (samples are 16bit)
-                playbackPosition += nSamples*2;
-
-                break; // fetched all
-            }
-            else
-            {
-                // not enough decoded samples available:
-                // copy what we have and go on
-                std::copy(data, data+availableSamples, to);
-                fetchedSamples += availableSamples;
-
-                // Update playback position (samples are 16bit)
-                playbackPosition += availableSamples*2;
-
-                to+=availableSamples;
-                nSamples-=availableSamples;
-                assert ( nSamples );
-
-            }
-        }
-
-        // We haven't finished fetching yet, so see if we
-        // have more to decode or not
-
-        if ( decodingCompleted() || reachedCustomEnd() )
-        {
-            if ( loopCount )
-            {
-#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
-                log_debug("Loops left: %d", loopCount);
-#endif
-
-                // loops ahead, reset playbackPosition to the starting 
-                // position and keep looping
-                --loopCount;
-
-                // Start next loop
-                playbackPosition = _inPoint; 
-                _samplesFetched = 0;
-
-                continue;
-            }
+    if (decodingCompleted() || reachedCustomEnd()) {
 
-#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
-            if ( reachedCustomEnd() )
-            {
-                log_debug("Reached custom end (pos:%d out:%d) and no looping, "
-                          "sound is over", playbackPosition, _outPoint);
-            }
-            else
-            {
-                log_debug("Decoding completed and no looping, sound is over");
-            }
-#endif
-            break; // fetched what possible, filled with silence the rest
+        if (loopCount) {
+            --loopCount;
+            restart();
+            return true;
         }
-
-        // More to decode, then decode it
-        decodeNextBlock();
+        // Nothing more to do.
+        return false;
     }
 
-    // update samples played
-    _samplesFetched += fetchedSamples;
-
-    return fetchedSamples;
+    // It's not clear if this happens for Embedded sounds, but it
+    // would permit incremental decoding.
+    decodeNextBlock();
+    return true;
 }
 
-/*private*/
 void
 EmbedSoundInst::decodeNextBlock()
 {
     assert(!decodingCompleted());
 
-    // Should only be called when no more decoded data
-    // are available for fetching.
-    // Doing so we know what's the sample number
-    // of the first sample in the newly decoded block.
-    //
-    assert(playbackPosition >= _decodedData.size());
-
-    boost::uint32_t inputSize = 0; // or blockSize
-    bool parse = true; // need to parse ?
-
-    // this block figures inputSize (blockSize) and need to parse (parse)
-    // @todo: turn into a private function
-    {
-        const EmbedSound& sndData = _soundDef;
-
-        // Figure the need to parse..
-        switch (sndData.soundinfo.getFormat())
-        {
-            case media::AUDIO_CODEC_ADPCM:
-#ifdef GNASH_DEBUG_SOUNDS_DECODING
-                log_debug(" sound format is ADPCM");
-#endif
-                parse = false;
-                break;
-            default:
-                break;
-        }
-
-        // Figure the frame size ...
-        inputSize = encodedDataSize() - decodingPosition;
-    }
+    const bool parse = requiresParsing(_soundDef.soundinfo);
+    const boost::uint32_t inputSize = _soundDef.size() - decodingPosition;
 
 #ifdef GNASH_DEBUG_SOUNDS_DECODING
     log_debug("  decoding %d bytes, parse:%d", inputSize, parse);
 #endif
 
     assert(inputSize);
-    const boost::uint8_t* input = getEncodedData(decodingPosition);
+    const boost::uint8_t* input = _soundDef.data(decodingPosition);
 
     boost::uint32_t consumed = 0;
     boost::uint32_t decodedDataSize = 0;
-    boost::uint8_t* decodedData = _decoder->decode(
-                                      input, 
-                                      inputSize,
-                                      decodedDataSize,
-                                      consumed,
-                                      parse);
+    boost::uint8_t* decodedData = decoder().decode(input, inputSize,
+            decodedDataSize, consumed, parse);
 
     decodingPosition += consumed;
 
@@ -276,18 +118,15 @@ EmbedSoundInst::decodeNextBlock()
             "of decoded data", decodedDataSize, nSamples);
 #endif
 
-    // If the volume needs adjustments we call a function to do that (why are 
we doing this manually ?)
-    if (_soundDef.volume != 100) // volume is a private member
-    {
+    // Adjust volume
+    if (_soundDef.volume != 100) {
         adjustVolume(samples, samples + nSamples, _soundDef.volume/100.0);
     }
 
     /// @todo is use of envelopes really mutually exclusive with
     ///       setting the volume ??
-    else if (envelopes) // envelopes are a private member
-    {
-        unsigned int firstSample = playbackPosition/2;
-
+    else if (envelopes) {
+        unsigned int firstSample = playbackPosition() / 2;
         applyEnvelopes(samples, nSamples, firstSample, *envelopes);
     }
 
@@ -300,14 +139,6 @@ EmbedSoundInst::decodeNextBlock()
     appendDecodedData(decodedData, decodedDataSize);
 }
 
-
-const boost::uint8_t*
-EmbedSoundInst::getEncodedData(unsigned long int pos)
-{
-    return _soundDef.data(pos);
-}
-
-/* private */
 void
 EmbedSoundInst::applyEnvelopes(boost::int16_t* samples, unsigned int nSamples,
         unsigned int firstSampleOffset, const SoundEnvelopes& env)
@@ -379,7 +210,8 @@ EmbedSoundInst::eof() const
 {
     // it isn't threaded, but just in case, we call decodingCompleted first
     // and we also check loopCount... (over paranoid?)
-    return ( ( decodingCompleted() || reachedCustomEnd() ) && !loopCount && 
!decodedSamplesAhead() );
+    return ((decodingCompleted() || reachedCustomEnd())
+            && !loopCount && !decodedSamplesAhead());
 }
 
 EmbedSoundInst::~EmbedSoundInst()
@@ -387,14 +219,6 @@ EmbedSoundInst::~EmbedSoundInst()
     _soundDef.eraseActiveSound(this);
 }
 
-void
-EmbedSoundInst::appendDecodedData(boost::uint8_t* data, unsigned int size)
-{
-    _decodedData.append(data, size);
-
-    delete [] data; // ownership transferred...
-}
-
 } // gnash.sound namespace 
 } // namespace gnash
 
diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index f93bd61..c758ab3 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -20,17 +20,15 @@
 #ifndef SOUND_EMBEDSOUNDINST_H
 #define SOUND_EMBEDSOUNDINST_H
 
-#include "InputStream.h" // for inheritance
-#include "AudioDecoder.h" // for dtor visibility
-#include "SoundEnvelope.h" // for SoundEnvelopes typedef
-#include "SimpleBuffer.h" // for composition (decoded data)
-#include "EmbedSound.h" // for inlines
-#include "sound_handler.h" // for StreamBlockId typedef
-
 #include <memory>
 #include <cassert>
 #include <boost/cstdint.hpp> // For C99 int types
 
+#include "LiveSound.h"
+#include "AudioDecoder.h" 
+#include "SoundEnvelope.h" 
+#include "EmbedSound.h" 
+#include "sound_handler.h" 
 
 // Forward declarations
 namespace gnash {
@@ -46,14 +44,7 @@ namespace gnash {
 namespace sound {
 
 /// Instance of a defined %sound (EmbedSound)
-//
-/// This class contains a pointer to the EmbedSound used for playing
-/// and a SimpleBuffer to use when decoding is needed.
-///
-/// When the SimpleBuffer is NULL we'll play the EmbedSound bytes directly
-/// (we assume they are decoded already)
-///
-class EmbedSoundInst : public InputStream
+class EmbedSoundInst : public LiveSound
 {
 public:
 
@@ -83,7 +74,6 @@ public:
     ///     Number of times this instance should loop over the defined sound.
     ///     Note that every loop begins and ends at the range given by
     ///     inPoint and outPoint.
-    ///
     EmbedSoundInst(EmbedSound& def, media::MediaHandler& mh,
             unsigned int inPoint,
             unsigned int outPoint,
@@ -91,39 +81,19 @@ public:
             unsigned int loopCount);
 
     // See dox in sound_handler.h (InputStream)
-    unsigned int fetchSamples(boost::int16_t* to, unsigned int nSamples);
-
-    // See dox in sound_handler.h (InputStream)
-    unsigned int samplesFetched() const;
-
-    // See dox in sound_handler.h (InputStream)
-    bool eof() const;
+    virtual bool eof() const;
 
     /// Unregister self from the associated EmbedSound
     //
     /// WARNING: must be thread-safe!
-    ///
-    ~EmbedSoundInst();
+    virtual ~EmbedSoundInst();
 
 private:
 
-    /// Append size bytes to this raw data 
-    //
-    /// @param data
-    /// Data bytes, allocated with new[]. Ownership transferred.
-    ///
-    /// @param size
-    /// Size of the 'data' buffer.
-    ///
-    void appendDecodedData(boost::uint8_t* data, unsigned int size);
-
-    size_t encodedDataSize() const {
-        return _soundDef.size();
-    }
+    virtual bool moreData();
 
     /// Apply envelope-volume adjustments
     //
-    ///
     /// Modified envelopes cursor (current_env)
     ///
     /// @param samples
@@ -143,85 +113,28 @@ private:
     void applyEnvelopes(boost::int16_t* samples, unsigned int nSamples,
             unsigned int firstSampleNum, const SoundEnvelopes& env);
 
-    /// Returns the data pointer in the encoded datastream
-    /// for the given position. Boundaries are checked.
-    //
-    /// Uses _samplesFetched and playbackPosition
-    const boost::uint8_t* getEncodedData(unsigned long int pos);
-
-    /// Return number of already-decoded samples available
-    /// from playback position on
-    unsigned int decodedSamplesAhead() const {
-        unsigned int dds = _decodedData.size();
-        if ( dds <= playbackPosition ) return 0; 
-        unsigned int bytesAhead = dds - playbackPosition;
-        assert(!(bytesAhead%2));
-
-        if ( _outPoint < std::numeric_limits<unsigned long>::max() )
-        {
-            unsigned int toCustomEnd = _outPoint-playbackPosition;
-            if ( toCustomEnd < bytesAhead ) bytesAhead = toCustomEnd;
-        }
-
-        unsigned int samplesAhead = bytesAhead/2;
-
-        return samplesAhead;
-    }
-
     bool reachedCustomEnd() const;
 
     /// Return true if there's nothing more to decode
-    bool decodingCompleted() const
-    {
-        // example: 10 bytes of encoded data, decodingPosition 8 : more to 
decode
-        // example: 10 bytes of encoded data, decodingPosition 10 : nothing 
more to decode
-
-        return ( decodingPosition >= encodedDataSize() );
+    virtual bool decodingCompleted() const {
+        return (decodingPosition >= _soundDef.size());
     }
-  
-    /// Create a decoder for this instance
-    //
-    /// If decoder creation fails an error will
-    /// be logged, and _decoder won't be set
-    /// 
-    void createDecoder(media::MediaHandler& mediaHandler);
-
-    /// \brief
-    /// Returns the data pointer in the decoded datastream
-    /// for the given byte-offset.
-    //
-    /// Boundaries are checked.
-    ///
-    /// @param pos offsets in bytes. This should usually be
-    ///        a multiple of two, since decoded data is
-    ///        composed of signed 16bit PCM samples..
-    ///
-    boost::int16_t* getDecodedData(unsigned long int pos);
-
 
     /// Decode next input block
     //
     /// It's assumed !decodingCompleted()
-    ///
-    void decodeNextBlock();
+    virtual void decodeNextBlock();
 
     /// Current decoding position in the encoded stream
     unsigned long decodingPosition;
 
-    /// Current playback position in the decoded stream
-    unsigned long playbackPosition;
-
     /// Numbers of loops: -1 means loop forever, 0 means play once.
     /// For every loop completed, it is decremented.
     long loopCount;
 
-    /// Offset in bytes samples from start of the block
-    /// to begin playback from
-    unsigned long _inPoint;
-
     /// Offset in bytes to end playback at
     /// Never if numeric_limits<unsigned long>::max()
-    unsigned long _outPoint;
+    const unsigned long _outPoint;
 
     /// Sound envelopes for the current sound, which determine the volume level
     /// from a given position. Only used with event sounds.
@@ -230,11 +143,6 @@ private:
     /// Index of current envelope.
     boost::uint32_t current_env;
 
-    /// Number of samples fetched so far.
-    unsigned long _samplesFetched;
-
-    /// The decoder object used to convert the data into the playable format
-    std::auto_ptr<media::AudioDecoder> _decoder;
     /// The encoded data
     //
     /// It is non-const because we deregister ourselves
@@ -242,8 +150,6 @@ private:
     ///
     EmbedSound& _soundDef;
 
-    /// The decoded buffer
-    SimpleBuffer _decodedData;
 };
 
 
diff --git a/libsound/LiveSound.cpp b/libsound/LiveSound.cpp
index 3a78fb5..bca4f2b 100644
--- a/libsound/LiveSound.cpp
+++ b/libsound/LiveSound.cpp
@@ -21,16 +21,20 @@
 #include "LiveSound.h"
 
 #include <algorithm>
+#include <cassert>
 
 #include "log.h"
 #include "SoundInfo.h"
+#include "MediaHandler.h"
 
 namespace gnash {
 namespace sound {
 
-LiveSound::LiveSound(media::MediaHandler& mh, const media::SoundInfo& info, 
int inPoint)
+LiveSound::LiveSound(media::MediaHandler& mh, const media::SoundInfo& info,
+        size_t inPoint)
     :
-    _playbackPosition(inPoint),
+    _inPoint(inPoint * 4),
+    _playbackPosition(_inPoint),
     _samplesFetched(0)
 {
     createDecoder(mh, info);
@@ -40,7 +44,7 @@ void
 LiveSound::createDecoder(media::MediaHandler& mh, const media::SoundInfo& si)
 {
 
-    media::AudioInfo info((int)si.getFormat(), si.getSampleRate(), 
+    media::AudioInfo info(si.getFormat(), si.getSampleRate(), 
         si.is16bit() ? 2 : 1, si.isStereo(), 0, media::CODEC_TYPE_FLASH);
 
     try {
@@ -54,11 +58,6 @@ LiveSound::createDecoder(media::MediaHandler& mh, const 
media::SoundInfo& si)
 unsigned int 
 LiveSound::fetchSamples(boost::int16_t* to, unsigned int nSamples)
 {
-    // If there is no decoder, then we can't decode!
-    // TODO: isn't it documented that an StreamingSound w/out a decoder
-    //       means that the StreamingSoundData data is already decoded ?
-    if (!_decoder.get()) return 0;
-
     unsigned int fetchedSamples = 0;
 
     while (nSamples) {
@@ -72,7 +71,7 @@ LiveSound::fetchSamples(boost::int16_t* to, unsigned int 
nSamples)
                 fetchedSamples += nSamples;
 
                 // Update playback position (samples are 16bit)
-                _playbackPosition += nSamples*2;
+                _playbackPosition += nSamples * 2;
 
                 break; // fetched all
             }
@@ -91,20 +90,13 @@ LiveSound::fetchSamples(boost::int16_t* to, unsigned int 
nSamples)
             }
         }
 
-        // We haven't finished fetching yet, so see if we
-        // have more to decode or not
-        if (decodingCompleted()) {
-            break; 
-        }
-
-        // Should only be called when no more decoded data
-        // are available for fetching.
-        // Doing so we know what's the sample number
-        // of the first sample in the newly decoded block.
-        assert(_playbackPosition >= _decodedData.size());
+        // Get more data if it's ready. This could involve looping.
+        // Even if no data is available now, it can become available
+        // later.
+        if (!moreData()) break;
 
-        // More to decode, then decode it
-        decodeNextBlock();
+        // We have looped.
+        if (!_samplesFetched) continue;
     }
 
     // update samples played
diff --git a/libsound/LiveSound.h b/libsound/LiveSound.h
index a7bf91c..9747228 100644
--- a/libsound/LiveSound.h
+++ b/libsound/LiveSound.h
@@ -1,7 +1,7 @@
-// LiveSound.h - instance of an embedded sound, for gnash
+// LiveSound.h: - base class for embedded sound handling, for gnash
 // 
-//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
-//   2011 Free Software Foundation, Inc
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
+//   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
@@ -26,16 +26,11 @@
 
 #include "InputStream.h" 
 #include "AudioDecoder.h" 
-#include "SoundEnvelope.h"
 #include "SimpleBuffer.h" 
-#include "sound_handler.h" 
 #include "SoundInfo.h"
 
 // Forward declarations
 namespace gnash {
-    namespace sound {
-        class LiveSoundData;
-    }
     namespace media {
         class MediaHandler;
     }
@@ -50,45 +45,56 @@ namespace sound {
 /// and a SimpleBuffer to use when decoding is needed.
 class LiveSound : public InputStream
 {
-public:
+protected:
 
     /// Create an embedded %sound instance
     //
-    /// @param def      The sound data for this sound 
     /// @param mh       The MediaHandler to use for on-demand decoding
-    /// @param blockId  Identifier of the encoded block to start decoding from.
-    ///                 @see gnash::swf::StreamSoundBlockTag
     /// @param inPoint  Offset in output samples this instance should start
     ///                 playing from. These are post-resampling samples (44100 
     ///                 for one second of samples).
-    LiveSound(media::MediaHandler& mh, const media::SoundInfo& info, int 
inPoint);
+    /// @param info     The media::SoundInfo for this sound.
+    LiveSound(media::MediaHandler& mh, const media::SoundInfo& info,
+            size_t inPoint);
 
     // Pointer handling and checking functions
-    const boost::int16_t*
-    getDecodedData(unsigned long int pos) const {
+    const boost::int16_t* getDecodedData(unsigned long int pos) const {
         assert(pos < _decodedData.size());
-        return reinterpret_cast<const boost::int16_t*>(_decodedData.data() + 
pos);
+        return reinterpret_cast<const boost::int16_t*>(
+                _decodedData.data() + pos);
     }
 
+    /// Called when more decoded sound data is required.
+    //
+    /// This will be called whenever no more decoded data is available
+    /// but decoding is not complete.
+    virtual bool moreData() = 0;
+
+    /// True if there is no more data.
     virtual bool eof() const = 0;
 
+    void restart() {
+        _playbackPosition = _inPoint;
+        _samplesFetched = 0;
+    }
+
     unsigned int samplesFetched() const {
         return _samplesFetched;
     }
 
-protected:
+    size_t playbackPosition() const {
+        return _playbackPosition;
+    }
 
-    media::AudioDecoder* decoder() const {
-        return _decoder.get();
+    media::AudioDecoder& decoder() const {
+        return *_decoder;
     }
 
-    void appendDecodedData(boost::uint8_t* data, unsigned int size)
-    {
+    void appendDecodedData(boost::uint8_t* data, unsigned int size) {
         _decodedData.append(data, size);
-        delete [] data; // ownership transferred...
+        delete [] data;
     }
 
-
     /// Return number of already-decoded samples available
     /// from playback position on
     unsigned int decodedSamplesAhead() const {
@@ -103,24 +109,24 @@ protected:
         return samplesAhead;
     }
 
+private:
+
     // See dox in sound_handler.h (InputStream)
     unsigned int fetchSamples(boost::int16_t* to, unsigned int nSamples);
 
     void createDecoder(media::MediaHandler& mediaHandler,
             const media::SoundInfo& info);
 
+    virtual bool decodingCompleted() const = 0;
+
+    const size_t _inPoint;
+
     /// Current playback position in the decoded stream
     size_t _playbackPosition;
 
     /// Number of samples fetched so far.
     unsigned long _samplesFetched;
 
-private:
-
-    virtual void decodeNextBlock() = 0;
-
-    virtual bool decodingCompleted() const = 0;
-
     boost::scoped_ptr<media::AudioDecoder> _decoder;
 
     /// The decoded buffer
@@ -128,6 +134,12 @@ private:
 
 };
 
+inline bool
+requiresParsing(const media::SoundInfo& info)
+{
+    return info.getFormat() != media::AUDIO_CODEC_ADPCM;
+}
+
 
 } // gnash.sound namespace 
 } // namespace gnash
diff --git a/libsound/StreamingSound.cpp b/libsound/StreamingSound.cpp
index 6b21202..aa317c5 100644
--- a/libsound/StreamingSound.cpp
+++ b/libsound/StreamingSound.cpp
@@ -1,7 +1,7 @@
 // StreamingSound.cpp - instance of an embedded sound, for gnash
 //
-//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
-//   2011 Free Software Foundation, Inc
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
+//   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
@@ -22,35 +22,35 @@
 
 #include <cmath>
 
-#include "SoundInfo.h" // for use
-#include "MediaHandler.h" // for use
-#include "GnashException.h" // for SoundException
-#include "AudioDecoder.h" // for use
-#include "log.h" // will import boost::format too
+#include "AudioDecoder.h" 
+#include "log.h" 
 #include "SoundUtils.h"
 
-// Debug sound decoding
-//#define GNASH_DEBUG_SOUNDS_DECODING
-
-//#define GNASH_DEBUG_SOUNDS_MANAGEMENT
-
 namespace gnash {
 namespace sound {
 
-StreamingSound::StreamingSound(StreamingSoundData& soundData,
-            media::MediaHandler& mh,
-            sound_handler::StreamBlockId blockOffset,
+StreamingSound::StreamingSound(StreamingSoundData& sd,
+            media::MediaHandler& mh, sound_handler::StreamBlockId block,
             unsigned int inPoint)
         :
-        LiveSound(mh, soundData.soundinfo, inPoint),
-        _currentBlock(blockOffset),
+        LiveSound(mh, sd.soundinfo, inPoint),
+        _currentBlock(block),
         _positionInBlock(0),
         // parameter is in stereo samples (44100 per second)
         // we double to take 2 channels into account
         // and double again to use bytes
         _inPoint(inPoint * 4),
-        _soundDef(soundData)
+        _soundDef(sd)
+{
+}
+
+bool
+StreamingSound::moreData()
 {
+    if (decodingCompleted()) return false;
+
+    decodeNextBlock();
+    return true;
 }
 
 void
@@ -58,36 +58,22 @@ StreamingSound::decodeNextBlock()
 {
     assert(!decodingCompleted());
 
-    const StreamingSoundData& sndData = _soundDef;
-    const bool parse =
-        sndData.soundinfo.getFormat() == media::AUDIO_CODEC_ADPCM ?
-        false : true;
+    const bool parse = requiresParsing(_soundDef.soundinfo);
 
+    // Get the current block of sound data.
     const SimpleBuffer& block = _soundDef.getBlock(_currentBlock);
 
-    // Move onto next block.
-    // decode it, add to decoded sound.
-
-    // This is a streaming sound. This function is only called if there is
-    // data to decode. If there is data, there must be frames.
+    // If we didn't decode all of a block, do so now. Not sure if this
+    // can happen.
     const boost::uint32_t inputSize = block.size() - _positionInBlock; 
 
-#ifdef GNASH_DEBUG_SOUNDS_DECODING
-    log_debug(" frame size for frame starting at offset %d is %d",
-        decodingPosition, inputSize);
-#endif
-
     assert(inputSize);
     const boost::uint8_t* input = block.data() + _positionInBlock;
 
     boost::uint32_t consumed = 0;
     boost::uint32_t decodedDataSize = 0;
-    boost::uint8_t* decodedData = decoder()->decode(
-                                      input, 
-                                      inputSize,
-                                      decodedDataSize,
-                                      consumed,
-                                      parse);
+    boost::uint8_t* decodedData = decoder().decode(input, inputSize,
+            decodedDataSize, consumed, parse);
 
     // Check if the entire block was consumed.
     if (consumed == block.size()) {
@@ -106,10 +92,6 @@ StreamingSound::decodeNextBlock()
         adjustVolume(samples, samples + nSamples, _soundDef.volume/100.0);
     }
 
-#ifdef GNASH_DEBUG_MIXING
-    log_debug("  appending %d bytes to decoded buffer", decodedDataSize);
-#endif
-
     // decodedData ownership transferred here
     appendDecodedData(decodedData, decodedDataSize);
 }
diff --git a/libsound/StreamingSound.h b/libsound/StreamingSound.h
index 6262316..f68578a 100644
--- a/libsound/StreamingSound.h
+++ b/libsound/StreamingSound.h
@@ -75,6 +75,12 @@ public:
 
 private:
 
+    /// Called when more data is required.
+    //
+    /// StreamingSounds can temporarily run out of data if not enough
+    /// samples are present for a frame.
+    virtual bool moreData();
+
     /// Return true if there's nothing more to decode
     virtual bool decodingCompleted() const {
         return _positionInBlock == 0 && 
@@ -84,7 +90,7 @@ private:
     /// Decode next input block
     //
     /// It's assumed !decodingCompleted()
-    virtual void decodeNextBlock();
+    void decodeNextBlock();
 
     // The current block of sound.
     size_t _currentBlock;
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 7d7569f..3675eb3 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -149,8 +149,7 @@ sound_handler::delete_sound(int handle)
 #endif
 
     EmbedSound* def = _sounds[handle];
-    if ( ! def )
-    {
+    if (!def) {
         log_error("handle passed to delete_sound (%d) "
                   "already deleted", handle);
         return;
@@ -462,7 +461,7 @@ sound_handler::isSoundPlaying(int handle) const
 void
 sound_handler::playStream(int soundId, StreamBlockId blockId)
 {
-    const unsigned int inPoint=0;
+    const unsigned int inPoint = 0;
 
     StreamingSoundData& s = *_streamingSounds[soundId];
     if (s.isPlaying() || s.empty()) return;
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 8726c20..2b65bae 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -23,21 +23,21 @@
 #include "gnashconfig.h"
 #endif
 
-#include "dsodefs.h" // for DSOEXPORT
-#include "MediaHandler.h" // for inlined ctor
-#include "SoundEnvelope.h" // for SoundEnvelopes typedef
-#include "AuxStream.h" // for aux_stramer_ptr typedef
-#include "WAVWriter.h" // for dtor visibility 
-
 #include <string>
 #include <vector>
 #include <memory>
 #include <cassert>
 #include <cstring>
 #include <limits>
-#include <set> // for composition
+#include <set>
 #include <boost/scoped_ptr.hpp>
 
+#include "dsodefs.h" // for DSOEXPORT
+#include "MediaHandler.h" // for inlined ctor
+#include "SoundEnvelope.h" // for SoundEnvelopes typedef
+#include "AuxStream.h" // for aux_streamer_ptr typedef
+#include "WAVWriter.h" // for dtor visibility 
+
 namespace gnash {
     namespace media {
         class SoundInfo;

http://git.savannah.gnu.org/cgit//commit/?id=8f659a54c78f8e0f072de027d1a9fd2320f3e867


commit 8f659a54c78f8e0f072de027d1a9fd2320f3e867
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 14:47:44 2011 +0200

    Introduce a common base class for sounds.

diff --git a/libsound/EmbedSound.cpp b/libsound/EmbedSound.cpp
index 35b8270..1b2c231 100644
--- a/libsound/EmbedSound.cpp
+++ b/libsound/EmbedSound.cpp
@@ -33,22 +33,13 @@ namespace gnash {
 namespace sound {
 
 EmbedSound::EmbedSound(std::auto_ptr<SimpleBuffer> data,
-        const media::SoundInfo& info, int nVolume, size_t paddingBytes)
+        const media::SoundInfo& info, int nVolume)
     :
     _buf(data.release()),
     soundinfo(info),
     volume(nVolume)
 {
-    if (_buf.get()) {
-        if (_buf->capacity() - _buf->size() < paddingBytes) {
-            log_error("EmbedSound creator didn't appropriately pad sound data. 
"
-                "We'll do now, but will cost memory copies.");
-            _buf->reserve(_buf->size()+paddingBytes);
-        }
-    }
-    else {
-        _buf.reset(new SimpleBuffer());
-    }
+    if (!_buf.get()) _buf.reset(new SimpleBuffer());
 }
 
 void
diff --git a/libsound/EmbedSound.h b/libsound/EmbedSound.h
index 0f99100..bbdc224 100644
--- a/libsound/EmbedSound.h
+++ b/libsound/EmbedSound.h
@@ -53,21 +53,15 @@ public:
     /// Vector containing the active instances of this sounds being played
     //
     /// NOTE: This class does NOT own the active sounds
-    ///
     typedef std::list<EmbedSoundInst*> Instances;
 
     /// Construct a sound with given data, info and volume.
     //
     /// @param data The encoded sound data.
-    ///     May be the NULL pointer for streaming sounds,
-    ///     in which case data will be appended later using ::append()
-    ///
     /// @param info encoding info
-    ///
     /// @param nVolume initial volume (0..100). Optional, defaults to 100.
-    ///
     EmbedSound(std::auto_ptr<SimpleBuffer> data, const media::SoundInfo& info,
-            int nVolume, size_t paddingBytes);
+            int nVolume);
 
     ~EmbedSound();
 
diff --git a/libsound/LiveSound.cpp b/libsound/LiveSound.cpp
new file mode 100644
index 0000000..3a78fb5
--- /dev/null
+++ b/libsound/LiveSound.cpp
@@ -0,0 +1,119 @@
+// LiveSound.cpp - instance of an embedded sound, for gnash
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
+//   2011 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 "LiveSound.h"
+
+#include <algorithm>
+
+#include "log.h"
+#include "SoundInfo.h"
+
+namespace gnash {
+namespace sound {
+
+LiveSound::LiveSound(media::MediaHandler& mh, const media::SoundInfo& info, 
int inPoint)
+    :
+    _playbackPosition(inPoint),
+    _samplesFetched(0)
+{
+    createDecoder(mh, info);
+}
+
+void
+LiveSound::createDecoder(media::MediaHandler& mh, const media::SoundInfo& si)
+{
+
+    media::AudioInfo info((int)si.getFormat(), si.getSampleRate(), 
+        si.is16bit() ? 2 : 1, si.isStereo(), 0, media::CODEC_TYPE_FLASH);
+
+    try {
+        _decoder.reset(mh.createAudioDecoder(info).release());
+    }
+    catch (const MediaException& e) {
+        log_error("AudioDecoder initialization failed: %s", e.what());
+    }
+}
+
+unsigned int 
+LiveSound::fetchSamples(boost::int16_t* to, unsigned int nSamples)
+{
+    // If there is no decoder, then we can't decode!
+    // TODO: isn't it documented that an StreamingSound w/out a decoder
+    //       means that the StreamingSoundData data is already decoded ?
+    if (!_decoder.get()) return 0;
+
+    unsigned int fetchedSamples = 0;
+
+    while (nSamples) {
+        unsigned int availableSamples = decodedSamplesAhead();
+
+        if (availableSamples) {
+            const boost::int16_t* data = getDecodedData(_playbackPosition);
+
+            if (availableSamples >= nSamples) {
+                std::copy(data, data + nSamples, to);
+                fetchedSamples += nSamples;
+
+                // Update playback position (samples are 16bit)
+                _playbackPosition += nSamples*2;
+
+                break; // fetched all
+            }
+            else {
+                // not enough decoded samples available:
+                // copy what we have and go on
+                std::copy(data, data + availableSamples, to);
+                fetchedSamples += availableSamples;
+
+                // Update playback position (samples are 16bit)
+                _playbackPosition += availableSamples * 2;
+
+                to += availableSamples;
+                nSamples -= availableSamples;
+                assert(nSamples);
+            }
+        }
+
+        // We haven't finished fetching yet, so see if we
+        // have more to decode or not
+        if (decodingCompleted()) {
+            break; 
+        }
+
+        // Should only be called when no more decoded data
+        // are available for fetching.
+        // Doing so we know what's the sample number
+        // of the first sample in the newly decoded block.
+        assert(_playbackPosition >= _decodedData.size());
+
+        // More to decode, then decode it
+        decodeNextBlock();
+    }
+
+    // update samples played
+    _samplesFetched += fetchedSamples;
+
+    return fetchedSamples;
+}
+
+
+} // sound namespace 
+} // namespace gnash
+
diff --git a/libsound/StreamingSound.h b/libsound/LiveSound.h
similarity index 52%
copy from libsound/StreamingSound.h
copy to libsound/LiveSound.h
index 3e88f7f..a7bf91c 100644
--- a/libsound/StreamingSound.h
+++ b/libsound/LiveSound.h
@@ -1,4 +1,4 @@
-// StreamingSound.h - instance of an embedded sound, for gnash
+// LiveSound.h - instance of an embedded sound, for gnash
 // 
 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
 //   2011 Free Software Foundation, Inc
@@ -17,8 +17,8 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-#ifndef SOUND_STREAMINGSOUND_H
-#define SOUND_STREAMINGSOUND_H
+#ifndef SOUND_LIVESOUND_H
+#define SOUND_LIVESOUND_H
 
 #include <boost/scoped_ptr.hpp>
 #include <cassert>
@@ -28,13 +28,13 @@
 #include "AudioDecoder.h" 
 #include "SoundEnvelope.h"
 #include "SimpleBuffer.h" 
-#include "StreamingSoundData.h" 
 #include "sound_handler.h" 
+#include "SoundInfo.h"
 
 // Forward declarations
 namespace gnash {
     namespace sound {
-        class StreamingSoundData;
+        class LiveSoundData;
     }
     namespace media {
         class MediaHandler;
@@ -44,11 +44,11 @@ namespace gnash {
 namespace gnash {
 namespace sound {
 
-/// Instance of a defined %sound (StreamingSoundData)
+/// Instance of a defined %sound (LiveSoundData)
 //
-/// This class contains a pointer to the StreamingSoundData used for playing
+/// This class contains a pointer to the LiveSoundData used for playing
 /// and a SimpleBuffer to use when decoding is needed.
-class StreamingSound : public InputStream
+class LiveSound : public InputStream
 {
 public:
 
@@ -61,40 +61,33 @@ public:
     /// @param inPoint  Offset in output samples this instance should start
     ///                 playing from. These are post-resampling samples (44100 
     ///                 for one second of samples).
-    StreamingSound(StreamingSoundData& def, media::MediaHandler& mh,
-            sound_handler::StreamBlockId blockId,
-            unsigned int inPoint);
+    LiveSound(media::MediaHandler& mh, const media::SoundInfo& info, int 
inPoint);
 
-    // See dox in sound_handler.h (InputStream)
-    unsigned int fetchSamples(boost::int16_t* to, unsigned int nSamples);
+    // Pointer handling and checking functions
+    const boost::int16_t*
+    getDecodedData(unsigned long int pos) const {
+        assert(pos < _decodedData.size());
+        return reinterpret_cast<const boost::int16_t*>(_decodedData.data() + 
pos);
+    }
 
-    // See dox in sound_handler.h (InputStream)
-    unsigned int samplesFetched() const;
+    virtual bool eof() const = 0;
 
-    // See dox in sound_handler.h (InputStream)
-    bool eof() const;
+    unsigned int samplesFetched() const {
+        return _samplesFetched;
+    }
 
-    /// Unregister self from the associated StreamingSoundData
-    //
-    /// WARNING: must be thread-safe!
-    ~StreamingSound();
+protected:
 
-private:
+    media::AudioDecoder* decoder() const {
+        return _decoder.get();
+    }
+
+    void appendDecodedData(boost::uint8_t* data, unsigned int size)
+    {
+        _decodedData.append(data, size);
+        delete [] data; // ownership transferred...
+    }
 
-    /// Append size bytes to this raw data 
-    //
-    /// @param data
-    /// Data bytes, allocated with new[]. Ownership transferred.
-    ///
-    /// @param size
-    /// Size of the 'data' buffer.
-    void appendDecodedData(boost::uint8_t* data, unsigned int size);
-
-    /// Returns the data pointer in the encoded datastream
-    /// for the given position. Boundaries are checked.
-    //
-    /// Uses _samplesFetched and _playbackPosition
-    const boost::uint8_t* getEncodedData(unsigned long int pos);
 
     /// Return number of already-decoded samples available
     /// from playback position on
@@ -110,60 +103,29 @@ private:
         return samplesAhead;
     }
 
-    /// Return true if there's nothing more to decode
-    bool decodingCompleted() const {
-        return _positionInBlock == 0 && 
-            _currentBlock >= _soundDef.blockCount();
-    }
-
-    /// Create a decoder for this instance
-    //
-    /// If decoder creation fails an error will
-    /// be logged, and _decoder won't be set
-    void createDecoder(media::MediaHandler& mediaHandler);
-
-    /// Access data in the decoded datastream for the given byte offset.
-    //
-    /// Boundaries are checked.
-    ///
-    /// @param pos offsets in bytes. This should usually be
-    ///        a multiple of two, since decoded data is
-    ///        composed of signed 16bit PCM samples..
-    boost::int16_t* getDecodedData(unsigned long int pos);
-
-    /// Decode next input block
-    //
-    /// It's assumed !decodingCompleted()
-    void decodeNextBlock();
-
-    // The current block of sound.
-    size_t _currentBlock;
+    // See dox in sound_handler.h (InputStream)
+    unsigned int fetchSamples(boost::int16_t* to, unsigned int nSamples);
 
-    // The position within the current block.
-    size_t _positionInBlock;
+    void createDecoder(media::MediaHandler& mediaHandler,
+            const media::SoundInfo& info);
 
     /// Current playback position in the decoded stream
     size_t _playbackPosition;
 
-    /// Offset in bytes samples from start of the block
-    /// to begin playback from
-    unsigned long _inPoint;
-
     /// Number of samples fetched so far.
     unsigned long _samplesFetched;
 
-    /// The decoder object used to convert the data into the playable format
-    boost::scoped_ptr<media::AudioDecoder> _decoder;
+private:
 
-    /// The encoded data
-    //
-    /// It is non-const because we deregister ourselves
-    /// from its container of playing instances on destruction
-    ///
-    StreamingSoundData& _soundDef;
+    virtual void decodeNextBlock() = 0;
+
+    virtual bool decodingCompleted() const = 0;
+
+    boost::scoped_ptr<media::AudioDecoder> _decoder;
 
     /// The decoded buffer
     SimpleBuffer _decodedData;
+
 };
 
 
diff --git a/libsound/Makefile.am b/libsound/Makefile.am
index 8125d67..f927c42 100644
--- a/libsound/Makefile.am
+++ b/libsound/Makefile.am
@@ -26,6 +26,8 @@ libgnashsound_la_SOURCES = \
        StreamingSoundData.h \
        StreamingSound.cpp \
        StreamingSound.h \
+       LiveSound.cpp \
+       LiveSound.h \
        EmbedSoundInst.cpp \
        EmbedSoundInst.h \
        SoundUtils.h \
diff --git a/libsound/StreamingSound.cpp b/libsound/StreamingSound.cpp
index 5e55321..6b21202 100644
--- a/libsound/StreamingSound.cpp
+++ b/libsound/StreamingSound.cpp
@@ -21,7 +21,6 @@
 #include "StreamingSound.h"
 
 #include <cmath>
-#include <vector>
 
 #include "SoundInfo.h" // for use
 #include "MediaHandler.h" // for use
@@ -38,128 +37,27 @@
 namespace gnash {
 namespace sound {
 
-unsigned int
-StreamingSound::samplesFetched() const
-{
-    return _samplesFetched;
-}
-
 StreamingSound::StreamingSound(StreamingSoundData& soundData,
-            media::MediaHandler& mediaHandler,
+            media::MediaHandler& mh,
             sound_handler::StreamBlockId blockOffset,
             unsigned int inPoint)
         :
+        LiveSound(mh, soundData.soundinfo, inPoint),
         _currentBlock(blockOffset),
         _positionInBlock(0),
         // parameter is in stereo samples (44100 per second)
         // we double to take 2 channels into account
         // and double again to use bytes
         _inPoint(inPoint * 4),
-        _samplesFetched(0),
-        _decoder(0),
         _soundDef(soundData)
 {
-    _playbackPosition = _inPoint; 
-    createDecoder(mediaHandler);
 }
 
-/*private*/
-void
-StreamingSound::createDecoder(media::MediaHandler& mediaHandler)
-{
-    const media::SoundInfo& si = _soundDef.soundinfo;
-
-    media::AudioInfo info(
-        (int)si.getFormat(), 
-        si.getSampleRate(), 
-        si.is16bit() ? 2 : 1, 
-        si.isStereo(), 
-        0, media::CODEC_TYPE_FLASH);
-
-    try {
-        _decoder.reset(mediaHandler.createAudioDecoder(info).release());
-    }
-    catch (const MediaException& e) {
-        log_error("AudioDecoder initialization failed: %s", e.what());
-    }
-}
-
-// Pointer handling and checking functions
-boost::int16_t*
-StreamingSound::getDecodedData(unsigned long int pos)
-{
-    assert(pos < _decodedData.size());
-    return reinterpret_cast<boost::int16_t*>(_decodedData.data() + pos);
-}
-
-unsigned int 
-StreamingSound::fetchSamples(boost::int16_t* to, unsigned int nSamples)
-{
-    // If there is no decoder, then we can't decode!
-    // TODO: isn't it documented that an StreamingSound w/out a decoder
-    //       means that the StreamingSoundData data is already decoded ?
-    if (!_decoder.get()) return 0;
-
-    unsigned int fetchedSamples = 0;
-
-    while (nSamples) {
-        unsigned int availableSamples = decodedSamplesAhead();
-
-        if (availableSamples) {
-            boost::int16_t* data = getDecodedData(_playbackPosition);
-
-            if (availableSamples >= nSamples) {
-                std::copy(data, data + nSamples, to);
-                fetchedSamples += nSamples;
-
-                // Update playback position (samples are 16bit)
-                _playbackPosition += nSamples*2;
-
-                break; // fetched all
-            }
-            else {
-                // not enough decoded samples available:
-                // copy what we have and go on
-                std::copy(data, data + availableSamples, to);
-                fetchedSamples += availableSamples;
-
-                // Update playback position (samples are 16bit)
-                _playbackPosition += availableSamples * 2;
-
-                to += availableSamples;
-                nSamples -= availableSamples;
-                assert(nSamples);
-            }
-        }
-
-        // We haven't finished fetching yet, so see if we
-        // have more to decode or not
-        if (decodingCompleted()) {
-            break; 
-        }
-
-        // More to decode, then decode it
-        decodeNextBlock();
-    }
-
-    // update samples played
-    _samplesFetched += fetchedSamples;
-
-    return fetchedSamples;
-}
-
-/*private*/
 void
 StreamingSound::decodeNextBlock()
 {
     assert(!decodingCompleted());
 
-    // Should only be called when no more decoded data
-    // are available for fetching.
-    // Doing so we know what's the sample number
-    // of the first sample in the newly decoded block.
-    assert(_playbackPosition >= _decodedData.size());
-
     const StreamingSoundData& sndData = _soundDef;
     const bool parse =
         sndData.soundinfo.getFormat() == media::AUDIO_CODEC_ADPCM ?
@@ -184,7 +82,7 @@ StreamingSound::decodeNextBlock()
 
     boost::uint32_t consumed = 0;
     boost::uint32_t decodedDataSize = 0;
-    boost::uint8_t* decodedData = _decoder->decode(
+    boost::uint8_t* decodedData = decoder()->decode(
                                       input, 
                                       inputSize,
                                       decodedDataSize,
@@ -228,13 +126,6 @@ StreamingSound::~StreamingSound()
     _soundDef.eraseActiveSound(this);
 }
 
-void
-StreamingSound::appendDecodedData(boost::uint8_t* data, unsigned int size)
-{
-    _decodedData.append(data, size);
-    delete [] data; // ownership transferred...
-}
-
 } // gnash.sound namespace 
 } // namespace gnash
 
diff --git a/libsound/StreamingSound.h b/libsound/StreamingSound.h
index 3e88f7f..6262316 100644
--- a/libsound/StreamingSound.h
+++ b/libsound/StreamingSound.h
@@ -24,7 +24,7 @@
 #include <cassert>
 #include <boost/cstdint.hpp> // For C99 int types
 
-#include "InputStream.h" 
+#include "LiveSound.h" 
 #include "AudioDecoder.h" 
 #include "SoundEnvelope.h"
 #include "SimpleBuffer.h" 
@@ -48,7 +48,7 @@ namespace sound {
 //
 /// This class contains a pointer to the StreamingSoundData used for playing
 /// and a SimpleBuffer to use when decoding is needed.
-class StreamingSound : public InputStream
+class StreamingSound : public LiveSound
 {
 public:
 
@@ -66,13 +66,7 @@ public:
             unsigned int inPoint);
 
     // See dox in sound_handler.h (InputStream)
-    unsigned int fetchSamples(boost::int16_t* to, unsigned int nSamples);
-
-    // See dox in sound_handler.h (InputStream)
-    unsigned int samplesFetched() const;
-
-    // See dox in sound_handler.h (InputStream)
-    bool eof() const;
+    virtual bool eof() const;
 
     /// Unregister self from the associated StreamingSoundData
     //
@@ -81,60 +75,16 @@ public:
 
 private:
 
-    /// Append size bytes to this raw data 
-    //
-    /// @param data
-    /// Data bytes, allocated with new[]. Ownership transferred.
-    ///
-    /// @param size
-    /// Size of the 'data' buffer.
-    void appendDecodedData(boost::uint8_t* data, unsigned int size);
-
-    /// Returns the data pointer in the encoded datastream
-    /// for the given position. Boundaries are checked.
-    //
-    /// Uses _samplesFetched and _playbackPosition
-    const boost::uint8_t* getEncodedData(unsigned long int pos);
-
-    /// Return number of already-decoded samples available
-    /// from playback position on
-    unsigned int decodedSamplesAhead() const {
-
-        const unsigned int dds = _decodedData.size();
-        if (dds <= _playbackPosition) return 0; 
-
-        const unsigned int bytesAhead = dds - _playbackPosition;
-        assert(!(bytesAhead % 2));
-
-        const unsigned int samplesAhead = bytesAhead / 2;
-        return samplesAhead;
-    }
-
     /// Return true if there's nothing more to decode
-    bool decodingCompleted() const {
+    virtual bool decodingCompleted() const {
         return _positionInBlock == 0 && 
             _currentBlock >= _soundDef.blockCount();
     }
 
-    /// Create a decoder for this instance
-    //
-    /// If decoder creation fails an error will
-    /// be logged, and _decoder won't be set
-    void createDecoder(media::MediaHandler& mediaHandler);
-
-    /// Access data in the decoded datastream for the given byte offset.
-    //
-    /// Boundaries are checked.
-    ///
-    /// @param pos offsets in bytes. This should usually be
-    ///        a multiple of two, since decoded data is
-    ///        composed of signed 16bit PCM samples..
-    boost::int16_t* getDecodedData(unsigned long int pos);
-
     /// Decode next input block
     //
     /// It's assumed !decodingCompleted()
-    void decodeNextBlock();
+    virtual void decodeNextBlock();
 
     // The current block of sound.
     size_t _currentBlock;
@@ -142,32 +92,20 @@ private:
     // The position within the current block.
     size_t _positionInBlock;
 
-    /// Current playback position in the decoded stream
-    size_t _playbackPosition;
-
     /// Offset in bytes samples from start of the block
     /// to begin playback from
     unsigned long _inPoint;
 
-    /// Number of samples fetched so far.
-    unsigned long _samplesFetched;
-
-    /// The decoder object used to convert the data into the playable format
-    boost::scoped_ptr<media::AudioDecoder> _decoder;
-
     /// The encoded data
     //
     /// It is non-const because we deregister ourselves
     /// from its container of playing instances on destruction
     ///
     StreamingSoundData& _soundDef;
-
-    /// The decoded buffer
-    SimpleBuffer _decodedData;
 };
 
 
 } // gnash.sound namespace 
 } // namespace gnash
 
-#endif // SOUND_EMBEDSOUNDINST_H
+#endif
diff --git a/libsound/StreamingSoundData.cpp b/libsound/StreamingSoundData.cpp
index f46bfdf..be8917b 100644
--- a/libsound/StreamingSoundData.cpp
+++ b/libsound/StreamingSoundData.cpp
@@ -38,23 +38,15 @@ StreamingSoundData::append(std::auto_ptr<SimpleBuffer> 
data, size_t sampleCount)
 {
     UNUSED(sampleCount);
     assert(data.get());
-
-    if (data->capacity() - data->size() < _paddingBytes) {
-        log_error("Streaming sound block creator didn't appropriately pad "
-                "sound data. We'll do so now, but will cost memory copies.");
-        data->reserve(data->size() + _paddingBytes);
-    }
-
     _buffers.push_back(data);
     return _buffers.size() - 1;
 }
 
 StreamingSoundData::StreamingSoundData(const media::SoundInfo& info,
-        int nVolume, size_t paddingBytes)
+        int nVolume)
     :
     soundinfo(info),
-    volume(nVolume),
-    _paddingBytes(paddingBytes)
+    volume(nVolume)
 {
 }
 
diff --git a/libsound/StreamingSoundData.h b/libsound/StreamingSoundData.h
index c976d2f..dffa6dd 100644
--- a/libsound/StreamingSoundData.h
+++ b/libsound/StreamingSoundData.h
@@ -58,23 +58,17 @@ public:
 
     /// Construct a sound with given data, info and volume.
     //
-    /// @param data The encoded sound data.
-    ///     May be the NULL pointer for streaming sounds,
-    ///     in which case data will be appended later using ::append()
-    ///
     /// @param info encoding info
-    ///
-    /// @param nVolume initial volume (0..100). Optional, defaults to 100.
-    ///
-    StreamingSoundData(const media::SoundInfo& info,
-            int nVolume, size_t paddingBytes);
+    /// @param nVolume initial volume (0..100).
+    StreamingSoundData(const media::SoundInfo& info, int nVolume);
 
     ~StreamingSoundData();
 
     /// Append a sound data block
     //
-    /// @param data             Undecoded sound data.
-    /// @param sampleCount      The number of samples when decoded.
+    /// @param data          Undecoded sound data. Must be appropriately
+    ///                      padded (see MediaHandler::getInputPaddingBytes())
+    /// @param sampleCount   The number of samples when decoded.
     size_t append(std::auto_ptr<SimpleBuffer> data, size_t sampleCount);
 
     /// Do we have any data?
@@ -172,8 +166,6 @@ public:
     /// Mutex protecting access to _soundInstances
     mutable boost::mutex _soundInstancesMutex;
 
-    const size_t _paddingBytes;
-
     boost::ptr_vector<SimpleBuffer> _buffers;
 };
 
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 5847626..7d7569f 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -30,6 +30,7 @@
 #include "log.h" // for use
 #include "StreamingSound.h"
 #include "StreamingSoundData.h"
+#include "SimpleBuffer.h"
 
 // Debug create_sound/delete_sound/playSound/stop_sound, loops
 //#define GNASH_DEBUG_SOUNDS_MANAGEMENT
@@ -37,6 +38,9 @@
 // Debug samples fetching
 //#define GNASH_DEBUG_SAMPLES_FETCHING 1
 
+namespace gnash {
+namespace sound {
+
 namespace {
 
 unsigned int
@@ -54,10 +58,22 @@ validHandle(const T& container, int handle)
     return handle >= 0 && static_cast<size_t>(handle) < container.size();
 }
 
+/// Ensure that each buffer has appropriate padding for the decoder.
+//
+/// Note: all callers passing a SimpleBuffer should already do this,
+/// so this is a paranoid check.
+void
+ensurePadding(SimpleBuffer& data, media::MediaHandler* m)
+{
+    const size_t padding = m ? m->getInputPaddingSize() : 0;
+    if (data.capacity() - data.size() < padding) {
+        log_error("Sound data creator didn't appropriately pad "
+                "buffer. We'll do so now, but will cost memory copies.");
+        data.reserve(data.size() + padding);
+    }
 }
 
-namespace gnash {
-namespace sound {
+} // anonymous namespace
 
 sound_handler::StreamBlockId
 sound_handler::addSoundBlock(std::auto_ptr<SimpleBuffer> data,
@@ -76,6 +92,9 @@ sound_handler::addSoundBlock(std::auto_ptr<SimpleBuffer> data,
         return -1;
     }
 
+    assert(data.get());
+    ensurePadding(*data, _mediaHandler);
+
     // Handling of the sound data
     return sounddata->append(data, sample_count);
 }
@@ -355,8 +374,7 @@ int
 sound_handler::createStreamingSound(const media::SoundInfo& sinfo)
 {
     std::auto_ptr<StreamingSoundData> sounddata(
-            new StreamingSoundData(sinfo, 100,
-                _mediaHandler ? _mediaHandler->getInputPaddingSize() : 0));
+            new StreamingSoundData(sinfo, 100));
 
     int sound_id = _streamingSounds.size();
     // the vector takes ownership
@@ -369,9 +387,13 @@ int
 sound_handler::create_sound(std::auto_ptr<SimpleBuffer> data,
                             const media::SoundInfo& sinfo)
 {
-    std::auto_ptr<EmbedSound> sounddata(
-            new EmbedSound(data, sinfo, 100,
-                _mediaHandler ? _mediaHandler->getInputPaddingSize() : 0));
+    if (data.get()) {
+        ensurePadding(*data, _mediaHandler);
+    }
+    else {
+        log_debug("Event sound with no data!");
+    }
+    std::auto_ptr<EmbedSound> sounddata(new EmbedSound(data, sinfo, 100));
 
     int sound_id = _sounds.size();
 
@@ -436,66 +458,6 @@ sound_handler::isSoundPlaying(int handle) const
     return sounddata.isPlaying();
 }
 
-
-/* private */
-void
-sound_handler::playSound(EmbedSound& sounddata,
-        int loopCount, unsigned int inPoint, unsigned int outPoint,
-        const SoundEnvelopes* envelopes,
-        bool allowMultiples)
-{
-
-#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
-    log_debug("playSound %d called, SoundInfo format is %s",
-            sound_handle, sounddata.soundinfo.getFormat());
-#endif
-
-    // When this is called from a StreamSoundBlockTag,
-    // we only start if this sound isn't already playing.
-    if ( ! allowMultiples && sounddata.isPlaying() )
-    {
-#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
-        log_debug(" playSound: multiple instances not allowed, "
-                  "and sound is already playing");
-#endif
-        // log_debug("Stream sound block play request, "
-        //           "but an instance of the stream is "
-        //           "already playing, so we do nothing");
-        return;
-    }
-
-    // Make sure sound actually got some data
-    if ( sounddata.empty() )
-    {
-        // @@ should this be a log_error ? or even an assert ?
-        IF_VERBOSE_MALFORMED_SWF(
-            log_swferror(_("Trying to play sound with size 0"));
-        );
-        return;
-    }
-
-    // Make a "EmbedSoundInst" for this sound and plug it into  
-    // the set of InputStream channels
-    //
-    std::auto_ptr<InputStream> sound ( sounddata.createInstance(
-
-            // MediaHandler to use for decoding
-            *_mediaHandler,
-
-            // Samples range
-            inPoint, outPoint,
-
-            // Volume envelopes to use for this instance
-            envelopes,
-
-            // Loop count
-            loopCount
-
-    ) );
-
-    plugInputStream(sound);
-}
-
 /*public*/
 void
 sound_handler::playStream(int soundId, StreamBlockId blockId)
@@ -515,8 +477,7 @@ sound_handler::playStream(int soundId, StreamBlockId 
blockId)
 
 /*public*/
 void
-sound_handler::startSound(int handle, int loops, 
-                      const SoundEnvelopes* env,
+sound_handler::startSound(int handle, int loops, const SoundEnvelopes* env,
                       bool allowMultiple, unsigned int inPoint,
                    unsigned int outPoint)
 {
@@ -532,9 +493,8 @@ sound_handler::startSound(int handle, int loops,
     EmbedSound& sounddata = *(_sounds[handle]);
     const media::SoundInfo& sinfo = sounddata.soundinfo;
 
-    int swfDelaySeek = sinfo.getDelaySeek(); 
-    if ( swfDelaySeek )
-    {
+    const int swfDelaySeek = sinfo.getDelaySeek(); 
+    if (swfDelaySeek) {
         // NOTE: differences between delaySeek and inPoint:
         //
         //      - Sample count semantic:
@@ -571,7 +531,36 @@ sound_handler::startSound(int handle, int loops,
 #endif
     }
 
-    playSound(sounddata, loops, inPoint, outPoint, env, allowMultiple);
+#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
+    log_debug("startSound %d called, SoundInfo format is %s",
+            sound_handle, sounddata.soundinfo.getFormat());
+#endif
+
+    // When this is called from a StreamSoundBlockTag,
+    // we only start if this sound isn't already playing.
+    if (!allowMultiple && sounddata.isPlaying()) {
+#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
+        log_debug(" playSound: multiple instances not allowed, "
+                  "and sound is already playing");
+#endif
+        return;
+    }
+
+    // Make sure sound actually got some data
+    if (sounddata.empty()) {
+        // @@ should this be a log_error ? or even an assert ?
+        IF_VERBOSE_MALFORMED_SWF(
+            log_swferror(_("Trying to play sound with size 0"));
+        );
+        return;
+    }
+
+    // Make an InputStream for this sound and plug it into  
+    // the set of InputStream channels
+    std::auto_ptr<InputStream> sound(sounddata.createInstance(*_mediaHandler,
+            inPoint, outPoint, env, loops));
+
+    plugInputStream(sound);
 }
 
 void
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 7398277..8726c20 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -113,17 +113,13 @@ public:
     
     /// Create a sound buffer slot, for on-demand playback.
     //
-    /// @param data
-    ///     The data to be stored. The data is in encoded format, with
-    ///     format specified with the sinfo parameter, this is to allow
-    ///     on-demand decoding (if the sound is never played, it's never
-    ///     decoded).
-    ///
-    /// @param sinfo
-    ///     A SoundInfo object containing info about samplerate, samplecount,
-    /// stereo and more.
-    ///
-    /// @return the id given by the soundhandler for later identification.
+    /// @param data         The sound data to be stored. May not be null.
+    ///                     This should be appropriately padded (@see
+    ///                     MediaHandler::getInputPaddingBytes()), or a
+    ///                     reallocation will take place here.
+    /// @param sinfo        A SoundInfo object containing info about
+    ///                     samplerate, samplecount, stereo etc.
+    /// @return             handle for later identification.
     virtual int create_sound(std::auto_ptr<SimpleBuffer> data,
             const media::SoundInfo& sinfo);
         
@@ -176,7 +172,7 @@ public:
     ///     If false, the sound will not be scheduled if there's another
     ///     instance of it already playing.
     void startSound(int id, int loops, const SoundEnvelopes* env,
-                   bool allowMultiple, unsigned int inPoint=0,
+                   bool allowMultiple, unsigned int inPoint = 0,
                    unsigned int outPoint = 
                    std::numeric_limits<unsigned int>::max());
 
@@ -226,13 +222,15 @@ public:
     ///
     /// Gnash's parser calls this to fill up soundstreams data.
     ///
-    /// @param data         The sound data to be stored.
+    /// @param data         The sound data to be stored. May not be null.
+    ///                     This should be appropriately padded (@see
+    ///                     MediaHandler::getInputPaddingBytes()), or a
+    ///                     reallocation will take place here.
     /// @param sampleCount  Number of samples in the data
     /// @param streamId     The soundhandlers id of the sound we want
     ///                     to add data to
-    ///
-    /// @return an identifier for the new block for use in playSound
-    /// @throw SoundException on error
+    /// @return             a handler for the new block for use in playStream()
+    /// @throw              SoundException on error
     virtual StreamBlockId addSoundBlock(std::auto_ptr<SimpleBuffer> data,
                                        unsigned int sampleCount,
                                        int streamId);
@@ -532,39 +530,6 @@ private:
     /// Unplug any completed input stream
     void unplugCompletedInputStreams();
 
-    /// Schedule playing of a sound buffer slot
-    //
-    /// All scheduled sounds will be played on next output flush.
-    ///
-    /// @param id
-    ///     Id of the sound buffer slot schedule playback of.
-    ///
-    /// @param loops
-    ///     loops == 0 means play the sound once (1 means play it twice, etc)
-    ///
-    /// @param inPoint
-    ///     Offset in output samples this instance should start
-    ///     playing from. These are post-resampling samples (44100 
-    ///     for one second of samples).
-    ///
-    /// @param outPoint
-    ///     Offset in output samples this instance should stop
-    ///     playing at. These are post-resampling samples (44100 
-    ///     for one second of samples).
-    ///
-    /// @param env
-    ///     Some eventsounds have some volume control mechanism called
-    ///     envelopes.
-    ///     They basically tells that from sample X the volume should be Y.
-    ///
-    /// @param allowMultiple
-    ///     If false, the sound will not be scheduled if there's another
-    ///     instance of it already playing.
-    ///
-    void playSound(EmbedSound& sound, int loops, unsigned int inPoint,
-                   unsigned int outPoint, 
-                   const SoundEnvelopes* env, bool allowMultiple);
-
     /// Convert SWF-specified number of samples to output number of samples
     //
     /// SWF-specified number of samples are: delaySeek in DEFINESOUND,

http://git.savannah.gnu.org/cgit//commit/?id=ff6a7aabad29872a16d73393f0dd81d0aeb69584


commit ff6a7aabad29872a16d73393f0dd81d0aeb69584
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 13:39:28 2011 +0200

    Remove comment.

diff --git a/libsound/StreamingSoundData.h b/libsound/StreamingSoundData.h
index 2643cfd..c976d2f 100644
--- a/libsound/StreamingSoundData.h
+++ b/libsound/StreamingSoundData.h
@@ -170,9 +170,6 @@ public:
     Instances _soundInstances;
 
     /// Mutex protecting access to _soundInstances
-    //
-    /// @todo make private
-    ///
     mutable boost::mutex _soundInstancesMutex;
 
     const size_t _paddingBytes;

http://git.savannah.gnu.org/cgit//commit/?id=59603b1b726579cd9538f24f82218e03ac3b5478


commit 59603b1b726579cd9538f24f82218e03ac3b5478
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 13:38:32 2011 +0200

    Rearrange classes, restrict access.

diff --git a/libsound/EmbedSound.cpp b/libsound/EmbedSound.cpp
index 33ec5bb..35b8270 100644
--- a/libsound/EmbedSound.cpp
+++ b/libsound/EmbedSound.cpp
@@ -35,7 +35,7 @@ namespace sound {
 EmbedSound::EmbedSound(std::auto_ptr<SimpleBuffer> data,
         const media::SoundInfo& info, int nVolume, size_t paddingBytes)
     :
-    _buf(data),
+    _buf(data.release()),
     soundinfo(info),
     volume(nVolume)
 {
diff --git a/libsound/EmbedSound.h b/libsound/EmbedSound.h
index 0392ee1..0f99100 100644
--- a/libsound/EmbedSound.h
+++ b/libsound/EmbedSound.h
@@ -20,16 +20,16 @@
 #ifndef SOUND_EMBEDSOUND_H
 #define SOUND_EMBEDSOUND_H
 
-#include "SimpleBuffer.h" // for composition
-#include "SoundInfo.h" // for composition
-#include "SoundEnvelope.h" // for SoundEnvelopes define
-
 #include <vector>
 #include <memory> // for auto_ptr (composition)
 #include <set> // for composition (_soundInstances)
 #include <cassert>
 #include <boost/thread/mutex.hpp>
+#include <boost/scoped_ptr.hpp>
 
+#include "SimpleBuffer.h" // for composition
+#include "SoundInfo.h" // for composition
+#include "SoundEnvelope.h" // for SoundEnvelopes define
 
 // Forward declarations
 namespace gnash {
@@ -48,13 +48,14 @@ namespace sound {
 /// Definition of an embedded sound
 class EmbedSound
 {
-    /// The undecoded data
-    std::auto_ptr<SimpleBuffer> _buf;
-
-    void ensureBufferPadding();
-
 public:
 
+    /// Vector containing the active instances of this sounds being played
+    //
+    /// NOTE: This class does NOT own the active sounds
+    ///
+    typedef std::list<EmbedSoundInst*> Instances;
+
     /// Construct a sound with given data, info and volume.
     //
     /// @param data The encoded sound data.
@@ -70,9 +71,6 @@ public:
 
     ~EmbedSound();
 
-    /// Object holding information about the sound
-    media::SoundInfo soundinfo;
-
     /// Return size of the data buffer
     size_t size() const {
         return _buf->size();
@@ -88,11 +86,6 @@ public:
         return _buf->data();
     }
 
-    /// Return a pointer to the underlying buffer
-    boost::uint8_t* data() {
-        return _buf->data();
-    }
-
     /// Return a pointer to an offset in the underlying buffer
     //
     /// @param pos The offset value.
@@ -103,16 +96,6 @@ public:
         return _buf->data()+pos;
     }
 
-    /// Return a pointer to an offset in the underlying buffer
-    //
-    /// @param pos The offset value.
-    ///     An assertion will fail if pos > size()
-    ///
-    boost::uint8_t* data(size_t pos) {
-        assert(pos < _buf->size());
-        return _buf->data()+pos;
-    }
-
     /// Are there known playing instances of this sound ?
     //
     /// Locks _soundInstancesMutex
@@ -158,46 +141,15 @@ public:
     /// @param loopCount
     ///     Number of times this instance should loop over the defined sound.
     ///     @todo document if every loop starts at secsOffset !
-    ///
-    /// @todo split this in createEventSoundInstance
-    ///                 and createStreamingSoundInstance
-    ///
-    ///
     /// Locks the _soundInstancesMutex when pushing to it
     ///
-    std::auto_ptr<EmbedSoundInst> createInstance( media::MediaHandler& mh,
+    std::auto_ptr<EmbedSoundInst> createInstance(media::MediaHandler& mh,
             unsigned int inPoint, unsigned int outPoint,
             const SoundEnvelopes* envelopes, unsigned int loopCount);
 
-    /// Volume for AS-sounds, range: 0-100.
-    /// It's the SWF range that is represented here.
-    int volume;
-
-    /// Vector containing the active instances of this sounds being played
-    //
-    /// NOTE: This class does NOT own the active sounds
-    ///
-    typedef std::list<EmbedSoundInst*> Instances;
-
-    /// Playing instances of this sound definition
-    //
-    /// Multithread access to this member is protected
-    /// by the _soundInstancesMutex mutex
-    ///
-    /// @todo make private
-    ///
-    Instances _soundInstances;
-
-    /// Mutex protecting access to _soundInstances
-    //
-    /// @todo make private
-    ///
-    mutable boost::mutex _soundInstancesMutex;
-
     /// Drop all active sounds
     //
     /// Locks _soundInstancesMutex
-    ///
     void clearInstances();
 
     /// Drop an active sound (by iterator)
@@ -205,7 +157,6 @@ public:
     /// Does *NOT* lock the _soundInstancesMutex
     ///
     /// @return iterator after the one being erased
-    ///
     Instances::iterator eraseActiveSound(Instances::iterator i);
 
     /// Drop an active sound (by pointer)
@@ -221,6 +172,28 @@ public:
     /// @todo make private and mark EmbedSoundInst as friend ?
     ///
     void eraseActiveSound(EmbedSoundInst* inst);
+
+    /// The undecoded data
+    boost::scoped_ptr<SimpleBuffer> _buf;
+
+    /// Object holding information about the sound
+    media::SoundInfo soundinfo;
+
+    /// Volume for AS-sounds, range: 0-100.
+    /// It's the SWF range that is represented here.
+    int volume;
+
+private:
+
+    /// Playing instances of this sound definition
+    //
+    /// Multithread access to this member is protected
+    /// by the _soundInstancesMutex mutex
+    Instances _soundInstances;
+
+    /// Mutex protecting access to _soundInstances
+    //
+    mutable boost::mutex _soundInstancesMutex;
 };
 
 } // gnash.sound namespace 
diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index 9a5551b..753ea96 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -220,7 +220,7 @@ EmbedSoundInst::decodeNextBlock()
     // Doing so we know what's the sample number
     // of the first sample in the newly decoded block.
     //
-    assert( playbackPosition >= decodedDataSize() );
+    assert(playbackPosition >= _decodedData.size());
 
     boost::uint32_t inputSize = 0; // or blockSize
     bool parse = true; // need to parse ?
diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index 85186c5..f93bd61 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -152,7 +152,7 @@ private:
     /// Return number of already-decoded samples available
     /// from playback position on
     unsigned int decodedSamplesAhead() const {
-        unsigned int dds = decodedDataSize();
+        unsigned int dds = _decodedData.size();
         if ( dds <= playbackPosition ) return 0; 
         unsigned int bytesAhead = dds - playbackPosition;
         assert(!(bytesAhead%2));
@@ -186,12 +186,6 @@ private:
     /// 
     void createDecoder(media::MediaHandler& mediaHandler);
 
-    /// Return full size of the decoded data buffer
-    size_t decodedDataSize() const
-    {
-        return _decodedData.size();
-    }
-
     /// \brief
     /// Returns the data pointer in the decoded datastream
     /// for the given byte-offset.
diff --git a/libsound/StreamingSound.cpp b/libsound/StreamingSound.cpp
index 39b2f9d..5e55321 100644
--- a/libsound/StreamingSound.cpp
+++ b/libsound/StreamingSound.cpp
@@ -57,8 +57,7 @@ StreamingSound::StreamingSound(StreamingSoundData& soundData,
         _inPoint(inPoint * 4),
         _samplesFetched(0),
         _decoder(0),
-        _soundDef(soundData),
-        _decodedData(0)
+        _soundDef(soundData)
 {
     _playbackPosition = _inPoint; 
     createDecoder(mediaHandler);
@@ -89,11 +88,8 @@ StreamingSound::createDecoder(media::MediaHandler& 
mediaHandler)
 boost::int16_t*
 StreamingSound::getDecodedData(unsigned long int pos)
 {
-    if (_decodedData.get()) {
-        assert(pos < _decodedData->size());
-        return reinterpret_cast<boost::int16_t*>(_decodedData->data() + pos);
-    }
-    return 0;
+    assert(pos < _decodedData.size());
+    return reinterpret_cast<boost::int16_t*>(_decodedData.data() + pos);
 }
 
 unsigned int 
@@ -162,20 +158,21 @@ StreamingSound::decodeNextBlock()
     // are available for fetching.
     // Doing so we know what's the sample number
     // of the first sample in the newly decoded block.
-    assert(_playbackPosition >= decodedDataSize());
+    assert(_playbackPosition >= _decodedData.size());
 
     const StreamingSoundData& sndData = _soundDef;
     const bool parse =
         sndData.soundinfo.getFormat() == media::AUDIO_CODEC_ADPCM ?
         false : true;
 
+    const SimpleBuffer& block = _soundDef.getBlock(_currentBlock);
+
     // Move onto next block.
     // decode it, add to decoded sound.
 
     // This is a streaming sound. This function is only called if there is
     // data to decode. If there is data, there must be frames.
-    const boost::uint32_t inputSize = sndData._buffers[_currentBlock].size() -
-        _positionInBlock; 
+    const boost::uint32_t inputSize = block.size() - _positionInBlock; 
 
 #ifdef GNASH_DEBUG_SOUNDS_DECODING
     log_debug(" frame size for frame starting at offset %d is %d",
@@ -183,8 +180,7 @@ StreamingSound::decodeNextBlock()
 #endif
 
     assert(inputSize);
-    const boost::uint8_t* input = sndData._buffers[_currentBlock].data() + 
-        _positionInBlock;
+    const boost::uint8_t* input = block.data() + _positionInBlock;
 
     boost::uint32_t consumed = 0;
     boost::uint32_t decodedDataSize = 0;
@@ -195,7 +191,8 @@ StreamingSound::decodeNextBlock()
                                       consumed,
                                       parse);
 
-    if (consumed == sndData._buffers[_currentBlock].size()) {
+    // Check if the entire block was consumed.
+    if (consumed == block.size()) {
         // Go to next block
         ++_currentBlock;
         _positionInBlock = 0;
@@ -234,12 +231,7 @@ StreamingSound::~StreamingSound()
 void
 StreamingSound::appendDecodedData(boost::uint8_t* data, unsigned int size)
 {
-    if (!_decodedData.get()) {
-        _decodedData.reset(new SimpleBuffer);
-    }
-
-    _decodedData->append(data, size);
-
+    _decodedData.append(data, size);
     delete [] data; // ownership transferred...
 }
 
diff --git a/libsound/StreamingSound.h b/libsound/StreamingSound.h
index fa81855..3e88f7f 100644
--- a/libsound/StreamingSound.h
+++ b/libsound/StreamingSound.h
@@ -48,30 +48,19 @@ namespace sound {
 //
 /// This class contains a pointer to the StreamingSoundData used for playing
 /// and a SimpleBuffer to use when decoding is needed.
-///
-/// When the SimpleBuffer is NULL we'll play the StreamingSoundData bytes 
directly
-/// (we assume they are decoded already)
-///
 class StreamingSound : public InputStream
 {
 public:
 
     /// Create an embedded %sound instance
     //
-    /// @param def
-    ///     The definition of this sound (where immutable data is kept)
-    ///
-    /// @param mh
-    ///     The MediaHandler to use for on-demand decoding
-    ///
-    /// @param blockId
-    ///     Identifier of the encoded block to start decoding from.
-    ///     @see gnash::swf::StreamSoundBlockTag
-    ///
-    /// @param inPoint
-    ///     Offset in output samples this instance should start
-    ///     playing from. These are post-resampling samples (44100 
-    ///     for one second of samples).
+    /// @param def      The sound data for this sound 
+    /// @param mh       The MediaHandler to use for on-demand decoding
+    /// @param blockId  Identifier of the encoded block to start decoding from.
+    ///                 @see gnash::swf::StreamSoundBlockTag
+    /// @param inPoint  Offset in output samples this instance should start
+    ///                 playing from. These are post-resampling samples (44100 
+    ///                 for one second of samples).
     StreamingSound(StreamingSoundData& def, media::MediaHandler& mh,
             sound_handler::StreamBlockId blockId,
             unsigned int inPoint);
@@ -111,11 +100,11 @@ private:
     /// from playback position on
     unsigned int decodedSamplesAhead() const {
 
-        const unsigned int dds = decodedDataSize();
+        const unsigned int dds = _decodedData.size();
         if (dds <= _playbackPosition) return 0; 
 
         const unsigned int bytesAhead = dds - _playbackPosition;
-        assert(!(bytesAhead%2));
+        assert(!(bytesAhead % 2));
 
         const unsigned int samplesAhead = bytesAhead / 2;
         return samplesAhead;
@@ -124,7 +113,7 @@ private:
     /// Return true if there's nothing more to decode
     bool decodingCompleted() const {
         return _positionInBlock == 0 && 
-            _currentBlock >= _soundDef._buffers.size();
+            _currentBlock >= _soundDef.blockCount();
     }
 
     /// Create a decoder for this instance
@@ -133,11 +122,6 @@ private:
     /// be logged, and _decoder won't be set
     void createDecoder(media::MediaHandler& mediaHandler);
 
-    /// Return full size of the decoded data buffer
-    size_t decodedDataSize() const {
-        return _decodedData.get() ? _decodedData->size() : 0;
-    }
-
     /// Access data in the decoded datastream for the given byte offset.
     //
     /// Boundaries are checked.
@@ -150,7 +134,6 @@ private:
     /// Decode next input block
     //
     /// It's assumed !decodingCompleted()
-    ///
     void decodeNextBlock();
 
     // The current block of sound.
@@ -180,11 +163,7 @@ private:
     StreamingSoundData& _soundDef;
 
     /// The decoded buffer
-    //
-    /// If NULL, the _soundDef will be considered
-    /// decoded instead
-    ///
-    boost::scoped_ptr<SimpleBuffer> _decodedData;
+    SimpleBuffer _decodedData;
 };
 
 
diff --git a/libsound/StreamingSoundData.cpp b/libsound/StreamingSoundData.cpp
index 79981b6..f46bfdf 100644
--- a/libsound/StreamingSoundData.cpp
+++ b/libsound/StreamingSoundData.cpp
@@ -52,7 +52,6 @@ StreamingSoundData::append(std::auto_ptr<SimpleBuffer> data, 
size_t sampleCount)
 StreamingSoundData::StreamingSoundData(const media::SoundInfo& info,
         int nVolume, size_t paddingBytes)
     :
-    _buf(new SimpleBuffer()),
     soundinfo(info),
     volume(nVolume),
     _paddingBytes(paddingBytes)
diff --git a/libsound/StreamingSoundData.h b/libsound/StreamingSoundData.h
index a632df5..2643cfd 100644
--- a/libsound/StreamingSoundData.h
+++ b/libsound/StreamingSoundData.h
@@ -49,13 +49,13 @@ namespace sound {
 /// Definition of an embedded sound
 class StreamingSoundData
 {
-    /// The undecoded data
-    boost::scoped_ptr<SimpleBuffer> _buf;
-
-    void ensureBufferPadding();
-
 public:
 
+    /// Container for the active instances of this sounds being played
+    //
+    /// NOTE: This class does NOT own the active sounds
+    typedef std::list<InputStream*> Instances;
+
     /// Construct a sound with given data, info and volume.
     //
     /// @param data The encoded sound data.
@@ -71,22 +71,25 @@ public:
 
     ~StreamingSoundData();
 
-    /// Object holding information about the sound
-    media::SoundInfo soundinfo;
-
-    boost::ptr_vector<SimpleBuffer> _buffers;
-
     /// Append a sound data block
     //
     /// @param data             Undecoded sound data.
     /// @param sampleCount      The number of samples when decoded.
     size_t append(std::auto_ptr<SimpleBuffer> data, size_t sampleCount);
 
-    /// Is the data buffer empty ?
+    /// Do we have any data?
     bool empty() const {
         return _buffers.empty();
     }
 
+    const SimpleBuffer& getBlock(size_t index) const {
+        return _buffers[index];
+    }
+
+    size_t blockCount() const {
+        return _buffers.size();
+    }
+
     /// Are there known playing instances of this sound ?
     //
     /// Locks _soundInstancesMutex
@@ -112,50 +115,19 @@ public:
     //
     /// The returned instance ownership is transferred
     ///
-    /// @param mh
-    ///     The MediaHandler to use for on-demand decoding
-    ///
-    /// @param blockOffset
-    ///     Byte offset in the immutable (encoded) data this
-    ///     instance should start decoding.
-    ///     This is currently used for streaming embedded sounds
-    ///     to refer to a specific StreamSoundBlock.
-    ///     @see gnash::swf::StreamSoundBlockTag
-    ///
-    /// @param inPoint
-    ///     Offset in output samples this instance should start
-    ///     playing from. These are post-resampling samples from
-    ///     the start of the specified blockId.
+    /// @param mh               The MediaHandler to use for on-demand decoding
+    /// @param blockOffset      Block number in the immutable (encoded) data
+    ///                         this instance should start decoding.
+    ///                         This refers to a specific StreamSoundBlock.
+    ///                         @see gnash::swf::StreamSoundBlockTag
+    /// @param inPoint          Offset in output samples this instance
+    ///                         should start playing from. These are
+    ///                         post-resampling samples from
+    ///                         the start of the specified blockId.
     /// Locks the _soundInstancesMutex when pushing to it
-    ///
     std::auto_ptr<StreamingSound> createInstance(media::MediaHandler& mh,
             unsigned long blockOffset, unsigned int inPoint);
 
-    /// Volume for AS-sounds, range: 0-100.
-    /// It's the SWF range that is represented here.
-    int volume;
-
-    /// Vector containing the active instances of this sounds being played
-    //
-    /// NOTE: This class does NOT own the active sounds
-    ///
-    typedef std::list<InputStream*> Instances;
-
-    /// Playing instances of this sound definition
-    //
-    /// Multithread access to this member is protected
-    /// by the _soundInstancesMutex mutex
-    ///
-    /// @todo make private
-    ///
-    Instances _soundInstances;
-
-    /// Mutex protecting access to _soundInstances
-    //
-    /// @todo make private
-    ///
-    mutable boost::mutex _soundInstancesMutex;
-
     /// Drop all active sounds
     //
     /// Locks _soundInstancesMutex
@@ -181,7 +153,31 @@ public:
     /// Does lock the _soundInstancesMutex
     void eraseActiveSound(InputStream* inst);
 
+    /// Object holding information about the sound
+    media::SoundInfo soundinfo;
+
+    /// Volume for AS-sounds, range: 0-100.
+    /// It's the SWF range that is represented here.
+    int volume;
+
+    /// Playing instances of this sound definition
+    //
+    /// Multithread access to this member is protected
+    /// by the _soundInstancesMutex mutex
+    ///
+    /// @todo make private
+    ///
+    Instances _soundInstances;
+
+    /// Mutex protecting access to _soundInstances
+    //
+    /// @todo make private
+    ///
+    mutable boost::mutex _soundInstancesMutex;
+
     const size_t _paddingBytes;
+
+    boost::ptr_vector<SimpleBuffer> _buffers;
 };
 
 } // gnash.sound namespace 

http://git.savannah.gnu.org/cgit//commit/?id=516bba3ab56e9e673295a5fe2af5ad5700bc1643


commit 516bba3ab56e9e673295a5fe2af5ad5700bc1643
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 13:10:01 2011 +0200

    Update comments to match implementation.
    
    All sound data is decoded to a buffer, so it need not be stored by pointer
    or checked.

diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index fb5c103..9a5551b 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -73,8 +73,7 @@ EmbedSoundInst::EmbedSoundInst(EmbedSound& soundData,
         current_env(0),
         _samplesFetched(0),
         _decoder(0),
-        _soundDef(soundData),
-        _decodedData(0)
+        _soundDef(soundData)
 {
     playbackPosition = _inPoint; 
 
@@ -107,12 +106,8 @@ EmbedSoundInst::createDecoder(media::MediaHandler& 
mediaHandler)
 boost::int16_t*
 EmbedSoundInst::getDecodedData(unsigned long int pos)
 {
-    if ( _decodedData.get() )
-    {
-        assert(pos < _decodedData->size());
-        return reinterpret_cast<boost::int16_t*>(_decodedData->data()+pos);
-    }
-    else return 0;
+    assert(pos < _decodedData.size());
+    return reinterpret_cast<boost::int16_t*>(_decodedData.data() + pos);
 }
 
 bool
@@ -128,8 +123,6 @@ unsigned int
 EmbedSoundInst::fetchSamples(boost::int16_t* to, unsigned int nSamples)
 {
     // If there exist no decoder, then we can't decode!
-    // TODO: isn't it documented that an EmbedSoundInst w/out a decoder
-    //       means that the EmbedSound data is already decoded ?
     if (!_decoder.get())
     {
         return 0;
@@ -397,12 +390,7 @@ EmbedSoundInst::~EmbedSoundInst()
 void
 EmbedSoundInst::appendDecodedData(boost::uint8_t* data, unsigned int size)
 {
-    if ( ! _decodedData.get() )
-    {
-        _decodedData.reset( new SimpleBuffer );
-    }
-
-    _decodedData->append(data, size);
+    _decodedData.append(data, size);
 
     delete [] data; // ownership transferred...
 }
diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index 012bce5..85186c5 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -189,11 +189,7 @@ private:
     /// Return full size of the decoded data buffer
     size_t decodedDataSize() const
     {
-        if ( _decodedData.get() )
-        {
-            return _decodedData->size();
-        }
-        else return 0;
+        return _decodedData.size();
     }
 
     /// \brief
@@ -253,11 +249,7 @@ private:
     EmbedSound& _soundDef;
 
     /// The decoded buffer
-    //
-    /// If NULL, the _soundDef will be considered
-    /// decoded instead
-    ///
-    std::auto_ptr<SimpleBuffer> _decodedData;
+    SimpleBuffer _decodedData;
 };
 
 

http://git.savannah.gnu.org/cgit//commit/?id=b3f5274f0f2f342eba296a4586120986c9f51766


commit b3f5274f0f2f342eba296a4586120986c9f51766
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 08:45:45 2011 +0200

    Add a StreamingSound input stream and data class.
    
    Store sound blocks as a series of buffers.

diff --git a/libcore/swf/StreamSoundBlockTag.cpp 
b/libcore/swf/StreamSoundBlockTag.cpp
index ea230f7..6c30688 100644
--- a/libcore/swf/StreamSoundBlockTag.cpp
+++ b/libcore/swf/StreamSoundBlockTag.cpp
@@ -30,6 +30,7 @@
 #include "SWFStream.h"
 #include "log.h"
 #include "RunResources.h"
+#include "MediaHandler.h"
 
 namespace gnash {
 namespace SWF {
@@ -105,25 +106,27 @@ StreamSoundBlockTag::loader(SWFStream& in, TagType tag, 
movie_definition& m,
         return;
     }
 
-    unsigned char* data = new unsigned char[dataLength];
-    const unsigned int bytesRead = in.read(reinterpret_cast<char*>(data),
-            dataLength);
+    media::MediaHandler* mh = r.mediaHandler();
+    const size_t padding = mh ? mh->getInputPaddingSize() : 0;
+
+    // Reserve padding too.
+    std::auto_ptr<SimpleBuffer> buf(new SimpleBuffer(dataLength + padding));
+    buf->resize(dataLength);
+
+    const unsigned int bytesRead = in.read((char*)buf->data(), dataLength);
     
     if (bytesRead < dataLength) {
-        delete [] data;
         throw ParserException(_("Tag boundary reported past end of stream!"));
     }
 
     // Fill the data on the apropiate sound, and receives the starting point
     // for later "start playing from this frame" events.
     //
-    // ownership of 'data' is transferred here
-    //
     // TODO: the amount of sound data used should depend on the sampleCount,
     // not on the size of the data. Currently the sound_handler ignores
     // sampleCount completely.
     sound::sound_handler::StreamBlockId blockId =
-        handler->addSoundBlock(data, dataLength, sampleCount, sId);
+        handler->addSoundBlock(buf, sampleCount, sId);
 
     boost::intrusive_ptr<ControlTag> s(new StreamSoundBlockTag(sId, blockId));
 
diff --git a/libsound/EmbedSound.cpp b/libsound/EmbedSound.cpp
index 72cc217..33ec5bb 100644
--- a/libsound/EmbedSound.cpp
+++ b/libsound/EmbedSound.cpp
@@ -19,59 +19,34 @@
 //
 
 #include "EmbedSound.h"
-#include "EmbedSoundInst.h" // for createInstance
-#include "SoundInfo.h"
-
-#include "MediaHandler.h" // for the singleton (getInputPaddingSize)
 
-#include "log.h" // will import boost::format too
-#include "GnashException.h" // for SoundException
-
-//#include <cmath>
 #include <vector>
-//#include <boost/scoped_array.hpp>
-#include <boost/cstdint.hpp> // For C99 int types
+#include <boost/cstdint.hpp>
+
+#include "EmbedSoundInst.h" 
+#include "SoundInfo.h"
+#include "MediaHandler.h" 
+#include "log.h"
+#include "GnashException.h" 
 
 namespace gnash {
 namespace sound {
 
-void
-EmbedSound::append(boost::uint8_t* data, unsigned int size)
-{
-    /// @todo, rather then copying the data over,
-    ///        keep it in its original form (multi-buffer)
-    ///        This way we avoid memory copies and we'd
-    ///        have no need for the additional m_frames_sizes
-    ///        map..
-
-    // Remember size of this block, indexing by offset
-    m_frames_size[_buf->size()] = size;
-
-    _buf->reserve(_buf->size() + size + _paddingBytes);
-    _buf->append(data, size);
-
-    // since ownership was transferred...
-    delete [] data;
-}
-
 EmbedSound::EmbedSound(std::auto_ptr<SimpleBuffer> data,
         const media::SoundInfo& info, int nVolume, size_t paddingBytes)
     :
     _buf(data),
     soundinfo(info),
-    volume(nVolume),
-    _paddingBytes(paddingBytes)
+    volume(nVolume)
 {
-    if ( _buf.get() )
-    {
+    if (_buf.get()) {
         if (_buf->capacity() - _buf->size() < paddingBytes) {
             log_error("EmbedSound creator didn't appropriately pad sound data. 
"
                 "We'll do now, but will cost memory copies.");
             _buf->reserve(_buf->size()+paddingBytes);
         }
     }
-    else
-    {
+    else {
         _buf.reset(new SimpleBuffer());
     }
 }
@@ -92,15 +67,14 @@ EmbedSound::eraseActiveSound(Instances::iterator i)
 
 std::auto_ptr<EmbedSoundInst>
 EmbedSound::createInstance(media::MediaHandler& mh,
-            unsigned long blockOffset,
             unsigned int inPoint,
             unsigned int outPoint,
             const SoundEnvelopes* envelopes,
             unsigned int loopCount)
 {
-    std::auto_ptr<EmbedSoundInst> ret ( new EmbedSoundInst(
+    std::auto_ptr<EmbedSoundInst> ret(new EmbedSoundInst(
                                 *this,
-                                mh, blockOffset,
+                                mh, 
                                 inPoint, outPoint,
                                 envelopes,
                                 loopCount) );
@@ -123,13 +97,10 @@ EmbedSound::eraseActiveSound(EmbedSoundInst* inst)
 {
     boost::mutex::scoped_lock lock(_soundInstancesMutex);
 
-    Instances::iterator it = std::find(
-            _soundInstances.begin(),
-            _soundInstances.end(),
-            inst);
+    Instances::iterator it = std::find( _soundInstances.begin(),
+            _soundInstances.end(), inst);
 
-    if ( it == _soundInstances.end() )
-    {
+    if (it == _soundInstances.end()) {
         log_error("EmbedSound::eraseActiveSound: instance %p not found!", 
inst);
         return;
     }
diff --git a/libsound/EmbedSound.h b/libsound/EmbedSound.h
index 810b041..0392ee1 100644
--- a/libsound/EmbedSound.h
+++ b/libsound/EmbedSound.h
@@ -25,7 +25,6 @@
 #include "SoundEnvelope.h" // for SoundEnvelopes define
 
 #include <vector>
-#include <map> // for composition (m_frame_size)
 #include <memory> // for auto_ptr (composition)
 #include <set> // for composition (_soundInstances)
 #include <cassert>
@@ -74,30 +73,13 @@ public:
     /// Object holding information about the sound
     media::SoundInfo soundinfo;
 
-    typedef std::map<boost::uint32_t,boost::uint32_t> FrameSizeMap;
-
-    /// Maps frame sizes to start-of-frame offsets
-    FrameSizeMap m_frames_size;
-
-    /// Append size bytes to this sound
-    //
-    /// @param data
-    /// Data bytes, allocated with new[]. Ownership transferred.
-    ///
-    /// @param size
-    /// Size of the 'data' buffer.
-    ///
-    void append(boost::uint8_t* data, unsigned int size);
-
     /// Return size of the data buffer
-    size_t size() const 
-    {
+    size_t size() const {
         return _buf->size();
     }
 
     /// Is the data buffer empty ?
-    bool empty() const 
-    {
+    bool empty() const {
         return _buf->empty();
     }
 
@@ -159,13 +141,6 @@ public:
     /// @param mh
     ///     The MediaHandler to use for on-demand decoding
     ///
-    /// @param blockOffset
-    ///     Byte offset in the immutable (encoded) data this
-    ///     instance should start decoding.
-    ///     This is currently used for streaming embedded sounds
-    ///     to refer to a specific StreamSoundBlock.
-    ///     @see gnash::swf::StreamSoundBlockTag
-    ///
     /// @param inPoint
     ///     Offset in output samples this instance should start
     ///     playing from. These are post-resampling samples from
@@ -191,7 +166,6 @@ public:
     /// Locks the _soundInstancesMutex when pushing to it
     ///
     std::auto_ptr<EmbedSoundInst> createInstance( media::MediaHandler& mh,
-            unsigned long blockOffset,
             unsigned int inPoint, unsigned int outPoint,
             const SoundEnvelopes* envelopes, unsigned int loopCount);
 
@@ -247,8 +221,6 @@ public:
     /// @todo make private and mark EmbedSoundInst as friend ?
     ///
     void eraseActiveSound(EmbedSoundInst* inst);
-
-    const size_t _paddingBytes;
 };
 
 } // gnash.sound namespace 
diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index 0eb36d9..fb5c103 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -22,7 +22,6 @@
 
 #include <cmath>
 #include <vector>
-#include <boost/scoped_array.hpp>
 
 #include "SoundInfo.h" // for use
 #include "MediaHandler.h" // for use
@@ -48,15 +47,13 @@ EmbedSoundInst::samplesFetched() const
 
 EmbedSoundInst::EmbedSoundInst(EmbedSound& soundData,
             media::MediaHandler& mediaHandler,
-            sound_handler::StreamBlockId blockOffset,
             unsigned int inPoint,
             unsigned int outPoint,
             const SoundEnvelopes* env,
             unsigned int loopCount)
         :
 
-        // should store blockOffset somewhere else too, for resetting
-        decodingPosition(blockOffset),
+        decodingPosition(0),
 
         loopCount(loopCount),
 
@@ -255,28 +252,6 @@ EmbedSoundInst::decodeNextBlock()
 
         // Figure the frame size ...
         inputSize = encodedDataSize() - decodingPosition;
-        if (!sndData.m_frames_size.empty())
-        {
-            const EmbedSound::FrameSizeMap& m = sndData.m_frames_size;
-            EmbedSound::FrameSizeMap::const_iterator it =
-                        m.find(decodingPosition);
-            if ( it != m.end() )
-            {
-                inputSize = it->second; 
-#ifdef GNASH_DEBUG_SOUNDS_DECODING
-                log_debug(" frame size for frame starting at offset %d is %d",
-                    decodingPosition, inputSize);
-#endif
-            }
-            else
-            {
-                // this should never happen, as we keep track of 
-                // sizes for each audio block in input
-                log_error("Unknown size of audio block starting at offset %d",
-                    " (should never happen)",
-                    decodingPosition);
-            }
-        }
     }
 
 #ifdef GNASH_DEBUG_SOUNDS_DECODING
diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index 1c7c1c8..012bce5 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -65,10 +65,6 @@ public:
     /// @param mh
     ///     The MediaHandler to use for on-demand decoding
     ///
-    /// @param blockId
-    ///     Identifier of the encoded block to start decoding from.
-    ///     @see gnash::swf::StreamSoundBlockTag
-    ///
     /// @param inPoint
     ///     Offset in output samples this instance should start
     ///     playing from. These are post-resampling samples (44100 
@@ -89,7 +85,6 @@ public:
     ///     inPoint and outPoint.
     ///
     EmbedSoundInst(EmbedSound& def, media::MediaHandler& mh,
-            sound_handler::StreamBlockId blockId,
             unsigned int inPoint,
             unsigned int outPoint,
             const SoundEnvelopes* envelopes,
@@ -112,39 +107,6 @@ public:
 
 private:
 
-    /// Current decoding position in the encoded stream
-    unsigned long decodingPosition;
-
-    /// Current playback position in the decoded stream
-    unsigned long playbackPosition;
-
-    /// Numbers of loops: -1 means loop forever, 0 means play once.
-    /// For every loop completed, it is decremented.
-    long loopCount;
-
-    /// Offset in bytes samples from start of the block
-    /// to begin playback from
-    unsigned long _inPoint;
-
-    /// Offset in bytes to end playback at
-    /// Never if numeric_limits<unsigned long>::max()
-    unsigned long _outPoint;
-
-    /// Sound envelopes for the current sound, which determine the volume level
-    /// from a given position. Only used with event sounds.
-    const SoundEnvelopes* envelopes;
-
-    /// Index of current envelope.
-    boost::uint32_t current_env;
-
-    /// Number of samples fetched so far.
-    unsigned long _samplesFetched;
-
-    /// Get the sound definition this object is an instance of
-    const EmbedSound& getSoundData() {    
-        return _soundDef;
-    }
-
     /// Append size bytes to this raw data 
     //
     /// @param data
@@ -154,29 +116,8 @@ private:
     /// Size of the 'data' buffer.
     ///
     void appendDecodedData(boost::uint8_t* data, unsigned int size);
-  
-    /// Set decoded data
-    //
-    /// @param data
-    /// Data bytes, allocated with new[]. Ownership transferred.
-    ///
-    /// @param size
-    /// Size of the 'data' buffer.
-    ///
-    void setDecodedData(boost::uint8_t* data, unsigned int size)
-    {
-        if ( ! _decodedData.get() )
-        {
-            _decodedData.reset( new SimpleBuffer() );
-        }
-
-        _decodedData->resize(0); // shouldn't release memory
-        _decodedData->append(data, size);
-        delete [] data; // ownership transferred...
-    }
 
-    size_t encodedDataSize() const
-    {
+    size_t encodedDataSize() const {
         return _soundDef.size();
     }
 
@@ -199,25 +140,18 @@ private:
     ///
     /// @param env
     ///     SoundEnvelopes to apply.
-    ///
-    ///
     void applyEnvelopes(boost::int16_t* samples, unsigned int nSamples,
-            unsigned int firstSampleNum,
-            const SoundEnvelopes& env);
+            unsigned int firstSampleNum, const SoundEnvelopes& env);
 
     /// Returns the data pointer in the encoded datastream
     /// for the given position. Boundaries are checked.
     //
     /// Uses _samplesFetched and playbackPosition
-    ///
-    /// @todo make private
-    ///
     const boost::uint8_t* getEncodedData(unsigned long int pos);
 
     /// Return number of already-decoded samples available
     /// from playback position on
-    unsigned int decodedSamplesAhead() const
-    {
+    unsigned int decodedSamplesAhead() const {
         unsigned int dds = decodedDataSize();
         if ( dds <= playbackPosition ) return 0; 
         unsigned int bytesAhead = dds - playbackPosition;
@@ -245,10 +179,6 @@ private:
         return ( decodingPosition >= encodedDataSize() );
     }
   
-
-    /// The decoder object used to convert the data into the playable format
-    std::auto_ptr<media::AudioDecoder> _decoder;
-
     /// Create a decoder for this instance
     //
     /// If decoder creation fails an error will
@@ -278,6 +208,43 @@ private:
     ///
     boost::int16_t* getDecodedData(unsigned long int pos);
 
+
+    /// Decode next input block
+    //
+    /// It's assumed !decodingCompleted()
+    ///
+    void decodeNextBlock();
+
+    /// Current decoding position in the encoded stream
+    unsigned long decodingPosition;
+
+    /// Current playback position in the decoded stream
+    unsigned long playbackPosition;
+
+    /// Numbers of loops: -1 means loop forever, 0 means play once.
+    /// For every loop completed, it is decremented.
+    long loopCount;
+
+    /// Offset in bytes samples from start of the block
+    /// to begin playback from
+    unsigned long _inPoint;
+
+    /// Offset in bytes to end playback at
+    /// Never if numeric_limits<unsigned long>::max()
+    unsigned long _outPoint;
+
+    /// Sound envelopes for the current sound, which determine the volume level
+    /// from a given position. Only used with event sounds.
+    const SoundEnvelopes* envelopes;
+
+    /// Index of current envelope.
+    boost::uint32_t current_env;
+
+    /// Number of samples fetched so far.
+    unsigned long _samplesFetched;
+
+    /// The decoder object used to convert the data into the playable format
+    std::auto_ptr<media::AudioDecoder> _decoder;
     /// The encoded data
     //
     /// It is non-const because we deregister ourselves
@@ -291,12 +258,6 @@ private:
     /// decoded instead
     ///
     std::auto_ptr<SimpleBuffer> _decodedData;
-
-    /// Decode next input block
-    //
-    /// It's assumed !decodingCompleted()
-    ///
-    void decodeNextBlock();
 };
 
 
diff --git a/libsound/Makefile.am b/libsound/Makefile.am
index a20e97e..8125d67 100644
--- a/libsound/Makefile.am
+++ b/libsound/Makefile.am
@@ -22,6 +22,10 @@ libgnashsound_la_SOURCES = \
        AuxStream.h \
        EmbedSound.cpp \
        EmbedSound.h \
+       StreamingSoundData.cpp \
+       StreamingSoundData.h \
+       StreamingSound.cpp \
+       StreamingSound.h \
        EmbedSoundInst.cpp \
        EmbedSoundInst.h \
        SoundUtils.h \
diff --git a/libsound/StreamingSound.cpp b/libsound/StreamingSound.cpp
new file mode 100644
index 0000000..39b2f9d
--- /dev/null
+++ b/libsound/StreamingSound.cpp
@@ -0,0 +1,248 @@
+// StreamingSound.cpp - instance of an embedded sound, for gnash
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
+//   2011 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 "StreamingSound.h"
+
+#include <cmath>
+#include <vector>
+
+#include "SoundInfo.h" // for use
+#include "MediaHandler.h" // for use
+#include "GnashException.h" // for SoundException
+#include "AudioDecoder.h" // for use
+#include "log.h" // will import boost::format too
+#include "SoundUtils.h"
+
+// Debug sound decoding
+//#define GNASH_DEBUG_SOUNDS_DECODING
+
+//#define GNASH_DEBUG_SOUNDS_MANAGEMENT
+
+namespace gnash {
+namespace sound {
+
+unsigned int
+StreamingSound::samplesFetched() const
+{
+    return _samplesFetched;
+}
+
+StreamingSound::StreamingSound(StreamingSoundData& soundData,
+            media::MediaHandler& mediaHandler,
+            sound_handler::StreamBlockId blockOffset,
+            unsigned int inPoint)
+        :
+        _currentBlock(blockOffset),
+        _positionInBlock(0),
+        // parameter is in stereo samples (44100 per second)
+        // we double to take 2 channels into account
+        // and double again to use bytes
+        _inPoint(inPoint * 4),
+        _samplesFetched(0),
+        _decoder(0),
+        _soundDef(soundData),
+        _decodedData(0)
+{
+    _playbackPosition = _inPoint; 
+    createDecoder(mediaHandler);
+}
+
+/*private*/
+void
+StreamingSound::createDecoder(media::MediaHandler& mediaHandler)
+{
+    const media::SoundInfo& si = _soundDef.soundinfo;
+
+    media::AudioInfo info(
+        (int)si.getFormat(), 
+        si.getSampleRate(), 
+        si.is16bit() ? 2 : 1, 
+        si.isStereo(), 
+        0, media::CODEC_TYPE_FLASH);
+
+    try {
+        _decoder.reset(mediaHandler.createAudioDecoder(info).release());
+    }
+    catch (const MediaException& e) {
+        log_error("AudioDecoder initialization failed: %s", e.what());
+    }
+}
+
+// Pointer handling and checking functions
+boost::int16_t*
+StreamingSound::getDecodedData(unsigned long int pos)
+{
+    if (_decodedData.get()) {
+        assert(pos < _decodedData->size());
+        return reinterpret_cast<boost::int16_t*>(_decodedData->data() + pos);
+    }
+    return 0;
+}
+
+unsigned int 
+StreamingSound::fetchSamples(boost::int16_t* to, unsigned int nSamples)
+{
+    // If there is no decoder, then we can't decode!
+    // TODO: isn't it documented that an StreamingSound w/out a decoder
+    //       means that the StreamingSoundData data is already decoded ?
+    if (!_decoder.get()) return 0;
+
+    unsigned int fetchedSamples = 0;
+
+    while (nSamples) {
+        unsigned int availableSamples = decodedSamplesAhead();
+
+        if (availableSamples) {
+            boost::int16_t* data = getDecodedData(_playbackPosition);
+
+            if (availableSamples >= nSamples) {
+                std::copy(data, data + nSamples, to);
+                fetchedSamples += nSamples;
+
+                // Update playback position (samples are 16bit)
+                _playbackPosition += nSamples*2;
+
+                break; // fetched all
+            }
+            else {
+                // not enough decoded samples available:
+                // copy what we have and go on
+                std::copy(data, data + availableSamples, to);
+                fetchedSamples += availableSamples;
+
+                // Update playback position (samples are 16bit)
+                _playbackPosition += availableSamples * 2;
+
+                to += availableSamples;
+                nSamples -= availableSamples;
+                assert(nSamples);
+            }
+        }
+
+        // We haven't finished fetching yet, so see if we
+        // have more to decode or not
+        if (decodingCompleted()) {
+            break; 
+        }
+
+        // More to decode, then decode it
+        decodeNextBlock();
+    }
+
+    // update samples played
+    _samplesFetched += fetchedSamples;
+
+    return fetchedSamples;
+}
+
+/*private*/
+void
+StreamingSound::decodeNextBlock()
+{
+    assert(!decodingCompleted());
+
+    // Should only be called when no more decoded data
+    // are available for fetching.
+    // Doing so we know what's the sample number
+    // of the first sample in the newly decoded block.
+    assert(_playbackPosition >= decodedDataSize());
+
+    const StreamingSoundData& sndData = _soundDef;
+    const bool parse =
+        sndData.soundinfo.getFormat() == media::AUDIO_CODEC_ADPCM ?
+        false : true;
+
+    // Move onto next block.
+    // decode it, add to decoded sound.
+
+    // This is a streaming sound. This function is only called if there is
+    // data to decode. If there is data, there must be frames.
+    const boost::uint32_t inputSize = sndData._buffers[_currentBlock].size() -
+        _positionInBlock; 
+
+#ifdef GNASH_DEBUG_SOUNDS_DECODING
+    log_debug(" frame size for frame starting at offset %d is %d",
+        decodingPosition, inputSize);
+#endif
+
+    assert(inputSize);
+    const boost::uint8_t* input = sndData._buffers[_currentBlock].data() + 
+        _positionInBlock;
+
+    boost::uint32_t consumed = 0;
+    boost::uint32_t decodedDataSize = 0;
+    boost::uint8_t* decodedData = _decoder->decode(
+                                      input, 
+                                      inputSize,
+                                      decodedDataSize,
+                                      consumed,
+                                      parse);
+
+    if (consumed == sndData._buffers[_currentBlock].size()) {
+        // Go to next block
+        ++_currentBlock;
+        _positionInBlock = 0;
+    }
+    else _positionInBlock += consumed;
+
+    assert(!(decodedDataSize % 2));
+
+    boost::int16_t* samples = reinterpret_cast<boost::int16_t*>(decodedData);
+    unsigned int nSamples = decodedDataSize / 2;
+
+    if (_soundDef.volume != 100) {
+        adjustVolume(samples, samples + nSamples, _soundDef.volume/100.0);
+    }
+
+#ifdef GNASH_DEBUG_MIXING
+    log_debug("  appending %d bytes to decoded buffer", decodedDataSize);
+#endif
+
+    // decodedData ownership transferred here
+    appendDecodedData(decodedData, decodedDataSize);
+}
+
+bool
+StreamingSound::eof() const
+{
+    // it isn't threaded, but just in case, we call decodingCompleted first
+    return (decodingCompleted() && !decodedSamplesAhead());
+}
+
+StreamingSound::~StreamingSound()
+{
+    _soundDef.eraseActiveSound(this);
+}
+
+void
+StreamingSound::appendDecodedData(boost::uint8_t* data, unsigned int size)
+{
+    if (!_decodedData.get()) {
+        _decodedData.reset(new SimpleBuffer);
+    }
+
+    _decodedData->append(data, size);
+
+    delete [] data; // ownership transferred...
+}
+
+} // gnash.sound namespace 
+} // namespace gnash
+
diff --git a/libsound/StreamingSound.h b/libsound/StreamingSound.h
new file mode 100644
index 0000000..fa81855
--- /dev/null
+++ b/libsound/StreamingSound.h
@@ -0,0 +1,194 @@
+// StreamingSound.h - instance of an embedded sound, for gnash
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
+//   2011 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
+
+#ifndef SOUND_STREAMINGSOUND_H
+#define SOUND_STREAMINGSOUND_H
+
+#include <boost/scoped_ptr.hpp>
+#include <cassert>
+#include <boost/cstdint.hpp> // For C99 int types
+
+#include "InputStream.h" 
+#include "AudioDecoder.h" 
+#include "SoundEnvelope.h"
+#include "SimpleBuffer.h" 
+#include "StreamingSoundData.h" 
+#include "sound_handler.h" 
+
+// Forward declarations
+namespace gnash {
+    namespace sound {
+        class StreamingSoundData;
+    }
+    namespace media {
+        class MediaHandler;
+    }
+}
+
+namespace gnash {
+namespace sound {
+
+/// Instance of a defined %sound (StreamingSoundData)
+//
+/// This class contains a pointer to the StreamingSoundData used for playing
+/// and a SimpleBuffer to use when decoding is needed.
+///
+/// When the SimpleBuffer is NULL we'll play the StreamingSoundData bytes 
directly
+/// (we assume they are decoded already)
+///
+class StreamingSound : public InputStream
+{
+public:
+
+    /// Create an embedded %sound instance
+    //
+    /// @param def
+    ///     The definition of this sound (where immutable data is kept)
+    ///
+    /// @param mh
+    ///     The MediaHandler to use for on-demand decoding
+    ///
+    /// @param blockId
+    ///     Identifier of the encoded block to start decoding from.
+    ///     @see gnash::swf::StreamSoundBlockTag
+    ///
+    /// @param inPoint
+    ///     Offset in output samples this instance should start
+    ///     playing from. These are post-resampling samples (44100 
+    ///     for one second of samples).
+    StreamingSound(StreamingSoundData& def, media::MediaHandler& mh,
+            sound_handler::StreamBlockId blockId,
+            unsigned int inPoint);
+
+    // See dox in sound_handler.h (InputStream)
+    unsigned int fetchSamples(boost::int16_t* to, unsigned int nSamples);
+
+    // See dox in sound_handler.h (InputStream)
+    unsigned int samplesFetched() const;
+
+    // See dox in sound_handler.h (InputStream)
+    bool eof() const;
+
+    /// Unregister self from the associated StreamingSoundData
+    //
+    /// WARNING: must be thread-safe!
+    ~StreamingSound();
+
+private:
+
+    /// Append size bytes to this raw data 
+    //
+    /// @param data
+    /// Data bytes, allocated with new[]. Ownership transferred.
+    ///
+    /// @param size
+    /// Size of the 'data' buffer.
+    void appendDecodedData(boost::uint8_t* data, unsigned int size);
+
+    /// Returns the data pointer in the encoded datastream
+    /// for the given position. Boundaries are checked.
+    //
+    /// Uses _samplesFetched and _playbackPosition
+    const boost::uint8_t* getEncodedData(unsigned long int pos);
+
+    /// Return number of already-decoded samples available
+    /// from playback position on
+    unsigned int decodedSamplesAhead() const {
+
+        const unsigned int dds = decodedDataSize();
+        if (dds <= _playbackPosition) return 0; 
+
+        const unsigned int bytesAhead = dds - _playbackPosition;
+        assert(!(bytesAhead%2));
+
+        const unsigned int samplesAhead = bytesAhead / 2;
+        return samplesAhead;
+    }
+
+    /// Return true if there's nothing more to decode
+    bool decodingCompleted() const {
+        return _positionInBlock == 0 && 
+            _currentBlock >= _soundDef._buffers.size();
+    }
+
+    /// Create a decoder for this instance
+    //
+    /// If decoder creation fails an error will
+    /// be logged, and _decoder won't be set
+    void createDecoder(media::MediaHandler& mediaHandler);
+
+    /// Return full size of the decoded data buffer
+    size_t decodedDataSize() const {
+        return _decodedData.get() ? _decodedData->size() : 0;
+    }
+
+    /// Access data in the decoded datastream for the given byte offset.
+    //
+    /// Boundaries are checked.
+    ///
+    /// @param pos offsets in bytes. This should usually be
+    ///        a multiple of two, since decoded data is
+    ///        composed of signed 16bit PCM samples..
+    boost::int16_t* getDecodedData(unsigned long int pos);
+
+    /// Decode next input block
+    //
+    /// It's assumed !decodingCompleted()
+    ///
+    void decodeNextBlock();
+
+    // The current block of sound.
+    size_t _currentBlock;
+
+    // The position within the current block.
+    size_t _positionInBlock;
+
+    /// Current playback position in the decoded stream
+    size_t _playbackPosition;
+
+    /// Offset in bytes samples from start of the block
+    /// to begin playback from
+    unsigned long _inPoint;
+
+    /// Number of samples fetched so far.
+    unsigned long _samplesFetched;
+
+    /// The decoder object used to convert the data into the playable format
+    boost::scoped_ptr<media::AudioDecoder> _decoder;
+
+    /// The encoded data
+    //
+    /// It is non-const because we deregister ourselves
+    /// from its container of playing instances on destruction
+    ///
+    StreamingSoundData& _soundDef;
+
+    /// The decoded buffer
+    //
+    /// If NULL, the _soundDef will be considered
+    /// decoded instead
+    ///
+    boost::scoped_ptr<SimpleBuffer> _decodedData;
+};
+
+
+} // gnash.sound namespace 
+} // namespace gnash
+
+#endif // SOUND_EMBEDSOUNDINST_H
diff --git a/libsound/StreamingSoundData.cpp b/libsound/StreamingSoundData.cpp
new file mode 100644
index 0000000..79981b6
--- /dev/null
+++ b/libsound/StreamingSoundData.cpp
@@ -0,0 +1,149 @@
+// StreamingSoundData.cpp - embedded sound definition, for gnash
+//
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
+//   2011 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 "StreamingSoundData.h"
+
+#include <vector>
+#include <boost/cstdint.hpp> 
+
+#include "SoundInfo.h"
+#include "MediaHandler.h" 
+#include "log.h"
+#include "GnashException.h" 
+#include "StreamingSound.h"
+#include "utility.h"
+
+namespace gnash {
+namespace sound {
+
+size_t
+StreamingSoundData::append(std::auto_ptr<SimpleBuffer> data, size_t 
sampleCount)
+{
+    UNUSED(sampleCount);
+    assert(data.get());
+
+    if (data->capacity() - data->size() < _paddingBytes) {
+        log_error("Streaming sound block creator didn't appropriately pad "
+                "sound data. We'll do so now, but will cost memory copies.");
+        data->reserve(data->size() + _paddingBytes);
+    }
+
+    _buffers.push_back(data);
+    return _buffers.size() - 1;
+}
+
+StreamingSoundData::StreamingSoundData(const media::SoundInfo& info,
+        int nVolume, size_t paddingBytes)
+    :
+    _buf(new SimpleBuffer()),
+    soundinfo(info),
+    volume(nVolume),
+    _paddingBytes(paddingBytes)
+{
+}
+
+void
+StreamingSoundData::clearInstances()
+{
+    boost::mutex::scoped_lock lock(_soundInstancesMutex);
+    _soundInstances.clear();
+}
+
+StreamingSoundData::Instances::iterator
+StreamingSoundData::eraseActiveSound(Instances::iterator i)
+{
+    // Mutex intentionally NOT locked...
+    return _soundInstances.erase(i);
+}
+
+std::auto_ptr<StreamingSound>
+StreamingSoundData::createInstance(media::MediaHandler& mh,
+            unsigned long blockOffset,
+            unsigned int inPoint)
+{
+    std::auto_ptr<StreamingSound> ret(new StreamingSound(*this, mh,
+                blockOffset, inPoint));
+
+    boost::mutex::scoped_lock lock(_soundInstancesMutex);
+
+    // Push the sound onto the playing sounds container.
+    _soundInstances.push_back(ret.get());
+
+    return ret;
+}
+
+StreamingSoundData::~StreamingSoundData()
+{
+    clearInstances();
+}
+
+void
+StreamingSoundData::eraseActiveSound(InputStream* inst)
+{
+    boost::mutex::scoped_lock lock(_soundInstancesMutex);
+
+    Instances::iterator it = std::find(
+            _soundInstances.begin(),
+            _soundInstances.end(),
+            inst);
+
+    if (it == _soundInstances.end()) {
+        log_error("StreamingSoundData::eraseActiveSound: instance %p "
+                "not found!", inst);
+        return;
+    }
+    
+    eraseActiveSound(it);
+}
+
+bool
+StreamingSoundData::isPlaying() const
+{
+    boost::mutex::scoped_lock lock(_soundInstancesMutex);
+    return !_soundInstances.empty();
+}
+
+size_t
+StreamingSoundData::numPlayingInstances() const
+{
+    boost::mutex::scoped_lock lock(_soundInstancesMutex);
+    return _soundInstances.size();
+}
+
+InputStream*
+StreamingSoundData::firstPlayingInstance() const
+{
+    boost::mutex::scoped_lock lock(_soundInstancesMutex);
+    return _soundInstances.front();
+}
+
+void
+StreamingSoundData::getPlayingInstances(std::vector<InputStream*>& to) const
+{
+    boost::mutex::scoped_lock lock(_soundInstancesMutex);
+    for (Instances::const_iterator i=_soundInstances.begin(), 
e=_soundInstances.end();
+            i!=e; ++i)
+    {
+        to.push_back(*i);
+    }
+}
+
+} // gnash.sound namespace 
+} // namespace gnash
diff --git a/libsound/EmbedSound.h b/libsound/StreamingSoundData.h
similarity index 58%
copy from libsound/EmbedSound.h
copy to libsound/StreamingSoundData.h
index 810b041..a632df5 100644
--- a/libsound/EmbedSound.h
+++ b/libsound/StreamingSoundData.h
@@ -1,4 +1,4 @@
-// EmbedSound.h - embedded sound definition, for gnash
+// StreamingSoundData.h - embedded sound definition, for gnash
 // 
 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
 //   2011 Free Software Foundation, Inc
@@ -17,26 +17,26 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-#ifndef SOUND_EMBEDSOUND_H
-#define SOUND_EMBEDSOUND_H
-
-#include "SimpleBuffer.h" // for composition
-#include "SoundInfo.h" // for composition
-#include "SoundEnvelope.h" // for SoundEnvelopes define
+#ifndef SOUND_STREAMING_SOUND_DATA_H
+#define SOUND_STREAMING_SOUND_DATA_H
 
 #include <vector>
-#include <map> // for composition (m_frame_size)
-#include <memory> // for auto_ptr (composition)
-#include <set> // for composition (_soundInstances)
+#include <map> 
+#include <memory> 
+#include <set> 
 #include <cassert>
 #include <boost/thread/mutex.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
 
+#include "SimpleBuffer.h" 
+#include "SoundInfo.h" 
 
 // Forward declarations
 namespace gnash {
     namespace sound {
-        class EmbedSoundInst;
         class InputStream;
+        class StreamingSound;
     }
     namespace media {
         class MediaHandler;
@@ -47,10 +47,10 @@ namespace gnash {
 namespace sound {
 
 /// Definition of an embedded sound
-class EmbedSound
+class StreamingSoundData
 {
     /// The undecoded data
-    std::auto_ptr<SimpleBuffer> _buf;
+    boost::scoped_ptr<SimpleBuffer> _buf;
 
     void ensureBufferPadding();
 
@@ -66,69 +66,25 @@ public:
     ///
     /// @param nVolume initial volume (0..100). Optional, defaults to 100.
     ///
-    EmbedSound(std::auto_ptr<SimpleBuffer> data, const media::SoundInfo& info,
+    StreamingSoundData(const media::SoundInfo& info,
             int nVolume, size_t paddingBytes);
 
-    ~EmbedSound();
+    ~StreamingSoundData();
 
     /// Object holding information about the sound
     media::SoundInfo soundinfo;
 
-    typedef std::map<boost::uint32_t,boost::uint32_t> FrameSizeMap;
-
-    /// Maps frame sizes to start-of-frame offsets
-    FrameSizeMap m_frames_size;
+    boost::ptr_vector<SimpleBuffer> _buffers;
 
-    /// Append size bytes to this sound
+    /// Append a sound data block
     //
-    /// @param data
-    /// Data bytes, allocated with new[]. Ownership transferred.
-    ///
-    /// @param size
-    /// Size of the 'data' buffer.
-    ///
-    void append(boost::uint8_t* data, unsigned int size);
-
-    /// Return size of the data buffer
-    size_t size() const 
-    {
-        return _buf->size();
-    }
+    /// @param data             Undecoded sound data.
+    /// @param sampleCount      The number of samples when decoded.
+    size_t append(std::auto_ptr<SimpleBuffer> data, size_t sampleCount);
 
     /// Is the data buffer empty ?
-    bool empty() const 
-    {
-        return _buf->empty();
-    }
-
-    /// Return a pointer to the underlying buffer
-    const boost::uint8_t* data() const {
-        return _buf->data();
-    }
-
-    /// Return a pointer to the underlying buffer
-    boost::uint8_t* data() {
-        return _buf->data();
-    }
-
-    /// Return a pointer to an offset in the underlying buffer
-    //
-    /// @param pos The offset value.
-    ///     An assertion will fail if pos > size()
-    ///
-    const boost::uint8_t* data(size_t pos) const {
-        assert(pos < _buf->size());
-        return _buf->data()+pos;
-    }
-
-    /// Return a pointer to an offset in the underlying buffer
-    //
-    /// @param pos The offset value.
-    ///     An assertion will fail if pos > size()
-    ///
-    boost::uint8_t* data(size_t pos) {
-        assert(pos < _buf->size());
-        return _buf->data()+pos;
+    bool empty() const {
+        return _buffers.empty();
     }
 
     /// Are there known playing instances of this sound ?
@@ -150,7 +106,7 @@ public:
     //
     /// Locks _soundInstancesMutex
     ///
-    EmbedSoundInst* firstPlayingInstance() const;
+    InputStream* firstPlayingInstance() const;
 
     /// Create an instance of this sound
     //
@@ -170,30 +126,10 @@ public:
     ///     Offset in output samples this instance should start
     ///     playing from. These are post-resampling samples from
     ///     the start of the specified blockId.
-    ///     
-    ///
-    /// @param outPoint
-    ///     Offset in output samples this instance should stop
-    ///     playing at. These are post-resampling samples from
-    ///     the start of the specified blockId.
-    ///
-    /// @param envelopes
-    ///     SoundEnvelopes to apply to this sound. May be 0 for none.
-    ///
-    /// @param loopCount
-    ///     Number of times this instance should loop over the defined sound.
-    ///     @todo document if every loop starts at secsOffset !
-    ///
-    /// @todo split this in createEventSoundInstance
-    ///                 and createStreamingSoundInstance
-    ///
-    ///
     /// Locks the _soundInstancesMutex when pushing to it
     ///
-    std::auto_ptr<EmbedSoundInst> createInstance( media::MediaHandler& mh,
-            unsigned long blockOffset,
-            unsigned int inPoint, unsigned int outPoint,
-            const SoundEnvelopes* envelopes, unsigned int loopCount);
+    std::auto_ptr<StreamingSound> createInstance(media::MediaHandler& mh,
+            unsigned long blockOffset, unsigned int inPoint);
 
     /// Volume for AS-sounds, range: 0-100.
     /// It's the SWF range that is represented here.
@@ -203,7 +139,7 @@ public:
     //
     /// NOTE: This class does NOT own the active sounds
     ///
-    typedef std::list<EmbedSoundInst*> Instances;
+    typedef std::list<InputStream*> Instances;
 
     /// Playing instances of this sound definition
     //
@@ -238,15 +174,12 @@ public:
     //
     /// @param inst The active sound instance to unregister
     ///
-    /// This is intended to be called by EmbedSoundInst
+    /// This is intended to be called by StreamingSoundDataInst
     /// destructor, which may be called by a separate thread
     /// so MUST be thread-safe
     ///
     /// Does lock the _soundInstancesMutex
-    ///
-    /// @todo make private and mark EmbedSoundInst as friend ?
-    ///
-    void eraseActiveSound(EmbedSoundInst* inst);
+    void eraseActiveSound(InputStream* inst);
 
     const size_t _paddingBytes;
 };
diff --git a/libsound/sdl/sound_handler_sdl.cpp 
b/libsound/sdl/sound_handler_sdl.cpp
index de769e7..126be62 100644
--- a/libsound/sdl/sound_handler_sdl.cpp
+++ b/libsound/sdl/sound_handler_sdl.cpp
@@ -149,13 +149,12 @@ 
SDL_sound_handler::create_sound(std::auto_ptr<SimpleBuffer> data,
 }
 
 sound_handler::StreamBlockId
-SDL_sound_handler::addSoundBlock(unsigned char* data,
-        unsigned int dataBytes, unsigned int nSamples,
-        int streamId)
+SDL_sound_handler::addSoundBlock(std::auto_ptr<SimpleBuffer> buf,
+        unsigned int nSamples, int streamId)
 {
 
     boost::mutex::scoped_lock lock(_mutex);
-    return sound_handler::addSoundBlock(data, dataBytes, nSamples, streamId);
+    return sound_handler::addSoundBlock(buf, nSamples, streamId);
 }
 
 
diff --git a/libsound/sdl/sound_handler_sdl.h b/libsound/sdl/sound_handler_sdl.h
index 00cbb26..cd9995f 100644
--- a/libsound/sdl/sound_handler_sdl.h
+++ b/libsound/sdl/sound_handler_sdl.h
@@ -100,8 +100,7 @@ public:
 
     // See dox in sound_handler.h
     // overridden to serialize access to the data buffer slot
-    virtual StreamBlockId addSoundBlock(unsigned char* data,
-                                       unsigned int data_bytes,
+    virtual StreamBlockId addSoundBlock(std::auto_ptr<SimpleBuffer> buf,
                                        unsigned int sample_count,
                                        int streamId);
 
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 57182f3..5847626 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -20,14 +20,16 @@
 #include "sound_handler.h"
 
 #include <boost/cstdint.hpp> // For C99 int types
-#include <vector> // for use
-#include <cmath> // for floor (debugging)
+#include <vector> 
+#include <cmath> 
+#include <boost/scoped_array.hpp>
 
 #include "EmbedSound.h" // for use
 #include "InputStream.h" // for use
 #include "EmbedSoundInst.h" // for upcasting to InputStream
 #include "log.h" // for use
-#include "WallClockTimer.h" // for debugging
+#include "StreamingSound.h"
+#include "StreamingSoundData.h"
 
 // Debug create_sound/delete_sound/playSound/stop_sound, loops
 //#define GNASH_DEBUG_SOUNDS_MANAGEMENT
@@ -58,18 +60,16 @@ namespace gnash {
 namespace sound {
 
 sound_handler::StreamBlockId
-sound_handler::addSoundBlock(unsigned char* data,
-        unsigned int data_bytes, unsigned int /*sample_count*/,
-        int handle)
+sound_handler::addSoundBlock(std::auto_ptr<SimpleBuffer> data,
+        unsigned int sample_count, int handle)
 {
     if (!validHandle(_streamingSounds, handle)) {
         log_error("Invalid (%d) handle passed to fill_stream_data, "
                   "doing nothing", handle);
-        delete [] data;
         return -1;
     }
 
-    EmbedSound* sounddata = _streamingSounds[handle];
+    StreamingSoundData* sounddata = _streamingSounds[handle];
     if (!sounddata) {
         log_error("handle passed to fill_stream_data (%d) "
                   "was deleted", handle);
@@ -77,15 +77,7 @@ sound_handler::addSoundBlock(unsigned char* data,
     }
 
     // Handling of the sound data
-    size_t start_size = sounddata->size();
-    sounddata->append(reinterpret_cast<boost::uint8_t*>(data), data_bytes);
-
-#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
-    log_debug("fill_stream_data: sound %d, %d samples (%d bytes) appended at 
offset %d",
-        handle, data_bytes/2, data_bytes, start_size);
-#endif
-
-    return start_size;
+    return sounddata->append(data, sample_count);
 }
 
 void
@@ -106,10 +98,10 @@ sound_handler::delete_all_sounds()
     }
     _sounds.clear();
 
-    for (Sounds::iterator i = _streamingSounds.begin(),
+    for (StreamingSounds::iterator i = _streamingSounds.begin(),
                           e = _streamingSounds.end(); i != e; ++i)
     {
-        EmbedSound* sdef = *i;
+        StreamingSoundData* sdef = *i;
 
         // Streaming sounds are never deleted.
         assert(sdef);
@@ -162,11 +154,11 @@ sound_handler::stop_all_sounds()
         stopEmbedSoundInstances(*sounddata);
     }
 
-    for (Sounds::iterator i = _streamingSounds.begin(),
+    for (StreamingSounds::iterator i = _streamingSounds.begin(),
                           e = _streamingSounds.end(); i != e; ++i)
     {
-        EmbedSound* sounddata = *i;
-        if ( ! sounddata ) continue; 
+        StreamingSoundData* sounddata = *i;
+        if (!sounddata) continue; 
         stopEmbedSoundInstances(*sounddata);
     }
 }
@@ -207,7 +199,7 @@ sound_handler::stopStreamingSound(int handle)
         return;
     }
     
-    EmbedSound* sounddata = _streamingSounds[handle];
+    StreamingSoundData* sounddata = _streamingSounds[handle];
     assert(sounddata);
 
     stopEmbedSoundInstances(*sounddata);
@@ -237,10 +229,36 @@ sound_handler::stopEventSound(int handle)
 }
 
 void   
-sound_handler::stopEmbedSoundInstances(EmbedSound& def)
+sound_handler::stopEmbedSoundInstances(StreamingSoundData& def)
 {
     // Assert _mutex is locked ...
+    typedef std::vector<InputStream*> InputStreamVect;
+    InputStreamVect playing;
+    def.getPlayingInstances(playing);
+
+    // Now, for each playing InputStream, unplug it!
+    // NOTE: could be optimized...
+    for (InputStreamVect::iterator i=playing.begin(), e=playing.end();
+            i!=e; ++i)
+    {
+#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
+        log_debug(" unplugging input stream %p from stopEmbedSoundInstances", 
*i);
+#endif
 
+        // Explicitly calling the base class implementation
+        // is a (dirty?) way to avoid mutex-locking overrides
+        // in subclasses causing deadlocks.
+        sound_handler::unplugInputStream(*i);
+    }
+
+    def.clearInstances();
+
+}
+
+void   
+sound_handler::stopEmbedSoundInstances(EmbedSound& def)
+{
+    // Assert _mutex is locked ...
     typedef std::vector<InputStream*> InputStreamVect;
     InputStreamVect playing;
     def.getPlayingInstances(playing);
@@ -336,9 +354,8 @@ sound_handler::get_duration(int handle) const
 int
 sound_handler::createStreamingSound(const media::SoundInfo& sinfo)
 {
-    std::auto_ptr<SimpleBuffer> b;
-    std::auto_ptr<EmbedSound> sounddata(
-            new EmbedSound(b, sinfo, 100,
+    std::auto_ptr<StreamingSoundData> sounddata(
+            new StreamingSoundData(sinfo, 100,
                 _mediaHandler ? _mediaHandler->getInputPaddingSize() : 0));
 
     int sound_id = _streamingSounds.size();
@@ -424,7 +441,7 @@ sound_handler::isSoundPlaying(int handle) const
 void
 sound_handler::playSound(EmbedSound& sounddata,
         int loopCount, unsigned int inPoint, unsigned int outPoint,
-        StreamBlockId blockId, const SoundEnvelopes* envelopes,
+        const SoundEnvelopes* envelopes,
         bool allowMultiples)
 {
 
@@ -465,9 +482,6 @@ sound_handler::playSound(EmbedSound& sounddata,
             // MediaHandler to use for decoding
             *_mediaHandler,
 
-            // Sound block identifier
-            blockId, 
-
             // Samples range
             inPoint, outPoint,
 
@@ -486,11 +500,17 @@ sound_handler::playSound(EmbedSound& sounddata,
 void
 sound_handler::playStream(int soundId, StreamBlockId blockId)
 {
-    unsigned int inPoint=0;
-    unsigned int outPoint=std::numeric_limits<unsigned int>::max();
+    const unsigned int inPoint=0;
+
+    StreamingSoundData& s = *_streamingSounds[soundId];
+    if (s.isPlaying() || s.empty()) return;
+
+    std::auto_ptr<InputStream> is(
+        s.createInstance(*_mediaHandler, blockId, inPoint));
+
+    s._soundInstances.push_back(is.get());
 
-    playSound(*_streamingSounds[soundId], 0, inPoint, outPoint, blockId, 0,
-            false);
+    plugInputStream(is);
 }
 
 /*public*/
@@ -551,7 +571,7 @@ sound_handler::startSound(int handle, int loops,
 #endif
     }
 
-    playSound(sounddata, loops, inPoint, outPoint, 0, env, allowMultiple);
+    playSound(sounddata, loops, inPoint, outPoint, env, allowMultiple);
 }
 
 void
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index be9f7c6..7398277 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -44,6 +44,8 @@ namespace gnash {
     }
     namespace sound {
         class EmbedSound;
+        class StreamingSound;
+        class StreamingSoundData;
         class InputStream;
     }
     class SimpleBuffer;
@@ -223,28 +225,15 @@ public:
     /// Append data for a streaming sound.
     ///
     /// Gnash's parser calls this to fill up soundstreams data.
-    /// TODO: the current code uses memory reallocation to grow the sound,
-    /// which is suboptimal; instead, we should maintain sound sources as a 
-    /// list of buffers, to avoid reallocations.
     ///
-    /// @param data
-    ///     The sound data to be saved, allocated by new[].
-    ///     Ownership is transferred.
-    ///     TODO: use SimpleBuffer ?
-    ///
-    /// @param dataBytes
-    ///     Size of the data in bytes
-    ///
-    /// @param sampleCount
-    ///     Number of samples in the data
-    ///
-    /// @param streamId
-    ///     The soundhandlers id of the sound we want to add data to
+    /// @param data         The sound data to be stored.
+    /// @param sampleCount  Number of samples in the data
+    /// @param streamId     The soundhandlers id of the sound we want
+    ///                     to add data to
     ///
     /// @return an identifier for the new block for use in playSound
     /// @throw SoundException on error
-    virtual StreamBlockId addSoundBlock(unsigned char* data,
-                                       unsigned int dataBytes,
+    virtual StreamBlockId addSoundBlock(std::auto_ptr<SimpleBuffer> data,
                                        unsigned int sampleCount,
                                        int streamId);
 
@@ -517,14 +506,19 @@ private:
     /// Elements of the vector are owned by this class
     Sounds  _sounds;
 
+    typedef std::vector<StreamingSoundData*> StreamingSounds;
+
     /// Vector containing streaming sounds.
     //
     /// Elements of the vector are owned by this class
-    Sounds _streamingSounds;
+    StreamingSounds _streamingSounds;
 
     /// Stop all instances of an embedded sound
     void stopEmbedSoundInstances(EmbedSound& def);
 
+    /// Stop all instances of an embedded sound
+    void stopEmbedSoundInstances(StreamingSoundData& def);
+
     typedef std::set< InputStream* > InputStreams;
 
     /// Sound input streams.
@@ -558,12 +552,6 @@ private:
     ///     playing at. These are post-resampling samples (44100 
     ///     for one second of samples).
     ///
-    /// @param blockId
-    ///     When starting a soundstream from a random frame, this tells which
-    ///     block to start decoding from.
-    ///     If non-zero, the sound will only start when no other instances of
-    ///     it are already playing.
-    ///
     /// @param env
     ///     Some eventsounds have some volume control mechanism called
     ///     envelopes.
@@ -574,7 +562,7 @@ private:
     ///     instance of it already playing.
     ///
     void playSound(EmbedSound& sound, int loops, unsigned int inPoint,
-                   unsigned int outPoint, StreamBlockId blockId,
+                   unsigned int outPoint, 
                    const SoundEnvelopes* env, bool allowMultiple);
 
     /// Convert SWF-specified number of samples to output number of samples

http://git.savannah.gnu.org/cgit//commit/?id=0d6ee955540b788243abbd46a50beb34a5687265


commit 0d6ee955540b788243abbd46a50beb34a5687265
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 08:37:38 2011 +0200

    More pedantic errors.

diff --git a/libmedia/gst/AudioInputGst.cpp b/libmedia/gst/AudioInputGst.cpp
index 4ce343d..8099075 100644
--- a/libmedia/gst/AudioInputGst.cpp
+++ b/libmedia/gst/AudioInputGst.cpp
@@ -44,7 +44,7 @@ GnashAudio::GnashAudio() {
     _devLocation = NULL;
     _gstreamerSrc = NULL;
     _productName = NULL;
-};
+}
 
 GnashAudioPrivate::GnashAudioPrivate() {
     audioSource = NULL;
@@ -58,7 +58,7 @@ GnashAudioPrivate::GnashAudioPrivate() {
     _audioSaveBin = NULL;
     _pipelineIsPlaying = false;
     _mux = NULL;
-};
+}
 
 AudioInputGst::AudioInputGst() 
     :

http://git.savannah.gnu.org/cgit//commit/?id=a7c6bcd0770d57315d0208f855e5dc5abbc507a9


commit a7c6bcd0770d57315d0208f855e5dc5abbc507a9
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 08:34:34 2011 +0200

    Use C comments in C.

diff --git a/gui/pythonmod/gnash-view.h b/gui/pythonmod/gnash-view.h
index 244119c..629cc40 100644
--- a/gui/pythonmod/gnash-view.h
+++ b/gui/pythonmod/gnash-view.h
@@ -1,21 +1,21 @@
-// gnash-view.h: Gtk view widget for gnash
-// 
-//   Copyright (C) 2009, 2010, 2011 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
-//
+/* gnash-view.h: Gtk view widget for gnash
+** 
+**   Copyright (C) 2009, 2010, 2011 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
+*/
 
 #ifndef __GNASH_VIEW_H__
 #define __GNASH_VIEW_H__

http://git.savannah.gnu.org/cgit//commit/?id=8c07bb0c532dc604cec068ef93ab515dd252339b


commit 8c07bb0c532dc604cec068ef93ab515dd252339b
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 08:20:10 2011 +0200

    Fix more pedantic errors.

diff --git a/libcore/SWFMatrix.cpp b/libcore/SWFMatrix.cpp
index e037ae7..3d7f35f 100644
--- a/libcore/SWFMatrix.cpp
+++ b/libcore/SWFMatrix.cpp
@@ -50,7 +50,7 @@ rotationX(const SWFMatrix& m)
     const double b = m.b();
     const double a = m.a();
     return std::atan2(b, a);
-};
+}
 
 inline double
 rotationY(const SWFMatrix& m)
@@ -58,7 +58,7 @@ rotationY(const SWFMatrix& m)
     const double c = m.c();
     const double d = m.d();
     return std::atan2(-c, d);
-};
+}
 
 inline boost::int32_t
 toFixed16(double a)

http://git.savannah.gnu.org/cgit//commit/?id=3329c1197538d551e8d58241ec7643177f1838b1


commit 3329c1197538d551e8d58241ec7643177f1838b1
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 08:18:03 2011 +0200

    Make macros standard compliant.

diff --git a/libcore/asobj/Global_as.h b/libcore/asobj/Global_as.h
index 3b1d028..aeae5c1 100644
--- a/libcore/asobj/Global_as.h
+++ b/libcore/asobj/Global_as.h
@@ -200,8 +200,9 @@ invoke(const as_value& method, const as_environment& env, 
as_object* this_ptr,
        return val;
 }
 
-/// Helper macro for callMethod arguments.
-#define VALUE_ARG(z, n, t) BOOST_PP_COMMA_IF(n) t arg##n
+/// Helper macros for callMethod arguments.
+#define FUNC_PARAM(z, n, t) BOOST_PP_COMMA_IF(n) t arg##n
+#define VALUE_ARG(z, n, t) BOOST_PP_COMMA_IF(n) arg##n
 
 /// Call a member function of this object in an AS-compatible way
 //
@@ -225,12 +226,12 @@ invoke(const as_value& method, const as_environment& env, 
as_object* this_ptr,
 #define CALL_METHOD(x, n, t) \
 inline as_value \
 callMethod(as_object* obj, const ObjectURI& uri BOOST_PP_COMMA_IF(n)\
-        BOOST_PP_REPEAT(n, VALUE_ARG, const as_value&)) {\
+        BOOST_PP_REPEAT(n, FUNC_PARAM, const as_value&)) {\
     if (!obj) return as_value();\
     as_value func;\
     if (!obj->get_member(uri, &func)) return as_value();\
     fn_call::Args args;\
-    BOOST_PP_EXPR_IF(n, (args += BOOST_PP_REPEAT(n, VALUE_ARG, ));)\
+    BOOST_PP_EXPR_IF(n, (args += BOOST_PP_REPEAT(n, VALUE_ARG, 
BOOST_PP_EMPTY));)\
     return invoke(func, as_environment(getVM(*obj)), obj, args);\
 }
 
@@ -238,6 +239,11 @@ callMethod(as_object* obj, const ObjectURI& uri 
BOOST_PP_COMMA_IF(n)\
 #define MAX_ARGS 4
 BOOST_PP_REPEAT(BOOST_PP_INC(MAX_ARGS), CALL_METHOD, BOOST_PP_EMPTY)
 
+#undef VALUE_ARG
+#undef FUNC_PARAM
+#undef MAX_ARGS
+#undef CALL_METHOD
+
 /// Convenience function for finding a class constructor.
 //
 /// Only currently useful in AS2.

http://git.savannah.gnu.org/cgit//commit/?id=88c2bfa52125639346f3c064c9058ebad3ce84b5


commit 88c2bfa52125639346f3c064c9058ebad3ce84b5
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 08:17:50 2011 +0200

    Fix pedantic error.

diff --git a/libbase/GnashTexture.h b/libbase/GnashTexture.h
index cc00415..2cd62e4 100644
--- a/libbase/GnashTexture.h
+++ b/libbase/GnashTexture.h
@@ -27,7 +27,7 @@ namespace gnash {
 
 /// Texture flags
 enum {
-    GNASH_TEXTURE_VAAPI = 1 << 0,
+    GNASH_TEXTURE_VAAPI = 1 << 0
 };
 
 /// OpenGL texture format

http://git.savannah.gnu.org/cgit//commit/?id=42ef363d57ac03c77a7d6d4b0c497b9c318d38e2


commit 42ef363d57ac03c77a7d6d4b0c497b9c318d38e2
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 07:49:59 2011 +0200

    Reduce duplication.

diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 5fcfe13..57182f3 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -45,6 +45,13 @@ silentStream(void*, boost::int16_t* stream, unsigned int 
len, bool& atEOF)
     return len;
 }
 
+template<typename T>
+bool
+validHandle(const T& container, int handle)
+{
+    return handle >= 0 && static_cast<size_t>(handle) < container.size();
+}
+
 }
 
 namespace gnash {
@@ -53,22 +60,19 @@ namespace sound {
 sound_handler::StreamBlockId
 sound_handler::addSoundBlock(unsigned char* data,
         unsigned int data_bytes, unsigned int /*sample_count*/,
-        int handleId)
+        int handle)
 {
-    // @@ does a negative handle_id have any meaning ?
-    //    should we change it to unsigned instead ?
-    if (handleId < 0 || (unsigned int) handleId+1 > _streamingSounds.size())
-    {
-        log_error("Invalid (%d) sound_handle passed to fill_stream_data, "
-                  "doing nothing", handleId);
+    if (!validHandle(_streamingSounds, handle)) {
+        log_error("Invalid (%d) handle passed to fill_stream_data, "
+                  "doing nothing", handle);
         delete [] data;
         return -1;
     }
 
-    EmbedSound* sounddata = _streamingSounds[handleId];
+    EmbedSound* sounddata = _streamingSounds[handle];
     if (!sounddata) {
-        log_error("sound_handle passed to fill_stream_data (%d) "
-                  "was deleted", handleId);
+        log_error("handle passed to fill_stream_data (%d) "
+                  "was deleted", handle);
         return -1;
     }
 
@@ -78,7 +82,7 @@ sound_handler::addSoundBlock(unsigned char* data,
 
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
     log_debug("fill_stream_data: sound %d, %d samples (%d bytes) appended at 
offset %d",
-        handleId, data_bytes/2, data_bytes, start_size);
+        handle, data_bytes/2, data_bytes, start_size);
 #endif
 
     return start_size;
@@ -120,31 +124,30 @@ sound_handler::delete_all_sounds()
 }
 
 void
-sound_handler::delete_sound(int sound_handle)
+sound_handler::delete_sound(int handle)
 {
     // Check if the sound exists
-    if (sound_handle < 0 || static_cast<unsigned int>(sound_handle) >= 
_sounds.size())
-    {
-        log_error("Invalid (%d) sound_handle passed to delete_sound, "
-                  "doing nothing", sound_handle);
+    if (!validHandle(_sounds, handle)) {
+        log_error("Invalid (%d) handle passed to delete_sound, "
+                  "doing nothing", handle);
         return;
     }
 
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
-    log_debug ("deleting sound :%d", sound_handle);
+    log_debug ("deleting sound :%d", handle);
 #endif
 
-    EmbedSound* def = _sounds[sound_handle];
+    EmbedSound* def = _sounds[handle];
     if ( ! def )
     {
-        log_error("sound_handle passed to delete_sound (%d) "
-                  "already deleted", sound_handle);
+        log_error("handle passed to delete_sound (%d) "
+                  "already deleted", handle);
         return;
     }
     
     stopEmbedSoundInstances(*def);
     delete def;
-    _sounds[sound_handle] = 0;
+    _sounds[handle] = 0;
 
 }
 
@@ -169,56 +172,40 @@ sound_handler::stop_all_sounds()
 }
 
 int
-sound_handler::get_volume(int soundHandle) const
+sound_handler::get_volume(int handle) const
 {
-    if (soundHandle >= 0 && static_cast<size_t>(soundHandle) < _sounds.size())
-    {
-        return _sounds[soundHandle]->volume;
-    } 
+    if (validHandle(_sounds, handle)) return _sounds[handle]->volume; 
 
     // Invalid handle.
     return 0;
 }
 
 void   
-sound_handler::set_volume(int sound_handle, int volume)
+sound_handler::set_volume(int handle, int volume)
 {
-    // Check if the sound exists.
-    if (sound_handle < 0 || static_cast<unsigned int>(sound_handle) >= 
_sounds.size())
-    {
-        // Invalid handle.
-    } else {
-
-        // Set volume for this sound. Should this only apply to the active 
sounds?
-        _sounds[sound_handle]->volume = volume;
-    }
-
-
+    // Set volume for this sound.
+    // Should this only apply to the active sounds?
+    if (validHandle(_sounds, handle)) _sounds[handle]->volume = volume;
 }
 
 media::SoundInfo*
-sound_handler::get_sound_info(int sound_handle) const
+sound_handler::get_sound_info(int handle) const
 {
     // Check if the sound exists.
-    if (sound_handle >= 0 &&
-            static_cast<size_t>(sound_handle) < _streamingSounds.size())
-    {
-        return &_streamingSounds[sound_handle]->soundinfo;
+    if (validHandle(_streamingSounds, handle)) {
+        return &_streamingSounds[handle]->soundinfo;
     } 
-    return NULL;
+    return 0;
 }
 
 void
 sound_handler::stopStreamingSound(int handle)
 {
     // Check if the sound exists.
-    if (handle < 0 || (size_t)handle >= _streamingSounds.size())
-    {
+    if (!validHandle(_streamingSounds, handle)) {
         log_debug("stop_sound(%d): invalid sound id", handle);
-        // Invalid handle.
         return;
     }
-
     
     EmbedSound* sounddata = _streamingSounds[handle];
     assert(sounddata);
@@ -230,12 +217,10 @@ void
 sound_handler::stopEventSound(int handle)
 {
     // Check if the sound exists.
-    if (handle < 0 || (unsigned int) handle >= _sounds.size()) {
+    if (!validHandle(_sounds, handle)) {
         log_debug("stop_sound(%d): invalid sound id", handle);
-        // Invalid handle.
         return;
     }
-
     
     EmbedSound* sounddata = _sounds[handle];
     if (!sounddata) {
@@ -305,16 +290,12 @@ sound_handler::unplugInputStream(InputStream* id)
 }
 
 unsigned int
-sound_handler::tell(int sound_handle) const
+sound_handler::tell(int handle) const
 {
     // Check if the sound exists.
-    if (sound_handle < 0 || (unsigned int) sound_handle >= _sounds.size())
-    {
-        // Invalid handle.
-        return 0;
-    }
+    if (!validHandle(_sounds, handle)) return 0;
 
-    const EmbedSound* sounddata = _sounds[sound_handle];
+    const EmbedSound* sounddata = _sounds[handle];
 
     // If there is no active sounds, return 0
     if (!sounddata->isPlaying()) return 0;
@@ -332,16 +313,12 @@ sound_handler::tell(int sound_handle) const
 }
 
 unsigned int
-sound_handler::get_duration(int sound_handle) const
+sound_handler::get_duration(int handle) const
 {
     // Check if the sound exists.
-    if (sound_handle < 0 || (unsigned int) sound_handle >= _sounds.size())
-    {
-        // Invalid handle.
-        return 0;
-    }
+    if (!validHandle(_sounds, handle)) return 0;
 
-    const EmbedSound* sounddata = _sounds[sound_handle];
+    const EmbedSound* sounddata = _sounds[handle];
 
     const boost::uint32_t sampleCount = sounddata->soundinfo.getSampleCount();
     const boost::uint32_t sampleRate = sounddata->soundinfo.getSampleRate();
@@ -431,15 +408,11 @@ sound_handler::swfToOutSamples(const media::SoundInfo& 
sinfo,
 
 /* public */
 bool
-sound_handler::isSoundPlaying(int sound_handle) const
+sound_handler::isSoundPlaying(int handle) const
 {
-    if ( sound_handle < 0 ||
-         static_cast<unsigned int>(sound_handle) >= _sounds.size() )
-    {
-        return false;
-    }
+    if (!validHandle(_sounds, handle)) return false;
 
-    EmbedSound& sounddata = *(_sounds[sound_handle]);
+    EmbedSound& sounddata = *(_sounds[handle]);
 
     // When this is called from a StreamSoundBlockTag,
     // we only start if this sound isn't already playing.
@@ -522,23 +495,21 @@ sound_handler::playStream(int soundId, StreamBlockId 
blockId)
 
 /*public*/
 void
-sound_handler::startSound(int soundId, int loops, 
+sound_handler::startSound(int handle, int loops, 
                       const SoundEnvelopes* env,
                       bool allowMultiple, unsigned int inPoint,
                    unsigned int outPoint)
 {
     // Check if the sound exists
-    if (soundId < 0 ||
-        static_cast<unsigned int>(soundId) >= _sounds.size())
-    {
+    if (!validHandle(_sounds, handle)) {
         log_error("Invalid (%d) sound_handle passed to startSound, "
-                  "doing nothing", soundId);
+                  "doing nothing", handle);
         return;
     }
 
     // Handle delaySeek
 
-    EmbedSound& sounddata = *(_sounds[soundId]);
+    EmbedSound& sounddata = *(_sounds[handle]);
     const media::SoundInfo& sinfo = sounddata.soundinfo;
 
     int swfDelaySeek = sinfo.getDelaySeek(); 

http://git.savannah.gnu.org/cgit//commit/?id=f5e7e38569e50b9cb376fe7fa927f278222b26dc


commit f5e7e38569e50b9cb376fe7fa927f278222b26dc
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Jul 4 07:26:21 2011 +0200

    Include order.

diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 02d3845..5fcfe13 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -18,16 +18,17 @@
 //
 
 #include "sound_handler.h"
+
+#include <boost/cstdint.hpp> // For C99 int types
+#include <vector> // for use
+#include <cmath> // for floor (debugging)
+
 #include "EmbedSound.h" // for use
 #include "InputStream.h" // for use
 #include "EmbedSoundInst.h" // for upcasting to InputStream
 #include "log.h" // for use
 #include "WallClockTimer.h" // for debugging
 
-#include <boost/cstdint.hpp> // For C99 int types
-#include <vector> // for use
-#include <cmath> // for floor (debugging)
-
 // Debug create_sound/delete_sound/playSound/stop_sound, loops
 //#define GNASH_DEBUG_SOUNDS_MANAGEMENT
 
@@ -39,7 +40,7 @@ namespace {
 unsigned int
 silentStream(void*, boost::int16_t* stream, unsigned int len, bool& atEOF)
 {
-    std::fill(stream, stream+len, 0);
+    std::fill(stream, stream + len, 0);
     atEOF=false;
     return len;
 }

http://git.savannah.gnu.org/cgit//commit/?id=4f02ec270fe77b2c4c5af7ebaa71af60b657e1d5


commit 4f02ec270fe77b2c4c5af7ebaa71af60b657e1d5
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 18:02:34 2011 +0200

    Update documentation.

diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index c77136f..be9f7c6 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -100,57 +100,47 @@ public:
     /// Mixed functions:
     ////////////////////////////////////////////////
 
-    /// Create a sound buffer slot, for on-demand playback.
+    /// Remove all scheduled request for playback of sound buffer slots
     //
-    /// TODO: create a separate function for streaming sounds.
+    /// This applies both to streaming and event sounds.
+    virtual void stop_all_sounds();
+
+    ////////////////////////////////////////////////
+    /// Event sound functions:
+    ////////////////////////////////////////////////
+    
+    /// Create a sound buffer slot, for on-demand playback.
     //
     /// @param data
-    ///     The data to be stored. For soundstream this is NULL.
-    ///     The data is in encoded format, with format specified
-    ///     with the sinfo parameter, this is to allow on-demand
-    ///     decoding (if the sound is never played, it's never decoded).
+    ///     The data to be stored. The data is in encoded format, with
+    ///     format specified with the sinfo parameter, this is to allow
+    ///     on-demand decoding (if the sound is never played, it's never
+    ///     decoded).
     ///
     /// @param sinfo
-    ///     A SoundInfo object contained in an auto_ptr, which contains
-    ///     info about samplerate, samplecount, stereo and more.
-    ///     The SoundObject must be not-NULL!
+    ///     A SoundInfo object containing info about samplerate, samplecount,
+    /// stereo and more.
     ///
     /// @return the id given by the soundhandler for later identification.
     virtual int create_sound(std::auto_ptr<SimpleBuffer> data,
             const media::SoundInfo& sinfo);
-
-    virtual int createStreamingSound(const media::SoundInfo& sinfo);
-
-    /// Remove all scheduled request for playback of sound buffer slots
-    //
-    /// This applies both to streaming and event sounds.
-    virtual void stop_all_sounds();
-
-    ////////////////////////////////////////////////
-    /// Event sound functions:
-    ////////////////////////////////////////////////
         
     /// Remove scheduled requests to play the specified sound buffer slot
     //
-    /// Note: this currently is used for both streaming and events sounds.
-    /// TODO: use a separate function for each.
-    //
-    /// Stop all instances of the specified sound if it's playing.
+    /// Stop all instances of the specified event sound if it's playing.
     /// (Normally a full-featured sound API would take a
     /// handle specifying the *instance* of a playing
     /// sample, but SWF is not expressive that way.)
     //
-    /// @param sound_handle
-    /// The sound_handlers id for the sound to be deleted
+    /// @param sound_handle     id for the sound to be stopped
     virtual void stopEventSound(int sound_handle);
 
-    /// Discard the sound data for an event sound
+    /// Discard the sound data for an embedded event sound
     //
     /// Only embedded event sounds are deleted; this happens when the
-    /// associated sound_definition is deleted.
+    /// associated sound_sample is deleted.
     //
-    /// @param sound_handle     The sound_handlers id for the event sound to be
-    ///                         deleted
+    /// @param sound_handle     The id for the event sound to be deleted
     virtual void delete_sound(int sound_handle);
 
     /// Start playback of an event sound
@@ -222,11 +212,13 @@ public:
     /// Streaming sound functions:
     ////////////////////////////////////////////////
 
+    virtual int createStreamingSound(const media::SoundInfo& sinfo);
+
     /// Remove scheduled requests to play the specified sound buffer slot
     //
     /// @param sound_handle     The sound_handlers id for the sound to be
     ///                         stopped.
-    virtual void stopStreamingSound(int sound_handle);
+    virtual void stopStreamingSound(int handle);
 
     /// Append data for a streaming sound.
     ///
@@ -266,7 +258,7 @@ public:
     ///                     info about.
     /// @return             a pointer to the SoundInfo object for the sound
     ///                     with the given id or 0 if no such sound exists.
-    virtual media::SoundInfo* get_sound_info(int soundHandle) const;
+    virtual media::SoundInfo* get_sound_info(int handle) const;
 
     /// Start playback of a streaming sound, if not playing already
     //

http://git.savannah.gnu.org/cgit//commit/?id=558fc598e39d5e9911a64352c5580389c1d05208


commit 558fc598e39d5e9911a64352c5580389c1d05208
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 14:49:36 2011 +0200

    More splitting.
    
    Actually use a separate vector for streaming sounds.

diff --git a/libcore/swf/SoundStreamHeadTag.cpp 
b/libcore/swf/SoundStreamHeadTag.cpp
index eea4c5f..68abcb8 100644
--- a/libcore/swf/SoundStreamHeadTag.cpp
+++ b/libcore/swf/SoundStreamHeadTag.cpp
@@ -153,8 +153,7 @@ SoundStreamHeadTag::loader(SWFStream& in, TagType tag, 
movie_definition& m,
 
     // Stores the sounddata in the soundhandler, and the ID returned
     // can be used to starting, stopping and deleting that sound
-    const int handler_id =
-        handler->create_sound(std::auto_ptr<SimpleBuffer>(0), sinfo);
+    const int handler_id = handler->createStreamingSound(sinfo);
 
     m.set_loading_sound_stream_id(handler_id);
 }
diff --git a/libsound/sdl/sound_handler_sdl.cpp 
b/libsound/sdl/sound_handler_sdl.cpp
index b810358..de769e7 100644
--- a/libsound/sdl/sound_handler_sdl.cpp
+++ b/libsound/sdl/sound_handler_sdl.cpp
@@ -133,6 +133,12 @@ SDL_sound_handler::~SDL_sound_handler()
 
 }
 
+int
+SDL_sound_handler::createStreamingSound(const media::SoundInfo& sinfo)
+{
+    boost::mutex::scoped_lock lock(_mutex);
+    return sound_handler::createStreamingSound(sinfo);
+}
 
 int
 SDL_sound_handler::create_sound(std::auto_ptr<SimpleBuffer> data,
diff --git a/libsound/sdl/sound_handler_sdl.h b/libsound/sdl/sound_handler_sdl.h
index bec34c9..00cbb26 100644
--- a/libsound/sdl/sound_handler_sdl.h
+++ b/libsound/sdl/sound_handler_sdl.h
@@ -92,6 +92,8 @@ public:
 
     ~SDL_sound_handler();
 
+    virtual int createStreamingSound(const media::SoundInfo& sinfo);
+
     // See dox in sound_handler.h
     virtual int create_sound(std::auto_ptr<SimpleBuffer> data,
             const media::SoundInfo& sinfo);
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 272b78b..02d3845 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -36,7 +36,8 @@
 
 namespace {
 
-unsigned int silentStream(void*, boost::int16_t* stream, unsigned int len, 
bool& atEOF)
+unsigned int
+silentStream(void*, boost::int16_t* stream, unsigned int len, bool& atEOF)
 {
     std::fill(stream, stream+len, 0);
     atEOF=false;
@@ -45,7 +46,6 @@ unsigned int silentStream(void*, boost::int16_t* stream, 
unsigned int len, bool&
 
 }
 
-
 namespace gnash {
 namespace sound {
 
@@ -56,7 +56,7 @@ sound_handler::addSoundBlock(unsigned char* data,
 {
     // @@ does a negative handle_id have any meaning ?
     //    should we change it to unsigned instead ?
-    if (handleId < 0 || (unsigned int) handleId+1 > _sounds.size())
+    if (handleId < 0 || (unsigned int) handleId+1 > _streamingSounds.size())
     {
         log_error("Invalid (%d) sound_handle passed to fill_stream_data, "
                   "doing nothing", handleId);
@@ -64,9 +64,8 @@ sound_handler::addSoundBlock(unsigned char* data,
         return -1;
     }
 
-    EmbedSound* sounddata = _sounds[handleId];
-    if ( ! sounddata )
-    {
+    EmbedSound* sounddata = _streamingSounds[handleId];
+    if (!sounddata) {
         log_error("sound_handle passed to fill_stream_data (%d) "
                   "was deleted", handleId);
         return -1;
@@ -101,6 +100,22 @@ sound_handler::delete_all_sounds()
         delete sdef; 
     }
     _sounds.clear();
+
+    for (Sounds::iterator i = _streamingSounds.begin(),
+                          e = _streamingSounds.end(); i != e; ++i)
+    {
+        EmbedSound* sdef = *i;
+
+        // Streaming sounds are never deleted.
+        assert(sdef);
+
+        stopEmbedSoundInstances(*sdef);
+        assert(!sdef->numPlayingInstances());
+
+        delete sdef; 
+    }
+    _streamingSounds.clear();
+
 }
 
 void
@@ -142,6 +157,14 @@ sound_handler::stop_all_sounds()
         if ( ! sounddata ) continue; // could have been deleted already
         stopEmbedSoundInstances(*sounddata);
     }
+
+    for (Sounds::iterator i = _streamingSounds.begin(),
+                          e = _streamingSounds.end(); i != e; ++i)
+    {
+        EmbedSound* sounddata = *i;
+        if ( ! sounddata ) continue; 
+        stopEmbedSoundInstances(*sounddata);
+    }
 }
 
 int
@@ -176,9 +199,10 @@ media::SoundInfo*
 sound_handler::get_sound_info(int sound_handle) const
 {
     // Check if the sound exists.
-    if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) < 
_sounds.size())
+    if (sound_handle >= 0 &&
+            static_cast<size_t>(sound_handle) < _streamingSounds.size())
     {
-        return &_sounds[sound_handle]->soundinfo;
+        return &_streamingSounds[sound_handle]->soundinfo;
     } 
     return NULL;
 }
@@ -186,30 +210,40 @@ sound_handler::get_sound_info(int sound_handle) const
 void
 sound_handler::stopStreamingSound(int handle)
 {
-    stopEventSound(handle);
+    // Check if the sound exists.
+    if (handle < 0 || (size_t)handle >= _streamingSounds.size())
+    {
+        log_debug("stop_sound(%d): invalid sound id", handle);
+        // Invalid handle.
+        return;
+    }
+
+    
+    EmbedSound* sounddata = _streamingSounds[handle];
+    assert(sounddata);
+
+    stopEmbedSoundInstances(*sounddata);
 }
 
 void
-sound_handler::stopEventSound(int sound_handle)
+sound_handler::stopEventSound(int handle)
 {
     // Check if the sound exists.
-    if (sound_handle < 0 || (unsigned int) sound_handle >= _sounds.size())
-    {
-        log_debug("stop_sound(%d): invalid sound id", sound_handle);
+    if (handle < 0 || (unsigned int) handle >= _sounds.size()) {
+        log_debug("stop_sound(%d): invalid sound id", handle);
         // Invalid handle.
         return;
     }
 
     
-    EmbedSound* sounddata = _sounds[sound_handle];
-    if ( ! sounddata )
-    {
-        log_error("stop_sound(%d): sound was deleted", sound_handle);
+    EmbedSound* sounddata = _sounds[handle];
+    if (!sounddata) {
+        log_error("stop_sound(%d): sound was deleted", handle);
         return;
     }
 
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
-    log_debug("stop_sound %d called", sound_handle);
+    log_debug("stop_sound %d called", handle);
 #endif
 
     stopEmbedSoundInstances(*sounddata);
@@ -322,6 +356,21 @@ sound_handler::get_duration(int sound_handle) const
 }
 
 int
+sound_handler::createStreamingSound(const media::SoundInfo& sinfo)
+{
+    std::auto_ptr<SimpleBuffer> b;
+    std::auto_ptr<EmbedSound> sounddata(
+            new EmbedSound(b, sinfo, 100,
+                _mediaHandler ? _mediaHandler->getInputPaddingSize() : 0));
+
+    int sound_id = _streamingSounds.size();
+    // the vector takes ownership
+    _streamingSounds.push_back(sounddata.release());
+
+    return sound_id;
+}
+
+int
 sound_handler::create_sound(std::auto_ptr<SimpleBuffer> data,
                             const media::SoundInfo& sinfo)
 {
@@ -466,7 +515,8 @@ sound_handler::playStream(int soundId, StreamBlockId 
blockId)
     unsigned int inPoint=0;
     unsigned int outPoint=std::numeric_limits<unsigned int>::max();
 
-    playSound(*_sounds[soundId], 0, inPoint, outPoint, blockId, 0, false);
+    playSound(*_streamingSounds[soundId], 0, inPoint, outPoint, blockId, 0,
+            false);
 }
 
 /*public*/
@@ -692,7 +742,7 @@ sound_handler::unplugCompletedInputStreams()
             delete is;
 
             // Increment number of sound stop request for the testing framework
-            _soundsStopped++;
+            ++_soundsStopped;
         }
         else
         {
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 2bc4cce..c77136f 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -119,6 +119,8 @@ public:
     virtual int create_sound(std::auto_ptr<SimpleBuffer> data,
             const media::SoundInfo& sinfo);
 
+    virtual int createStreamingSound(const media::SoundInfo& sinfo);
+
     /// Remove all scheduled request for playback of sound buffer slots
     //
     /// This applies both to streaming and event sounds.

http://git.savannah.gnu.org/cgit//commit/?id=e9ac16f78a66ad46b797c6511415e0d28aac9b98


commit e9ac16f78a66ad46b797c6511415e0d28aac9b98
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 13:59:18 2011 +0200

    Add separate functions for stopping sounds.
    
    Both currently do the same thing until the streaming and event sounds
    are properly distributed to the relevant storage.

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index 11e90cf..4f2f9e0 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -547,7 +547,7 @@ Button::mouseEvent(const event_id& event)
         if (!bs.sample) break;
 
         if (bs.soundInfo.stopPlayback) {
-            s->stop_sound(bs.sample->m_sound_handler_id);
+            s->stopEventSound(bs.sample->m_sound_handler_id);
         }
         else {
             const SWF::SoundInfoRecord& sinfo = bs.soundInfo;
diff --git a/libcore/MovieClip.cpp b/libcore/MovieClip.cpp
index dd43ce6..b5c8176 100644
--- a/libcore/MovieClip.cpp
+++ b/libcore/MovieClip.cpp
@@ -2044,7 +2044,7 @@ MovieClip::stopStreamSound()
 
     sound::sound_handler* handler = 
getRunResources(*getObject(this)).soundHandler();
     if (handler) {
-        handler->stop_sound(m_sound_stream_id);
+        handler->stopStreamingSound(m_sound_stream_id);
     }
 
     m_sound_stream_id = -1;
diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index 760abce..b4101d7 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -737,10 +737,10 @@ Sound_as::stop(int si)
                 _inputStream=0;
             }
         } else {
-            _soundHandler->stop_sound(soundId);
+            _soundHandler->stopEventSound(soundId);
         }
     } else {
-        _soundHandler->stop_sound(si);
+        _soundHandler->stopEventSound(si);
     }
 }
 
diff --git a/libcore/swf/StartSoundTag.cpp b/libcore/swf/StartSoundTag.cpp
index b622167..599b3b9 100644
--- a/libcore/swf/StartSoundTag.cpp
+++ b/libcore/swf/StartSoundTag.cpp
@@ -84,7 +84,7 @@ StartSoundTag::executeActions(MovieClip* m, DisplayList& /* 
dlist */) const
     if (handler) {
         if (_soundInfo.stopPlayback) {
             //log_debug("Execute StartSoundTag with 'stop playback' flag on");
-            handler->stop_sound(m_handler_id);
+            handler->stopEventSound(m_handler_id);
         }
         else {
 
diff --git a/libsound/sdl/sound_handler_sdl.cpp 
b/libsound/sdl/sound_handler_sdl.cpp
index 5bf60e9..b810358 100644
--- a/libsound/sdl/sound_handler_sdl.cpp
+++ b/libsound/sdl/sound_handler_sdl.cpp
@@ -154,10 +154,17 @@ SDL_sound_handler::addSoundBlock(unsigned char* data,
 
 
 void
-SDL_sound_handler::stop_sound(int soundHandle)
+SDL_sound_handler::stopEventSound(int soundHandle)
 {
     boost::mutex::scoped_lock lock(_mutex);
-    sound_handler::stop_sound(soundHandle);
+    sound_handler::stopEventSound(soundHandle);
+}
+
+void
+SDL_sound_handler::stopStreamingSound(int soundHandle)
+{
+    boost::mutex::scoped_lock lock(_mutex);
+    sound_handler::stopStreamingSound(soundHandle);
 }
 
 
diff --git a/libsound/sdl/sound_handler_sdl.h b/libsound/sdl/sound_handler_sdl.h
index d5b6f2b..bec34c9 100644
--- a/libsound/sdl/sound_handler_sdl.h
+++ b/libsound/sdl/sound_handler_sdl.h
@@ -104,7 +104,9 @@ public:
                                        int streamId);
 
     // See dox in sound_handler.h
-    virtual void    stop_sound(int sound_handle);
+    virtual void stopEventSound(int sound_handle);
+
+    virtual void stopStreamingSound(int sound_handle);
 
     // See dox in sound_handler.h
     virtual void    delete_sound(int sound_handle);
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 0cc3450..272b78b 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -184,7 +184,13 @@ sound_handler::get_sound_info(int sound_handle) const
 }
 
 void
-sound_handler::stop_sound(int sound_handle)
+sound_handler::stopStreamingSound(int handle)
+{
+    stopEventSound(handle);
+}
+
+void
+sound_handler::stopEventSound(int sound_handle)
 {
     // Check if the sound exists.
     if (sound_handle < 0 || (unsigned int) sound_handle >= _sounds.size())
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 1de6fce..2bc4cce 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -123,6 +123,10 @@ public:
     //
     /// This applies both to streaming and event sounds.
     virtual void stop_all_sounds();
+
+    ////////////////////////////////////////////////
+    /// Event sound functions:
+    ////////////////////////////////////////////////
         
     /// Remove scheduled requests to play the specified sound buffer slot
     //
@@ -136,11 +140,7 @@ public:
     //
     /// @param sound_handle
     /// The sound_handlers id for the sound to be deleted
-    virtual void stop_sound(int sound_handle);
-
-    ////////////////////////////////////////////////
-    /// Event sound functions:
-    ////////////////////////////////////////////////
+    virtual void stopEventSound(int sound_handle);
 
     /// Discard the sound data for an event sound
     //
@@ -220,6 +220,12 @@ public:
     /// Streaming sound functions:
     ////////////////////////////////////////////////
 
+    /// Remove scheduled requests to play the specified sound buffer slot
+    //
+    /// @param sound_handle     The sound_handlers id for the sound to be
+    ///                         stopped.
+    virtual void stopStreamingSound(int sound_handle);
+
     /// Append data for a streaming sound.
     ///
     /// Gnash's parser calls this to fill up soundstreams data.

http://git.savannah.gnu.org/cgit//commit/?id=fb6606bd9d4ee4254d6816018923109bff9bd920


commit fb6606bd9d4ee4254d6816018923109bff9bd920
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 13:53:33 2011 +0200

    Add separate storage for streaming sounds.

diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 1ff7a37..1de6fce 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -512,12 +512,16 @@ private:
 
     typedef std::vector<EmbedSound*> Sounds;
 
-    /// Vector containing all sounds.
+    /// Vector containing event sounds.
     //
     /// Elements of the vector are owned by this class
-    ///
     Sounds  _sounds;
 
+    /// Vector containing streaming sounds.
+    //
+    /// Elements of the vector are owned by this class
+    Sounds _streamingSounds;
+
     /// Stop all instances of an embedded sound
     void stopEmbedSoundInstances(EmbedSound& def);
 

http://git.savannah.gnu.org/cgit//commit/?id=289ea1475b5a21d3a66e66940fa16e75525fea45


commit 289ea1475b5a21d3a66e66940fa16e75525fea45
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 13:51:56 2011 +0200

    Pass sound data from callers, not sound handle.
    
    This makes it simpler to split event and streaming sounds.

diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index e0a3d3d..0cc3450 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -393,14 +393,11 @@ sound_handler::isSoundPlaying(int sound_handle) const
 
 /* private */
 void
-sound_handler::playSound(int sound_handle,
+sound_handler::playSound(EmbedSound& sounddata,
         int loopCount, unsigned int inPoint, unsigned int outPoint,
         StreamBlockId blockId, const SoundEnvelopes* envelopes,
         bool allowMultiples)
 {
-    assert (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) < 
_sounds.size());
-
-    EmbedSound& sounddata = *(_sounds[sound_handle]);
 
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
     log_debug("playSound %d called, SoundInfo format is %s",
@@ -413,7 +410,7 @@ sound_handler::playSound(int sound_handle,
     {
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
         log_debug(" playSound: multiple instances not allowed, "
-                  "and sound %d is already playing", sound_handle);
+                  "and sound is already playing");
 #endif
         // log_debug("Stream sound block play request, "
         //           "but an instance of the stream is "
@@ -463,7 +460,7 @@ sound_handler::playStream(int soundId, StreamBlockId 
blockId)
     unsigned int inPoint=0;
     unsigned int outPoint=std::numeric_limits<unsigned int>::max();
 
-    playSound(soundId, 0, inPoint, outPoint, blockId, 0, false);
+    playSound(*_sounds[soundId], 0, inPoint, outPoint, blockId, 0, false);
 }
 
 /*public*/
@@ -482,7 +479,6 @@ sound_handler::startSound(int soundId, int loops,
         return;
     }
 
-
     // Handle delaySeek
 
     EmbedSound& sounddata = *(_sounds[soundId]);
@@ -527,7 +523,7 @@ sound_handler::startSound(int soundId, int loops,
 #endif
     }
 
-    playSound(soundId, loops, inPoint, outPoint, 0, env, allowMultiple);
+    playSound(sounddata, loops, inPoint, outPoint, 0, env, allowMultiple);
 }
 
 void
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index a92a097..1ff7a37 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -569,11 +569,9 @@ private:
     ///     If false, the sound will not be scheduled if there's another
     ///     instance of it already playing.
     ///
-    void playSound(int id, int loops,
-                   unsigned int inPoint,
-                   unsigned int outPoint,
-                   StreamBlockId blockId, const SoundEnvelopes* env,
-                   bool allowMultiple);
+    void playSound(EmbedSound& sound, int loops, unsigned int inPoint,
+                   unsigned int outPoint, StreamBlockId blockId,
+                   const SoundEnvelopes* env, bool allowMultiple);
 
     /// Convert SWF-specified number of samples to output number of samples
     //

http://git.savannah.gnu.org/cgit//commit/?id=4afcf00239dfbc9c199bbe8843540ab851df9626


commit 4afcf00239dfbc9c199bbe8843540ab851df9626
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 13:43:42 2011 +0200

    Const correct and document interface.
    
    Document and reorder functions in preparation for splitting.

diff --git a/libcore/parser/sound_definition.h 
b/libcore/parser/sound_definition.h
index 9f41527..044d8d7 100644
--- a/libcore/parser/sound_definition.h
+++ b/libcore/parser/sound_definition.h
@@ -33,6 +33,16 @@ namespace gnash {
 //
 /// Definition tags will maintain a mapping between SWF-defined id
 /// of the sound and these identifiers.
+//
+/// A sound_definition is used only by DefineSoundTags for embedded event
+/// sounds. These sounds can be started either through the AS sound class
+/// or using a StartSoundTag.
+//
+/// sound_definitions are not used for:
+///     - embedded streaming sounds
+///     - loaded event sounds.
+//
+/// Streaming event sounds (Sound class).
 ///
 /// Specifying an identifier for use by sound_handler would likely be
 /// claner, anyway this is what it is *currently*.
diff --git a/libsound/sdl/sound_handler_sdl.cpp 
b/libsound/sdl/sound_handler_sdl.cpp
index 04b13ca..5bf60e9 100644
--- a/libsound/sdl/sound_handler_sdl.cpp
+++ b/libsound/sdl/sound_handler_sdl.cpp
@@ -177,7 +177,7 @@ SDL_sound_handler::stop_all_sounds()
 
 
 int
-SDL_sound_handler::get_volume(int soundHandle)
+SDL_sound_handler::get_volume(int soundHandle) const
 {
     boost::mutex::scoped_lock lock(_mutex);
     return sound_handler::get_volume(soundHandle);
@@ -192,21 +192,21 @@ SDL_sound_handler::set_volume(int soundHandle, int volume)
 }
     
 media::SoundInfo*
-SDL_sound_handler::get_sound_info(int soundHandle)
+SDL_sound_handler::get_sound_info(int soundHandle) const
 {
     boost::mutex::scoped_lock lock(_mutex);
     return sound_handler::get_sound_info(soundHandle);
 }
 
 unsigned int
-SDL_sound_handler::get_duration(int soundHandle)
+SDL_sound_handler::get_duration(int soundHandle) const
 {
     boost::mutex::scoped_lock lock(_mutex);
     return sound_handler::get_duration(soundHandle);
 }
 
 unsigned int
-SDL_sound_handler::tell(int soundHandle)
+SDL_sound_handler::tell(int soundHandle) const
 {
     boost::mutex::scoped_lock lock(_mutex);
     return sound_handler::tell(soundHandle);
diff --git a/libsound/sdl/sound_handler_sdl.h b/libsound/sdl/sound_handler_sdl.h
index 6129de7..d5b6f2b 100644
--- a/libsound/sdl/sound_handler_sdl.h
+++ b/libsound/sdl/sound_handler_sdl.h
@@ -58,7 +58,7 @@ private:
     bool _audioOpened;
     
     /// Mutex for making sure threads doesn't mess things up
-    boost::mutex _mutex;
+    mutable boost::mutex _mutex;
 
     /// Mutex protecting _muted (defined in base class)
     mutable boost::mutex _mutedMutex;
@@ -116,13 +116,13 @@ public:
     virtual void    stop_all_sounds();
 
     // See dox in sound_handler.h
-    virtual int get_volume(int sound_handle);
+    virtual int get_volume(int sound_handle) const;
 
     // See dox in sound_handler.h
-    virtual void    set_volume(int sound_handle, int volume);
+    virtual void set_volume(int sound_handle, int volume);
         
     // See dox in sound_handler.h
-    virtual media::SoundInfo* get_sound_info(int soundHandle);
+    virtual media::SoundInfo* get_sound_info(int soundHandle) const;
 
     // See dox in sound_handler.h
     // overridden to serialize access to the _muted member
@@ -145,10 +145,10 @@ public:
     virtual void unpause();
 
     // See dox in sound_handler.h
-    virtual unsigned int get_duration(int sound_handle);
+    virtual unsigned int get_duration(int sound_handle) const;
 
     // See dox in sound_handler.h
-    virtual unsigned int tell(int sound_handle);
+    virtual unsigned int tell(int sound_handle) const;
     
     // See dox in sound_handler.h
     // Overridden to unpause SDL audio
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 5ce9c02..e0a3d3d 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -145,17 +145,15 @@ sound_handler::stop_all_sounds()
 }
 
 int
-sound_handler::get_volume(int soundHandle)
+sound_handler::get_volume(int soundHandle) const
 {
-    int ret;
-    // Check if the sound exists.
-    if (soundHandle >= 0 && static_cast<unsigned int>(soundHandle) < 
_sounds.size())
+    if (soundHandle >= 0 && static_cast<size_t>(soundHandle) < _sounds.size())
     {
-        ret = _sounds[soundHandle]->volume;
-    } else {
-        ret = 0; // Invalid handle
-    }
-    return ret;
+        return _sounds[soundHandle]->volume;
+    } 
+
+    // Invalid handle.
+    return 0;
 }
 
 void   
@@ -175,15 +173,14 @@ sound_handler::set_volume(int sound_handle, int volume)
 }
 
 media::SoundInfo*
-sound_handler::get_sound_info(int sound_handle)
+sound_handler::get_sound_info(int sound_handle) const
 {
     // Check if the sound exists.
     if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) < 
_sounds.size())
     {
         return &_sounds[sound_handle]->soundinfo;
-    } else {
-        return NULL;
-    }
+    } 
+    return NULL;
 }
 
 void
@@ -267,7 +264,7 @@ sound_handler::unplugInputStream(InputStream* id)
 }
 
 unsigned int
-sound_handler::tell(int sound_handle)
+sound_handler::tell(int sound_handle) const
 {
     // Check if the sound exists.
     if (sound_handle < 0 || (unsigned int) sound_handle >= _sounds.size())
@@ -276,13 +273,13 @@ sound_handler::tell(int sound_handle)
         return 0;
     }
 
-    EmbedSound* sounddata = _sounds[sound_handle];
+    const EmbedSound* sounddata = _sounds[sound_handle];
 
     // If there is no active sounds, return 0
-    if ( ! sounddata->isPlaying() ) return 0;
+    if (!sounddata->isPlaying()) return 0;
 
     // We use the first active sound of this.
-    InputStream* asound = sounddata->firstPlayingInstance();
+    const InputStream* asound = sounddata->firstPlayingInstance();
 
     // Return the playhead position in milliseconds
     unsigned int samplesPlayed = asound->samplesFetched();
@@ -294,7 +291,7 @@ sound_handler::tell(int sound_handle)
 }
 
 unsigned int
-sound_handler::get_duration(int sound_handle)
+sound_handler::get_duration(int sound_handle) const
 {
     // Check if the sound exists.
     if (sound_handle < 0 || (unsigned int) sound_handle >= _sounds.size())
@@ -303,10 +300,10 @@ sound_handler::get_duration(int sound_handle)
         return 0;
     }
 
-    EmbedSound* sounddata = _sounds[sound_handle];
+    const EmbedSound* sounddata = _sounds[sound_handle];
 
-    boost::uint32_t sampleCount = sounddata->soundinfo.getSampleCount();
-    boost::uint32_t sampleRate = sounddata->soundinfo.getSampleRate();
+    const boost::uint32_t sampleCount = sounddata->soundinfo.getSampleCount();
+    const boost::uint32_t sampleRate = sounddata->soundinfo.getSampleRate();
 
     // Return the sound duration in milliseconds
     if (sampleCount > 0 && sampleRate > 0) {
@@ -314,9 +311,8 @@ sound_handler::get_duration(int sound_handle)
         unsigned int ret = sampleCount / sampleRate * 1000;
         ret += ((sampleCount % sampleRate) * 1000) / sampleRate;
         return ret;
-    } else {
-        return 0;
-    }
+    } 
+    return 0;
 }
 
 int
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 1cd8030..a92a097 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -77,19 +77,32 @@ namespace sound {
 ///
 /// @todo rename to gnash::sound::Mixer ?
 ///
+/// The sound_handler class stores embedded sounds. Embedded sounds can be
+/// either streaming sounds (embedded in many StreamSoundBlock tags through
+/// the SWF) or event sounds (defined in a single DefineSoundTag).
+//
+/// The interface is partly divided into separate functions for these types
+/// of sound.
+/// TODO: separate the functions fully.
 class DSOEXPORT sound_handler
 {
 public:
 
+    virtual ~sound_handler();
+
     /// Identifier of a streaming sound block
     //
     /// Use coupled with a soundId for fully qualified identifier
     ///
     typedef unsigned long StreamBlockId;
 
+    ////////////////////////////////////////////////
+    /// Mixed functions:
+    ////////////////////////////////////////////////
+
     /// Create a sound buffer slot, for on-demand playback.
     //
-    /// Subclasses must override this function and then call it.
+    /// TODO: create a separate function for streaming sounds.
     //
     /// @param data
     ///     The data to be stored. For soundstream this is NULL.
@@ -104,52 +117,39 @@ public:
     ///
     /// @return the id given by the soundhandler for later identification.
     virtual int create_sound(std::auto_ptr<SimpleBuffer> data,
-            const media::SoundInfo& sinfo) = 0;
+            const media::SoundInfo& sinfo);
 
-    /// Append data to an existing sound buffer slot.
+    /// Remove all scheduled request for playback of sound buffer slots
     //
-    ///
-    /// Gnash's parser calls this to fill up soundstreams data.
-    /// TODO: the current code uses memory reallocation to grow the sound,
-    /// which is suboptimal; instead, we should maintain sound sources as a 
-    /// list of buffers, to avoid reallocations.
-    ///
-    /// @param data
-    ///     The sound data to be saved, allocated by new[].
-    ///     Ownership is transferred.
-    ///     TODO: use SimpleBuffer ?
-    ///
-    /// @param dataBytes
-    ///     Size of the data in bytes
-    ///
-    /// @param sampleCount
-    ///     Number of samples in the data
-    ///
-    /// @param streamId
-    ///     The soundhandlers id of the sound we want to add data to
-    ///
-    /// @return an identifier for the new block for use in playSound
-    ///
-    /// @throw SoundException on error
-    ///
-    virtual StreamBlockId addSoundBlock(unsigned char* data,
-                                       unsigned int dataBytes,
-                                       unsigned int sampleCount,
-                                       int streamId);
+    /// This applies both to streaming and event sounds.
+    virtual void stop_all_sounds();
+        
+    /// Remove scheduled requests to play the specified sound buffer slot
+    //
+    /// Note: this currently is used for both streaming and events sounds.
+    /// TODO: use a separate function for each.
+    //
+    /// Stop all instances of the specified sound if it's playing.
+    /// (Normally a full-featured sound API would take a
+    /// handle specifying the *instance* of a playing
+    /// sample, but SWF is not expressive that way.)
+    //
+    /// @param sound_handle
+    /// The sound_handlers id for the sound to be deleted
+    virtual void stop_sound(int sound_handle);
 
-    /// \brief
-    /// Returns a pointer to the SoundInfo object for the sound
-    /// with the given id.
+    ////////////////////////////////////////////////
+    /// Event sound functions:
+    ////////////////////////////////////////////////
+
+    /// Discard the sound data for an event sound
     //
-    /// The SoundInfo object is still owned by the soundhandler.
-    ///
-    /// @param soundHandle
-    ///     The soundhandlers id of the sound we want some info about.
-    ///
-    /// @return a pointer to the SoundInfo object for the sound with
-    ///         the given id.
-    ///
-    virtual media::SoundInfo* get_sound_info(int soundHandle);
+    /// Only embedded event sounds are deleted; this happens when the
+    /// associated sound_definition is deleted.
+    //
+    /// @param sound_handle     The sound_handlers id for the event sound to be
+    ///                         deleted
+    virtual void delete_sound(int sound_handle);
 
     /// Start playback of an event sound
     //
@@ -181,19 +181,84 @@ public:
     /// @param allowMultiple
     ///     If false, the sound will not be scheduled if there's another
     ///     instance of it already playing.
-    ///
-    ///
-    void startSound(int id, int loops, 
-                   const SoundEnvelopes* env,
+    void startSound(int id, int loops, const SoundEnvelopes* env,
                    bool allowMultiple, unsigned int inPoint=0,
-                   unsigned int outPoint=std::numeric_limits<unsigned 
int>::max());
+                   unsigned int outPoint = 
+                   std::numeric_limits<unsigned int>::max());
 
     /// Check if an event sound is playing
     //
-    /// @param id
-    ///     Id of the sound buffer slot check for being alive
-    ///
+    /// Note: this should not be used for streaming sounds.
+    //
+    /// @param id   Id of the sound buffer slot check for being alive
     bool isSoundPlaying(int id) const;
+    
+    /// Gets the duration in milliseconds of an event sound.
+    //
+    /// @param sound_handle     The id of the event sound
+    /// @return                 the duration of the sound in milliseconds
+    virtual unsigned int get_duration(int sound_handle) const;
+
+    /// Gets the playhead position in milliseconds of an event sound.
+    //
+    /// @param sound_handle     The id of the event sound
+    /// @return                 The playhead position of the sound in
+    ///                         milliseconds
+    virtual unsigned int tell(int sound_handle) const;
+
+    /// Gets the volume for a given sound buffer slot.
+    //
+    /// Only use for event sounds!
+    ///
+    /// @param sound_handle     The sound to get the volume for.
+    /// @return                 the sound volume level as an integer from
+    ///                         0 to 100, where 0 is off and 100 is full
+    ///                         volume. The default setting is 100.
+    virtual int get_volume(int sound_handle) const;
+
+    ////////////////////////////////////////////////
+    /// Streaming sound functions:
+    ////////////////////////////////////////////////
+
+    /// Append data for a streaming sound.
+    ///
+    /// Gnash's parser calls this to fill up soundstreams data.
+    /// TODO: the current code uses memory reallocation to grow the sound,
+    /// which is suboptimal; instead, we should maintain sound sources as a 
+    /// list of buffers, to avoid reallocations.
+    ///
+    /// @param data
+    ///     The sound data to be saved, allocated by new[].
+    ///     Ownership is transferred.
+    ///     TODO: use SimpleBuffer ?
+    ///
+    /// @param dataBytes
+    ///     Size of the data in bytes
+    ///
+    /// @param sampleCount
+    ///     Number of samples in the data
+    ///
+    /// @param streamId
+    ///     The soundhandlers id of the sound we want to add data to
+    ///
+    /// @return an identifier for the new block for use in playSound
+    /// @throw SoundException on error
+    virtual StreamBlockId addSoundBlock(unsigned char* data,
+                                       unsigned int dataBytes,
+                                       unsigned int sampleCount,
+                                       int streamId);
+
+    /// Returns a SoundInfo object for the sound with the given id.
+    //
+    /// Note: This should only be used for streaming sounds.
+    //
+    /// The SoundInfo object is still owned by the soundhandler.
+    ///
+    /// @param soundHandle  The soundhandlers id of the sound we want some
+    ///                     info about.
+    /// @return             a pointer to the SoundInfo object for the sound
+    ///                     with the given id or 0 if no such sound exists.
+    virtual media::SoundInfo* get_sound_info(int soundHandle) const;
 
     /// Start playback of a streaming sound, if not playing already
     //
@@ -213,27 +278,16 @@ public:
     ///
     void playStream(int id, StreamBlockId blockId);
 
-    /// Remove all scheduled request for playback of sound buffer slots
-    virtual void    stop_all_sounds();
-
-    /// Gets the volume for a given sound buffer slot.
-    //
-    /// Only used by the AS Sound class
-    ///
-    /// @param sound_handle
-    /// The sound_handlers id for the sound to be deleted
-    ///
-    /// @return the sound volume level as an integer from 0 to 100,
-    ///     where 0 is off and 100 is full volume. The default setting is 100.
-    ///
-    virtual int get_volume(int sound_handle);
+    ////////////////////////////////////////////////
+    /// Sound output functions.
+    ////////////////////////////////////////////////
 
     /// Get the volume to apply to mixed output
     //
     /// @return percent value. 100 is full, 0 is none.
     ///        Can be negative or over 100 too.
     ///
-    int getFinalVolume() { return _volume; }
+    int getFinalVolume() const { return _volume; }
     
     /// Sets the volume for a given sound buffer slot.
     //
@@ -255,28 +309,6 @@ public:
     ///       Can be negative or over 100 too.
     ///
     void setFinalVolume(int v) { _volume=v; }
-        
-    /// Remove scheduled requests to play the specified sound buffer slot
-    //
-    /// Stop the specified sound if it's playing.
-    /// (Normally a full-featured sound API would take a
-    /// handle specifying the *instance* of a playing
-    /// sample, but SWF is not expressive that way.)
-    //
-    /// @param sound_handle
-    /// The sound_handlers id for the sound to be deleted
-    ///
-    virtual void    stop_sound(int sound_handle);
-
-    /// Discard a sound buffer slot
-    //
-    /// @param sound_handle
-    /// The sound_handlers id for the sound to be deleted
-    ///
-    virtual void delete_sound(int sound_handle);
-
-    // Stop and delete all sounds
-    virtual void delete_all_sounds();
 
     /// \brief
     /// Discard all sound inputs (slots and aux streamers)
@@ -359,30 +391,6 @@ public:
     ///
     virtual void unplugInputStream(InputStream* id);
 
-    virtual ~sound_handler();
-    
-    /// \brief
-    /// Gets the duration in milliseconds of an event sound connected
-    /// to an AS Sound obejct.
-    //
-    /// @param sound_handle
-    /// The id of the event sound
-    ///
-    /// @return the duration of the sound in milliseconds
-    ///
-    virtual unsigned int get_duration(int sound_handle);
-
-    /// \brief
-    /// Gets the playhead position in milliseconds of an event sound connected
-    /// to an AS Sound obejct.
-    //
-    /// @param sound_handle
-    /// The id of the event sound
-    ///
-    /// @return the duration of the sound in milliseconds
-    ///
-    virtual unsigned int tell(int sound_handle);
-
     /// Special test-fuction. Reports how many times a sound has been started
     //
     /// @deprecated Use a TestingSoundHanlder !
@@ -445,7 +453,6 @@ public:
     virtual void mix(boost::int16_t* outSamples, boost::int16_t* inSamples,
                 unsigned int nSamples, float volume) = 0;
 
-
     /// Request to dump audio to the given filename
     //
     /// Every call to this function starts recording
@@ -455,7 +462,6 @@ public:
 
 protected:
 
-
     sound_handler(media::MediaHandler* m)
         :
         _soundsStarted(0),
@@ -482,6 +488,11 @@ protected:
     /// Does the mixer have input streams ?
     bool hasInputStreams() const;
 
+    /// Stop and delete all sounds
+    //
+    /// This is used only on reset.
+    virtual void delete_all_sounds();
+
 private:
 
     /// Special test-member. Stores count of started sounds.

http://git.savannah.gnu.org/cgit//commit/?id=e18bd688b8fe1a4e7685f68507ad59b8484a39fa


commit e18bd688b8fe1a4e7685f68507ad59b8484a39fa
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 12:55:55 2011 +0200

    Pass SoundInfos by value.
    
    They aren't very big, don't get passed very often, and this saves a load
    of code required for the auto_ptrs.
    
    Force implementation of sound_handler::create_sound in base classes by
    making it pure virtual with an implementation. This should help
    externally-maintained parts to adapt to the interface changes.

diff --git a/libcore/swf/SoundStreamHeadTag.cpp 
b/libcore/swf/SoundStreamHeadTag.cpp
index 971fddc..eea4c5f 100644
--- a/libcore/swf/SoundStreamHeadTag.cpp
+++ b/libcore/swf/SoundStreamHeadTag.cpp
@@ -148,9 +148,8 @@ SoundStreamHeadTag::loader(SWFStream& in, TagType tag, 
movie_definition& m,
     );
 
     // Store all the data in a SoundInfo object
-    std::auto_ptr<media::SoundInfo> sinfo;
-    sinfo.reset(new media::SoundInfo(format, streamSoundStereo,
-                streamSoundRate, sampleCount, streamSound16bit, latency));
+    const media::SoundInfo sinfo(format, streamSoundStereo,
+                streamSoundRate, sampleCount, streamSound16bit, latency);
 
     // Stores the sounddata in the soundhandler, and the ID returned
     // can be used to starting, stopping and deleting that sound
diff --git a/libcore/swf/tag_loaders.cpp b/libcore/swf/tag_loaders.cpp
index e132d24..e75c856 100644
--- a/libcore/swf/tag_loaders.cpp
+++ b/libcore/swf/tag_loaders.cpp
@@ -218,9 +218,8 @@ define_sound_loader(SWFStream& in, TagType tag, 
movie_definition& m,
         }
 
         // Store all the data in a SoundInfo object
-        std::auto_ptr<media::SoundInfo> sinfo;
-        sinfo.reset(new media::SoundInfo(format, stereo, sample_rate,
-                    sample_count, sample_16bit, delaySeek));
+        const media::SoundInfo sinfo(format, stereo, sample_rate,
+                    sample_count, sample_16bit, delaySeek);
 
         // Stores the sounddata in the soundhandler, and the ID returned
         // can be used to starting, stopping and deleting that sound
diff --git a/libsound/EmbedSound.cpp b/libsound/EmbedSound.cpp
index 2015da2..72cc217 100644
--- a/libsound/EmbedSound.cpp
+++ b/libsound/EmbedSound.cpp
@@ -55,7 +55,7 @@ EmbedSound::append(boost::uint8_t* data, unsigned int size)
 }
 
 EmbedSound::EmbedSound(std::auto_ptr<SimpleBuffer> data,
-        std::auto_ptr<media::SoundInfo> info, int nVolume, size_t paddingBytes)
+        const media::SoundInfo& info, int nVolume, size_t paddingBytes)
     :
     _buf(data),
     soundinfo(info),
diff --git a/libsound/EmbedSound.h b/libsound/EmbedSound.h
index 17e7901..810b041 100644
--- a/libsound/EmbedSound.h
+++ b/libsound/EmbedSound.h
@@ -66,14 +66,13 @@ public:
     ///
     /// @param nVolume initial volume (0..100). Optional, defaults to 100.
     ///
-    EmbedSound(std::auto_ptr<SimpleBuffer> data,
-            std::auto_ptr<media::SoundInfo> info, int nVolume,
-            size_t paddingBytes);
+    EmbedSound(std::auto_ptr<SimpleBuffer> data, const media::SoundInfo& info,
+            int nVolume, size_t paddingBytes);
 
     ~EmbedSound();
 
     /// Object holding information about the sound
-    std::auto_ptr<media::SoundInfo> soundinfo;
+    media::SoundInfo soundinfo;
 
     typedef std::map<boost::uint32_t,boost::uint32_t> FrameSizeMap;
 
diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index a924666..0eb36d9 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -88,7 +88,7 @@ EmbedSoundInst::EmbedSoundInst(EmbedSound& soundData,
 void
 EmbedSoundInst::createDecoder(media::MediaHandler& mediaHandler)
 {
-    media::SoundInfo& si = *_soundDef.soundinfo;
+    const media::SoundInfo& si = _soundDef.soundinfo;
 
     media::AudioInfo info(
         (int)si.getFormat(), // codeci
@@ -241,7 +241,7 @@ EmbedSoundInst::decodeNextBlock()
         const EmbedSound& sndData = _soundDef;
 
         // Figure the need to parse..
-        switch (sndData.soundinfo->getFormat())
+        switch (sndData.soundinfo.getFormat())
         {
             case media::AUDIO_CODEC_ADPCM:
 #ifdef GNASH_DEBUG_SOUNDS_DECODING
diff --git a/libsound/sdl/sound_handler_sdl.cpp 
b/libsound/sdl/sound_handler_sdl.cpp
index f3fa12a..04b13ca 100644
--- a/libsound/sdl/sound_handler_sdl.cpp
+++ b/libsound/sdl/sound_handler_sdl.cpp
@@ -136,7 +136,7 @@ SDL_sound_handler::~SDL_sound_handler()
 
 int
 SDL_sound_handler::create_sound(std::auto_ptr<SimpleBuffer> data,
-                                std::auto_ptr<media::SoundInfo> sinfo)
+                                const media::SoundInfo& sinfo)
 {
     boost::mutex::scoped_lock lock(_mutex);
     return sound_handler::create_sound(data, sinfo);
diff --git a/libsound/sdl/sound_handler_sdl.h b/libsound/sdl/sound_handler_sdl.h
index a876f88..6129de7 100644
--- a/libsound/sdl/sound_handler_sdl.h
+++ b/libsound/sdl/sound_handler_sdl.h
@@ -93,7 +93,8 @@ public:
     ~SDL_sound_handler();
 
     // See dox in sound_handler.h
-    virtual int create_sound(std::auto_ptr<SimpleBuffer> data, 
std::auto_ptr<media::SoundInfo> sinfo);
+    virtual int create_sound(std::auto_ptr<SimpleBuffer> data,
+            const media::SoundInfo& sinfo);
 
     // See dox in sound_handler.h
     // overridden to serialize access to the data buffer slot
diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 168957b..5ce9c02 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -180,7 +180,7 @@ sound_handler::get_sound_info(int sound_handle)
     // Check if the sound exists.
     if (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) < 
_sounds.size())
     {
-        return _sounds[sound_handle]->soundinfo.get();
+        return &_sounds[sound_handle]->soundinfo;
     } else {
         return NULL;
     }
@@ -305,15 +305,14 @@ sound_handler::get_duration(int sound_handle)
 
     EmbedSound* sounddata = _sounds[sound_handle];
 
-    boost::uint32_t sampleCount = sounddata->soundinfo->getSampleCount();
-    boost::uint32_t sampleRate = sounddata->soundinfo->getSampleRate();
+    boost::uint32_t sampleCount = sounddata->soundinfo.getSampleCount();
+    boost::uint32_t sampleRate = sounddata->soundinfo.getSampleRate();
 
     // Return the sound duration in milliseconds
     if (sampleCount > 0 && sampleRate > 0) {
         // TODO: should we cache this in the EmbedSound object ?
         unsigned int ret = sampleCount / sampleRate * 1000;
         ret += ((sampleCount % sampleRate) * 1000) / sampleRate;
-        //if (sounddata->soundinfo->isStereo()) ret = ret / 2;
         return ret;
     } else {
         return 0;
@@ -322,10 +321,8 @@ sound_handler::get_duration(int sound_handle)
 
 int
 sound_handler::create_sound(std::auto_ptr<SimpleBuffer> data,
-                            std::auto_ptr<media::SoundInfo> sinfo)
+                            const media::SoundInfo& sinfo)
 {
-    assert(sinfo.get());
-
     std::auto_ptr<EmbedSound> sounddata(
             new EmbedSound(data, sinfo, 100,
                 _mediaHandler ? _mediaHandler->getInputPaddingSize() : 0));
@@ -334,10 +331,10 @@ sound_handler::create_sound(std::auto_ptr<SimpleBuffer> 
data,
 
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
     log_debug("create_sound: sound %d, format %s %s %dHz, %d samples (%d 
bytes)",
-        sound_id, sounddata->soundinfo->getFormat(),
-        sounddata->soundinfo->isStereo() ? "stereo" : "mono",
-        sounddata->soundinfo->getSampleRate(),
-        sounddata->soundinfo->getSampleCount(),
+        sound_id, sounddata->soundinfo.getFormat(),
+        sounddata->soundinfo.isStereo() ? "stereo" : "mono",
+        sounddata->soundinfo.getSampleRate(),
+        sounddata->soundinfo.getSampleCount(),
         sounddata->size());
 #endif
 
@@ -411,7 +408,7 @@ sound_handler::playSound(int sound_handle,
 
 #ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
     log_debug("playSound %d called, SoundInfo format is %s",
-            sound_handle, sounddata.soundinfo->getFormat());
+            sound_handle, sounddata.soundinfo.getFormat());
 #endif
 
     // When this is called from a StreamSoundBlockTag,
@@ -493,7 +490,7 @@ sound_handler::startSound(int soundId, int loops,
     // Handle delaySeek
 
     EmbedSound& sounddata = *(_sounds[soundId]);
-    const media::SoundInfo& sinfo = *(sounddata.soundinfo);
+    const media::SoundInfo& sinfo = sounddata.soundinfo;
 
     int swfDelaySeek = sinfo.getDelaySeek(); 
     if ( swfDelaySeek )
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 25bf27a..1cd8030 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -89,6 +89,8 @@ public:
 
     /// Create a sound buffer slot, for on-demand playback.
     //
+    /// Subclasses must override this function and then call it.
+    //
     /// @param data
     ///     The data to be stored. For soundstream this is NULL.
     ///     The data is in encoded format, with format specified
@@ -101,11 +103,8 @@ public:
     ///     The SoundObject must be not-NULL!
     ///
     /// @return the id given by the soundhandler for later identification.
-    ///
-    virtual int create_sound(
-        std::auto_ptr<SimpleBuffer> data,
-        std::auto_ptr<media::SoundInfo> sinfo
-        );
+    virtual int create_sound(std::auto_ptr<SimpleBuffer> data,
+            const media::SoundInfo& sinfo) = 0;
 
     /// Append data to an existing sound buffer slot.
     //

http://git.savannah.gnu.org/cgit//commit/?id=537f39dcc3fb6e90a422256c3ef006eefb0e04fb


commit 537f39dcc3fb6e90a422256c3ef006eefb0e04fb
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 12:22:39 2011 +0200

    Remove done TODOs.

diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index 23aedea..a924666 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -311,7 +311,6 @@ EmbedSoundInst::decodeNextBlock()
     // If the volume needs adjustments we call a function to do that (why are 
we doing this manually ?)
     if (_soundDef.volume != 100) // volume is a private member
     {
-        // TODO: have adjust_volume take samples, not bytes
         adjustVolume(samples, samples + nSamples, _soundDef.volume/100.0);
     }
 
@@ -321,7 +320,6 @@ EmbedSoundInst::decodeNextBlock()
     {
         unsigned int firstSample = playbackPosition/2;
 
-        // TODO: have applyEnvelopes take samples, not bytes
         applyEnvelopes(samples, nSamples, firstSample, *envelopes);
     }
 

http://git.savannah.gnu.org/cgit//commit/?id=7a6bea85cbfe3b02e205d6bf72d70117bb8e1b74


commit 7a6bea85cbfe3b02e205d6bf72d70117bb8e1b74
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 11:21:25 2011 +0200

    Use SoundUtils.h

diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index 2779e71..23aedea 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -20,16 +20,17 @@
 
 #include "EmbedSoundInst.h"
 
+#include <cmath>
+#include <vector>
+#include <boost/scoped_array.hpp>
+
 #include "SoundInfo.h" // for use
 #include "MediaHandler.h" // for use
 #include "GnashException.h" // for SoundException
 #include "AudioDecoder.h" // for use
 #include "SoundEnvelope.h" // for use
 #include "log.h" // will import boost::format too
-
-#include <cmath>
-#include <vector>
-#include <boost/scoped_array.hpp>
+#include "SoundUtils.h"
 
 // Debug sound decoding
 //#define GNASH_DEBUG_SOUNDS_DECODING
@@ -311,7 +312,7 @@ EmbedSoundInst::decodeNextBlock()
     if (_soundDef.volume != 100) // volume is a private member
     {
         // TODO: have adjust_volume take samples, not bytes
-        adjustVolume(samples, nSamples, _soundDef.volume/100.0);
+        adjustVolume(samples, samples + nSamples, _soundDef.volume/100.0);
     }
 
     /// @todo is use of envelopes really mutually exclusive with
@@ -340,37 +341,22 @@ EmbedSoundInst::getEncodedData(unsigned long int pos)
     return _soundDef.data(pos);
 }
 
-/* static private */
-void
-EmbedSoundInst::adjustVolume(boost::int16_t* data, unsigned int nSamples, 
float volume)
-{
-    //log_error("skipping volume adjustment (intentionally)"); return;
-
-    for (unsigned int i=0; i<nSamples; ++i)
-    {
-        data[i] = data[i] * volume;
-    }
-}
-
 /* private */
 void
 EmbedSoundInst::applyEnvelopes(boost::int16_t* samples, unsigned int nSamples,
         unsigned int firstSampleOffset, const SoundEnvelopes& env)
 {
-    //log_error("skipping envelopes (intentionally)"); return;
 
     // Number of envelopes defined
     size_t numEnvs = env.size();
 
     // Nothing to do if we applied all envelopes already
-    if ( numEnvs <= current_env)
-    {
+    if (numEnvs <= current_env) {
         return;
     }
 
     // Not yet time to use the current envelope
-    if (env[current_env].m_mark44 >= firstSampleOffset+nSamples)
-    {
+    if (env[current_env].m_mark44 >= firstSampleOffset+nSamples) {
         return;
     }
 
@@ -378,42 +364,45 @@ EmbedSoundInst::applyEnvelopes(boost::int16_t* samples, 
unsigned int nSamples,
 
     // Get next envelope position (absolute samples offset)
     boost::uint32_t next_env_pos = 0;
-    if (current_env == (env.size()-1)) {
-        // If there is no "next envelope" then set the next envelope start 
point to be unreachable
+    if (current_env == (env.size() - 1)) {
+        // If there is no "next envelope" then set the next envelope
+        // start point to be unreachable
         next_env_pos = env[current_env].m_mark44 + nSamples + 1;
-    } else {
-        next_env_pos = env[current_env+1].m_mark44;
+    }
+    else {
+        next_env_pos = env[current_env + 1].m_mark44;
     }
 
     // Scan all samples in the block, applying the envelope
     // which is in effect in each subportion
-    for (unsigned int i=0; i<nSamples/2; i+=2)
-    {
+    for (unsigned int i = 0; i < nSamples / 2; i += 2) {
+
         // @todo cache these left/right floats (in the SoundEnvelope class?)
         float left = env[current_env].m_level0 / 32768.0;
         float right = env[current_env].m_level1 / 32768.0;
 
         samples[i] = samples[i] * left; // Left
-        samples[i+1] = samples[i+1] * right; // Right
+        samples[i + 1] = samples[i + 1] * right; // Right
 
         // TODO: continue from here (what is the code below doing ??
 
         // if we encounter the offset of next envelope,
         // switch to it !
-        if ( (firstSampleOffset+nSamples-i) >= next_env_pos )
+        if ((firstSampleOffset+nSamples-i) >= next_env_pos)
         {
-            if ( numEnvs <= ++current_env )
-            {
+            if (numEnvs <= ++current_env) {
                 // no more envelopes to apply
                 return;
             }
 
             // Get next envelope position (absolute samples offset)
-            if (current_env == (env.size()-1)) {
-                // If there is no "next envelope" then set the next envelope 
start point to be unreachable
+            if (current_env == (env.size() - 1)) {
+                // If there is no "next envelope" then set the next
+                // envelope start point to be unreachable
                 next_env_pos = env[current_env].m_mark44 + nSamples + 1;
-            } else {
-                next_env_pos = env[current_env+1].m_mark44;
+            }
+            else {
+                next_env_pos = env[current_env + 1].m_mark44;
             }
         }
     }
diff --git a/libsound/EmbedSoundInst.h b/libsound/EmbedSoundInst.h
index 26152b7..1c7c1c8 100644
--- a/libsound/EmbedSoundInst.h
+++ b/libsound/EmbedSoundInst.h
@@ -205,20 +205,6 @@ private:
             unsigned int firstSampleNum,
             const SoundEnvelopes& env);
 
-    /// AS-volume adjustment
-    //
-    /// @param samples
-    ///     The 16bit samples to adjust volume of
-    ///
-    /// @param nSamples
-    ///     Number of samples in the array
-    ///
-    /// @param volume
-    ///     Volume factor
-    ///
-    static void adjustVolume(boost::int16_t* samples,
-            unsigned int nSamples, float volume);
-
     /// Returns the data pointer in the encoded datastream
     /// for the given position. Boundaries are checked.
     //

http://git.savannah.gnu.org/cgit//commit/?id=8bb5b40f347e5f23350b89a47838c708fd4c055b


commit 8bb5b40f347e5f23350b89a47838c708fd4c055b
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 11:21:04 2011 +0200

    Use SoundUtils.h

diff --git a/libcore/asobj/NetStream_as.cpp b/libcore/asobj/NetStream_as.cpp
index 5f2ac34..526e692 100644
--- a/libcore/asobj/NetStream_as.cpp
+++ b/libcore/asobj/NetStream_as.cpp
@@ -43,6 +43,7 @@
 #include "sound_handler.h"
 #include "AMFConverter.h"
 #include "AMF.h"
+#include "SoundUtils.h"
 
 // Define the following macro to have status notification handling debugged
 //#define GNASH_DEBUG_STATUS
@@ -74,13 +75,6 @@ namespace {
 
     void attachNetStreamInterface(as_object& o);
 
-    /// Transform the volume by the requested amount
-    //
-    /// @param data     The data to transform
-    /// @param size     The length of the array
-    /// @param volume   The volume in percent.
-    void adjustVolume(boost::int16_t* data, size_t size, int volume);
-
     // TODO: see where this can be done more centrally.
     void executeTag(const SimpleBuffer& _buffer, as_object& thisPtr);
 }
@@ -682,8 +676,9 @@ NetStream_as::decodeNextAudioFrame()
                 // NOTE: adjust_volume assumes samples 
                 // are 16 bits in size, and signed.
                 // Size is still given in bytes..
-                adjustVolume(reinterpret_cast<boost::int16_t*>(raw->m_data),
-                        raw->m_size / 2, vol);
+                boost::int16_t* const start =
+                    reinterpret_cast<boost::int16_t*>(raw->m_data);
+                sound::adjustVolume(start, start + raw->m_size / 2, vol);
             }
         }
     }
@@ -1878,13 +1873,5 @@ executeTag(const SimpleBuffer& _buffer, as_object& 
thisPtr)
        callMethod(&thisPtr, funcKey, arg);
 }
 
-// AS-volume adjustment
-void
-adjustVolume(boost::int16_t* data, size_t size, int volume)
-{
-    std::transform(data, data + size, data,
-            boost::bind(std::multiplies<double>(), volume / 100.0, _1));
-}
-
 } // anonymous namespace
 } // gnash namespace

http://git.savannah.gnu.org/cgit//commit/?id=85c638107b0688c104f629e22e5bd621e63165cd


commit 85c638107b0688c104f629e22e5bd621e63165cd
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Jul 3 10:59:40 2011 +0200

    Add sound utilities.

diff --git a/libsound/Makefile.am b/libsound/Makefile.am
index 43dcfaa..a20e97e 100644
--- a/libsound/Makefile.am
+++ b/libsound/Makefile.am
@@ -24,6 +24,7 @@ libgnashsound_la_SOURCES = \
        EmbedSound.h \
        EmbedSoundInst.cpp \
        EmbedSoundInst.h \
+       SoundUtils.h \
        InputStream.h \
        sound_handler.cpp \
        sound_handler.h \
diff --git a/libsound/SoundUtils.h b/libsound/SoundUtils.h
new file mode 100644
index 0000000..fd4e725
--- /dev/null
+++ b/libsound/SoundUtils.h
@@ -0,0 +1,47 @@
+// SoundUtils.h     Utilities for handling sound data.
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
+//   2011 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
+
+#ifndef GNASH_SOUND_UTILS_H
+#define GNASH_SOUND_UTILS_H
+
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
+
+namespace gnash {
+namespace sound {
+
+
+/// Volume adjustment
+//
+/// @param start        The beginning of the range to adjust volume for
+/// @param end         The end of the range to adjust volume for
+/// @param volume       Volume factor
+template<typename T>
+inline void
+adjustVolume(T* start, T* end, float volume)
+{
+    std::transform(start, end, start,
+            boost::bind(std::multiplies<float>(), volume, _1));
+}
+
+} // namespace sound
+} // namespace gnash
+
+#endif

http://git.savannah.gnu.org/cgit//commit/?id=3c2a7c1b8e834d8ef98e22ec43f017c673b09f77


commit 3c2a7c1b8e834d8ef98e22ec43f017c673b09f77
Author: Benjamin Wolsey <address@hidden>
Date:   Sat Jul 2 13:10:29 2011 +0200

    Clean includes.

diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index e7aa254..3529edd 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -19,6 +19,18 @@
 //
 
 #include "as_value.h"
+
+#include <boost/shared_ptr.hpp>
+#include <cmath> 
+#include <cctype> 
+#include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
+#include <locale>
+#include <sstream>
+#include <iomanip>
+#include <string>
+#include <algorithm>
+
 #include "as_object.h"
 #include "as_function.h" // for as_function
 #include "MovieClip.h" // for DISPLAYOBJECT values
@@ -38,18 +50,6 @@
 #include "String_as.h"
 #include "AMFConverter.h"
 
-#include <boost/shared_ptr.hpp>
-#include <cmath> 
-#include <cctype> 
-#include <boost/algorithm/string/case_conv.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/format.hpp>
-#include <locale>
-#include <sstream>
-#include <iomanip>
-#include <string>
-#include <algorithm>
-
 // Define the macro below to make abstract equality operator verbose
 //#define GNASH_DEBUG_EQUALITY 1
 

-----------------------------------------------------------------------

Summary of changes:
 gui/gui.cpp                                       |    7 +-
 gui/pythonmod/gnash-view.h                        |   36 +-
 libbase/GnashTexture.h                            |    2 +-
 libcore/Button.cpp                                |    2 +-
 libcore/MovieClip.cpp                             |    2 +-
 libcore/SWFMatrix.cpp                             |    4 +-
 libcore/as_value.cpp                              |   24 +-
 libcore/asobj/Global_as.h                         |   14 +-
 libcore/asobj/NetStream_as.cpp                    |   21 +-
 libcore/asobj/Sound_as.cpp                        |   56 ++-
 libcore/parser/sound_definition.h                 |   10 +
 libcore/swf/SoundStreamHeadTag.cpp                |    8 +-
 libcore/swf/StartSoundTag.cpp                     |    2 +-
 libcore/swf/StreamSoundBlockTag.cpp               |   28 +-
 libcore/swf/tag_loaders.cpp                       |    5 +-
 libmedia/{haiku/VideoInputHaiku.cpp => Id3Info.h} |   59 ++--
 libmedia/Makefile.am                              |    1 +
 libmedia/MediaParser.cpp                          |   12 +-
 libmedia/MediaParser.h                            |   16 +-
 libmedia/ffmpeg/MediaParserFfmpeg.cpp             |  155 ++++----
 libmedia/ffmpeg/MediaParserFfmpeg.h               |   12 +-
 libmedia/gst/AudioInputGst.cpp                    |    4 +-
 libmedia/gst/MediaParserGst.cpp                   |    5 +
 libmedia/gst/MediaParserGst.h                     |   12 +-
 libsound/EmbedSound.cpp                           |   80 +---
 libsound/EmbedSound.h                             |  134 ++----
 libsound/EmbedSoundInst.cpp                       |  341 +++------------
 libsound/EmbedSoundInst.h                         |  269 +++---------
 libsound/LiveSound.cpp                            |  111 +++++
 libsound/LiveSound.h                              |  164 +++++++
 libsound/Makefile.am                              |    7 +
 libsound/SoundUtils.h                             |   72 +++
 libsound/StreamingSound.cpp                       |  127 ++++++
 libsound/StreamingSound.h                         |  109 +++++
 libsound/StreamingSoundData.cpp                   |  141 ++++++
 libsound/StreamingSoundData.h                     |  194 ++++++++
 libsound/sdl/sound_handler_sdl.cpp                |   34 +-
 libsound/sdl/sound_handler_sdl.h                  |   27 +-
 libsound/sound_handler.cpp                        |  489 ++++++++++-----------
 libsound/sound_handler.h                          |  350 ++++++---------
 testsuite/actionscript.all/Sound.as               |   42 ++
 testsuite/media/README                            |   18 +
 testsuite/media/click.mp3                         |  Bin 0 -> 48472 bytes
 43 files changed, 1845 insertions(+), 1361 deletions(-)
 copy libmedia/{haiku/VideoInputHaiku.cpp => Id3Info.h} (52%)
 create mode 100644 libsound/LiveSound.cpp
 create mode 100644 libsound/LiveSound.h
 create mode 100644 libsound/SoundUtils.h
 create mode 100644 libsound/StreamingSound.cpp
 create mode 100644 libsound/StreamingSound.h
 create mode 100644 libsound/StreamingSoundData.cpp
 create mode 100644 libsound/StreamingSoundData.h
 create mode 100644 testsuite/media/click.mp3


hooks/post-receive
-- 
Gnash



reply via email to

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