private static void ReadDirectRecording(BinaryReader fileReader, DirectRecording directRecording) { directRecording.TStatesPerSample = fileReader.ReadUInt16(); directRecording.PauseInMs = fileReader.ReadUInt16(); directRecording.UsedBitsOfTheLastByte = fileReader.ReadByte(); directRecording.DataLength = fileReader.ReadUInt16() + (fileReader.ReadByte() * 256 * 256); directRecording.BitStream = fileReader.ReadBytes(directRecording.DataLength); }
private static TzxDataBlock ReadTzxDataBlock(BinaryReader fileReader) { TzxDataBlock resultDataBlock = null; byte id = fileReader.ReadByte(); TzxDataBlockType dataBlockType = TzxDataBlock.GetTZXDataBlockTypeFromID(id); switch (dataBlockType) { // ID 10 - Standard Speed Data Block case TzxDataBlockType.StandardSpeedDataBlock: resultDataBlock = new StandardSpeedDataBlock(); ReadStandardSpeedDataBlock(fileReader, (StandardSpeedDataBlock)resultDataBlock); break; // ID 11 - Turbo Speed Data Block case TzxDataBlockType.TurboSpeedDataBlock: resultDataBlock = new TurboSpeedDataBlock(); ReadTurboSpeedDataBlock(fileReader, (TurboSpeedDataBlock)resultDataBlock); break; // ID 12 - Pure Tone case TzxDataBlockType.PureTone: resultDataBlock = new PureTone(); ReadPureTone(fileReader, (PureTone)resultDataBlock); break; // ID 13 - Pulse sequence case TzxDataBlockType.PulseSequence: resultDataBlock = new PulseSequence(); ReadPulseSequence(fileReader, (PulseSequence)resultDataBlock); break; // ID 14 - Pure Data Block case TzxDataBlockType.PureDataBlock: resultDataBlock = new PureDataBlock(); ReadPureDataBlock(fileReader, (PureDataBlock)resultDataBlock); break; // ID 15 - Direct Recording case TzxDataBlockType.DirectRecording: resultDataBlock = new DirectRecording(); ReadDirectRecording(fileReader, (DirectRecording)resultDataBlock); break; // ID 20 - Pause (silence) or 'Stop the Tape' command case TzxDataBlockType.PauseOrStopTheTape: resultDataBlock = new PauseOrStopTheTape(); ReadPauseOrStopTheTape(fileReader, (PauseOrStopTheTape)resultDataBlock); break; // ID 21 - Group start case TzxDataBlockType.GroupStart: resultDataBlock = new GroupStart(); ReadGroupStart(fileReader, (GroupStart)resultDataBlock); break; // ID 22 - Group end case TzxDataBlockType.GroupEnd: resultDataBlock = new GroupEnd(); break; // ID 30 - Text description case TzxDataBlockType.TextDescription: resultDataBlock = new TextDescription(); ReadTextDescription(fileReader, (TextDescription)resultDataBlock); break; // ID 32 - Archive info case TzxDataBlockType.ArchiveInfo: resultDataBlock = new ArchiveInfo(); ReadArchiveInfo(fileReader, (ArchiveInfo)resultDataBlock); break; default: throw new NotImplementedException("TZX data block ID " + id.ToString("X") + " is not yet implemented"); } return(resultDataBlock); }
private static TzxDataBlock ReadTzxDataBlock(BinaryReader fileReader) { TzxDataBlock resultDataBlock = null; byte id = fileReader.ReadByte(); TzxDataBlockType dataBlockType = TzxDataBlock.GetTZXDataBlockTypeFromID(id); switch (dataBlockType) { // ID 10 - Standard Speed Data Block case TzxDataBlockType.StandardSpeedDataBlock: resultDataBlock = new StandardSpeedDataBlock(); ReadStandardSpeedDataBlock(fileReader, (StandardSpeedDataBlock)resultDataBlock); break; // ID 11 - Turbo Speed Data Block case TzxDataBlockType.TurboSpeedDataBlock: resultDataBlock = new TurboSpeedDataBlock(); ReadTurboSpeedDataBlock(fileReader, (TurboSpeedDataBlock)resultDataBlock); break; // ID 12 - Pure Tone case TzxDataBlockType.PureTone: resultDataBlock = new PureTone(); ReadPureTone(fileReader, (PureTone)resultDataBlock); break; // ID 13 - Pulse sequence case TzxDataBlockType.PulseSequence: resultDataBlock = new PulseSequence(); ReadPulseSequence(fileReader, (PulseSequence)resultDataBlock); break; // ID 14 - Pure Data Block case TzxDataBlockType.PureDataBlock: resultDataBlock = new PureDataBlock(); ReadPureDataBlock(fileReader, (PureDataBlock)resultDataBlock); break; // ID 15 - Direct Recording case TzxDataBlockType.DirectRecording: resultDataBlock = new DirectRecording(); ReadDirectRecording(fileReader, (DirectRecording)resultDataBlock); break; // ID 20 - Pause (silence) or 'Stop the Tape' command case TzxDataBlockType.PauseOrStopTheTape: resultDataBlock = new PauseOrStopTheTape(); ReadPauseOrStopTheTape(fileReader, (PauseOrStopTheTape)resultDataBlock); break; // ID 21 - Group start case TzxDataBlockType.GroupStart: resultDataBlock = new GroupStart(); ReadGroupStart(fileReader, (GroupStart)resultDataBlock); break; // ID 22 - Group end case TzxDataBlockType.GroupEnd: resultDataBlock = new GroupEnd(); break; // ID 30 - Text description case TzxDataBlockType.TextDescription: resultDataBlock = new TextDescription(); ReadTextDescription(fileReader, (TextDescription)resultDataBlock); break; // ID 32 - Archive info case TzxDataBlockType.ArchiveInfo: resultDataBlock = new ArchiveInfo(); ReadArchiveInfo(fileReader, (ArchiveInfo)resultDataBlock); break; default: throw new NotImplementedException("TZX data block ID "+ id.ToString("X") + " is not yet implemented"); } return resultDataBlock; }
public TapeSection(TzxDataBlock tzxBlock) { switch (tzxBlock.Type) { // ID 10 - Standard Speed Data Block // 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 // Pause after this block (ms.) {1000} case TzxDataBlockType.StandardSpeedDataBlock: StandardSpeedDataBlock standardDataBlock = (StandardSpeedDataBlock)tzxBlock; // PILOT tone if (standardDataBlock.TapeDataBlock.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", standardDataBlock.TapeDataBlock.TapeData, 855, 1710, 8)); // Pause if (standardDataBlock.PauseInMs > 0) { _soundSequences.Add(new PauseSequence("Pause", standardDataBlock.PauseInMs)); } break; // ID 11 - Turbo Speed Data Block // PILOT tone : // - number of pulses // - pulse length // First SYNC pulse : // - pulse length // Second SYNC pulse : // - pulse length // DATA : // - length of ZERO bit pulse // - length of ONE bit pulse // Pause after this block (ms.) case TzxDataBlockType.TurboSpeedDataBlock: TurboSpeedDataBlock turboDataBlock = (TurboSpeedDataBlock)tzxBlock; // PILOT tone _soundSequences.Add(new ToneSequence("Pilot tone", turboDataBlock.PilotTonePulseCount, turboDataBlock.PilotTonePulseLength)); // First and Second SYNC pulse _soundSequences.Add(new PulsesSequence("Sync pulses", new ushort[] { turboDataBlock.FirstSyncPulseLength, turboDataBlock.SecondSyncPulseLength })); // DATA _soundSequences.Add(new DataSequence("Data", turboDataBlock.TapeDataBlock.TapeData, turboDataBlock.ZeroBitPulseLength, turboDataBlock.OneBitPulseLength, turboDataBlock.UsedBitsOfTheLastByte)); // Pause if (turboDataBlock.PauseInMs > 0) { _soundSequences.Add(new PauseSequence("Pause", turboDataBlock.PauseInMs)); } break; // ID 12 - Pure Tone // Length of one pulse in T-states // Number of pulses case TzxDataBlockType.PureTone: PureTone toneBlock = (PureTone)tzxBlock; _soundSequences.Add(new ToneSequence("Pure tone", toneBlock.PulseCount, toneBlock.LengthOfOnePulse)); break; // ID 13 - Pulse sequence // Number of pulses // Table of pulses' lengths case TzxDataBlockType.PulseSequence: PulseSequence pulseBlock = (PulseSequence)tzxBlock; _soundSequences.Add(new PulsesSequence("Pulse sequence", pulseBlock.PulsesLengths)); break; // ID 14 - Pure Data Block // DATA : Length of ZERO bit pulse / Length of ONE bit pulse // Pause after this block (ms.) case TzxDataBlockType.PureDataBlock: PureDataBlock dataBlock = (PureDataBlock)tzxBlock; // DATA _soundSequences.Add(new DataSequence("Pure data", dataBlock.TapeDataBlock.TapeData, dataBlock.ZeroBitPulseLength, dataBlock.OneBitPulseLength, dataBlock.UsedBitsOfTheLastByte)); // Pause if (dataBlock.PauseInMs > 0) { _soundSequences.Add(new PauseSequence("Pause", dataBlock.PauseInMs)); } break; // ID 15 - Direct Recording // Number of T-states per sample (bit of data). When creating a 'Direct recording' block please stick to the standard sampling frequencies of 22050 or 44100 Hz. This will ensure correct playback when using PC's soundcards. // Pause after this block in milliseconds (ms.) case TzxDataBlockType.DirectRecording: DirectRecording samplesBlock = (DirectRecording)tzxBlock; _soundSequences.Add(new SamplesSequence("Samples", samplesBlock.BitStream, samplesBlock.TStatesPerSample, samplesBlock.UsedBitsOfTheLastByte)); if (samplesBlock.PauseInMs > 0) { _soundSequences.Add(new PauseSequence("Pause", samplesBlock.PauseInMs)); } break; // ID 20 - Pause (silence) or 'Stop the Tape' command // Pause duration (ms.) // This will make a silence (low amplitude level (0)) for a given time in milliseconds. If the value is 0 then the emulator or utility should (in effect) STOP THE TAPE, i.e. should not continue loading until the user or emulator requests it. case TzxDataBlockType.PauseOrStopTheTape: PauseOrStopTheTape pauseBlock = (PauseOrStopTheTape)tzxBlock; if (pauseBlock.PauseInMs > 0) { _soundSequences.Add(new PauseSequence("Pause", pauseBlock.PauseInMs)); } break; case TzxDataBlockType.GroupStart: case TzxDataBlockType.GroupEnd: case TzxDataBlockType.TextDescription: case TzxDataBlockType.ArchiveInfo: // Documentation only, ignore these blocks at runtime break; default: throw new NotSupportedException("Tzx file block type " + tzxBlock.Type.ToString() + " is not yet supported"); } ComputeDuration(); Label = GetSectionLabel(tzxBlock) + " [" + Math.Round(Duration / 1000f) + " sec]"; }