public void UploadCustomPatterns(IEnumerable<UploadAudioPattern> audioPatterns, IEnumerable<UploadLedPattern> ledPatterns, Action<int> progressFunc)
        {
            EnsureConnected();
            progressFunc(10);

            FileSystemBuilder fileSystemBuilder = new FileSystemBuilder();
            using (Stream fileSystemStream = fileSystemBuilder.Build(audioPatterns, ledPatterns))
            {
                // set the audio and led pattern count to 0 for the first run so that if the upload fails
                // the returned names will not be corrupt
                fileSystemStream.Position = 0;
                fileSystemBuilder.WriteHeader(fileSystemStream, 0, 0);

                fileSystemStream.Position = 0;
                for (int address = 0; address < fileSystemStream.Length; address += 32)
                {
                    SendData(address, fileSystemStream);
                    double progress = (double)address / fileSystemStream.Length;
                    progressFunc((int)(10 + (progress * 80.0)));
                }
                progressFunc(90);

                // set the real audio and led pattern count
                fileSystemStream.Position = 0;
                fileSystemBuilder.WriteHeader(fileSystemStream, audioPatterns.Count(), ledPatterns.Count());
                fileSystemStream.Position = 0;
                for (int address = 0; address < FlashSectorSize; address += 32)
                {
                    SendData(address, fileSystemStream);
                }
                progressFunc(100);
            }
        }