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); }
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); } } }