[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11059: Implement inPoint/outPoint a
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11059: Implement inPoint/outPoint and Sound.start(<secs_offset>) for event sounds. |
Date: |
Wed, 10 Jun 2009 13:27:47 +0200 |
User-agent: |
Bazaar (1.13.1) |
------------------------------------------------------------
revno: 11059
committer: Sandro Santilli <address@hidden>
branch nick: trunk
timestamp: Wed 2009-06-10 13:27:47 +0200
message:
Implement inPoint/outPoint and Sound.start(<secs_offset>) for event sounds.
Drop delaySeek implementation as it proved wrong
(http://wiki.gnashdev.org/MP3_Sound_tags#Embedded_Event_sounds).
NOTE: there's no automated test yet so please try not to break it.
I'll try to work on extending the eventSoundTest1
modified:
libcore/Button.cpp
libcore/asobj/flash/media/Sound_as.cpp
libcore/asobj/flash/media/Sound_as.h
libcore/swf/SoundInfoRecord.cpp
libcore/swf/SoundInfoRecord.h
libcore/swf/StartSoundTag.cpp
libcore/swf/tag_loaders.cpp
libsound/EmbedSound.cpp
libsound/EmbedSound.h
libsound/EmbedSoundInst.cpp
libsound/EmbedSoundInst.h
libsound/sound_handler.cpp
libsound/sound_handler.h
testsuite/misc-ming.all/eventSoundTest1.c
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp 2009-06-09 14:04:51 +0000
+++ b/libcore/Button.cpp 2009-06-10 11:27:47 +0000
@@ -553,9 +553,10 @@
s->startSound(bs.sample->m_sound_handler_id,
bs.soundInfo.loopCount,
- 0, // secs offset
env, // envelopes
- !sinfo.noMultiple // allow multiple instances ?
+ !sinfo.noMultiple, // allow multiple instances ?
+ sinfo.inPoint,
+ sinfo.outPoint
);
}
=== modified file 'libcore/asobj/flash/media/Sound_as.cpp'
--- a/libcore/asobj/flash/media/Sound_as.cpp 2009-06-09 17:32:44 +0000
+++ b/libcore/asobj/flash/media/Sound_as.cpp 2009-06-10 11:27:47 +0000
@@ -463,7 +463,7 @@
}
void
-Sound_as::start(int offset, int loops)
+Sound_as::start(double secOff, int loops)
{
if ( ! _soundHandler )
{
@@ -479,10 +479,10 @@
return;
}
- if (offset > 0)
+ if (secOff > 0)
{
- _startTime=offset*1000;
- boost::uint32_t seekms = boost::uint32_t(offset*1000);
+ _startTime = secOff * 1000;
+ boost::uint32_t seekms = boost::uint32_t(secOff * 1000);
// TODO: boost::mutex::scoped_lock parserLock(_parserMutex);
_mediaParser->seek(seekms); // well, we try...
}
@@ -511,12 +511,20 @@
}
else
{
+ unsigned int inPoint = 0;
+
+ if ( secOff > 0 ) {
+ inPoint = (secOff*44100);
+ }
+
+ log_debug("Sound.start: secOff:%d", secOff);
+
_soundHandler->startSound(
soundId,
loops,
- offset, // in seconds
0, // envelopes
- true // allow multiple instances (checked)
+ true, // allow multiple instances (checked)
+ inPoint
);
}
}
@@ -825,10 +833,10 @@
)
boost::intrusive_ptr<Sound_as> so = ensureType<Sound_as>(fn.this_ptr);
int loop = 0;
- int secondOffset = 0;
+ double secondOffset = 0;
if (fn.nargs > 0) {
- secondOffset = (int) fn.arg(0).to_number();
+ secondOffset = fn.arg(0).to_number();
if (fn.nargs > 1) {
loop = (int) fn.arg(1).to_number() - 1;
=== modified file 'libcore/asobj/flash/media/Sound_as.h'
--- a/libcore/asobj/flash/media/Sound_as.h 2009-06-09 17:32:44 +0000
+++ b/libcore/asobj/flash/media/Sound_as.h 2009-06-10 11:27:47 +0000
@@ -91,7 +91,7 @@
void loadSound(const std::string& file, bool streaming);
void setPan();
void setTransform();
- void start(int offset, int loops);
+ void start(double secsStart, int loops);
void stop(int si);
unsigned int getDuration();
unsigned int getPosition();
=== modified file 'libcore/swf/SoundInfoRecord.cpp'
--- a/libcore/swf/SoundInfoRecord.cpp 2009-05-20 08:16:47 +0000
+++ b/libcore/swf/SoundInfoRecord.cpp 2009-06-10 11:27:47 +0000
@@ -44,12 +44,10 @@
in.ensureBytes(hasInPoint * 4 + hasOutPoint * 4 + hasLoops * 2);
if (hasInPoint) {
- LOG_ONCE( log_unimpl(_("SoundInfo record with in point")) );
inPoint = in.read_u32();
}
if (hasOutPoint) {
- LOG_ONCE( log_unimpl(_("SoundInfo record with out point")) );
outPoint = in.read_u32();
}
=== modified file 'libcore/swf/SoundInfoRecord.h'
--- a/libcore/swf/SoundInfoRecord.h 2009-02-25 22:33:03 +0000
+++ b/libcore/swf/SoundInfoRecord.h 2009-06-10 11:27:47 +0000
@@ -22,6 +22,8 @@
#include "sound_handler.h" // sound::SoundEnvelopes
+#include <limits>
+
namespace gnash {
class SWFStream;
}
@@ -38,7 +40,7 @@
:
loopCount(0),
inPoint(0),
- outPoint(0)
+ outPoint(std::numeric_limits<unsigned int>::max())
{}
bool noMultiple;
@@ -63,11 +65,19 @@
///
bool stopPlayback;
- /// In/Out points, currently unsupported
- //
- /// See http://sswf.sourceforge.net/SWFalexref.html#swf_soundinfo
- boost::uint32_t inPoint;
- boost::uint32_t outPoint;
+ /// In point, 44100 for one second
+ //
+ /// See http://sswf.sourceforge.net/SWFalexref.html#swf_soundinfo
+ ///
+ unsigned int inPoint;
+
+ /// Out point, 44100 for one second
+ //
+ /// See http://sswf.sourceforge.net/SWFalexref.html#swf_soundinfo
+ ///
+ /// NOTE: std::numeric_limits<unsigned int>::max() means none
+ ///
+ unsigned int outPoint;
/// Sound effects (envelopes) for this start of the sound
//
=== modified file 'libcore/swf/StartSoundTag.cpp'
--- a/libcore/swf/StartSoundTag.cpp 2009-06-09 14:04:51 +0000
+++ b/libcore/swf/StartSoundTag.cpp 2009-06-10 11:27:47 +0000
@@ -27,6 +27,8 @@
#include "SoundInfoRecord.h"
#include "MovieClip.h"
+#include <limits>
+
namespace gnash {
namespace SWF {
@@ -94,9 +96,10 @@
handler->startSound(m_handler_id,
_soundInfo.loopCount,
- 0, // secs offset
env, // envelopes
- !_soundInfo.noMultiple // allow multiple instances ?
+ !_soundInfo.noMultiple, // allow multiple instances ?
+ _soundInfo.inPoint,
+ _soundInfo.outPoint
);
}
}
=== modified file 'libcore/swf/tag_loaders.cpp'
--- a/libcore/swf/tag_loaders.cpp 2009-06-08 00:47:06 +0000
+++ b/libcore/swf/tag_loaders.cpp 2009-06-10 11:27:47 +0000
@@ -1126,11 +1126,6 @@
{
in.ensureBytes(2);
latency = in.read_s16();
- if ( latency )
- {
- LOG_ONCE ( log_unimpl("MP3 stream latency seek") );
- // TODO: should we pass as 'delaySeek' to SoundInfo ?
- }
}
catch (ParserException& ex)
{
@@ -1156,7 +1151,7 @@
// Store all the data in a SoundInfo object
std::auto_ptr<media::SoundInfo> sinfo;
- sinfo.reset(new media::SoundInfo(format, streamSoundStereo,
streamSoundRate, sampleCount, streamSound16bit));
+ sinfo.reset(new media::SoundInfo(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
=== modified file 'libsound/EmbedSound.cpp'
--- a/libsound/EmbedSound.cpp 2009-02-25 22:33:03 +0000
+++ b/libsound/EmbedSound.cpp 2009-06-10 11:27:47 +0000
@@ -100,14 +100,17 @@
std::auto_ptr<EmbedSoundInst>
EmbedSound::createInstance(media::MediaHandler& mh,
- unsigned long blockOffset, unsigned int secsOffset,
+ unsigned long blockOffset,
+ unsigned int inPoint,
+ unsigned int outPoint,
const SoundEnvelopes* envelopes,
unsigned int loopCount)
{
std::auto_ptr<EmbedSoundInst> ret ( new EmbedSoundInst(
*this,
mh, blockOffset,
- secsOffset, envelopes,
+ inPoint, outPoint,
+ envelopes,
loopCount) );
boost::mutex::scoped_lock lock(_soundInstancesMutex);
=== modified file 'libsound/EmbedSound.h'
--- a/libsound/EmbedSound.h 2009-02-25 22:33:03 +0000
+++ b/libsound/EmbedSound.h 2009-06-10 11:27:47 +0000
@@ -162,10 +162,16 @@
/// to refer to a specific StreamSoundBlock.
/// @see gnash::swf::StreamSoundBlockTag
///
- /// @param secsOffset
- /// Offset, in seconds, this instance should start playing
- /// from. @todo take samples (for easier implementation of
- /// seekSamples in streaming sound).
+ /// @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 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.
@@ -181,7 +187,8 @@
/// Locks the _soundInstancesMutex when pushing to it
///
std::auto_ptr<EmbedSoundInst> createInstance( media::MediaHandler& mh,
- unsigned long blockOffset, unsigned int secsOffset,
+ unsigned long blockOffset,
+ unsigned int inPoint, unsigned int outPoint,
const SoundEnvelopes* envelopes, unsigned int loopCount);
/// Volume for AS-sounds, range: 0-100.
=== modified file 'libsound/EmbedSoundInst.cpp'
--- a/libsound/EmbedSoundInst.cpp 2009-06-09 14:04:51 +0000
+++ b/libsound/EmbedSoundInst.cpp 2009-06-10 11:27:47 +0000
@@ -52,7 +52,8 @@
EmbedSoundInst::EmbedSoundInst(EmbedSound& soundData,
media::MediaHandler& mediaHandler,
sound_handler::StreamBlockId blockOffset,
- unsigned int secsOffset,
+ unsigned int inPoint,
+ unsigned int outPoint,
const SoundEnvelopes* env,
unsigned int loopCount)
:
@@ -60,11 +61,20 @@
// should store blockOffset somewhere else too, for resetting
decodingPosition(blockOffset),
- // should change based on offSecs I guess ?
- playbackPosition(0),
-
loopCount(loopCount),
- offSecs(secsOffset),
+
+ // 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)
+ // 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),
@@ -73,6 +83,8 @@
_soundDef(soundData),
_decodedData(0)
{
+ playbackPosition = _inPoint;
+
createDecoder(mediaHandler);
}
@@ -112,6 +124,15 @@
else return 0;
}
+bool
+EmbedSoundInst::reachedCustomEnd() const
+{
+ 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)
{
@@ -161,10 +182,8 @@
// We haven't finished fetching yet, so see if we
// have more to decode or not
- if ( decodingCompleted() )
+ if ( decodingCompleted() || reachedCustomEnd() )
{
- // No more to decode, see if we want to loop...
-
if ( loopCount )
{
#ifdef GNASH_DEBUG_SOUNDS_MANAGEMENT
@@ -175,14 +194,23 @@
// position and keep looping
--loopCount;
- // @todo playbackPosition is not necessarely 0
- // if we were asked to start somewhere after that!!
- playbackPosition=0;
+ // Start next loop
+ playbackPosition = _inPoint;
continue;
}
- log_debug("Decoding completed and no looping, sound is over");
+#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
}
@@ -207,7 +235,7 @@
// Doing so we know what's the sample number
// of the first sample in the newly decoded block.
//
- assert(playbackPosition >= decodedDataSize() );
+ assert( playbackPosition >= decodedDataSize() );
boost::uint32_t inputSize = 0; // or blockSize
bool parse = true; // need to parse ?
@@ -402,7 +430,7 @@
{
// it isn't threaded, but just in case, we call decodingCompleted first
// and we also check loopCount... (over paranoid?)
- return ( decodingCompleted() && !loopCount && !decodedSamplesAhead() );
+ return ( ( decodingCompleted() || reachedCustomEnd() ) && !loopCount &&
!decodedSamplesAhead() );
}
EmbedSoundInst::~EmbedSoundInst()
@@ -416,67 +444,9 @@
if ( ! _decodedData.get() )
{
_decodedData.reset( new SimpleBuffer );
-
- // Skip samples if requested and we're at the start
- const media::SoundInfo& sinfo = *(_soundDef.soundinfo);
- boost::int16_t delaySeek = sinfo.getDelaySeek();
-
- if ( delaySeek > 0 )
- {
- // seek the specified number of samples and throw them away
-
- // each sample is 2 bytes per channel, and we're stereo
- unsigned int off = delaySeek*4;
-
- // delaySeek refers to pre-resampled state so we need to
- // take that into account.
- //
- // NOTE: this was tested with inputs:
- // - isStereo?0 is16bit()?1 sampleRate?22050
- // - isStereo?1 is16bit()?1 sampleRate?22050
- // - isStereo?1 is16bit()?1 sampleRate?44100
- // TODO: test with other sample sizes !
- //log_debug("NOTE: isStereo?%d is16bit()?%d sampleRate?%d",
- // sinfo.isStereo(), sinfo.is16bit(), sinfo.getSampleRate());
- //
- off *= 44100/sinfo.getSampleRate();
-
-
- if ( off < size )
- {
- log_debug("Skipping first %d samples of event sound", off/2);
- _decodedData->append(data+off, size-off);
- }
- else
- {
- // TODO: could be there'll be more samples later
- // so we need to keep track of how many we decoded
- // at this stage
- log_error("delaySeek (%d) >= initial block samples (%d)",
- delaySeek, size/2);
- }
- }
- else if ( delaySeek < 0 )
- {
- // insert delaySeek samples of silence here
-
- // TODO: use a stack-allocated buffer and a loop here
- unsigned int silenceSize = -delaySeek*2; // we talk 8bit
- boost::scoped_array<boost::uint8_t> silence (
- new boost::uint8_t[silenceSize]
- );
- _decodedData->append(silence.get(), silenceSize);
- _decodedData->append(data, size);
- }
- else
- {
- _decodedData->append(data, size);
- }
- }
- else
- {
- _decodedData->append(data, size);
- }
+ }
+
+ _decodedData->append(data, size);
delete [] data; // ownership transferred...
}
=== modified file 'libsound/EmbedSoundInst.h'
--- a/libsound/EmbedSoundInst.h 2009-06-09 14:04:51 +0000
+++ b/libsound/EmbedSoundInst.h 2009-06-10 11:27:47 +0000
@@ -66,23 +66,32 @@
///
/// @param blockId
/// Identifier of the encoded block to start decoding from.
- /// @see gnash::swf::StreamBlockIdTag
- ///
- /// @param secsOffset
- /// Offset, in seconds, this instance should start playing
- /// from. @todo take samples (for easier implementation of
- /// seekSamples in streaming sound).
+ /// @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 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.
- /// @todo document if every loop starts at secsOffset !
+ /// Note that every loop begins and ends at the range given by
+ /// inPoint and outPoint.
///
EmbedSoundInst(EmbedSound& def, media::MediaHandler& mh,
sound_handler::StreamBlockId blockId,
- unsigned int secsOffset, const SoundEnvelopes* envelopes,
+ unsigned int inPoint,
+ unsigned int outPoint,
+ const SoundEnvelopes* envelopes,
unsigned int loopCount);
// See dox in sound_handler.h (InputStream)
@@ -112,11 +121,13 @@
/// For every loop completed, it is decremented.
long loopCount;
- /// Offset in seconds to make playback start in-sync
- //
- /// only used with mp3 streams.
- ///
- unsigned int offSecs;
+ /// 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.
@@ -220,13 +231,24 @@
/// from playback position on
unsigned int decodedSamplesAhead() const
{
- unsigned int bytesAhead = decodedDataSize() - playbackPosition;
+ unsigned int dds = decodedDataSize();
+ 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
{
=== modified file 'libsound/sound_handler.cpp'
--- a/libsound/sound_handler.cpp 2009-06-09 14:04:51 +0000
+++ b/libsound/sound_handler.cpp 2009-06-10 11:27:47 +0000
@@ -332,27 +332,49 @@
}
+/*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;
+}
+
+
+
void
-sound_handler::playSound(int sound_handle, int loopCount, int offSecs,
- StreamBlockId blockId,
- const SoundEnvelopes* envelopes,
- bool allowMultiples)
+sound_handler::playSound(int sound_handle, int loopCount,
+ unsigned int inPoint,
+ unsigned int outPoint,
+ StreamBlockId blockId,
+ const SoundEnvelopes* envelopes,
+ bool allowMultiples)
{
- // 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 playSound, "
- "doing nothing", sound_handle);
- return;
- }
-
- // parameter checking
- if (offSecs < 0)
- {
- log_error("Negative (%d) seconds offset passed to playSound, "
- "taking as zero ", offSecs);
- offSecs = 0;
- }
+ assert (sound_handle >= 0 && static_cast<unsigned int>(sound_handle) <
_sounds.size());
EmbedSound& sounddata = *(_sounds[sound_handle]);
@@ -385,11 +407,6 @@
return;
}
- if (offSecs)
- {
- LOG_ONCE(log_unimpl("Time based sound start offset"));
- }
-
// Make a "EmbedSoundInst" for this sound which is later placed
// on the vector of instances of this sound being played
//
@@ -404,10 +421,8 @@
// Sound block identifier
blockId,
- // Seconds offset
- // WARNING: this is wrong, offset is passed as seconds !!
- // (currently unused anyway)
- (sounddata.soundinfo->isStereo() ? offSecs : offSecs*2),
+ // Samples range
+ inPoint, outPoint,
// Volume envelopes to use for this instance
envelopes,
@@ -424,16 +439,74 @@
void
sound_handler::playStream(int soundId, StreamBlockId blockId)
{
- playSound(soundId, 0, 0, blockId, 0, false);
+ unsigned int inPoint=0;
+ unsigned int outPoint=std::numeric_limits<unsigned int>::max();
+
+ playSound(soundId, 0, inPoint, outPoint, blockId, 0, false);
}
/*public*/
void
-sound_handler::startSound(int soundId, int loops, int secsOffset,
+sound_handler::startSound(int soundId, int loops,
const SoundEnvelopes* env,
- bool allowMultiple)
+ bool allowMultiple, unsigned int inPoint,
+ unsigned int outPoint)
{
- playSound(soundId, loops, secsOffset, 0, env, allowMultiple);
+ // Check if the sound exists
+ if (soundId < 0 ||
+ static_cast<unsigned int>(soundId) >= _sounds.size())
+ {
+ log_error("Invalid (%d) sound_handle passed to startSound, "
+ "doing nothing", soundId);
+ return;
+ }
+
+
+ // Handle delaySeek
+
+ EmbedSound& sounddata = *(_sounds[soundId]);
+ const media::SoundInfo& sinfo = *(sounddata.soundinfo);
+
+ int swfDelaySeek = sinfo.getDelaySeek();
+ if ( swfDelaySeek )
+ {
+ // NOTE: differences between delaySeek and inPoint:
+ //
+ // - Sample count semantic:
+ // inPoint uses output sample rate (44100 for one second)
+ // while delaySeek uses source sample rate
+ // (SoundInfo.getSampleRate() for one second)
+ //
+ // - Loop-back semantic:
+ // An event sound always loops-back from inPoint with no gaps
+ // When delaySeek is specified it is still used as a start
+ // for the initial playback but when it comes to looping back
+ // it seems to play silence instead of samples for the amount
+ // skipped:
+ //
+ // [ delaySeekTime ]
+ // loop1 *****************
+ // loop2 ----------------*****************
+ // loop3 ----------------*****************
+ //
+ // [ inPoint ]
+ // loop1 *****************
+ // loop2 *****************
+ // loop3 *****************
+ //
+ LOG_ONCE(log_unimpl("MP3 delaySeek"));
+#if 0
+ unsigned int outDelaySeek = swfToOutSamples(sinfo, swfDelaySeek);
+
+ log_debug("inPoint(%d) + delaySeek(%d -> %d) == %d",
+ inPoint, swfDelaySeek, outDelaySeek,
+ inPoint+outDelaySeek);
+
+ inPoint += outDelaySeek;
+#endif
+ }
+
+ playSound(soundId, loops, inPoint, outPoint, 0, env, allowMultiple);
}
void
=== modified file 'libsound/sound_handler.h'
--- a/libsound/sound_handler.h 2009-06-09 14:53:45 +0000
+++ b/libsound/sound_handler.h 2009-06-10 11:27:47 +0000
@@ -37,6 +37,7 @@
#include <memory>
#include <cassert>
#include <cstring>
+#include <limits>
#include <set> // for composition
namespace gnash {
@@ -163,11 +164,17 @@
/// @param loops
/// loops == 0 means play the sound once (1 means play it twice, etc)
///
- /// @param secsOffset
- /// When starting event sounds there sometimes is a offset to make
- /// the sound start at the exact right moment. Gnash supports this
- /// through 'Sound' AS class only, not from the actual control tag
- /// (StartSound). Units given in seconds.
+ /// @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 std::numeric_limits<unsigned int>::max() for no limit
+ /// (default if missing)
///
/// @param env
/// Some eventsounds have some volume control mechanism called
@@ -178,12 +185,11 @@
/// If false, the sound will not be scheduled if there's another
/// instance of it already playing.
///
- /// TODO: add inPoint and outPoint parameters
- /// (pre-resampling samples offset of start and end)
- /// or take SWF::SoundInfoRecord& directly !
- void startSound(int id, int loops, int secsOffset,
+ ///
+ void startSound(int id, int loops,
const SoundEnvelopes* env,
- bool allowMultiple);
+ bool allowMultiple, unsigned int inPoint=0,
+ unsigned int outPoint=std::numeric_limits<unsigned
int>::max());
/// Start playback of a streaming sound, if not playing already
//
@@ -504,11 +510,15 @@
/// @param loops
/// loops == 0 means play the sound once (1 means play it twice, etc)
///
- /// @param secsOffset
- /// When starting event sounds there sometimes is a offset to make
- /// the sound start at the exact right moment. Gnash supports this
- /// through 'Sound' AS class only, not from the actual control tag
- /// (StartSound). Units given in seconds.
+ /// @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 blockId
/// When starting a soundstream from a random frame, this tells which
@@ -525,12 +535,30 @@
/// If false, the sound will not be scheduled if there's another
/// instance of it already playing.
///
- /// TODO: add out_point parameter (when to stop playing the sound)
- ///
- void playSound(int id, int loops, int secsOffset,
+ void playSound(int id, 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
+ //
+ /// 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);
+
};
// TODO: move to appropriate specific sound handlers
=== modified file 'testsuite/misc-ming.all/eventSoundTest1.c'
--- a/testsuite/misc-ming.all/eventSoundTest1.c 2009-06-10 11:08:18 +0000
+++ b/testsuite/misc-ming.all/eventSoundTest1.c 2009-06-10 11:27:47 +0000
@@ -323,6 +323,9 @@
pauseForNextTest(mo);
runAttachedSoundsTest(mo, so, &frame);
+ // TODO: test inPoint/outPoint (+ with loop ?)
+ // TODO: test start(<sec_offset>) (+ with loop ?)
+
endOfTests(mo);
//Output movie
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11059: Implement inPoint/outPoint and Sound.start(<secs_offset>) for event sounds.,
Sandro Santilli <=