Beispiel #1
0
        /// <summary>
        /// Write a shortened wave.
        /// </summary>
        /// <param name="w">The writer.</param>
        public void WriteShortened(FileWriter w)
        {
            //Format.
            PcmFormat pcmFormat = PcmFormat.Encoded;

            if (Audio.EncodingType.Equals(typeof(PCM8Signed)))
            {
                w.Write((byte)PcmFormat.SignedPCM8);
                pcmFormat = PcmFormat.SignedPCM8;
            }
            else if (Audio.EncodingType.Equals(typeof(PCM16)))
            {
                w.Write((byte)PcmFormat.PCM16);
                pcmFormat = PcmFormat.PCM16;
            }
            else if (Audio.EncodingType.Equals(typeof(ImaAdpcm)))
            {
                w.Write((byte)PcmFormat.Encoded);
                pcmFormat = PcmFormat.Encoded;
            }
            else
            {
                throw new Exception("Invalid channel format!");
            }

            //Data.
            w.Write(Loops);
            w.Write((ushort)SampleRate);
            ushort nTimeSampleRate = (ushort)(16756991 / SampleRate);

            if (BackupNTime != 0)
            {
                w.Write(BackupNTime);
            }
            else
            {
                w.Write(nTimeSampleRate);
            }
            if (Loops)
            {
                w.Write((ushort)(Sample2Offset(LoopStart, pcmFormat) / 4));
            }
            else
            {
                w.Write((ushort)(pcmFormat == PcmFormat.Encoded ? 1 : 0));
            }
            if (Loops)
            {
                w.Write((uint)((Audio.DataSize - Sample2Offset(LoopStart, pcmFormat)) / 4));
            }
            else
            {
                w.Write((uint)((Audio.DataSize - Sample2Offset((uint)(pcmFormat == PcmFormat.Encoded ? 1 : 0), pcmFormat)) / 4));
            }
            Audio.Write(w);
        }
Beispiel #2
0
        /// <summary>
        /// Read the file.
        /// </summary>
        /// <param name="r">The reader.</param>
        public override void Read(FileReader r)
        {
            //Read header.
            r.OpenFile <NHeader>(out _);

            //Head block.
            r.OpenBlock(0, out _, out _);
            PcmFormat pcmFormat = (PcmFormat)r.ReadByte();

            Loops = r.ReadBoolean();
            int numChannels = r.ReadByte();

            r.ReadByte();
            SampleRate = r.ReadUInt16();
            r.ReadUInt16();
            LoopStart = r.ReadUInt32();
            uint numSamples = r.ReadUInt32();

            if (Loops)
            {
                LoopEnd = numSamples;
            }
            r.OpenOffset("dataOffset");
            uint numBlocks        = r.ReadUInt32();
            uint blockSize        = r.ReadUInt32();
            uint blockSamples     = r.ReadUInt32();
            uint lastBlockSize    = r.ReadUInt32();
            uint lastBlockSamples = r.ReadUInt32();

            r.ReadBytes(32);

            //Encoding type.
            Type encodingType = null;

            switch (pcmFormat)
            {
            case PcmFormat.SignedPCM8:
                encodingType = typeof(PCM8Signed);
                break;

            case PcmFormat.PCM16:
                encodingType = typeof(PCM16);
                break;

            case PcmFormat.Encoded:
                encodingType = typeof(ImaAdpcm);
                break;
            }

            //Data block.
            r.JumpToOffset("dataOffset", true, true);
            Audio.Read(r, encodingType, numChannels, numBlocks, blockSize, blockSamples, lastBlockSize, lastBlockSamples, 0);
        }
Beispiel #3
0
        /// <summary>
        /// Read a shortened wave.
        /// </summary>
        /// <param name="r">The reader.</param>
        /// <param name="length">The data length.</param>
        /// <returns>A wave.</returns>
        public static Wave ReadShortened(FileReader r, uint length)
        {
            //Set up wave.
            Wave      w         = new Wave();
            PcmFormat pcmFormat = (PcmFormat)r.ReadByte();

            w.Loops = r.ReadBoolean();
            int numChannels = 1;

            w.SampleRate  = r.ReadUInt16();
            w.BackupNTime = r.ReadUInt16();
            w.LoopStart   = r.ReadUInt16();
            r.ReadUInt32(); //Non-loop length.

            //Data size.
            uint dataSize = length - 12;

            w.LoopEnd = dataSize * 2;

            //Loop start offset is divided by 4 for some reason.
            w.LoopStart = Offset2Samples(w.LoopStart * 4, pcmFormat);
            w.LoopEnd   = Offset2Samples(dataSize, pcmFormat);

            //Switch type.
            Type format = null;

            switch (pcmFormat)
            {
            case PcmFormat.SignedPCM8:
                format = typeof(PCM8Signed);
                break;

            case PcmFormat.PCM16:
                format = typeof(PCM16);
                break;

            case PcmFormat.Encoded:
                format = typeof(ImaAdpcm);
                break;
            }

            //Read channels.
            w.Audio.Read(r, format, numChannels, (int)dataSize, (int)w.LoopEnd, 0);

            //Return the wave.
            return(w);
        }
Beispiel #4
0
        /// <summary>
        /// Convert a sample to an offset.
        /// </summary>
        /// <param name="sample">The offset.</param>
        /// <param name="format">The format.</param>
        /// <returns>The offset number.</returns>
        public static uint Sample2Offset(uint sample, PcmFormat format)
        {
            //Offset.
            uint offset = sample;

            switch (format)
            {
            case PcmFormat.SignedPCM8:
                return(offset);

            case PcmFormat.PCM16:
                return(offset * 2);

            case PcmFormat.Encoded:
                return((offset + 8) / 2);
            }
            return(0);
        }
Beispiel #5
0
        /// <summary>
        /// Convert an offset to a sample.
        /// </summary>
        /// <param name="offset">The offset.</param>
        /// <param name="format">The format.</param>
        /// <returns>The sample number.</returns>
        public static uint Offset2Samples(uint offset, PcmFormat format)
        {
            //Sample.
            uint samples = offset;

            switch (format)
            {
            case PcmFormat.SignedPCM8:
                return(samples);

            case PcmFormat.PCM16:
                return(samples / 2);

            case PcmFormat.Encoded:
                return(samples * 2 - 8);
            }
            return(0);
        }
Beispiel #6
0
        /// <summary>
        /// Write the file.
        /// </summary>
        /// <param name="w">The writer.</param>
        public override void Write(FileWriter w)
        {
            //Init header.
            w.InitFile <NHeader>("STRM", ByteOrder.LittleEndian, null, 2);
            long countOff = w.Position - 2;

            //Head block.
            w.Write("HEAD".ToCharArray());
            w.Write((uint)0x50);

            //Format.
            PcmFormat pcmFormat    = PcmFormat.Encoded;
            uint      blockSamples = (uint)Audio.NumSamples;
            uint      blockSize    = (uint)Audio.DataSize;

            if (Audio.EncodingType.Equals(typeof(PCM8Signed)))
            {
                w.Write((byte)PcmFormat.SignedPCM8);
                pcmFormat = PcmFormat.SignedPCM8;
            }
            else if (Audio.EncodingType.Equals(typeof(PCM16)))
            {
                w.Write((byte)PcmFormat.PCM16);
                pcmFormat = PcmFormat.PCM16;
            }
            else if (Audio.EncodingType.Equals(typeof(ImaAdpcm)))
            {
                w.Write((byte)PcmFormat.Encoded);
                pcmFormat    = PcmFormat.Encoded;
                blockSize    = (uint)Audio.BlockSize;
                blockSamples = (blockSize - 4) * 2;
            }
            else
            {
                throw new Exception("Invalid channel format!");
            }
            w.Write(Loops);
            w.Write((byte)Audio.Channels.Count());
            w.Write((byte)0);
            w.Write((ushort)SampleRate);
            w.Write((ushort)Math.Floor((decimal)523655.96875 * ((decimal)1 / (decimal)SampleRate)));
            w.Write(LoopStart);
            w.Write(Audio.NumSamples);
            w.Write((uint)0x68);
            w.Write(Audio.NumBlocks);
            w.Write(blockSize);
            w.Write(blockSamples);
            w.Write(Audio.LastBlockSize);
            w.Write(Audio.LastBlockSamples);
            w.Write(new byte[0x20]);
            long bak = w.Position;

            w.Write("DATA".ToCharArray());
            w.Write((uint)0);
            Audio.Write(w);
            w.Pad(4);
            long bak2 = w.Position;

            w.Position = bak + 4;
            w.Write((uint)(bak2 - bak));
            w.Position = bak2;
            w.CloseFile();
            bak        = w.Position;
            w.Position = countOff;
            w.Write((ushort)2);
            w.Position = bak;
        }