int NextPulseLength(SequenceOfPulsesOfVariousLengths TZXDataBlock)
 {
     EarBit = EarBit ^ 64;
     TZXDataBlock.Progress++;
     if ((TZXDataBlock.Progress < TZXDataBlock.NumberOfPulses))
     {
         return(TZXDataBlock.PulsesLengths[TZXDataBlock.Progress]);
     }
     OnLoaded();
     return(GetNextBlock());
 }
        int GetNextBlock(bool increment)
        {
            if (TZXBlockIndex == 0)
            {
                TZXTapeCounter = 0;
            }
            if (increment)
            {
                TZXBlockIndex++;
            }
            if (TZXBlockIndex > TZXFile.Blocks.Count)
            {
                IsPlaying = false;
                OnLoaded();
                return(0);
            }
            pulseLength = 0;
            TZXBlock    = TZXFile.Blocks[TZXBlockIndex];

            switch (TZXBlock.ID)
            {
            case TZXBlockType.TapeDataBlock:
            case TZXBlockType.StandardSpeedDataBlock:
            case TZXBlockType.TurboSpeedDataBlock:
            {
                ITZXDataBlock tZXBlock = TZXBlock as ITZXDataBlock;
                pulseLength       = tZXBlock.PulseLength;
                tZXBlock.Progress = 0;
                usedBits          = tZXBlock.UsedBits;
                TZXState.Reset();
                TZXCurrentByte = tZXBlock.TAPBlock.FirstByte();
                break;
            }

            case TZXBlockType.PureDataBlock:
            {
                PureDataBlock tZXBlock = TZXBlock as PureDataBlock;
                PulseCounter = 2;

                if ((tZXBlock[0] & 0x80) > 0)
                {
                    pulseLength = tZXBlock.OneLength;
                }
                else
                {
                    pulseLength = tZXBlock.ZeroLength;
                }
                usedBits          = tZXBlock.UsedBits;
                tZXBlock.Progress = 0;
                TZXState.State    = TZXStates.DataBytes;
                TZXCurrentByte    = tZXBlock.TAPBlock.FirstByte();
                break;
            }

            case TZXBlockType.PureTone:
            {
                PureTone tZXBlock = TZXBlock as PureTone;
                PulseToneLength   = tZXBlock.numberOfPulses;
                pulseLength       = tZXBlock.PulseLength;
                tZXBlock.Progress = 0;
                TZXState.Reset();
                break;
            }

            case TZXBlockType.SequenceOfPulsesOfVariousLengths:
            {
                SequenceOfPulsesOfVariousLengths tZXBlock = TZXBlock as SequenceOfPulsesOfVariousLengths;
                PulseToneLength   = tZXBlock.PulseToneLength;
                pulseLength       = tZXBlock.PulsesLengths[0];
                tZXBlock.Progress = 0;
                TZXState.Reset();
                break;
            }

            case TZXBlockType.PauseSilenceOrStopTheTapeCommand:
            {
                PauseStopTheTape tZXBlock = TZXBlock as PauseStopTheTape;
                if (tZXBlock.PauseDuration == 0)
                {
                    StartStopTheTape();
                }
                else
                {
                    pulseLength    = tZXBlock.PauseDuration * 3500;
                    TZXState.State = TZXStates.EndPause;
                }
                break;
            }

            case TZXBlockType.StopTheTapeIfIn48kMode:
            {
                StartStopTheTape();
                break;
            }

            case TZXBlockType.JumpToBlock:
            {
                JumpToBlock tZXBlock = TZXBlock as JumpToBlock;
                sbyte       n        = (sbyte)tZXBlock.RelativeJumpValue;
                TZXBlockIndex += n;
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.LoopStart:
            {
                LoopStart tZXBlock = TZXBlock as LoopStart;
                loopCounter = tZXBlock.NumberOfRepetitions;
                TZXBlockIndex++;
                loopNext = TZXBlockIndex;
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.LoopEnd:
            {
                LoopEnd tZXBlock = TZXBlock as LoopEnd;
                loopCounter--;
                if (loopCounter > 0)
                {
                    TZXBlockIndex = loopNext;
                }
                else
                {
                    TZXBlockIndex++;
                }
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.CallSequence:
            {
                CallSequence tZXBlock = TZXBlock as CallSequence;
                stack.Push(TZXBlockIndex);
                numberOfCalls = tZXBlock.NumberOfCallsToBeMade;
                callList      = tZXBlock.ArrayOfCallBlockNumbers;
                callCounter   = 0;
                sbyte n = (sbyte)tZXBlock.ArrayOfCallBlockNumbers[callCounter++];
                TZXBlockIndex = TZXBlockIndex += n;
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.ReturnFromSequence:
            {
                if (callCounter < numberOfCalls)
                {
                    sbyte n = (sbyte)callList[callCounter++];
                    TZXBlockIndex = callSequenceOrigin + n;
                    GetNextBlock(false);
                }
                else
                {
                    if (stack != null)
                    {
                        if (stack.Count > 0)
                        {
                            TZXBlockIndex = stack.Pop();
                        }
                    }
                    GetNextBlock();
                }

                break;
            }

            case TZXBlockType.EndOfFile:
            {
                IsPlaying = false;
                OnLoaded();
            }
            break;

            default:
                GetNextBlock();
                break;
            }
            return(pulseLength);
        }