Beispiel #1
0
        // encoder functions
        public static byte[] Encode(byte[] inWav)
        {
            byte loop = 0x02;

            resample_var  = 1.0;
            resample_type = 'n';
            FIRen         = new bool[] { true, true, true, true };
            FIRstats      = new int[] { 0, 0, 0, 0 };
            List <byte> outBrr = new List <byte>();

            BRRBuffer = new byte[9];                    //9 bytes long buffer
            int offset = 0;

            if (Bits.GetString(inWav, offset, 4) != "RIFF")
            {
                //"RIFF" letters
                MessageBox.Show("Input file in unsupported format !");
                return(null);
            }
            offset += 4;
            offset += 4;
            if (Bits.GetString(inWav, offset, 4) != "WAVE")                                     //"WAVE letters
            {
                MessageBox.Show("Input file in unsupported format !");
                return(null);
            }
            offset += 4;
            if (Bits.GetString(inWav, offset, 4) != "fmt ")                                     //"WAVE letters
            {
                MessageBox.Show("Input file in unsupported format !");
                return(null);
            }
            offset += 4;
            int sc1size = Bits.GetInt32(inWav, offset);

            offset += 4;
            if (sc1size < 0x10 ||                       //Size of sub-chunk1 (header) must be at least 16
                Bits.GetShort(inWav, offset) != 1 ||    //Must be in PCM format
                Bits.GetShort(inWav, offset + 2) != 1)
            {
                //Must be in mono
                MessageBox.Show("Input file in unsupported format !");
                return(null);
            }
            offset += 4;
            offset += 8; //ignore sample and byte rate
            //Read block align and bits per sample numbers
            short BlockAlign   = (short)Bits.GetShort(inWav, offset); offset += 2;
            short BitPerSample = (short)Bits.GetShort(inWav, offset); offset += 2;

            if (BlockAlign != BitPerSample >> 3)
            {
                MessageBox.Show("Block align problem");
                return(null);
            }
            offset += sc1size - 0x10;
            //"data" letters for sub-chunk2
            if (Bits.GetString(inWav, offset, 4) != "data")
            {
                MessageBox.Show("Input file in unsupported format");
                return(null);
            }
            offset += 4;
            int Sub2Size = Bits.GetInt32(inWav, offset);                //Read sub-chunk 2 size

            offset += 4;
            short[] samples = new short[Sub2Size / BlockAlign];
            switch (BitPerSample)
            {
            case 8:
                short sample;
                for (int i = 0; i < Sub2Size / BlockAlign; i++)
                {
                    sample     = (short)inWav[offset++];                //Convert 8-bit samples to 16-bit
                    sample    -= 0x80;
                    samples[i] = (short)(sample << 8);
                }
                break;

            case 16:
                for (int i = 0; i < Sub2Size / BlockAlign; i++)
                {
                    samples[i] = (short)(Bits.GetShort(inWav, offset));
                    offset    += 2;
                }
                break;

            default:
                MessageBox.Show("Error : unsupported amount of bits per sample (8 or 16 are supported");
                return(null);
            }
            samples = resample(samples, resample_type);
            if ((samples.Length & 0xF) != 0)
            {
                MessageBox.Show("Warning ! The Amount of PCM samples isn't a multiple of 16 !");
                MessageBox.Show("The sample will be padded with " + (0x10 - (samples.Length & 0x0F)) + " zeroes at the begining");
                short[] a = new short[0x10 - (samples.Length & 0x0F)];
                samples = append(a, samples);
            }
            bool init = false;

            for (int i = 0; i < 16; i++)
            {
                init |= samples[i] != 0;                //Initialization needed if any of the first 16 samples isn't zero
            }
            //Write initial BRR block
            if (init)
            {
                outBrr.AddRange(new byte[] { loop, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
            }
            p1 = 0;
            p2 = 0;
            short[] samples2 = new short[16];
            for (int n = 0; n < samples.Length >> 4; n++)
            {
                for (int i = 0; i < 16; i++)
                {
                    samples2[i] = samples[i + (n << 4)];                        //Read 16 samples
                }
                BRRBuffer = new byte[9];
                ADPCMBlockMash(samples2);                                       //Compute BRR block
                BRRBuffer[0] |= loop;                                           //Set the loop flag if needed
                if (n == (samples.Length >> 4) - 1)
                {
                    BRRBuffer[0] |= 1;                                  //Set the end bit if we're on the last block
                }
                outBrr.AddRange(BRRBuffer);
            }
            return(outBrr.ToArray());
        }