Пример #1
0
        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));
        }
Пример #2
0
        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));
        }