NScumm.Scumm.Audio.IMuse.IMuseDigital.BundleCodecs.Decode12BitsSample C# (CSharp) Method

Decode12BitsSample() public static method

public static Decode12BitsSample ( byte src, byte &dst, int size ) : int
src byte
dst byte
size int
return int
        public static int Decode12BitsSample(byte[] src, out byte[] dst, int size)
        {
            int loop_size = size / 3;
            int s_size = loop_size * 4;
            dst = new byte[s_size];
            var i = 0;
            var ptr = 0;
            int tmp;
            while ((loop_size--) != 0)
            {
                byte v1 = src[i++];
                byte v2 = src[i++];
                byte v3 = src[i++];
                tmp = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000;
                Array.Copy(BitConverter.GetBytes(ScummHelper.SwapBytes((ushort)tmp)), 0, dst, ptr, 2);
                ptr += 2;
                tmp = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000;
                Array.Copy(BitConverter.GetBytes(ScummHelper.SwapBytes((ushort)tmp)), 0, dst, ptr, 2);
                ptr += 2;
            }
            return s_size;
        }

Usage Example

コード例 #1
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);
                        }
                    }
                }
            }
        }