Make automated FSCommand invocation tests show player-side output.
[gnash.git] / libsound / StreamingSound.cpp
blob1284ac530fef574e4b8ed03099c0315bc2ae5e77
1 // StreamingSound.cpp - instance of an embedded sound, for gnash
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "StreamingSound.h"
23 #include <cmath>
25 #include "AudioDecoder.h"
26 #include "log.h"
27 #include "SoundUtils.h"
29 namespace gnash {
30 namespace sound {
32 namespace {
34 int
35 getInPoint(StreamingSoundData& data, size_t block)
37 if (block >= data.blockCount()) return 0;
38 const int latency = data.soundinfo.getDelaySeek();
40 // For the first block just return the latency.
41 if (block == 0) return latency;
43 // For subsequent blocks add latency to seekSamples. This is documented
44 // but not verified.
45 return swfToOutSamples(data.soundinfo,
46 latency + data.getSeekSamples(block));
51 StreamingSound::StreamingSound(StreamingSoundData& sd,
52 media::MediaHandler& mh, sound_handler::StreamBlockId block)
54 LiveSound(mh, sd.soundinfo, getInPoint(sd, block)),
55 _currentBlock(block),
56 _positionInBlock(0),
57 _soundDef(sd)
61 bool
62 StreamingSound::moreData()
64 if (decodingCompleted()) return false;
66 decodeNextBlock();
67 return true;
70 void
71 StreamingSound::decodeNextBlock()
73 assert(!decodingCompleted());
75 // Get the current block of sound data.
76 const SimpleBuffer& block = _soundDef.getBlock(_currentBlock);
78 // If we didn't decode all of a block, do so now. Not sure if this
79 // can happen.
80 const std::uint32_t inputSize = block.size() - _positionInBlock;
82 std::uint32_t consumed = 0;
84 // Empty blocks serve to synchronize, so don't decode but carry on.
85 if (inputSize) {
86 std::uint32_t decodedDataSize = 0;
87 const std::uint8_t* input = block.data() + _positionInBlock;
88 std::uint8_t* decodedData = decoder().decode(input, inputSize,
89 decodedDataSize, consumed);
91 assert(!(decodedDataSize % 2));
93 std::int16_t* samples =
94 reinterpret_cast<std::int16_t*>(decodedData);
95 unsigned int nSamples = decodedDataSize / 2;
97 if (_soundDef.volume != 100) {
98 adjustVolume(samples, samples + nSamples, _soundDef.volume/100.0);
101 // decodedData ownership transferred here
102 appendDecodedData(decodedData, decodedDataSize);
105 // Check if the entire block was consumed.
106 if (consumed == block.size()) {
107 // Go to next block
108 ++_currentBlock;
109 _positionInBlock = 0;
111 else _positionInBlock += consumed;
115 bool
116 StreamingSound::eof() const
118 // it isn't threaded, but just in case, we call decodingCompleted first
119 return (decodingCompleted() && !decodedSamplesAhead());
122 StreamingSound::~StreamingSound()
124 _soundDef.eraseActiveSound(this);
127 } // gnash.sound namespace
128 } // namespace gnash