In 2005 musixdoc.pdf said:
Another question is: can I write an orchestral score and extract the
separate scores for individual instruments?
Since T.108, the answer is nearly 99%
I gave up trying to understand this chapter and I wrote my own program. It
splits the \notes line into smaller sections between the "&". It tries to
guess the right \NOTes or \notes for each section according to the note
durations it finds there.
It is certainly imperfect but I would be happy to try it on a working
MusiXTeX score. See the limits in my text file.
Bye,
Jean-Pierre Coulon
* Extraction des parties s�par�es d'un "conducteur" MusiXTeX
implicit none
integer longueur, indexpourc, ifichier, ipointeur, lgrsource
integer indexet, noinstru, iligne, nbinstru
integer isigneet, icenterp, iinstrpause
integer iasucrer, nbasucrer
character*1 champnoinstru
character*4 debligne
character*20 motasucrer(8)
character*40 nomsource
character*10 newnotes(11:23), newn, actuellenotes
character*30 nominput, nomoutput
character*200 ligne
character*1000 bigligne, newbout
logical asucrer
data nbasucrer/8/
data motasucrer/'alaligne', 'alapage', 'linegoal', 'interins',
+ 'mgfa', 'eject', 'smallmusicsize', 'afterruleskip'/
print *,' Nom de fichier "conducteur" .TEX ?'
read *, nomsource
ipointeur = longueur(nomsource)
nominput = '\partoche\'//nomsource(1:ipointeur)//'.TEX'
call trouvenb(nbinstru, nominput)
open (unit=10, file=nominput, status='old')
if (longueur(nomsource).eq.8) then
lgrsource = 7 ! perd 8e caractere
else
lgrsource = longueur(nomsource) ! ajoute 1 car pour no
endif
print *, 'coucou'
do ifichier = 11, 11+nbinstru-1
write (champnoinstru,'(z1)') ifichier-10
nomoutput = '\partoche\'//
+ nomsource(1:lgrsource)//champnoinstru//'.tex'
call ouvrefichier(ifichier, nomoutput)
enddo
iligne = 0
do
read (10, '(a)', end=1000) ligne
asucrer = .false.
do iasucrer = 1, nbasucrer
if (index(ligne, motasucrer(iasucrer)
+ (1:longueur(motasucrer(iasucrer)))).ne.0) asucrer = .true.
enddo
debligne = ligne(1:4)
if (index('\NOT\NOt\Not\not\zno', debligne).eq.0) then
if (index(ligne,'instrumentnumber').ne.0) then
do ifichier = 11, 11+nbinstru-1
write(ifichier,'(a)') '\instrumentnumber1'
write(ifichier,'(a)') '\nostartrule'
enddo
else if (index('\setclef\setname\setsign\setstaf',
+ ligne(1:8)).ge.1) then ! ligne specifique pour 1 instrum
call getnoinstru(ligne, noinstru)
write (10+noinstru,'(a)') ligne(1:longueur(ligne))
else if (asucrer) then
else if (index(ligne,'\def\atnextbar{\znotes').gt.0) then! cas des
\centerpause
iinstrpause = 1
do while (index(ligne,'\centerpause').gt.0)
do while ((index(ligne,'&').gt.0).and.
1 (index(ligne,'&').lt.index(ligne,'\centerpause')))
* comptage des & avant \centerpause
isigneet = index(ligne,'&')
iinstrpause = iinstrpause + 1
ligne(1:isigneet) = ' '
enddo
write (10+iinstrpause, '(a)') '\notes\sk\pause\sk\en'
icenterp = index(ligne,'\centerpause')
ligne(1:icenterp+11) = ' '
enddo
else
do ifichier = 11, 11+nbinstru-1 ! lignes communes
write(ifichier,'(a)') ligne(1:longueur(ligne))
enddo
endif
else ! lignes \NOtes etc.
indexpourc = index(ligne, '%')
if (indexpourc.eq.0) then
bigligne = ligne
else
bigligne = ligne(1:indexpourc-1)
endif
do while (index(ligne,'\en').eq.0) ! recollage en une ligne
read (10, '(a)', end=1000) ligne
indexpourc = index(ligne, '%')
if (indexpourc.eq.0) then
bigligne = bigligne(1:longueur(bigligne))//ligne
else
bigligne = bigligne(1:longueur(bigligne))//
+ ligne(1:indexpourc-1)
endif
enddo
ifichier = 11
* recherche du champ \Notes actuel :
ipointeur = 2
do while (index('\|&', bigligne(ipointeur:ipointeur)).eq.0)
ipointeur = ipointeur + 1
enddo
actuellenotes = bigligne(1:ipointeur-1)
indexet = index(bigligne,'&')
do while (indexet.ne.0)
newnotes(ifichier) = actuellenotes ! au cas o� ne changerait pas
newbout = bigligne(ipointeur:indexet-1)
if (longueur(newbout).ne.0) then
if (actuellenotes(1:7).ne.'\znotes') then
call cherchenotes(newbout, newnotes(ifichier))
newn = newnotes(ifichier)
else
newn = '\znotes'
endif
write(ifichier, '(a)') newn(1:longueur(newn))//
+ newbout(1:longueur(newbout))//'\en'
endif
ipointeur = indexet + 1
bigligne(1:ipointeur-1) = ' '
ifichier = ifichier + 1
indexet = index(bigligne,'&')
enddo ! reste le dernier instrument � faire
newbout = bigligne(ipointeur:longueur(bigligne))
if (actuellenotes(1:7).ne.'\znotes') then
call cherchenotes(newbout, newnotes(ifichier))
newn = newnotes(ifichier)
else
newn = '\znotes'
endif
write(ifichier, '(a)') newn(1:longueur(newn))//
+ bigligne(ipointeur:longueur(bigligne))
endif
iligne = iligne + 1
enddo
1000 stop
close (unit=11)
end
* remplacement de \NOtes, etc. selon valeurs notes
subroutine cherchenotes(pacson, newnotes)
implicit none
character*(*) pacson, newnotes
logical contextetrio
contextetrio = .false.
if ((index(pacson,'triolet').gt.0).or.
+ (index(pacson,'xtuplet6').gt.0)) contextetrio = .true.
if ((index(pacson,'\wh').gt.0).or.(index(pacson,'\pause').gt.0))
+ newnotes = '\NOTEs'
if ((index(pacson,'\hu').gt.0).or.(index(pacson,'\hl').gt.0)
+ .or.(index(pacson,'\ha').gt.0).or.
1 (index(pacson,'\hpause').gt.0)) newnotes = '\NOTes'
if ((index(pacson,'\qu').gt.0).or.(index(pacson,'\ql').gt.0)
+ .or.(index(pacson,'\qp').gt.0)
1 .or.(index(pacson,'\qa').gt.0)) newnotes = '\NOtes'
if ((index(pacson,'\qup').gt.0).or.(index(pacson,'\qlp').gt.0))
1 newnotes = '\NOtesp'
if ((index(pacson,'\cu').gt.0).or.(index(pacson,'\cl').gt.0)
+ .or.(index(pacson,'\ds').gt.0).or.(index(pacson,'\ib').gt.0)
1 .or.(index(pacson,'\ca').gt.0)) then
if (contextetrio) then
newnotes = '\notesp'
else
newnotes = '\Notes'
endif
endif
if ((index(pacson,'\cup').gt.0).or.(index(pacson,'\clp').gt.0)
+ .or.(index(pacson,'\qbp').gt.0)) newnotes = '\Notesp'
if ((index(pacson,'\ccu').gt.0).or.(index(pacson,'\ccl').gt.0)
+ .or.(index(pacson,'\qs').gt.0).or.(index(pacson,'\ibb').gt.0)
1 .or.(index(pacson,'\nbb').gt.0)) then
if (contextetrio) then
newnotes = '\notess'
else
newnotes = '\notes'
endif
endif
if ((index(pacson,'\ccup').gt.0).or.(index(pacson,'\cclp').gt.0)
1 .or.((index(pacson,'\ibb').gt.0).and.
2 (index(pacson,'\qbp').gt.0)))
3 newnotes = '\notesp'
if ((index(pacson,'\cccu').gt.0).or.(index(pacson,'\cccl').gt.0)
+ .or.(index(pacson,'\ibbb').gt.0).or.(index(pacson,'\nbbb').gt.0))
2 newnotes = '\notess'
return ! si rien trouv� on laisse newnotes tel quel(tqb, tqh, etc)
end
* recherche nb instruments dans tout le fichier
subroutine trouvenb(nbinstru, nominput)
integer nbinstru
character*2 champinstru
character*(*) nominput
character*200 ligne
open (unit=10, file=nominput, status='old')
nbinstru = 0
do while(nbinstru.eq.0)
read (10, '(a)', end=2000) ligne
if (index(ligne,'\instrumentnumber').ne.0) then
if (index(ligne,'{').eq.0) then
champinstru = ligne(18:18)
else
if (index(ligne,'{').eq.20) then
champinstru = ligne(19:19)! cas nbinstru entre {}
else
champinstru = ligne(19:20)! cas {10}, {11}, {12}
endif
endif
read (champinstru, *, err=2100) nbinstru
endif
enddo
2000 close (unit=10)
print *, 'nbinstru = ', nbinstru
return
2100 print *, 'Nb instruments illisible !'
print *, ligne
stop
end
* recherche no instru dans lignes \set??? et forcage no instru � 1
subroutine getnoinstru(ligne, noinstru)
implicit none
integer noinstru, pointeurferm
character*2 champinstru
character*(*) ligne
character*70 oldligne
oldligne = ligne
pointeurferm = index(ligne,'}')
if (index(ligne,'\setstaffs').eq.0) then
if (ligne(9:9).ne.'{') then
champinstru = ligne(9:9)
ligne(9:9) = '1'
else
champinstru = ligne(10:pointeurferm-1)
ligne(10:pointeurferm-1) = '1'
endif
else ! cas \setclef, \setname, \setsign
if (ligne(11:11).ne.'{') then
champinstru = ligne(11:11)!
ligne(11:11) = '1'
else
champinstru = ligne(12:pointeurferm-1)
ligne(12:pointeurferm-1) = '1'
endif
endif
read (champinstru, *, err=1100) noinstru
return
1100 print *, 'No instrument illisible !'
print *, oldligne
stop
end
include 'ouvrefile.inc'
include 'longueur.inc'
Avoid using \sk. commands, e.g. don't say:
\NOtes\hu C\sk\hu D&\qu{cdef}\en
but:
\NOtes\hu C&\qu{cd}\en
\NOtes\hu D&\qu{ef}\en
This because the program will automatically associate \NOTes with \hu.
Stick \Notes and \set{clef, name, sign, staffs} commands left. Do not
put several \set{something} commands on the same line. Otherwise they
won't be seen.
If you need notes closer to each other than provided by \notes, do not
create your own command similar to \notes, but say e.g. \multnoteskip{.7}
instead.
Do not create sophisticated macros, especially those involving commands
quoted above.
The parts produced may still require some work, e.g.:
- slurs and hairpins across bars,
- consecutive rest measures may need to be rewritten in \PAuse or \PAUSe,
with the corresponding number, and \barno needs be adjusted.
- cue notes or the like.
-------------------------------
[email protected] mailing list
If you want to unsubscribe or look at the archives, go to
http://tug.org/mailman/listinfo/tex-music