Beispiel #1
0
        public ISound Decode(Stream stream)
        {
            var riff = _riffStreamReader.Read(stream);

            if (riff.Format != "WAVE")
            {
                throw new RhythmCodexException("RIFF type must be WAVE.");
            }

            var fmt = riff.Chunks.FirstOrDefault(c => c.Id == "fmt ");

            if (fmt == null)
            {
                throw new RhythmCodexException("RIFF must contain the fmt chunk.");
            }
            var format = _waveFmtDecoder.Decode(fmt);

            var data = riff.Chunks.FirstOrDefault(c => c.Id == "data");

            if (data == null)
            {
                throw new RhythmCodexException("RIFF must contain the data chunk.");
            }

            var result = new Sound
            {
                [NumericData.Rate] = format.SampleRate,
                Samples            = new List <ISample>()
            };

            switch (format.Format)
            {
            case 0x0001:     // raw PCM
            {
                float[] decoded;
                switch (format.BitsPerSample)
                {
                case 8:
                    decoded = _pcmDecoder.Decode8Bit(data.Data);
                    break;

                case 16:
                    decoded = _pcmDecoder.Decode16Bit(data.Data);
                    break;

                case 24:
                    decoded = _pcmDecoder.Decode24Bit(data.Data);
                    break;

                case 32:
                    decoded = _pcmDecoder.Decode32Bit(data.Data);
                    break;

                default:
                    throw new RhythmCodexException("Invalid bits per sample.");
                }

                foreach (var channel in decoded.Deinterleave(1, format.Channels))
                {
                    result.Samples.Add(new Sample
                        {
                            [NumericData.Rate] = format.SampleRate,
                            Data = channel
                        });
                }

                break;
            }

            case 0x0002:     // Microsoft ADPCM
            {
                var exFormat = new MicrosoftAdpcmFormat(format.ExtraData);
                var decoded  = _microsoftAdpcmDecoder.Decode(data.Data.AsSpan(), format, exFormat);

                foreach (var sample in decoded.Samples)
                {
                    result.Samples.Add(sample);
                }

                break;
            }

            case 0x0003:     // 32-bit float
            {
                var decoded = _pcmDecoder.DecodeFloat(data.Data);

                foreach (var channel in decoded.Deinterleave(1, format.Channels))
                {
                    result.Samples.Add(new Sample
                        {
                            [NumericData.Rate] = format.SampleRate,
                            Data = channel
                        });
                }

                break;
            }

            case 0x0011:     // IMA ADPCM
            {
                var exFormat = new ImaAdpcmFormat(format.ExtraData);
                var decoded  = _imaAdpcmDecoder.Decode(new ImaAdpcmChunk
                    {
                        Channels = format.Channels,
                        Rate     = format.SampleRate,
                        Data     = data.Data,
                        ChannelSamplesPerFrame = exFormat.SamplesPerBlock
                    });

                foreach (var sample in decoded.SelectMany(s => s.Samples))
                {
                    result.Samples.Add(sample);
                }

                break;
            }
            }

            return(result);
        }
Beispiel #2
0
        private ISound DecodeSound(XwbSound sound)
        {
            var result = new Sound();
            var format = sound.Info.Format;

            switch (format.FormatTag)
            {
            case XwbConstants.WavebankminiformatTagPcm:
            {
                float[] decoded;
                switch (format.BitsPerSample)
                {
                case 8:
                    decoded = _pcmDecoder.Decode8Bit(sound.Data);
                    break;

                case 16:
                    decoded = _pcmDecoder.Decode16Bit(sound.Data);
                    break;

                case 24:
                    decoded = _pcmDecoder.Decode24Bit(sound.Data);
                    break;

                case 32:
                    decoded = _pcmDecoder.Decode32Bit(sound.Data);
                    break;

                default:
                    return(null);
                }

                foreach (var channel in decoded.Deinterleave(1, format.Channels))
                {
                    result.Samples.Add(new Sample
                        {
                            [NumericData.Rate] = format.SampleRate,
                            Data = channel
                        });
                }

                return(result);
            }

            case XwbConstants.WavebankminiformatTagXma:
            {
                return(_imaAdpcmDecoder.Decode(new ImaAdpcmChunk
                    {
                        Channels = format.Channels,
                        ChannelSamplesPerFrame = format.AdpcmSamplesPerBlock,
                        Data = sound.Data,
                        Rate = format.SampleRate
                    }).SingleOrDefault());
            }

            case XwbConstants.WavebankminiformatTagAdpcm:
            {
                return(_microsoftAdpcmDecoder.Decode(
                           sound.Data,
                           format,
                           new MicrosoftAdpcmFormat
                    {
                        Coefficients = new int[0],
                        SamplesPerBlock = format.AdpcmSamplesPerBlock
                    }));
            }

            default:
            {
                return(null);
            }
            }
        }