Beispiel #1
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 DspAdpcmInfo cxt, UInt32 samples)
        {
            //Each DSP-APCM 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;
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Encodes the samples.
        /// </summary>
        /// <returns>The samples.</returns>
        /// <param name="samples">Samples.</param>
        public static byte[] EncodeSamples(short[] samples, out DspAdpcmInfo info, uint loopStart)
        {
            //Encod data.
            short[] coeffs   = GcAdpcmCoefficients.CalculateCoefficients(samples);
            byte[]  dspAdpcm = GcAdpcmEncoder.Encode(samples, coeffs);

            info             = new DspAdpcmInfo();
            info.coefs       = new short[8][];
            info.coefs[0]    = new short[2];
            info.coefs[1]    = new short[2];
            info.coefs[2]    = new short[2];
            info.coefs[3]    = new short[2];
            info.coefs[4]    = new short[2];
            info.coefs[5]    = new short[2];
            info.coefs[6]    = new short[2];
            info.coefs[7]    = new short[2];
            info.coefs[0][0] = coeffs[0];
            info.coefs[0][1] = coeffs[1];
            info.coefs[1][0] = coeffs[2];
            info.coefs[1][1] = coeffs[3];
            info.coefs[2][0] = coeffs[4];
            info.coefs[2][1] = coeffs[5];
            info.coefs[3][0] = coeffs[6];
            info.coefs[3][1] = coeffs[7];
            info.coefs[4][0] = coeffs[8];
            info.coefs[4][1] = coeffs[9];
            info.coefs[5][0] = coeffs[10];
            info.coefs[5][1] = coeffs[11];
            info.coefs[6][0] = coeffs[12];
            info.coefs[6][1] = coeffs[13];
            info.coefs[7][0] = coeffs[14];
            info.coefs[7][1] = coeffs[15];

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

            return(dspAdpcm);
        }
Beispiel #3
0
        /// <summary>
        /// Read data.
        /// </summary>
        /// <param name="br">The reader.</param>
        public override void ReadData(BinaryDataReader br)
        {
            //Read data.
            WaveFormat  = (WaveFormatType)br.ReadUInt16();
            NumChannels = br.ReadUInt16();
            SampleRate  = br.ReadUInt32();
            br.ReadUInt32(); //Byte rate.
            br.ReadUInt16(); //Block align.
            BitsPerSample = br.ReadUInt16();

            //Extra parameters.
            if (WaveFormat == WaveFormatType.DSPADPCM)
            {
                //Read extra data.
                br.ReadUInt16(); //Extra data.
                br.ReadUInt16(); //Padding.
                br.ReadUInt16(); //Unknown.
                br.ReadUInt16(); //Padding.
                DspAdpcmNumSamples = br.ReadUInt32();

                //Foreach channel.
                ChannelInfo = new List <DspAdpcmInfo>();
                for (int i = 0; i < NumChannels; i++)
                {
                    DspAdpcmInfo d = new DspAdpcmInfo();
                    d.coefs = new short[8][];
                    for (int j = 0; j < 8; j++)
                    {
                        d.coefs[j] = br.ReadInt16s(2);
                    }
                    br.ReadUInt16(); //Padding.
                    d.pred_scale      = br.ReadUInt16();
                    d.yn1             = br.ReadInt16();
                    d.yn2             = br.ReadInt16();
                    d.loop_pred_scale = br.ReadUInt16();
                    d.loop_yn1        = br.ReadInt16();
                    d.loop_yn2        = br.ReadInt16();
                    ChannelInfo.Add(d);
                }

                //Read the last part.
                br.ReadUInt16(); //Unknown.
            }
        }