void EmbedSoundInst::decodeNextBlock() { assert(!decodingCompleted()); // this value is arbitrary, things would also work // with a smaller value, but 2^16 seems fast enough // to decode not to bother further streamlining it // See https://savannah.gnu.org/bugs/?25456 for a testcase // showing the benefit of chunked decoding. const std::uint32_t chunkSize = 65535; std::uint32_t inputSize = _soundDef.size() - decodingPosition; if ( inputSize > chunkSize ) inputSize = chunkSize; #ifdef GNASH_DEBUG_SOUNDS_DECODING log_debug(" decoding %d bytes", inputSize); #endif assert(inputSize); const std::uint8_t* input = _soundDef.data(decodingPosition); std::uint32_t consumed = 0; std::uint32_t decodedDataSize = 0; std::uint8_t* decodedData = decoder().decode(input, inputSize, decodedDataSize, consumed); decodingPosition += consumed; assert(!(decodedDataSize%2)); // @todo I hope there are no alignment issues in this cast from int8_t* to int16_t* ! std::int16_t* samples = reinterpret_cast<std::int16_t*>(decodedData); unsigned int nSamples = decodedDataSize/2; #ifdef GNASH_DEBUG_MIXING log_debug(" applying volume/envelope to %d bytes (%d samples)" "of decoded data", decodedDataSize, nSamples); #endif // 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) { unsigned int firstSample = playbackPosition() / 2; applyEnvelopes(samples, nSamples, firstSample, *envelopes); } #ifdef GNASH_DEBUG_MIXING log_debug(" appending %d bytes to decoded buffer", decodedDataSize); #endif // decodedData ownership transferred here appendDecodedData(SimpleBuffer(decodedDataSize, decodedData)); }
void StreamingSound::decodeNextBlock() { assert(!decodingCompleted()); // Get the current block of sound data. const SimpleBuffer& block = _soundDef.getBlock(_currentBlock); // If we didn't decode all of a block, do so now. Not sure if this // can happen. const std::uint32_t inputSize = block.size() - _positionInBlock; std::uint32_t consumed = 0; // Empty blocks serve to synchronize, so don't decode but carry on. if (inputSize) { std::uint32_t decodedDataSize = 0; const std::uint8_t* input = block.data() + _positionInBlock; std::uint8_t* decodedData = decoder().decode(input, inputSize, decodedDataSize, consumed); assert(!(decodedDataSize % 2)); std::int16_t* samples = reinterpret_cast<std::int16_t*>(decodedData); unsigned int nSamples = decodedDataSize / 2; if (_soundDef.volume != 100) { adjustVolume(samples, samples + nSamples, _soundDef.volume/100.0); } // decodedData ownership transferred here appendDecodedData(decodedData, decodedDataSize); } // Check if the entire block was consumed. if (consumed == block.size()) { // Go to next block ++_currentBlock; _positionInBlock = 0; } else _positionInBlock += consumed; }