public static void OutputShuffledFrames(Mp3 shuffled, Mp3 unshuffled, byte[][] shuffledFrames, string filename)
        {
            //counters
            int j = shuffled.dataStart;
            int f = 0;

            //get metadata in the new file
            if (shuffled.dataStart != 0)
            {
                for (int i = 0; i < shuffled.dataStart; i++)
                {
                    shuffled.mp3Bytes[i] = unshuffled.mp3Bytes[i];
                }
            }
            //fill frames
            while (f < shuffled.numFrames)
            {
                if (shuffledFrames[f] == null)
                {
                    break;
                }

                //get frame
                for (int k = 0; k < shuffled.frameLength; k++)
                {
                    shuffled.mp3Bytes[j] = shuffledFrames[f][k];
                    j++;
                }

                f++;
            }
            File.WriteAllBytes("E:/Documents/GitHub/ENSE496-Assignment4/Mp3FrameShuffler/" + filename + ".mp3", shuffled.mp3Bytes); //output frame-shuffled file
        }
        public static byte[][] GetFrameArray(Mp3 mp3)
        {
            int i = mp3.dataStart; //reset iterator to start of first header

            byte[][] frames = new byte[mp3.numFrames][];
            //intialize array columns
            for (int k = 0; k < frames.Length; k++)
            {
                frames[k] = new byte[mp3.frameLength];
            }
            int  f = 0; //frame tracker
            bool newFrame;

            //iterate through mp3 again to collect all the frames into an array
            while (f < mp3.numFrames)
            {
                byte[] frame = new byte[mp3.frameLength]; //current frame

                //ensure i does not extend out of range of the array
                if (i >= mp3.mp3Bytes.Length - 1)
                {
                    break;
                }

                //get frame
                //ensure we are at the start of a frame
                if (mp3.mp3Bytes[i] == mp3.syncWord[0] && mp3.mp3Bytes[i + 1] == mp3.syncWord[1])
                {
                    newFrame = true;

                    //iterate though and collect the frame
                    for (int j = 0; j < mp3.frameLength; j++)
                    {
                        frame[j] = mp3.mp3Bytes[i];
                        i++;
                        //ensure we aren't going out of range again
                        if (i >= mp3.mp3Bytes.Length)
                        {
                            break;
                        }
                    }
                }
                //if we aren't increment and continue looping
                else
                {
                    i++;
                    newFrame = false;
                }

                //if we were infact at a new frame, then it will be populated and can be added to the 2d array
                if (newFrame)
                {
                    frames[f] = frame;
                    f++;
                }
            }

            return(frames);
        }
        public static void OutputAllData(Mp3 shuffled, Mp3 unshuffled, byte[] shuffledData, string filename)
        {
            //get metadata in the new file
            if (shuffled.dataStart != 0)
            {
                for (int i = 0; i < shuffled.dataStart; i++)
                {
                    shuffled.mp3Bytes[i] = unshuffled.mp3Bytes[i];
                }
            }
            //insert shuffled mp3 data after id3 tag, if there is one
            for (int i = shuffled.dataStart; i < unshuffled.mp3Bytes.Length; i++)
            {
                shuffled.mp3Bytes[i] = shuffledData[i - shuffled.dataStart];
            }

            File.WriteAllBytes("E:/Documents/GitHub/ENSE496-Assignment4/Mp3FrameShuffler/" + filename + ".mp3", shuffled.mp3Bytes); //output frame-shuffled file
        }
        public static void GetMp3Data(Mp3 mp3)
        {
            int i = 0;
            int temp;

            //get mp3 data
            //check for ID3 header
            if (mp3.mp3Bytes[i] == 49 && mp3.mp3Bytes[i + 1] == 44 && mp3.mp3Bytes[i + 2] == 33)
            {
                //find end of ID3 header
                while (mp3.mp3Bytes[i] == mp3.syncWord[0] && mp3.mp3Bytes[i + 1] == mp3.syncWord[1])
                {
                    i++;
                }
                mp3.dataStart = i;   //get index of where the id3 header ends
            }

            //ensure we are at the start of the mp3 data
            while (mp3.mp3Bytes[i] != mp3.syncWord[0] || mp3.mp3Bytes[i + 1] != mp3.syncWord[1])
            {
                i++;
            }
            mp3.dataStart = i;
            mp3.numFrames++;

            temp = i - 1;
            i    = i + 1;
            //count iterations until next header
            while (mp3.mp3Bytes[i] != mp3.syncWord[0] || mp3.mp3Bytes[i + 1] != mp3.syncWord[1])
            {
                i++;
            }
            mp3.frameLength = i - temp;

            mp3.numFrames = (mp3.mp3Bytes.Length - mp3.dataStart) / mp3.frameLength;
        }
        static void Main(string[] args)
        {
            int key = 802797117; //shuffling key - taken from requirement 3
            Mp3 mp3 = new Mp3();

            mp3.mp3Bytes    = File.ReadAllBytes("E:/Documents/GitHub/ENSE496-Assignment4/Mp3FrameShuffler/mp3.mp3"); //get file
            mp3.syncWord[0] = 0xff;                                                                                  //mp3 sync word first byte
            mp3.syncWord[1] = 0xfb;                                                                                  //mp3 sync word second byte

            //get mp3 data
            GetMp3Data(mp3);
            byte[][] frames = GetFrameArray(mp3);

            //
            //SHUFFLE DATA BY FRAMES
            //
            byte[][] shuffledFrames = Shuffle(frames, mp3.numFrames, mp3.frameLength, key);
            //create new mp3 for export
            Mp3 mp3Shuffled = new Mp3();

            mp3Shuffled.mp3Bytes    = new byte[mp3.mp3Bytes.Length];
            mp3Shuffled.frameLength = mp3.frameLength;
            mp3Shuffled.numFrames   = mp3.numFrames;
            mp3Shuffled.dataStart   = mp3.dataStart;
            OutputShuffledFrames(mp3Shuffled, mp3, shuffledFrames, "mp3Shuffled");

            //
            //UNSHUFFLE DATA BY FRAMES
            //
            byte[][] unshuffledFrames = Unshuffle(shuffledFrames, mp3.numFrames, mp3.frameLength, key);
            //create new mp3 for export
            Mp3 mp3Unshuffled = new Mp3();

            mp3Unshuffled.mp3Bytes    = new byte[mp3.mp3Bytes.Length];
            mp3Unshuffled.frameLength = mp3.frameLength;
            mp3Unshuffled.numFrames   = mp3.numFrames;
            mp3Unshuffled.dataStart   = mp3.dataStart;
            OutputShuffledFrames(mp3Unshuffled, mp3, unshuffledFrames, "mp3Unshuffled");

            //
            //SHUFFLE ALL DATA
            //
            byte[] mp3Data = new byte[mp3.mp3Bytes.Length - mp3.dataStart];
            //get data minus ID3 tag
            for (int i = mp3.dataStart; i < mp3.mp3Bytes.Length; i++)
            {
                mp3Data[i - mp3.dataStart] = mp3.mp3Bytes[i];
            }
            byte[] shuffledData = ShuffleAll(mp3Data, key);
            //create new mp3 for export
            Mp3 mp3ShuffledData = new Mp3();

            mp3ShuffledData.mp3Bytes    = new byte[mp3.mp3Bytes.Length];
            mp3ShuffledData.frameLength = mp3.frameLength;
            mp3ShuffledData.numFrames   = mp3.numFrames;
            mp3ShuffledData.dataStart   = mp3.dataStart;
            OutputAllData(mp3ShuffledData, mp3, shuffledData, "mp3ShuffledData");

            //
            //UNSHUFFLE ALL DATA
            //
            byte[] unshuffledData = UnshuffleAll(shuffledData, key);
            //create new mp3 for export
            Mp3 mp3UnshuffledData = new Mp3();

            mp3UnshuffledData.mp3Bytes    = new byte[mp3.mp3Bytes.Length];
            mp3UnshuffledData.frameLength = mp3.frameLength;
            mp3UnshuffledData.numFrames   = mp3.numFrames;
            mp3UnshuffledData.dataStart   = mp3.dataStart;
            OutputAllData(mp3UnshuffledData, mp3, unshuffledData, "mp3UnshuffledData");
        }