public TapeSection(TapDataBlock tapBlock)
        {
            // PILOT tone :
            // - number of pulses : 8063 header (flag<128), 3223 data (flag>=128)
            // - pulse length : 2168
            // First SYNC pulse :
            // - pulse length : 667
            // Second SYNC pulse :
            // - pulse length : 735
            // DATA :
            // - length of ZERO bit pulse : 855
            // - length of ONE bit pulse : 1710
            // The 'current pulse level' after playing the block is the opposite of the last pulse level played, so that a subsequent pulse will produce an edge.

            if (tapBlock.Flag < 128)
            {
                _soundSequences.Add(new ToneSequence("Pilot tone", 8063, 2168));
            }
            else
            {
                _soundSequences.Add(new ToneSequence("Pilot tone", 3223, 2168));
            }
            // First and Second SYNC pulse
            _soundSequences.Add(new PulsesSequence("Sync pulses", new ushort[] { 667, 735 }));
            // DATA
            _soundSequences.Add(new DataSequence("Data", tapBlock.TapeData, 855, 1710, 8));

            ComputeDuration();

            Label = GetSectionLabel(tapBlock) + " [" + Math.Round(Duration / 1000f) + " sec]";
        }
Esempio n. 2
0
        public static TapFile ReadTapFile(Stream inputStream, string fileName)
        {
            TapFile resultFile = new TapFile(fileName);

            using (BinaryReader fileReader = new BinaryReader(inputStream, Encoding.GetEncoding("ISO-8859-1")))
            {
                while (fileReader.PeekChar() >= 0)
                {
                    TapDataBlock dataBlock = ReadTapDataBlock(fileReader);
                    resultFile.DataBlocks.Add(dataBlock);

                    TapeSection section = new TapeSection(dataBlock);
                    resultFile.Sections.Add(section);
                }
            }
            TapeSection       lastSection       = resultFile.Sections[resultFile.Sections.Count - 1];
            TapeSoundSequence lastSoundSequence = lastSection.SoundSequences[lastSection.SoundSequences.Count - 1];

            if (lastSoundSequence.GetType() != typeof(PauseSequence))
            {
                lastSection.SoundSequences.Add(new PauseSequence("End of tape", 1));
            }

            foreach (TapeSection section in resultFile.Sections)
            {
                resultFile.Duration += section.Duration;
            }
            resultFile.Description = ""; // Tap file do not contain metadata

            return(resultFile);
        }
        private static string GetSectionLabel(TapDataBlock dataBlock)
        {
            string sectionLabel = null;

            switch (dataBlock.Type)
            {
            case TapDataBlockType.StandardHeader:
                TapHeader header = (TapHeader)dataBlock;
                switch (header.HeaderType)
                {
                case TapHeaderType.ProgramHeader:
                    ProgramHeader programHeader = (ProgramHeader)header;
                    sectionLabel = "Program header : " + programHeader.GetProperties();
                    break;

                case TapHeaderType.ByteArrayHeader:
                    ByteArrayHeader byteArrayHeader = (ByteArrayHeader)header;
                    sectionLabel = "Byte array header : " + byteArrayHeader.GetProperties();
                    break;

                case TapHeaderType.StringArrayHeader:
                    AlphanumArrayHeader stringArrayHeader = (AlphanumArrayHeader)header;
                    sectionLabel = "String array header : " + stringArrayHeader.GetProperties();
                    break;

                case TapHeaderType.NumberArrayHeader:
                    AlphanumArrayHeader numberArrayHeader = (AlphanumArrayHeader)header;
                    sectionLabel = "Number array header : " + numberArrayHeader.GetProperties();
                    break;
                }
                break;

            case TapDataBlockType.StandardDataBlock:
                sectionLabel = "Standard data block : " + dataBlock.DataLength + " bytes";
                break;

            case TapDataBlockType.CustomDataBlock:
                sectionLabel = "Custom data block : " + dataBlock.DataLength + " bytes";
                break;

            case TapDataBlockType.FragmentedDataBlock:
                sectionLabel = "Fragmented data block : " + dataBlock.DataLength + " bytes";
                break;
            }
            if (dataBlock.HasInvalidChecksum)
            {
                sectionLabel += " [invalid checksum]";
            }
            return(sectionLabel);
        }
Esempio n. 4
0
 private static bool CheckIfChecksumIsValid(TapDataBlock tapDataBlock)
 {
     if (tapDataBlock.TapeData != null && tapDataBlock.TapeData.Length > 2)
     {
         byte computedChecksum = tapDataBlock.Flag;
         for (int i = 1; i < (tapDataBlock.TapeData.Length - 1); i++)
         {
             computedChecksum ^= tapDataBlock.TapeData[i];
         }
         return(computedChecksum == tapDataBlock.CheckSum);
     }
     else
     {
         return(false);
     }
 }
 private static string GetSectionLabel(TapDataBlock dataBlock)
 {
     string sectionLabel = null;
     switch (dataBlock.Type)
     {
         case TapDataBlockType.StandardHeader:
             TapHeader header = (TapHeader)dataBlock;
             switch (header.HeaderType)
             {
                 case TapHeaderType.ProgramHeader:
                     ProgramHeader programHeader = (ProgramHeader)header;
                     sectionLabel = "Program header : " + programHeader.GetProperties();
                     break;
                 case TapHeaderType.ByteArrayHeader:
                     ByteArrayHeader byteArrayHeader = (ByteArrayHeader)header;
                     sectionLabel = "Byte array header : " + byteArrayHeader.GetProperties();
                     break;
                 case TapHeaderType.StringArrayHeader:
                     AlphanumArrayHeader stringArrayHeader = (AlphanumArrayHeader)header;
                     sectionLabel = "String array header : " + stringArrayHeader.GetProperties();
                     break;
                 case TapHeaderType.NumberArrayHeader:
                     AlphanumArrayHeader numberArrayHeader = (AlphanumArrayHeader)header;
                     sectionLabel = "Number array header : " + numberArrayHeader.GetProperties();
                     break;
             }
             break;
         case TapDataBlockType.StandardDataBlock:
             sectionLabel = "Standard data block : " + dataBlock.DataLength + " bytes";
             break;
         case TapDataBlockType.CustomDataBlock:
             sectionLabel = "Custom data block : " + dataBlock.DataLength + " bytes";
             break;
         case TapDataBlockType.FragmentedDataBlock:
             sectionLabel = "Fragmented data block : " + dataBlock.DataLength + " bytes";
             break;
     }
     if (dataBlock.HasInvalidChecksum)
     {
         sectionLabel += " [invalid checksum]";
     }
     return sectionLabel;
 }
        public TapeSection(TapDataBlock tapBlock)
        {
            // PILOT tone :
            // - number of pulses : 8063 header (flag<128), 3223 data (flag>=128)
            // - pulse length : 2168
            // First SYNC pulse :
            // - pulse length : 667
            // Second SYNC pulse :
            // - pulse length : 735
            // DATA :
            // - length of ZERO bit pulse : 855
            // - length of ONE bit pulse : 1710
            // The 'current pulse level' after playing the block is the opposite of the last pulse level played, so that a subsequent pulse will produce an edge.

            if (tapBlock.Flag < 128)
            {
                _soundSequences.Add(new ToneSequence("Pilot tone", 8063, 2168));
            }
            else
            {
                _soundSequences.Add(new ToneSequence("Pilot tone", 3223, 2168));
            }
            // First and Second SYNC pulse
            _soundSequences.Add(new PulsesSequence("Sync pulses", new ushort[] { 667, 735 }));
            // DATA
            _soundSequences.Add(new DataSequence("Data", tapBlock.TapeData, 855, 1710, 8));

            ComputeDuration();

            Label = GetSectionLabel(tapBlock) + " [" + Math.Round(Duration / 1000f) + " sec]";
        }
        internal static TapDataBlock ReadTapDataBlock(BinaryReader fileReader, int dataLengthBytesCount)
        {
            // Data block length
            int dataLength = fileReader.ReadUInt16();
            if (dataLengthBytesCount == 3)
            {
                dataLength += (fileReader.ReadByte() * 256 * 256);
            }

            // Read tape data block
            byte[] tapeData = null;
            if (dataLength > 0)
            {
                tapeData = fileReader.ReadBytes(dataLength);
            }

            TapDataBlock tapDataBlock = null;
            if (dataLength > 0)
            {
                byte flag = tapeData[0];

                // Standard header
                if (flag == 0 && dataLength == 19)
                {
                    using (BinaryReader headerReader = new BinaryReader(new MemoryStream(tapeData)))
                    {
                        headerReader.ReadByte(); // flag

                        byte dataType = headerReader.ReadByte();
                        TapHeaderType headerType = TapHeader.GetTapHeaderTypeFromDataType(dataType);
                        switch (headerType)
                        {
                            case TapHeaderType.ProgramHeader:
                                tapDataBlock = new ProgramHeader();
                                break;
                            case TapHeaderType.NumberArrayHeader:
                            case TapHeaderType.StringArrayHeader:
                                tapDataBlock = new AlphanumArrayHeader(dataType);
                                break;
                            default:
                                //case TapHeaderType.ByteArrayHeader:
                                tapDataBlock = new ByteArrayHeader();
                                break;
                        }

                        TapHeader tapHeader = (TapHeader)tapDataBlock;
                        tapHeader.FileName = Encoding.GetEncoding("ISO-8859-1").GetString(headerReader.ReadBytes(10));
                        tapHeader.FollowingDataLength = headerReader.ReadUInt16();

                        switch (headerType)
                        {
                            case TapHeaderType.ProgramHeader:
                                ReadProgramHeader(headerReader, (ProgramHeader)tapDataBlock);
                                break;
                            case TapHeaderType.NumberArrayHeader:
                            case TapHeaderType.StringArrayHeader:
                                ReadAlphanumArrayHeader(headerReader, (AlphanumArrayHeader)tapDataBlock);
                                break;
                            default:
                                //case TapHeaderType.ByteArrayHeader:
                                ReadByteArrayHeader(headerReader, (ByteArrayHeader)tapDataBlock);
                                break;
                        }
                    }
                }
                // Anonymous data block
                else
                {
                    tapDataBlock = new TapDataBlock();
                    tapDataBlock.Flag = flag;
                }

                tapDataBlock.DataLength = dataLength;
                tapDataBlock.TapeData = tapeData;

                if (dataLength >= 2)
                {
                    tapDataBlock.CheckSum = tapeData[dataLength-1];
                    tapDataBlock.HasInvalidChecksum = !CheckIfChecksumIsValid(tapDataBlock);
                }
            }

            return tapDataBlock;
        }
 private static bool CheckIfChecksumIsValid(TapDataBlock tapDataBlock)
 {
     if(tapDataBlock.TapeData != null && tapDataBlock.TapeData.Length > 2)
     {
         byte computedChecksum = tapDataBlock.Flag;
         for (int i = 1; i < (tapDataBlock.TapeData.Length - 1); i++ )
         {
             computedChecksum ^= tapDataBlock.TapeData[i];
         }
         return computedChecksum == tapDataBlock.CheckSum;
     }
     else
     {
         return false;
     }
 }
Esempio n. 9
0
        internal static TapDataBlock ReadTapDataBlock(BinaryReader fileReader, int dataLengthBytesCount)
        {
            // Data block length
            int dataLength = fileReader.ReadUInt16();

            if (dataLengthBytesCount == 3)
            {
                dataLength += (fileReader.ReadByte() * 256 * 256);
            }

            // Read tape data block
            byte[] tapeData = null;
            if (dataLength > 0)
            {
                tapeData = fileReader.ReadBytes(dataLength);
            }

            TapDataBlock tapDataBlock = null;

            if (dataLength > 0)
            {
                byte flag = tapeData[0];

                // Standard header
                if (flag == 0 && dataLength == 19)
                {
                    using (BinaryReader headerReader = new BinaryReader(new MemoryStream(tapeData)))
                    {
                        headerReader.ReadByte(); // flag

                        byte          dataType   = headerReader.ReadByte();
                        TapHeaderType headerType = TapHeader.GetTapHeaderTypeFromDataType(dataType);
                        switch (headerType)
                        {
                        case TapHeaderType.ProgramHeader:
                            tapDataBlock = new ProgramHeader();
                            break;

                        case TapHeaderType.NumberArrayHeader:
                        case TapHeaderType.StringArrayHeader:
                            tapDataBlock = new AlphanumArrayHeader(dataType);
                            break;

                        default:
                            //case TapHeaderType.ByteArrayHeader:
                            tapDataBlock = new ByteArrayHeader();
                            break;
                        }

                        TapHeader tapHeader = (TapHeader)tapDataBlock;
                        tapHeader.FileName            = Encoding.GetEncoding("ISO-8859-1").GetString(headerReader.ReadBytes(10));
                        tapHeader.FollowingDataLength = headerReader.ReadUInt16();

                        switch (headerType)
                        {
                        case TapHeaderType.ProgramHeader:
                            ReadProgramHeader(headerReader, (ProgramHeader)tapDataBlock);
                            break;

                        case TapHeaderType.NumberArrayHeader:
                        case TapHeaderType.StringArrayHeader:
                            ReadAlphanumArrayHeader(headerReader, (AlphanumArrayHeader)tapDataBlock);
                            break;

                        default:
                            //case TapHeaderType.ByteArrayHeader:
                            ReadByteArrayHeader(headerReader, (ByteArrayHeader)tapDataBlock);
                            break;
                        }
                    }
                }
                // Anonymous data block
                else
                {
                    tapDataBlock      = new TapDataBlock();
                    tapDataBlock.Flag = flag;
                }

                tapDataBlock.DataLength = dataLength;
                tapDataBlock.TapeData   = tapeData;

                if (dataLength >= 2)
                {
                    tapDataBlock.CheckSum           = tapeData[dataLength - 1];
                    tapDataBlock.HasInvalidChecksum = !CheckIfChecksumIsValid(tapDataBlock);
                }
            }

            return(tapDataBlock);
        }