diff options
-rw-r--r-- | audio/decoders/ac3.cpp | 20 | ||||
-rw-r--r-- | audio/decoders/ac3.h | 2 | ||||
-rw-r--r-- | engines/zvision/video/video.cpp | 95 | ||||
-rw-r--r-- | video/mpegps_decoder.cpp | 9 | ||||
-rw-r--r-- | video/mpegps_decoder.h | 6 |
5 files changed, 116 insertions, 16 deletions
diff --git a/audio/decoders/ac3.cpp b/audio/decoders/ac3.cpp index c569179996..1b2a3bff76 100644 --- a/audio/decoders/ac3.cpp +++ b/audio/decoders/ac3.cpp @@ -24,6 +24,7 @@ #include "common/ptr.h" #include "common/stream.h" #include "common/textconsole.h" +#include "common/util.h" #include "audio/audiostream.h" #include "audio/decoders/ac3.h" @@ -37,7 +38,7 @@ namespace Audio { class AC3Stream : public PacketizedAudioStream { public: - AC3Stream(); + AC3Stream(double decibel); ~AC3Stream(); bool init(Common::SeekableReadStream &firstPacket); @@ -62,9 +63,14 @@ private: byte *_inBufPtr; int _flags; int _sampleRate; + double _audioGain; }; -AC3Stream::AC3Stream() : _a52State(0), _frameSize(0), _inBufPtr(0), _flags(0), _sampleRate(0) { +AC3Stream::AC3Stream(double decibel = 0.0) : _a52State(0), _frameSize(0), _inBufPtr(0), _flags(0), _sampleRate(0) { + if (decibel != 0.0) + _audioGain = pow(2, decibel / 6); + else + _audioGain = 1.0; } AC3Stream::~AC3Stream() { @@ -153,7 +159,7 @@ void AC3Stream::queuePacket(Common::SeekableReadStream *data) { } else { // TODO: Eventually support more than just stereo max int flags = A52_STEREO | A52_ADJUST_LEVEL; - sample_t level = 32767; + sample_t level = 32767 * _audioGain; if (a52_frame(_a52State, _inBuf, &flags, &level, 0) != 0) error("Frame fail"); @@ -165,8 +171,8 @@ void AC3Stream::queuePacket(Common::SeekableReadStream *data) { if (a52_block(_a52State) == 0) { sample_t *samples = a52_samples(_a52State); for (int j = 0; j < 256; j++) { - *outputPtr++ = (int16)samples[j]; - *outputPtr++ = (int16)samples[j + 256]; + *outputPtr++ = (int16)CLIP<sample_t>(samples[j], -32768, 32767); + *outputPtr++ = (int16)CLIP<sample_t>(samples[j + 256], -32768, 32767); } outputLength += 1024; @@ -189,8 +195,8 @@ void AC3Stream::queuePacket(Common::SeekableReadStream *data) { } } -PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket) { - Common::ScopedPtr<AC3Stream> stream(new AC3Stream()); +PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket, double decibel) { + Common::ScopedPtr<AC3Stream> stream(new AC3Stream(decibel)); if (!stream->init(firstPacket)) return 0; diff --git a/audio/decoders/ac3.h b/audio/decoders/ac3.h index a51107a410..249d1dcfa2 100644 --- a/audio/decoders/ac3.h +++ b/audio/decoders/ac3.h @@ -41,7 +41,7 @@ class PacketizedAudioStream; * @param firstPacket The stream containing the first packet of data * @return A new PacketizedAudioStream, or NULL on error */ -PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket); +PacketizedAudioStream *makeAC3Stream(Common::SeekableReadStream &firstPacket, double decibel = 0.0); } // End of namespace Audio diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 01e75a4a3d..54c113dc83 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -49,8 +49,99 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) { else if (tmpFileName.hasSuffix(".avi")) animation = new ZorkAVIDecoder(); #if defined(USE_MPEG2) && defined(USE_A52) - else if (tmpFileName.hasSuffix(".vob")) - animation = new Video::MPEGPSDecoder(); + else if (tmpFileName.hasSuffix(".vob")) { + // For some reason, we get much lower volume in the hi-res + // videos than in the low-res ones. So we artificially boost + // the volume here. This is an approximation, but I've tried + // to match the old volumes reasonably well. + // + // Some of these will cause audio clipping. Hopefully not + // enough to be noticeable. + double amplification = 0.0; + if (tmpFileName == "em00d011.vob") { + // The finale. + amplification = 10.0; + } else if (tmpFileName == "em00d021.vob") { + // Jack's escape and arrival at Flathead Mesa. + amplification = 9.0; + } else if (tmpFileName == "em00d032.vob") { + // The Grand Inquisitor's speech. + amplification = 11.0; + } else if (tmpFileName == "em00d122.vob") { + // Jack orders you to the radio tower. + amplification = 17.0; + } else if (tmpFileName == "em3ed012.vob") { + // The Grand Inquisitor gets the Coconut of Quendor. + amplification = 12.0; + } else if (tmpFileName == "g000d101.vob") { + // Griff gets captured. + amplification = 11.0; + } else if (tmpFileName == "g000d111.vob") { + // Brog gets totemized. The music seems to be mixed + // much softer in this than in the low-resolution + // version. + amplification = 12.0; + } else if (tmpFileName == "g000d122.vob") { + // Lucy gets captured. + amplification = 14.0; + } else if (tmpFileName == "g000d302.vob") { + // The Grand Inquisitor visits Jack in his cell. + amplification = 13.0; + } else if (tmpFileName == "g000d312.vob") { + // You get captured. + amplification = 14.0; + } else if (tmpFileName == "g000d411.vob") { + // Propaganda On Parade. No need to make it as loud as + // the low-resolution version. + amplification = 11.0; + } else if (tmpFileName == "pe1ed012.vob") { + // Jack lets you in with the lantern. + amplification = 14.0; + } else if (tmpFileName.hasPrefix("pe1ed")) { + // Jack answers the door. Several different ways. + amplification = 17.0; + } else if (tmpFileName == "pe5ed052.vob") { + // You get killed by the guards + amplification = 12.0; + } else if (tmpFileName == "pe6ed012.vob") { + // Jack gets captured by the guards + amplification = 17.0; + } else if (tmpFileName == "pp1ed022.vob") { + // Jack examines the lantern + amplification = 10.0; + } else if (tmpFileName == "qb1ed012.vob") { + // Lucy gets invited to the back room + amplification = 17.0; + } else if (tmpFileName.hasPrefix("qe1ed")) { + // Floyd answers the door. Several different ways. + amplification = 17.0; + } else if (tmpFileName == "qs1ed011.vob") { + // Jack explains the rules of the game. + amplification = 16.0; + } else if (tmpFileName == "qs1ed021.vob") { + // Jack loses the game. + amplification = 14.0; + } else if (tmpFileName == "uc1gd012.vob") { + // Y'Gael appears. + amplification = 12.0; + } else if (tmpFileName == "ue1ud012.vob") { + // Jack gets totemized... or what? + amplification = 12.0; + } else if (tmpFileName == "ue2qd012.vob") { + // Jack agrees to totemization. + amplification = 10.0; + } else if (tmpFileName == "g000d981.vob") { + // The Enterprise logo. Has no low-res version. Its + // volume is louder than the other logo animations. + amplification = 6.2; + } else if (tmpFileName.hasPrefix("g000d")) { + // The Dolby Digital and Activision logos. They have no + // low-res versions, but I've used the low-resolution + // Activision logo (slightly different) as reference. + amplification = 8.5; + } + animation = new Video::MPEGPSDecoder(amplification); + } #endif else error("Unknown suffix for animation %s", fileName.c_str()); diff --git a/video/mpegps_decoder.cpp b/video/mpegps_decoder.cpp index 361481b739..9b232ec792 100644 --- a/video/mpegps_decoder.cpp +++ b/video/mpegps_decoder.cpp @@ -50,7 +50,8 @@ enum { kStartCodePrivateStream2 = 0x1BF }; -MPEGPSDecoder::MPEGPSDecoder() { +MPEGPSDecoder::MPEGPSDecoder(double decibel) { + _decibel = decibel; _demuxer = new MPEGPSDemuxer(); } @@ -104,7 +105,7 @@ MPEGPSDecoder::MPEGStream *MPEGPSDecoder::getStream(uint32 startCode, Common::Se #ifdef USE_A52 handled = true; - AC3AudioTrack *ac3Track = new AC3AudioTrack(*packet, getSoundType()); + AC3AudioTrack *ac3Track = new AC3AudioTrack(*packet, _decibel, getSoundType()); stream = ac3Track; _streamMap[startCode] = ac3Track; addTrack(ac3Track); @@ -704,9 +705,9 @@ Audio::AudioStream *MPEGPSDecoder::MPEGAudioTrack::getAudioStream() const { #ifdef USE_A52 -MPEGPSDecoder::AC3AudioTrack::AC3AudioTrack(Common::SeekableReadStream &firstPacket, Audio::Mixer::SoundType soundType) : +MPEGPSDecoder::AC3AudioTrack::AC3AudioTrack(Common::SeekableReadStream &firstPacket, double decibel, Audio::Mixer::SoundType soundType) : AudioTrack(soundType) { - _audStream = Audio::makeAC3Stream(firstPacket); + _audStream = Audio::makeAC3Stream(firstPacket, decibel); if (!_audStream) error("Could not create AC-3 stream"); } diff --git a/video/mpegps_decoder.h b/video/mpegps_decoder.h index bd703a35ff..7960639d78 100644 --- a/video/mpegps_decoder.h +++ b/video/mpegps_decoder.h @@ -54,7 +54,7 @@ namespace Video { */ class MPEGPSDecoder : public VideoDecoder { public: - MPEGPSDecoder(); + MPEGPSDecoder(double decibel = 0.0); virtual ~MPEGPSDecoder(); bool loadStream(Common::SeekableReadStream *stream); @@ -166,7 +166,7 @@ private: #ifdef USE_A52 class AC3AudioTrack : public AudioTrack, public MPEGStream { public: - AC3AudioTrack(Common::SeekableReadStream &firstPacket, Audio::Mixer::SoundType soundType); + AC3AudioTrack(Common::SeekableReadStream &firstPacket, double decibel, Audio::Mixer::SoundType soundType); ~AC3AudioTrack(); bool sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts); @@ -199,6 +199,8 @@ private: // A map from stream types to stream handlers typedef Common::HashMap<int, MPEGStream *> StreamMap; StreamMap _streamMap; + + double _decibel; }; } // End of namespace Video |