\ifx\undefined\setvoice\else\endinput\fi
\immediate\write10{MusiXSERial voices 0.1\space<19 August 1999>}

\makeatletter

\def\max@int{2147483647}

\newcount\cur@staff
\newcount\cur@voice
\newcount\cur@col
\newcount\base@tics \base@tics=192
\newcount\next@delta
\newcount\prev@delta
\newcount\bar@delta \bar@delta\m@ne
\newcount\r@tval

\newtoks\stf@voc
\newtoks\barlinecmd \barlinecmd={\bar}

\newif\ifbar@pending
\newif\ifcol@empty

\newif\iftracingcolumns
\newif\iftracingtics
\newif\ifbarproc

\catcode`\+=\active

\def\setticsskip#1#2{\expandafter\def\csname notes@#1\endcsname{#2}}

\setticsskip{192}\NOTEs
\setticsskip{144}\NOTesp
\setticsskip{96}\NOTes
\setticsskip{72}\NOtesp
\setticsskip{48}\NOtes
\setticsskip{36}\Notesp
\setticsskip{24}\Notes
\setticsskip{18}\notesp
\setticsskip{12}\notes
\setticsskip{9}\notes
\setticsskip{6}\notes

% Fuer musixlyr: PMX vortaeuschen
\let\nextvoice\relax
\let\@pmx@nextvoicetrue\relax

\def\trace@col#1{\iftracingcolumns\immediate\write15{#1}\fi}

\def\barduration#1{%
  \calc@tics#1/\@end
  \bar@delta=\count@
  \edef\bar@tics{\the\count@}}

\def\setvoice#1#2#3{%
  % Muss \toks-Register allokiert werden?
  \expandafter\ifx\csname stf#1voc#2\endcsname\relax
   \begingroup
    \def\@newtoks{newtoks}% durch Gruppierung lokal
    \expandafter\csname\expandafter\@newtoks\expandafter\endcsname
       \csname stf#1voc#2\endcsname
   \endgroup
  \fi
  \expandafter\def\csname delta@stf#1voc#2\endcsname{0}% Delta-Tics
  \expandafter\def\csname dbars@stf#1voc#2\endcsname{0}% Delta-Takte
  \expandafter\let\csname barproc@stf#1voc#2\endcsname\empty % Takt-Material
  \csname stf#1voc#2\endcsname={#3+\end@voc}}

\def\setmaster#1{\setvoice01{#1}}

\def\barproc#1{%
  \expandafter\gdef
    \csname barproc@stf\the\noinstrum@nt voc\the\cur@voice\endcsname{#1}}
  
\def\onebarproc#1{%
  \expandafter\gdef
    \csname barproc@stf\the\noinstrum@nt voc\the\cur@voice\endcsname
    {#1\expandafter
	\gdef\csname barproc@stf\the\noinstrum@nt
			     voc\the\cur@voice\endcsname{}}}

\def\pauseon{\barproc{\centerbar\pause}}
\def\pauseoff{\barproc{}}
\def\onepause{\onebarproc{\centerbar\pause}}

\def\get@denom#1/{#1}

\def\calc@tics#1/#2\@end{%
  % Rueckgabewert in \count@
  \count@=\base@tics
  \ifx\relax#2\relax
   % Kein Zaehler gegeben:
   \divide\count@#1
  \else
   % Bruch gegeben:
   \expandafter\divide\expandafter\count@\get@denom#2\relax
   \multiply\count@#1
  \fi}

\def\calc@tics@w@bars#1b{\calc@tics#1/\@end}

\def\calc@delta#1b#2\@end{%
  % Rueckgabe:
  % \r@tval = Delta-Takte
  % \count@ = Delta-Tics
  \ifx\relax#2\relax
   % kein Takt-Delta angegeben:
   \r@tval\z@
   \calc@tics#1/\@end
  \else
   % Takt angegeben:
   \ifx\relax#1\relax \r@tval=1 % keine Taktzahl gegeben, also = 1
   \else \r@tval#1
   \fi
   \ifx b#2% keine Delta-Tics angegeben?
    \count@\z@
   \else
    \calc@tics@w@bars#2%
   \fi
  \fi}

\def+#1 #2+#3\end@voc{%
  % Delta-Angaben parsen:
  \calc@delta#1b\@end
  % Delta dieser Stimme festhalten:
  \trace@col{neudelta bars=\the\r@tval, tics=\the\count@}%
  \expandafter\edef\csname delta@\the\stf@voc\endcsname{\the\count@}%
  \expandafter\edef\csname dbars@\the\stf@voc\endcsname{\the\r@tval}%
  % Minimales Delta nur ermitteln, wenn keine Delta-Takte:
  \ifnum\r@tval=0
   \ifnum\count@<\next@delta \next@delta\count@ \fi
  \fi
  % Material fuer diese Spalte bereitstellen:
  \expandafter\gdef\csname @s\the\cur@staff v\the\cur@voice\endcsname{#2}%
  % Restmaterial bereitstellen:
  \ifx\relax#3\relax
   % nichts mehr uebrig:
   \expandafter\let\csname\the\stf@voc\endcsname\empty
  \else
   \csname\the\stf@voc\endcsname={+#3\end@voc}%
  \fi}

\def\process@voice{%
  \advance\cur@voice\@ne
  % "Array"-Zugriff vorbereiten:
  \stf@voc=\expandafter{stf\the\cur@staff voc\the\cur@voice}%
  % Zeile@Stimme definiert?
  \expandafter\ifx\csname\the\stf@voc\endcsname\relax
   \let\pv@next\relax  % nein
  \else
   % Zeile@Stimme nicht leer?
   \expandafter\ifx\csname\the\stf@voc\endcsname\empty\else
    \col@emptyfalse
    %
    % evtl Delta-Takte weiterzaehlen
    %
    \ifnum\csname dbars@\the\stf@voc\endcsname>0 % Warten wir auf Takte?
     \ifbar@pending
      % 1 Takt runterzaehlen:
      \count@=\csname dbars@\the\stf@voc\endcsname
      \advance\count@\m@ne
      \expandafter\edef\csname dbars@\the\stf@voc\endcsname{\the\count@}%
      \trace@col{S \the\cur@col, Z \the\cur@staff, St \the\cur@voice:
	  resttakte=\the\count@}%
     \fi % Takt runterzaehlen
    \else % warten nicht auf Takte
     % Stimmdelta vermindern:
     \count@=\csname delta@\the\stf@voc\endcsname\relax
     \trace@col{S \the\cur@col, Z \the\cur@staff, St \the\cur@voice:
	 prevdelta=\the\prev@delta, stimmdelta=\the\count@}%
     \advance\count@ -\prev@delta
     \expandafter\edef\csname delta@\the\stf@voc\endcsname{\the\count@}%
    \fi % Warten wir auf Takte?
    %
    % Enthaelt Stimme Event fuer diese Spalte?
    %
    \ifnum\csname dbars@\the\stf@voc\endcsname=0 % kein Taktwarten ...
     \ifnum\csname delta@\the\stf@voc\endcsname=0 % keine Delta-Tics
      % Event verarbeiten:
      \trace@col{Verarbeite Event}%
      \the\csname\the\stf@voc\endcsname
      \trace@col{neudelta=\csname delta@\the\stf@voc\endcsname}%
     \else % doch noch Delta-Tics uebrig
      % Minimales Spaltendelta ermitteln:
      \count@=\csname delta@\the\stf@voc\endcsname\relax
      \ifnum\count@<\next@delta \next@delta\count@ \fi
      \trace@col{restdelta=\csname delta@\the\stf@voc\endcsname}%
     \fi % keine Delta-Tics
    \fi % kein Taktwarten
   \fi % Zeile@Stimme nicht leer
   \let\pv@next\process@voice
  \fi % Zeile@Stimme definiert?
  \pv@next}

\def\process@staff{%
  \cur@voice\z@ \process@voice
  % Schleife:
  \advance\cur@staff\@ne
  \ifnum\cur@staff>\nbinstruments
   \let\ps@next\relax
  \else
   \let\ps@next\process@staff
  \fi
  \ps@next}

\def\flush@voice{%
  \global\advance\cur@voice\@ne
  \global\stf@voc=\expandafter{@s\the\noinstrum@nt v\the\cur@voice}%
  \expandafter\ifx\csname\the\stf@voc\endcsname\relax
   \let\fv@next\relax
  \else
   % Bei mehr als einer Stimme erst ein backskip (a la \nextvoice von PMX):
   \ifnum\cur@voice>1
    \@ndstaff\advance\noport@@-1\beginstaff
    \@pmx@nextvoicetrue
   \fi
   % Material anwenden:
   \csname\the\stf@voc\endcsname
   % anschliessend deaktivieren:
   \global\expandafter\let\csname\the\stf@voc\endcsname\empty
   \let\fv@next\flush@voice
  \fi
  \fv@next}

\def\flush@staff{%
  \global\cur@voice\z@\flush@voice
  \ifnum\noinstrum@nt<\nbinstruments
   \nextinstrument
   \let\fs@next\flush@staff
  \else
   \let\fs@next\relax
  \fi
  \fs@next}

\def\process@bar@voice{%
  \advance\cur@voice\@ne
  \stf@voc=\expandafter{barproc@stf\the\noinstrum@nt voc\the\cur@voice}%
  \expandafter\ifx\csname\the\stf@voc\endcsname\relax
   \let\pbv@next\relax
  \else
   % Material anwenden:
   \csname\the\stf@voc\endcsname
   \let\pbv@next\process@bar@voice
  \fi
  \pbv@next}

\def\process@bar@staff{%
  \cur@voice\z@\process@bar@voice
  \ifnum\noinstrum@nt<\nbinstruments
   \nextinstrument
   \let\pbs@next\process@bar@staff
  \else
   \let\pbs@next\relax
  \fi
  \pbs@next}

\def\process@column{%
  \advance\cur@col\@ne
  %
  % Takt zu Ende?
  %
  \ifnum\bar@delta>\m@ne % Ueberhaupt Takte definiert?
   \ifnum\bar@delta=0 \bar@pendingtrue \fi % Taktende vormerken
  \fi % Takte definiert
  %
  % Material fuer Spalte sammeln:
  %
  \cur@staff\z@ % nullte Zeile = Masterspur
  \next@delta=\max@int
  \col@emptytrue
  \process@staff
  % Spalte leer?
  \ifcol@empty
   % Spalte leer, Verarbeitung beenden:
   \let\pc@next\relax
  \else
   %
   % Spalte verarbeiten
   %
   % Takt zu Ende?
   \ifbar@pending
    % Taktmaterial ggf. verarbeiten:
    \ifbarproc
    \def\atnextbar{\znotes\process@bar@staff\en}\fi
    % Takt setzen:
    \the\barlinecmd
    \bar@delta=\bar@tics\relax
    \bar@pendingfalse
   \fi % Takt zu Ende
   %
   % Taktdelta fortschreiben
   %
   \ifnum\bar@delta>\m@ne % Ueberhaupt Takte definiert?
    \ifnum\bar@delta<\next@delta \next@delta\bar@delta \fi
    \advance\bar@delta-\next@delta
   \fi % Takte definiert
   % Spalte ausgeben. Spaltenbreite definiert?
   \expandafter\ifx\csname notes@\the\next@delta\endcsname\relax
    \errmessage{No column skip for \the\next@delta\space tics defined}%
   \fi
   % zuerst Masterspur verarbeiten:
   \noinstrum@nt\z@ \cur@voice\z@ \flush@voice
   % Noten setzen:
   \csname notes@\the\next@delta\endcsname
    \iftracingtics\zchar{-5}{\the\next@delta}\fi
    \flush@staff
   \en
   \prev@delta\next@delta
   \let\pc@next\process@column
  \fi
  \pc@next}

\def\processvoices{%
  \process@column}

\makeatother
