Example #1
0
 public ImuseDigiSndMgr(ScummEngine scumm)
 {
     _vm             = scumm;
     _disk           = 0;
     _cacheBundleDir = new BundleDirCache();
     BundleCodecs.InitializeImcTables();
 }
Example #2
0
        public int DecompressSampleByIndex(int index, int offset, int size, out byte[] compFinal, int headerSize, bool headerOutside)
        {
            int finalSize, outputSize;
            int skip, firstBlock, lastBlock;

            Debug.Assert(0 <= index && index < _numFiles);

            if (_curSampleId == -1)
            {
                _curSampleId = index;
            }

            Debug.Assert(_curSampleId == index);

            if (!_compTableLoaded)
            {
                _compTableLoaded = LoadCompTable(index);
                if (!_compTableLoaded)
                {
                    compFinal = null;
                    return(0);
                }
            }

            firstBlock = (offset + headerSize) / 0x2000;
            lastBlock  = (offset + headerSize + size - 1) / 0x2000;

            // Clip last_block by the total number of blocks (= "comp items")
            if ((lastBlock >= _numCompItems) && (_numCompItems > 0))
            {
                lastBlock = _numCompItems - 1;
            }

            int blocksFinalSize = 0x2000 * (1 + lastBlock - firstBlock);

            compFinal = new byte[blocksFinalSize];
            finalSize = 0;

            skip = (offset + headerSize) % 0x2000;

            for (var i = firstBlock; i <= lastBlock; i++)
            {
                if (_lastBlock != i)
                {
                    // CMI hack: one more zero byte at the end of input buffer
                    _compInputBuff[_compTable[i].Size] = 0;
                    _file.BaseStream.Seek(_bundleTable[index].Offset + _compTable[i].Offset, SeekOrigin.Begin);
                    _file.BaseStream.Read(_compInputBuff, 0, _compTable[i].Size);
                    _outputSize = BundleCodecs.DecompressCodec(_compTable[i].Codec, _compInputBuff, _compOutputBuff, _compTable[i].Size);
                    if (_outputSize > 0x2000)
                    {
//                        Console.Error.WriteLine("_outputSize: {0}", _outputSize);
                    }
                    _lastBlock = i;
                }

                outputSize = _outputSize;

                if (headerOutside)
                {
                    outputSize -= skip;
                }
                else
                {
                    if ((headerSize != 0) && (skip >= headerSize))
                    {
                        outputSize -= skip;
                    }
                }

                if ((outputSize + skip) > 0x2000) // workaround
                {
                    outputSize -= (outputSize + skip) - 0x2000;
                }

                if (outputSize > size)
                {
                    outputSize = size;
                }

                Debug.Assert(finalSize + outputSize <= blocksFinalSize);

                Array.Copy(_compOutputBuff, skip, compFinal, finalSize, outputSize);
                finalSize += outputSize;

                size -= outputSize;
                Debug.Assert(size >= 0);
                if (size == 0)
                {
                    break;
                }

                skip = 0;
            }

            return(finalSize);
        }
Example #3
0
        void Callback()
        {
            lock (_mutex)
            {
                for (int l = 0; l < MaxDigitalTracks + MaxDigitalFadeTracks; l++)
                {
                    var track = _track[l];
                    if (track.Used)
                    {
                        // Ignore tracks which are about to finish. Also, if it did finish in the meantime,
                        // mark it as unused.
                        if (track.Stream == null)
                        {
                            if (!_mixer.IsSoundHandleActive(track.MixChanHandle))
                            {
                                _track[l].Clear();
                            }
                            continue;
                        }

                        if (_pause)
                        {
                            return;
                        }

                        if (track.VolFadeUsed)
                        {
                            if (track.VolFadeStep < 0)
                            {
                                if (track.vol > track.VolFadeDest)
                                {
                                    track.vol += track.VolFadeStep;
                                    if (track.vol < track.VolFadeDest)
                                    {
                                        track.vol         = track.VolFadeDest;
                                        track.VolFadeUsed = false;
                                    }
                                    if (track.vol == 0)
                                    {
                                        // Fade out complete . remove this track
                                        FlushTrack(track);
                                        continue;
                                    }
                                }
                            }
                            else if (track.VolFadeStep > 0)
                            {
                                if (track.vol < track.VolFadeDest)
                                {
                                    track.vol += track.VolFadeStep;
                                    if (track.vol > track.VolFadeDest)
                                    {
                                        track.vol         = track.VolFadeDest;
                                        track.VolFadeUsed = false;
                                    }
                                }
                            }
//                            Debug.WriteLine("Fade: sound({0}), Vol({1})", track.SoundId, track.vol / 1000);
                        }

                        if (!track.SouStreamUsed)
                        {
                            Debug.Assert(track.Stream != null);
                            byte[] tmpSndBufferPtr = null;
                            int    curFeedSize     = 0;

                            if (track.CurRegion == -1)
                            {
                                SwitchToNextRegion(track);
                                if (track.Stream == null) // Seems we reached the end of the stream
                                {
                                    continue;
                                }
                            }

                            int bits     = _sound.GetBits(track.SoundDesc);
                            int channels = _sound.GetChannels(track.SoundDesc);

                            int feedSize = track.FeedSize / _callbackFps;

                            if (track.Stream.IsEndOfData)
                            {
                                feedSize *= 2;
                            }

                            if ((bits == 12) || (bits == 16))
                            {
                                if (channels == 1)
                                {
                                    feedSize &= ~1;
                                }
                                if (channels == 2)
                                {
                                    feedSize &= ~3;
                                }
                            }
                            else if (bits == 8)
                            {
                                if (channels == 2)
                                {
                                    feedSize &= ~1;
                                }
                            }
                            else
                            {
//                                Console.Error.WriteLine("IMuseDigita::callback: Unexpected sample width, {0} bits", bits);
                                continue;
                            }

                            if (feedSize == 0)
                            {
                                continue;
                            }

                            do
                            {
                                switch (bits)
                                {
                                case 12:
                                    byte[] tmpPtr;
                                    feedSize += track.DataMod12Bit;
                                    int tmpFeedSize12Bits = (feedSize * 3) / 4;
                                    int tmpLength12Bits   = (tmpFeedSize12Bits / 3) * 4;
                                    track.DataMod12Bit = feedSize - tmpLength12Bits;
                                    int tmpOffset   = (track.RegionOffset * 3) / 4;
                                    int tmpFeedSize = _sound.GetDataFromRegion(track.SoundDesc, track.CurRegion, out tmpPtr, tmpOffset, tmpFeedSize12Bits);
                                    curFeedSize = BundleCodecs.Decode12BitsSample(tmpPtr, out tmpSndBufferPtr, tmpFeedSize);
                                    break;

                                case 16:
                                    curFeedSize = _sound.GetDataFromRegion(track.SoundDesc, track.CurRegion, out tmpSndBufferPtr, track.RegionOffset, feedSize);
                                    if (channels == 1)
                                    {
                                        curFeedSize &= ~1;
                                    }
                                    if (channels == 2)
                                    {
                                        curFeedSize &= ~3;
                                    }
                                    break;

                                case 8:
                                    curFeedSize = _sound.GetDataFromRegion(track.SoundDesc, track.CurRegion, out tmpSndBufferPtr, track.RegionOffset, feedSize);
                                    if (RadioChatterSFX && track.SoundId == 10000)
                                    {
                                        if (curFeedSize > feedSize)
                                        {
                                            curFeedSize = feedSize;
                                        }
                                        var buf   = new byte[curFeedSize];
                                        int index = 0;
                                        int count = curFeedSize - 4;
                                        var ptr_1 = 0;
                                        var ptr_2 = 4;
                                        int value = tmpSndBufferPtr[ptr_1 + 0] - 0x80;
                                        value += tmpSndBufferPtr[ptr_1 + 1] - 0x80;
                                        value += tmpSndBufferPtr[ptr_1 + 2] - 0x80;
                                        value += tmpSndBufferPtr[ptr_1 + 3] - 0x80;
                                        do
                                        {
                                            int t = tmpSndBufferPtr[ptr_1++];
                                            int v = t - (value / 4);
                                            value        = tmpSndBufferPtr[ptr_2++] - 0x80 + (value - t + 0x80);
                                            buf[index++] = (byte)(v * 2 + 0x80);
                                        }while ((--count) != 0);
                                        buf[curFeedSize - 1] = 0x80;
                                        buf[curFeedSize - 2] = 0x80;
                                        buf[curFeedSize - 3] = 0x80;
                                        buf[curFeedSize - 4] = 0x80;
                                        tmpSndBufferPtr      = buf;
                                    }
                                    if (channels == 2)
                                    {
                                        curFeedSize &= ~1;
                                    }
                                    break;
                                }

                                if (curFeedSize > feedSize)
                                {
                                    curFeedSize = feedSize;
                                }

                                if (_mixer.IsReady)
                                {
                                    track.Stream.QueueBuffer(tmpSndBufferPtr, curFeedSize, true, MakeMixerFlags(track));
                                    track.RegionOffset += curFeedSize;
                                }
                                else
                                {
                                    tmpSndBufferPtr = null;
                                }

                                if (_sound.IsEndOfRegion(track.SoundDesc, track.CurRegion))
                                {
                                    SwitchToNextRegion(track);
                                    if (track.Stream == null) // Seems we reached the end of the stream
                                    {
                                        break;
                                    }
                                }
                                feedSize -= curFeedSize;
                                Debug.Assert(feedSize >= 0);
                            } while (feedSize != 0);
                        }
                        if (_mixer.IsReady)
                        {
                            _mixer.SetChannelVolume(track.MixChanHandle, track.Volume);
                            _mixer.SetChannelBalance(track.MixChanHandle, track.Pan);
                        }
                    }
                }
            }
        }