public static PcmAudio ToPcmAudio(RiffWaveChunk waveChunk) { int half = 1 << waveChunk.formatChunk.SampleSize - 1; int full = 1 << waveChunk.formatChunk.SampleSize; IEnumerable <double>[] blocks = new IEnumerable <double> [waveChunk.dataChunk.Size / waveChunk.formatChunk.BlockSize]; for (int blockIndex = 0; blockIndex < blocks.Length; blockIndex++) { double[] samples = new double[waveChunk.formatChunk.ChannelCount]; for (int sampleIndex = 0; sampleIndex < samples.Length; sampleIndex++) { int sample = 0; for (int part = 0; part < (waveChunk.formatChunk.SampleSize / 8); part++) { sample += waveChunk.dataChunk.Data[blockIndex * waveChunk.formatChunk.BlockSize + sampleIndex * (waveChunk.formatChunk.SampleSize / 8) + part] << part * 8; } if (sample >= half) { sample -= full; } samples[sampleIndex] = (double)sample / (double)half; } blocks[blockIndex] = samples; } return(PcmAudio.FromBlocks(blocks, (double)blocks.Length / (double)waveChunk.formatChunk.SampleRate)); }
public static RiffWaveChunk FromPcmAudio(PcmAudio pcmAudio) { IEnumerable <double>[] blocks = pcmAudio.Blocks.ToArray(); RiffFormatChunk formatChunk = new RiffFormatChunk((ushort)pcmAudio.Channels.Count(), (ushort)(blocks.Length / pcmAudio.Length), 16); byte[] data = new byte[formatChunk.BlockSize * blocks.Length]; int position = 0; for (int blockIndex = 0; blockIndex < blocks.Length; blockIndex++) { double[] samples = blocks[blockIndex].ToArray(); for (int sampleIndex = 0; sampleIndex < samples.Length; sampleIndex++) { if (samples[sampleIndex] < -1 || samples[sampleIndex] >= +1) { throw new InvalidDataException(string.Format("Sample at index {0} was out of range ({1}).", sampleIndex, samples[sampleIndex])); } foreach (byte part in BitConverter.GetBytes((short)(samples[sampleIndex] * 0x8000))) { data[position++] = part; } } } RiffDataChunk dataChunk = new RiffDataChunk(data); return(new RiffWaveChunk(formatChunk, dataChunk)); }