Exemple #1
0
        /// <summary>
        /// Convert the data to floating point PCM.
        /// </summary>
        /// <param name="decodingData">Decoding data.</param>
        /// <returns>Floating point PCM data.</returns>
        public float[] ToFloatPCM(object decodingData = null)
        {
            //Get context.
            DspAdpcmContext context = null;

            if (decodingData != null)
            {
                context = decodingData as DspAdpcmContext;
            }
            if (context == null)
            {
                context = Context;
            }

            //Decode data.
            short[] pcm = new short[SampleCount()];
            DspAdpcmDecoder.Decode(Data, ref pcm, ref Context, (uint)pcm.Length);
            var ret = pcm.Select(x => (float)x / short.MaxValue).ToArray();

            //Set pointers.
            decodingData = Context = context;

            //Return data.
            return(ret);
        }
Exemple #2
0
        /// <summary>
        /// Read the file.
        /// </summary>
        /// <param name="r">The reader.</param>
        public override void Read(FileReader r)
        {
            //Read data.
            r.ByteOrder = ByteOrder.BigEndian;
            uint numSamples = r.ReadUInt32();

            r.ReadUInt32(); //Num nibbles.
            SampleRate = r.ReadUInt32();
            Loops      = r.ReadUInt16() > 0;
            r.ReadUInt16(); //DSP-ADPCM is 0.
            LoopStart = r.ReadUInt32();
            LoopEnd   = r.ReadUInt32();
            r.ReadUInt32(); //Always 2???
            DspAdpcmContext context     = r.Read <DspAdpcmContext>();
            ushort          numChannels = r.ReadUInt16();

            BlockSize = (uint)(r.ReadUInt16() * 8);
            Extended  = numChannels > 0;

            //Add channel 0.
            //Channels = new List<AudioEncoding>();
            //Channels.Add(new DspAdpcmOLD() { Context = context });
            r.Align(0x60);

            //Extra channels.
            for (int i = 1; i < numChannels; i++)
            {
                r.ReadBytes(0x1C);
                //Channels.Add(new DspAdpcmOLD() { Context = r.Read<DspAdpcmContext>() });
                r.Align(0x60);
            }

            //Do block reading logic.
            if (numChannels == 0)
            {
                numChannels = 1;
            }
            long dataLen    = r.Length - r.Position;
            long channelLen = dataLen / numChannels;

            if (!Extended)
            {
                BlockSize = (uint)channelLen;
            }
            uint lastBlockSize = (uint)(channelLen % BlockSize);
            bool blockCarry    = false;

            if (lastBlockSize == 0)
            {
                lastBlockSize = BlockSize;
            }
            else
            {
                blockCarry = true;
            }
            uint numBlocks = (uint)(channelLen / BlockSize + (blockCarry ? 1 : 0));

            //Read data.
            //Audio.Read(r, encodingType, numChannels, numBlocks, BlockSize, blockSamples, lastBlockSize, lastBlockSamples, 0);
        }
Exemple #3
0
        /// <summary>
        /// Decode DSP-ADPCM data.
        /// </summary>
        /// <param name="src">DSP-ADPCM source.</param>
        /// <param name="dst">Destination array of samples.</param>
        /// <param name="cxt">DSP-APCM context.</param>
        /// <param name="samples">Number of samples.</param>
        public static void Decode(byte[] src, ref Int16[] dst, ref DspAdpcmContext cxt, UInt32 samples)
        {
            //Each DSP-ADPCM frame is 8 bytes long. It contains 1 header byte, and 7 sample bytes.

            //Set initial values.
            short hist1    = cxt.yn1;
            short hist2    = cxt.yn2;
            int   dstIndex = 0;
            int   srcIndex = 0;

            //Until all samples decoded.
            while (dstIndex < samples)
            {
                //Get the header.
                byte header = src[srcIndex++];

                //Get scale and co-efficient index.
                UInt16 scale      = (UInt16)(1 << (header & 0xF));
                byte   coef_index = (byte)(header >> 4);
                short  coef1      = cxt.coefs[coef_index][0];
                short  coef2      = cxt.coefs[coef_index][1];

                //7 sample bytes per frame.
                for (UInt32 b = 0; b < 7; b++)
                {
                    //Get byte.
                    byte byt = src[srcIndex++];

                    //2 samples per byte.
                    for (UInt32 s = 0; s < 2; s++)
                    {
                        sbyte adpcm_nibble = ((s == 0) ? GetHighNibble(byt) : GetLowNibble(byt));
                        short sample       = Clamp16(((adpcm_nibble * scale) << 11) + 1024 + ((coef1 * hist1) + (coef2 * hist2)) >> 11);
                        hist2           = hist1;
                        hist1           = sample;
                        dst[dstIndex++] = sample;

                        if (dstIndex >= samples)
                        {
                            break;
                        }
                    }
                    if (dstIndex >= samples)
                    {
                        break;
                    }
                }
            }

            //Set context.
            cxt.yn1 = hist1;
            cxt.yn2 = hist2;
        }
Exemple #4
0
        /// <summary>
        /// Encodes the samples.
        /// </summary>
        /// <returns>The samples.</returns>
        /// <param name="samples">Samples.</param>
        public static byte[] EncodeSamples(short[] samples, DspAdpcmContext info, int loopStart)
        {
            //Encode data.
            byte[] dspAdpcm = GcAdpcmEncoder.Encode(samples, info.GetCoeffs(), new GcAdpcmParameters()
            {
                History1 = info.yn1, History2 = info.yn2, SampleCount = samples.Length
            });

            //Loop stuff.
            if (loopStart > 0)
            {
                info.loop_yn1 = samples[loopStart - 1];
            }
            if (loopStart > 1)
            {
                info.loop_yn2 = samples[loopStart - 2];
            }

            //Return data.
            return(dspAdpcm);
        }
Exemple #5
0
        /// <summary>
        /// Convert from floating point PCM to the data.
        /// </summary>
        /// <param name="pcm">PCM data.</param>
        /// <param name="encodingData">Encoding data.</param>
        /// <param name="loopStart">Loop start.</param>
        /// <param name="loopEnd">Loop end.</param>
        public void FromFloatPCM(float[] pcm, object encodingData = null, int loopStart = -1, int loopEnd = -1)
        {
            //Convert data.
            short[] s = pcm.Select(x => ConvertFloat(x)).ToArray();

            //Get context.
            DspAdpcmContext context = null;

            if (encodingData != null)
            {
                context = encodingData as DspAdpcmContext;
            }
            if (context == null)
            {
                context = new DspAdpcmContext();
                context.LoadCoeffs(GcAdpcmCoefficients.CalculateCoefficients(s));
            }

            //Encode data.
            Data = DspAdpcmEncoder.EncodeSamples(s, context, loopStart);

            //Set pointers.
            encodingData = Context = context;
        }