ouvrir midi dans lilypond
- Pierolivier
- Pithéclarinethantropus
- Messages : 7081
- Inscription : 21 oct. 2002, 08:13
- Localisation : Là où naissent les cloches et les andouilles.
ouvrir midi dans lilypond
Tout est dans le titre, j'essaie d'ouvrir un fichier midi avec lilypond (frecobaldi) et je n'y arrive pas.
J'ai trouvé un tuto sur ubuntu mais ça gaze pas...
Je joint mon fichier si quelqu'un a une idée (je sais que c'est le genre de challenge que Dickie adore ) PO
J'ai trouvé un tuto sur ubuntu mais ça gaze pas...
Je joint mon fichier si quelqu'un a une idée (je sais que c'est le genre de challenge que Dickie adore ) PO
Froid de novembre, range ton membre
P. Desproges
P. Desproges
- Pierolivier
- Pithéclarinethantropus
- Messages : 7081
- Inscription : 21 oct. 2002, 08:13
- Localisation : Là où naissent les cloches et les andouilles.
Ah ben oui là forcémentDim a écrit :mais là c'est un fichier PDF que tu postes
Par contre je m’aperçois que ça n'est pas possible d'ajouter un fichier .midi quand j’essaie de l'ajouter j'obtiens le message suivant :
L’extension midi n’est pas autorisée.
PO
Froid de novembre, range ton membre
P. Desproges
P. Desproges
- Pierolivier
- Pithéclarinethantropus
- Messages : 7081
- Inscription : 21 oct. 2002, 08:13
- Localisation : Là où naissent les cloches et les andouilles.
- Dickie
- Râleur permanent
- Messages : 7467
- Inscription : 14 mai 2006, 11:42
- Localisation : A l'est du Mont St-Michel
- Contact :
Sur Ubuntu je ne sais pas mais sur MacOS oui (mais ce n'est pas très performant)
Mais puisqu'il est déjà en PDF, pourquoi tu veux importer le MIDI ?Pierolivier a écrit :Je joint mon fichier si quelqu'un a une idée (je sais que c'est le genre de challenge que Dickie adore )
catam clb (anne 2015).pdf
Il n'est pas nécessaire d'espérer pour entreprendre, ni de réussir pour persévérer - Guillaume d'Orange
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
- Dickie
- Râleur permanent
- Messages : 7467
- Inscription : 14 mai 2006, 11:42
- Localisation : A l'est du Mont St-Michel
- Contact :
Ou du moins je savais faire mais là j'ai systématiquement une erreur de syntaxe ligne 535 de l'utilitaire midi2ly
Il n'est pas nécessaire d'espérer pour entreprendre, ni de réussir pour persévérer - Guillaume d'Orange
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
- Pierolivier
- Pithéclarinethantropus
- Messages : 7081
- Inscription : 21 oct. 2002, 08:13
- Localisation : Là où naissent les cloches et les andouilles.
Ben j'ai des trucs à ajouter dedans et comme je n'ai que le pdf j'ai la flegme de tout me taper dans lilypondDickie a écrit :Sur Ubuntu je ne sais pas mais sur MacOS oui (mais ce n'est pas très performant)
Mais puisqu'il est déjà en PDF, pourquoi tu veux importer le MIDI ?Pierolivier a écrit :Je joint mon fichier si quelqu'un a une idée (je sais que c'est le genre de challenge que Dickie adore )
catam clb (anne 2015).pdf
A la base c'est un midi généré avec sibelius
Pas grave si personne n'a la réponse ça me fera travailler le clavier
PO
Froid de novembre, range ton membre
P. Desproges
P. Desproges
- Dickie
- Râleur permanent
- Messages : 7467
- Inscription : 14 mai 2006, 11:42
- Localisation : A l'est du Mont St-Michel
- Contact :
Le principe c'est de trouver l'utilitaire "midi2ly" dans ton paquet LilyPond (Sur MacOS clic droit sur l'application, Contents--> Resources --> Bin --> midi2ly) puis ouvrir le Terminal, faire glisser midi2ly sur la fenêtre du terminal puis le fichier midi, puis Enter, et avant ça marchait
Sous Unix le principe est le même, mais je ne sais pas ce qui vous sert de console (=Terminal sur Mac)
Et chez moi ça ne marche plus, il y a des erreurs de syntaxe
Si besoin je passe l'utilitaire si un bon en programmation sait lire ça
Sous Unix le principe est le même, mais je ne sais pas ce qui vous sert de console (=Terminal sur Mac)
Et chez moi ça ne marche plus, il y a des erreurs de syntaxe
Si besoin je passe l'utilitaire si un bon en programmation sait lire ça
Code : Tout sélectionner
#!/usr/bin/env python
#
# midi2ly.py -- LilyPond midi import script
# This file is part of LilyPond, the GNU music typesetter.
#
# Copyright (C) 1998--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
# Jan Nieuwenhuizen <janneke@gnu.org>
#
# LilyPond is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# LilyPond is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
'''
TODO:
'''
import os
import sys
"""
This generic code used for all python scripts.
The quotes are to ensure that the source .py file can still be
run as a python script, but does not include any sys.path handling.
Otherwise, the lilypond-book calls inside the build
might modify installed .pyc files.
"""
for d in ['/usr/share/lilypond/2.18.2',
'/usr/lib/lilypond/2.18.2']:
sys.path.insert (0, os.path.join (d, 'python'))
# dynamic relocation, for GUB binaries.
bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
for p in ['share', 'lib']:
datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
sys.path.insert (0, datadir)
"""
"""
import midi
import lilylib as ly
global _;_=ly._
################################################################
## CONSTANTS
LINE_BELL = 60
scale_steps = [0, 2, 4, 5, 7, 9, 11]
global_options = None
clocks_per_1 = 1536
clocks_per_4 = 0
time = None
reference_note = 0
start_quant_clocks = 0
duration_quant_clocks = 0
allowed_tuplet_clocks = []
bar_max = 0
################################################################
program_name = sys.argv[0]
program_version = '2.18.2'
authors = ('Jan Nieuwenhuizen <janneke@gnu.org>',
'Han-Wen Nienhuys <hanwen@xs4all.nl>')
errorport = sys.stderr
def identify ():
sys.stdout.write ('%s (GNU LilyPond) %s\n' % (program_name, program_version))
def warranty ():
identify ()
ly.encoded_write (sys.stdout, '''
%s
%s
%s
%s
''' % ( _ ('Copyright (c) %s by') % '1998--2012',
'\n '.join (authors),
_ ('Distributed under terms of the GNU General Public License.'),
_ ('It comes with NO WARRANTY.')))
def progress (s):
ly.encoded_write (errorport, s + '\n')
def warning (s):
progress (_ ("warning: ") + s)
def error (s):
progress (_ ("error: ") + s)
raise Exception (_ ("Exiting... "))
def debug (s):
if global_options.debug:
progress ("debug: " + s)
def system (cmd, ignore_error = 0):
return ly.system (cmd, ignore_error=ignore_error)
def strip_extension (f, ext):
(p, e) = os.path.splitext (f)
if e == ext:
e = ''
return p + e
class Duration:
allowed_durs = (1, 2, 4, 8, 16, 32, 64, 128)
def __init__ (self, clocks):
self.clocks = clocks
(self.dur, self.num, self.den) = self.dur_num_den (clocks)
def dur_num_den (self, clocks):
for i in range (len (allowed_tuplet_clocks)):
if clocks == allowed_tuplet_clocks[i]:
return global_options.allowed_tuplets[i]
dur = 0; num = 1; den = 1;
g = gcd (clocks, clocks_per_1)
if g:
(dur, num) = (clocks_per_1 / g, clocks / g)
if not dur in self.allowed_durs:
dur = 4; num = clocks; den = clocks_per_4
return (dur, num, den)
def dump (self):
if self.den == 1:
if self.num == 1:
s = '%d' % self.dur
elif self.num == 3 and self.dur != 1:
s = '%d.' % (self.dur / 2)
else:
s = '%d*%d' % (self.dur, self.num)
else:
s = '%d*%d/%d' % (self.dur, self.num, self.den)
global reference_note
reference_note.duration = self
return s
def compare (self, other):
return self.clocks - other.clocks
def sign (x):
if x >= 0:
return 1
else:
return -1
class Note:
names = (0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6)
alterations = (0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0)
alteration_names = ('eses', 'es', '', 'is' , 'isis')
def __init__ (self, clocks, pitch, velocity):
self.pitch = pitch
self.velocity = velocity
# hmm
self.clocks = clocks
self.duration = Duration (clocks)
(self.octave, self.notename, self.alteration) = self.o_n_a ()
def o_n_a (self):
# major scale: do-do
# minor scale: la-la (= + 5) '''
n = self.names[(self.pitch) % 12]
a = self.alterations[(self.pitch) % 12]
key = global_options.key
if not key:
key = Key (0, 0, 0)
if a and key.flats:
a = - self.alterations[(self.pitch) % 12]
n = (n - a) % 7
# By tradition, all scales now consist of a sequence
# of 7 notes each with a distinct name, from amongst
# a b c d e f g. But, minor scales have a wide
# second interval at the top - the 'leading note' is
# sharped. (Why? it just works that way! Anything
# else doesn't sound as good and isn't as flexible at
# saying things. In medieval times, scales only had 6
# notes to avoid this problem - the hexachords.)
# So, the d minor scale is d e f g a b-flat c-sharp d
# - using d-flat for the leading note would skip the
# name c and duplicate the name d. Why isn't c-sharp
# put in the key signature? Tradition. (It's also
# supposedly based on the Pythagorean theory of the
# cycle of fifths, but that really only applies to
# major scales...) Anyway, g minor is g a b-flat c d
# e-flat f-sharp g, and all the other flat minor keys
# end up with a natural leading note. And there you
# have it.
# John Sankey <bf250@freenet.carleton.ca>
#
# Let's also do a-minor: a b c d e f gis a
#
# --jcn
o = self.pitch / 12 - 4
if key.minor:
# as -> gis
if (key.sharps == 0 and key.flats == 0
and n == 5 and a == -1):
n = 4; a = 1
# des -> cis
elif key.flats == 1 and n == 1 and a == -1:
n = 0; a = 1
# ges -> fis
elif key.flats == 2 and n == 4 and a == -1:
n = 3; a = 1
# g -> fisis
elif key.sharps == 5 and n == 4 and a == 0:
n = 3; a = 2
# d -> cisis
elif key.sharps == 6 and n == 1 and a == 0:
n = 0; a = 2
# a -> gisis
elif key.sharps == 7 and n == 5 and a == 0:
n = 4; a = 2
# b -> ces
if key.flats >= 6 and n == 6 and a == 0:
n = 0; a = -1; o = o + 1
# e -> fes
if key.flats >= 7 and n == 2 and a == 0:
n = 3; a = -1
# f -> eis
if key.sharps >= 3 and n == 3 and a == 0:
n = 2; a = 1
# c -> bis
if key.sharps >= 4 and n == 0 and a == 0:
n = 6; a = 1; o = o - 1
return (o, n, a)
def __repr__ (self):
s = chr ((self.notename + 2) % 7 + ord ('a'))
return 'Note(%s %s)' % (s, self.duration.dump ())
def dump (self, dump_dur=True):
global reference_note
s = chr ((self.notename + 2) % 7 + ord ('a'))
s = s + self.alteration_names[self.alteration + 2]
if global_options.absolute_pitches:
commas = self.octave
else:
delta = self.pitch - reference_note.pitch
commas = sign (delta) * (abs (delta) / 12)
if (((sign (delta)
* (self.notename - reference_note.notename) + 7)
% 7 >= 4)
or ((self.notename == reference_note.notename)
and (abs (delta) > 4) and (abs (delta) < 12))):
commas = commas + sign (delta)
if commas > 0:
s = s + "'" * commas
elif commas < 0:
s = s + "," * -commas
if ((dump_dur
and self.duration.compare (reference_note.duration))
or global_options.explicit_durations):
s = s + self.duration.dump ()
reference_note = self
# TODO: move space
return s + ' '
class Time:
def __init__ (self, num, den):
self.clocks = 0
self.num = num
self.den = den
def bar_clocks (self):
return clocks_per_1 * self.num / self.den
def __repr__ (self):
return 'Time(%d/%d)' % (self.num, self.den)
def dump (self):
global time
time = self
return '\n ' + '\\time %d/%d ' % (self.num, self.den) + '\n '
class Tempo:
def __init__ (self, seconds_per_1):
self.clocks = 0
self.seconds_per_1 = seconds_per_1
def __repr__ (self):
return 'Tempo(%d)' % self.bpm ()
def bpm (self):
return 4 * 60 / self.seconds_per_1
def dump (self):
return '\n ' + '\\tempo 4 = %d ' % (self.bpm ()) + '\n '
class Clef:
clefs = ('"bass_8"', 'bass', 'violin', '"violin^8"')
def __init__ (self, type):
self.type = type
def __repr__ (self):
return 'Clef(%s)' % self.clefs[self.type]
def dump (self):
return '\n \\clef %s\n ' % self.clefs[self.type]
class Key:
key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis')
key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges')
def __init__ (self, sharps, flats, minor):
self.clocks = 0
self.flats = flats
self.sharps = sharps
self.minor = minor
def dump (self):
global_options.key = self
s = ''
if self.sharps and self.flats:
pass
else:
if self.flats:
k = (ord ('cfbeadg'[self.flats % 7]) - ord ('a') - 2 -2 * self.minor + 7) % 7
else:
k = (ord ('cgdaebf'[self.sharps % 7]) - ord ('a') - 2 -2 * self.minor + 7) % 7
if not self.minor:
name = chr ((k + 2) % 7 + ord ('a'))
else:
name = chr ((k + 2) % 7 + ord ('a'))
# fis cis gis dis ais eis bis
sharps = (2, 4, 6, 1, 3, 5, 7)
# bes es as des ges ces fes
flats = (6, 4, 2, 7, 5, 3, 1)
a = 0
if self.flats:
if flats[k] <= self.flats:
a = -1
else:
if sharps[k] <= self.sharps:
a = 1
if a:
name = name + Note.alteration_names[a + 2]
s = '\\key ' + name
if self.minor:
s = s + ' \\minor'
else:
s = s + ' \\major'
return '\n\n ' + s + '\n '
class Text:
text_types = (
'SEQUENCE_NUMBER',
'TEXT_EVENT',
'COPYRIGHT_NOTICE',
'SEQUENCE_TRACK_NAME',
'INSTRUMENT_NAME',
'LYRIC',
'MARKER',
'CUE_POINT',)
def __init__ (self, type, text):
self.clocks = 0
self.type = type
self.text = text
def dump (self):
# urg, we should be sure that we're in a lyrics staff
s = ''
if self.type == midi.LYRIC:
s = '"%s"' % self.text
d = Duration (self.clocks)
if (global_options.explicit_durations
or d.compare (reference_note.duration)):
s = s + Duration (self.clocks).dump ()
s = s + ' '
elif (self.text.strip ()
and self.type == midi.SEQUENCE_TRACK_NAME
and not self.text == 'control track'
and not self.track.lyrics_p_):
text = self.text.replace ('(MIDI)', '').strip ()
if text:
s = '\n \\set Staff.instrumentName = "%(text)s"\n ' % locals ()
elif self.text.strip ():
s = '\n % [' + self.text_types[self.type] + '] ' + self.text + '\n '
return s
def __repr__ (self):
return 'Text(%d=%s)' % (self.type, self.text)
def get_voice (channel, music):
debug ('channel: ' + str (channel) + '\n')
return unthread_notes (music)
class Channel:
def __init__ (self, number):
self.number = number
self.events = []
self.music = None
def add (self, event):
self.events.append (event)
def get_voice (self):
if not self.music:
self.music = self.parse ()
return get_voice (self.number, self.music)
def parse (self):
pitches = {}
notes = []
music = []
last_lyric = 0
last_time = 0
for e in self.events:
t = e[0]
if start_quant_clocks:
t = quantise_clocks (t, start_quant_clocks)
if (e[1][0] == midi.NOTE_OFF
or (e[1][0] == midi.NOTE_ON and e[1][2] == 0)):
debug ('%d: NOTE OFF: %s' % (t, e[1][1]))
if not e[1][2]:
debug (' ...treated as OFF')
end_note (pitches, notes, t, e[1][1])
elif e[1][0] == midi.NOTE_ON:
if not pitches.has_key (e[1][1]):
debug ('%d: NOTE ON: %s' % (t, e[1][1]))
pitches[e[1][1]] = (t, e[1][2])
else:
debug ('...ignored')
# all include ALL_NOTES_OFF
elif (e[1][0] >= midi.ALL_SOUND_OFF
and e[1][0] <= midi.POLY_MODE_ON):
for i in pitches:
end_note (pitches, notes, t, i)
elif e[1][0] == midi.META_EVENT:
if e[1][1] == midi.END_OF_TRACK:
for i in pitches:
end_note (pitches, notes, t, i)
break
elif e[1][1] == midi.SET_TEMPO:
(u0, u1, u2) = map (ord, e[1][2])
us_per_4 = u2 + 256 * (u1 + 256 * u0)
seconds_per_1 = us_per_4 * 4 / 1e6
music.append ((t, Tempo (seconds_per_1)))
elif e[1][1] == midi.TIME_SIGNATURE:
(num, dur, clocks4, count32) = map (ord, e[1][2])
den = 2 ** dur
music.append ((t, Time (num, den)))
elif e[1][1] == midi.KEY_SIGNATURE:
(alterations, minor) = map (ord, e[1][2])
sharps = 0
flats = 0
if alterations < 127:
sharps = alterations
else:
flats = 256 - alterations
k = Key (sharps, flats, minor)
if not t and global_options.key:
# At t == 0, a set --key overrides us
k = global_options.key
music.append ((t, k))
# ugh, must set key while parsing
# because Note init uses key
# Better do Note.calc () at dump time?
global_options.key = k
elif (e[1][1] == midi.LYRIC
or (global_options.text_lyrics
and e[1][1] == midi.TEXT_EVENT)):
self.lyrics_p_ = True
if last_lyric:
last_lyric.clocks = t - last_time
music.append ((last_time, last_lyric))
last_time = t
last_lyric = Text (midi.LYRIC, e[1][2])
elif (e[1][1] >= midi.SEQUENCE_NUMBER
and e[1][1] <= midi.CUE_POINT):
text = Text (e[1][1], e[1][2])
text.track = self
music.append ((t, text))
if (text.type == midi.SEQUENCE_TRACK_NAME):
self.name = text.text
else:
if global_options.verbose:
sys.stderr.write ("SKIP: %s\n" % `e`)
else:
if global_options.verbose:
sys.stderr.write ("SKIP: %s\n" % `e`)
if last_lyric:
# last_lyric.clocks = t - last_time
# hmm
last_lyric.clocks = clocks_per_4
music.append ((last_time, last_lyric))
last_lyric = 0
i = 0
while len (notes):
if i < len (music) and notes[0][0] >= music[i][0]:
i = i + 1
else:
music.insert (i, notes[0])
del notes[0]
return music
class Track (Channel):
def __init__ (self):
Channel.__init__ (self, None)
self.name = None
self.channels = {}
self.lyrics_p_ = False
def _add (self, event):
self.events.append (event)
def add (self, event, channel=None):
if channel == None:
self._add (event)
else:
self.channels[channel] = self.channels.get (channel, Channel (channel))
self.channels[channel].add (event)
def get_voices (self):
return ([self.get_voice ()]
+ [self.channels[k].get_voice ()
for k in sorted (self.channels.keys ())])
def create_track (events):
track = Track ()
for e in events:
data = list (e[1])
if data[0] > 0x7f and data[0] < 0xf0:
channel = data[0] & 0x0f
e = (e[0], tuple ([data[0] & 0xf0] + data[1:]))
track.add (e, channel)
else:
track.add (e)
return track
def quantise_clocks (clocks, quant):
q = int (clocks / quant) * quant
if q != clocks:
for tquant in allowed_tuplet_clocks:
if int (clocks / tquant) * tquant == clocks:
return clocks
if 2 * (clocks - q) > quant:
q = q + quant
return q
def end_note (pitches, notes, t, e):
try:
(lt, vel) = pitches[e]
del pitches[e]
i = len (notes) - 1
while i > 0:
if notes[i][0] > lt:
i = i -1
else:
break
d = t - lt
if duration_quant_clocks:
d = quantise_clocks (d, duration_quant_clocks)
if not d:
d = duration_quant_clocks
notes.insert (i + 1,
(lt, Note (d, e, vel)))
except KeyError:
pass
def unthread_notes (channel):
threads = []
while channel:
thread = []
end_busy_t = 0
start_busy_t = 0
todo = []
for e in channel:
t = e[0]
if (e[1].__class__ == Note
and ((t == start_busy_t
and e[1].clocks + t == end_busy_t)
or t >= end_busy_t)):
thread.append (e)
start_busy_t = t
end_busy_t = t + e[1].clocks
elif (e[1].__class__ == Time
or e[1].__class__ == Key
or e[1].__class__ == Text
or e[1].__class__ == Tempo):
thread.append (e)
else:
todo.append (e)
threads.append (thread)
channel = todo
return threads
def gcd (a,b):
if b == 0:
return a
c = a
while c:
c = a % b
a = b
b = c
return a
def dump_skip (skip, clocks):
return skip + Duration (clocks).dump () + ' '
def dump (d):
return d.dump ()
def dump_chord (ch):
s = ''
notes = []
for i in ch:
if i.__class__ == Note:
notes.append (i)
else:
s = s + i.dump ()
if len (notes) == 1:
s = s + dump (notes[0])
elif len (notes) > 1:
global reference_note
s = s + '<'
s = s + notes[0].dump (dump_dur=False)
r = reference_note
for i in notes[1:]:
s = s + i.dump (dump_dur=False)
s = s + '>'
s = s + notes[0].duration.dump () + ' '
reference_note = r
return s
def dump_bar_line (last_bar_t, t, bar_count):
s = ''
bar_t = time.bar_clocks ()
if t - last_bar_t >= bar_t:
bar_count = bar_count + (t - last_bar_t) / bar_t
if t - last_bar_t == bar_t:
s = '\n | %% %(bar_count)d\n ' % locals ()
last_bar_t = t
else:
# urg, this will barf at meter changes
last_bar_t = last_bar_t + (t - last_bar_t) / bar_t * bar_t
return (s, last_bar_t, bar_count)
def dump_voice (thread, skip):
global reference_note, time
ref = Note (0, 4*12, 0)
if not reference_note:
reference_note = ref
else:
ref.duration = reference_note.duration
reference_note = ref
last_e = None
chs = []
ch = []
for e in thread:
if last_e and last_e[0] == e[0]:
ch.append (e[1])
else:
if ch:
chs.append ((last_e[0], ch))
ch = [e[1]]
last_e = e
if ch:
chs.append ((last_e[0], ch))
t = 0
last_t = 0
last_bar_t = 0
bar_count = 1
lines = ['']
for ch in chs:
t = ch[0]
i = lines[-1].rfind ('\n') + 1
if len (lines[-1][i:]) > LINE_BELL:
lines.append ('')
if t - last_t > 0:
d = t - last_t
if bar_max and t > time.bar_clocks () * bar_max:
d = time.bar_clocks () * bar_max - last_t
lines[-1] = lines[-1] + dump_skip (skip, d)
elif t - last_t < 0:
errorport.write ('BUG: time skew')
(s, last_bar_t, bar_count) = dump_bar_line (last_bar_t,
t, bar_count)
if bar_max and bar_count > bar_max:
break
lines[-1] = lines[-1] + s
lines[-1] = lines[-1] + dump_chord (ch[1])
clocks = 0
for i in ch[1]:
if i.clocks > clocks:
clocks = i.clocks
last_t = t + clocks
(s, last_bar_t, bar_count) = dump_bar_line (last_bar_t,
last_t, bar_count)
lines[-1] = lines[-1] + s
return '\n '.join (lines) + '\n'
def number2ascii (i):
s = ''
i += 1
while i > 0:
m = (i - 1) % 26
s = '%c' % (m + ord ('A')) + s
i = (i - m)/26
return s
def get_track_name (i):
return 'track' + number2ascii (i)
def get_channel_name (i):
return 'channel' + number2ascii (i)
def get_voice_name (i, zero_too_p=False):
if i or zero_too_p:
return 'voice' + number2ascii (i)
return ''
def lst_append (lst, x):
lst.append (x)
return lst
def get_voice_layout (average_pitch):
d = {}
for i in range (len (average_pitch)):
d[average_pitch[i]] = lst_append (d.get (average_pitch[i], []), i)
s = list (reversed (sorted (average_pitch)))
non_empty = len (filter (lambda x: x, s))
names = ['One', 'Two']
if non_empty > 2:
names = ['One', 'Three', 'Four', 'Two']
layout = map (lambda x: '', range (len (average_pitch)))
for i, n in zip (s, names):
if i:
v = d[i]
if type (v) == list:
d[i] = v[1:]
v = v[0]
layout[v] = n
return layout
def dump_track (track, n):
s = '\n'
track_name = get_track_name (n)
average_pitch = track_average_pitch (track)
voices = len (filter (lambda x: x, average_pitch[1:]))
clef = get_best_clef (average_pitch[0])
c = 0
vv = 0
for channel in track:
v = 0
channel_name = get_channel_name (c)
c += 1
for voice in channel:
voice_name = get_voice_name (v)
voice_id = track_name + channel_name + voice_name
item = voice_first_item (voice)
if item and item.__class__ == Note:
skip = 'r'
if global_options.skip:
skip = 's'
s += '%(voice_id)s = ' % locals ()
if not global_options.absolute_pitches:
s += '\\relative c '
elif item and item.__class__ == Text:
skip = '" "'
s += '%(voice_id)s = \\lyricmode ' % locals ()
else:
skip = '\\skip '
s += '%(voice_id)s = ' % locals ()
s += '{\n'
if not n and not vv and global_options.key:
s += global_options.key.dump ()
if average_pitch[vv+1] and voices > 1:
vl = get_voice_layout (average_pitch[1:])[vv]
if vl:
s += ' \\voice' + vl + '\n'
else:
if not global_options.quiet:
warning (_ ('found more than 5 voices on a staff, expect bad output'))
s += ' ' + dump_voice (voice, skip)
s += '}\n\n'
v += 1
vv += 1
s += '%(track_name)s = <<\n' % locals ()
if clef.type != 2:
s += clef.dump () + '\n'
c = 0
vv = 0
for channel in track:
v = 0
channel_name = get_channel_name (c)
c += 1
for voice in channel:
voice_context_name = get_voice_name (vv, zero_too_p=True)
voice_name = get_voice_name (v)
v += 1
vv += 1
voice_id = track_name + channel_name + voice_name
item = voice_first_item (voice)
context = 'Voice'
if item and item.__class__ == Text:
context = 'Lyrics'
s += ' \\context %(context)s = %(voice_context_name)s \\%(voice_id)s\n' % locals ()
s += '>>\n\n'
return s
def voice_first_item (voice):
for event in voice:
if (event[1].__class__ == Note
or (event[1].__class__ == Text
and event[1].type == midi.LYRIC)):
return event[1]
return None
def channel_first_item (channel):
for voice in channel:
first = voice_first_item (voice)
if first:
return first
return None
def track_first_item (track):
for channel in track:
first = channel_first_item (channel)
if first:
return first
return None
def track_average_pitch (track):
i = 0
p = [0]
v = 1
for channel in track:
for voice in channel:
c = 0
p.append (0)
for event in voice:
if event[1].__class__ == Note:
i += 1
c += 1
p[v] += event[1].pitch
if c:
p[0] += p[v]
p[v] = p[v] / c
v += 1
if i:
p[0] = p[0] / i
return p
def get_best_clef (average_pitch):
if average_pitch:
if average_pitch <= 3*12:
return Clef (0)
elif average_pitch <= 5*12:
return Clef (1)
elif average_pitch >= 7*12:
return Clef (3)
return Clef (2)
class Staff:
def __init__ (self, track):
self.voices = track.get_voices ()
def dump (self, i):
return dump_track (self.voices, i)
def convert_midi (in_file, out_file):
global clocks_per_1, clocks_per_4, key
global start_quant_clocks
global duration_quant_clocks
global allowed_tuplet_clocks
global time
str = open (in_file, 'rb').read ()
clocks_max = bar_max * clocks_per_1 * 2
midi_dump = midi.parse (str, clocks_max)
clocks_per_1 = midi_dump[0][1]
clocks_per_4 = clocks_per_1 / 4
time = Time (4, 4)
if global_options.start_quant:
start_quant_clocks = clocks_per_1 / global_options.start_quant
if global_options.duration_quant:
duration_quant_clocks = clocks_per_1 / global_options.duration_quant
allowed_tuplet_clocks = []
for (dur, num, den) in global_options.allowed_tuplets:
allowed_tuplet_clocks.append (clocks_per_1 / dur * num / den)
if global_options.verbose:
print 'allowed tuplet clocks:', allowed_tuplet_clocks
tracks = [create_track (t) for t in midi_dump[1]]
# urg, parse all global track events, such as Key first
# this fixes key in different voice/staff problem
for t in tracks:
t.music = t.parse ()
prev = None
staves = []
for t in tracks:
voices = t.get_voices ()
if ((t.name and prev and prev.name)
and t.name.split (':')[0] == prev.name.split (':')[0]):
# staves[-1].voices += voices
# all global track events first
staves[-1].voices = ([staves[-1].voices[0]]
+ [voices[0]]
+ staves[-1].voices[1:]
+ voices[1:])
else:
staves.append (Staff (t))
prev = t
tag = '%% Lily was here -- automatically converted by %s from %s' % ( program_name, in_file)
s = tag
s += r'''
\version "2.14.0"
'''
s += r'''
\layout {
\context {
\Voice
\remove "Note_heads_engraver"
\consists "Completion_heads_engraver"
\remove "Rest_engraver"
\consists "Completion_rest_engraver"
}
}
'''
for i in global_options.include_header:
s += '\n%% included from %(i)s\n' % locals ()
s += open (i).read ()
if s[-1] != '\n':
s += '\n'
s += '% end\n'
for i, t in enumerate (staves):
s += t.dump (i)
s += '\n\\score {\n <<\n'
control_track = False
i = 0
for i, staff in enumerate (staves):
track_name = get_track_name (i)
item = track_first_item (staff.voices)
staff_name = track_name
context = None
if not i and not item and len (staves) > 1:
control_track = track_name
continue
elif (item and item.__class__ == Note):
context = 'Staff'
if control_track:
s += ' \\context %(context)s=%(staff_name)s \\%(control_track)s\n' % locals ()
elif item and item.__class__ == Text:
context = 'Lyrics'
if context:
s += ' \\context %(context)s=%(staff_name)s \\%(track_name)s\n' % locals ()
s = s + ''' >>
\layout {}
\midi {}
}
'''
if not global_options.quiet:
progress (_ ("%s output to `%s'...") % ('LY', out_file))
if out_file == '-':
handle = sys.stdout
else:
handle = open (out_file, 'w')
handle.write (s)
handle.close ()
def get_option_parser ():
p = ly.get_option_parser (usage=_ ("%s [OPTION]... FILE") % 'midi2ly',
description=_ ("Convert %s to LilyPond input.\n") % 'MIDI',
add_help_option=False)
p.add_option ('-a', '--absolute-pitches',
action='store_true',
help=_ ('print absolute pitches'))
p.add_option ('-d', '--duration-quant',
metavar=_ ('DUR'),
help=_ ('quantise note durations on DUR'))
p.add_option ('-D', '--debug',
action='store_true',
help=_ ('debug printing'))
p.add_option ('-e', '--explicit-durations',
action='store_true',
help=_ ('print explicit durations'))
p.add_option('-h', '--help',
action='help',
help=_ ('show this help and exit'))
p.add_option('-i', '--include-header',
help=_ ('prepend FILE to output'),
action='append',
default=[],
metavar=_ ('FILE'))
p.add_option('-k', '--key', help=_ ('set key: ALT=+sharps|-flats; MINOR=1'),
metavar=_ ('ALT[:MINOR]'),
default=None),
p.add_option ('-o', '--output', help=_ ('write output to FILE'),
metavar=_ ('FILE'),
action='store')
p.add_option ('-p', '--preview', help=_ ('preview of first 4 bars'),
action='store_true')
p.add_option ('-q', '--quiet',
action="store_true",
help=_ ("suppress progress messages and warnings about excess voices"))
p.add_option ('-s', '--start-quant',help= _ ('quantise note starts on DUR'),
metavar=_ ('DUR'))
p.add_option ('-S', '--skip',
action = "store_true",
help =_ ("use s instead of r for rests"))
p.add_option ('-t', '--allow-tuplet',
metavar=_ ('DUR*NUM/DEN'),
action = 'append',
dest='allowed_tuplets',
help=_ ('allow tuplet durations DUR*NUM/DEN'),
default=[])
p.add_option ('-V', '--verbose', help=_ ('be verbose'),
action='store_true')
p.version = 'midi2ly (LilyPond) 2.18.2'
p.add_option ('--version',
action='version',
help=_ ('show version number and exit'))
p.add_option ('-w', '--warranty', help=_ ('show warranty and copyright'),
action='store_true',)
p.add_option ('-x', '--text-lyrics', help=_ ('treat every text as a lyric'),
action='store_true')
p.add_option_group (ly.display_encode (_ ('Examples')),
description = r'''
$ midi2ly --key=-2:1 --duration-quant=32 --allow-tuplet=4*2/3 --allow-tuplet=2*4/3 foo.midi
''')
p.add_option_group ('',
description=(
_ ('Report bugs via %s')
% 'http://post.gmane.org/post.php'
'?group=gmane.comp.gnu.lilypond.bugs') + '\n')
return p
def do_options ():
opt_parser = get_option_parser ()
(options, args) = opt_parser.parse_args ()
if options.warranty:
warranty ()
sys.exit (0)
if not args or args[0] == '-':
opt_parser.print_help ()
ly.stderr_write ('\n%s: %s %s\n' % (program_name, _ ('error: '),
_ ('no files specified on command line.')))
sys.exit (2)
if options.duration_quant:
options.duration_quant = int (options.duration_quant)
if options.key:
(alterations, minor) = map (int, (options.key + ':0').split (':'))[0:2]
sharps = 0
flats = 0
if alterations >= 0:
sharps = alterations
else:
flats = - alterations
options.key = Key (sharps, flats, minor)
if options.start_quant:
options.start_quant = int (options.start_quant)
global bar_max
if options.preview:
bar_max = 4
options.allowed_tuplets = [map (int, a.replace ('/','*').split ('*'))
for a in options.allowed_tuplets]
if options.verbose:
sys.stderr.write ('Allowed tuplets: %s\n' % `options.allowed_tuplets`)
global global_options
global_options = options
return args
def main ():
files = do_options ()
exts = ['.midi', '.mid', '.MID']
for f in files:
g = f
for e in exts:
g = strip_extension (g, e)
if not os.path.exists (f):
for e in exts:
n = g + e
if os.path.exists (n):
f = n
break
if not global_options.output:
outdir = '.'
outbase = os.path.basename (g)
o = outbase + '-midi.ly'
elif (global_options.output[-1] == os.sep
or os.path.isdir (global_options.output)):
outdir = global_options.output
outbase = os.path.basename (g)
o = os.path.join (outdir, outbase + '-midi.ly')
else:
o = global_options.output
(outdir, outbase) = os.path.split (o)
if outdir and outdir != '.' and not os.path.exists (outdir):
os.mkdir (outdir, 0777)
convert_midi (f, o)
if __name__ == '__main__':
main ()
Il n'est pas nécessaire d'espérer pour entreprendre, ni de réussir pour persévérer - Guillaume d'Orange
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
- ceciledesb
- Cowboy
- Messages : 844
- Inscription : 21 août 2015, 13:45
- Localisation : Suisse (Lausanne)
tu peux pas faire un tiff import à partir de ton pdf ? je fais ça sous Finale
Selmer Récital Sib / La - BD4 - Steuer Exclusive 3.5 - Ligaphone C.L.A.S Or
Pour retrouver mon post de présentation c'est ici
"Jouer juste c'est jouer faux ensemble."
Pour retrouver mon post de présentation c'est ici
"Jouer juste c'est jouer faux ensemble."
- Dickie
- Râleur permanent
- Messages : 7467
- Inscription : 14 mai 2006, 11:42
- Localisation : A l'est du Mont St-Michel
- Contact :
On ne parle pas de Finale dans un fil consacré à LilyPond si on ne veut pas se faire exclure 10 jours
Il n'est pas nécessaire d'espérer pour entreprendre, ni de réussir pour persévérer - Guillaume d'Orange
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
À force de rater on finit par réussir - Les Shadoks
Association "En Coulisses"
Clarbasse, RC Prestige, clar alto, clar métal, clar mib
- ceciledesb
- Cowboy
- Messages : 844
- Inscription : 21 août 2015, 13:45
- Localisation : Suisse (Lausanne)
ok je sors de ce fil, visiblement pas fait pour moi !!
Selmer Récital Sib / La - BD4 - Steuer Exclusive 3.5 - Ligaphone C.L.A.S Or
Pour retrouver mon post de présentation c'est ici
"Jouer juste c'est jouer faux ensemble."
Pour retrouver mon post de présentation c'est ici
"Jouer juste c'est jouer faux ensemble."
la conversion fonctionne, par contre les rendu n'est pas jojo, mais on peut passer des paramètre de quantification je crois.
je regarderai à quoi ressemble le fichier midi.
je regarderai à quoi ressemble le fichier midi.
- Pièces jointes
-
- cat.ly
- (4.16 Kio) Téléchargé 326 fois
L'ingénieur Barnier est formel, le projecteur de particules à double polarisation chromatique entrera en résonnance avec le palpeur de mirette si vous avez le malheur de le laisser branché. Il en résultera la destruction de votre beau câbleur tout neuf.
- Pierolivier
- Pithéclarinethantropus
- Messages : 7081
- Inscription : 21 oct. 2002, 08:13
- Localisation : Là où naissent les cloches et les andouilles.
en fait exactement comme c'est écrit dans la doc :
Code : Tout sélectionner
midi2ly --output=cat Téléchargements/cat\ clb\ midi.mid
L'ingénieur Barnier est formel, le projecteur de particules à double polarisation chromatique entrera en résonnance avec le palpeur de mirette si vous avez le malheur de le laisser branché. Il en résultera la destruction de votre beau câbleur tout neuf.
Effectivement il faut trifouiller les paramètres de quantification pour que le résultat soit un peu plus propre, quoi que normalement si c'est un midi généré par un éditeur de partoches ça devrait être propre (notez l'emploi du conditionnel ...)
Personnellement je trouve que la plupart du temps je vais plus vite à saisir directos qu'à corriger les conneries.
Je jetterai un oeil à ton midi po, quand j'ai un moment, voir si y'a moyen de sortir un truc propre d'entrée de jeu.
Dickie, tes problèmes d'éxécution de midi2ly semblent dus à un conflit de version de python (midi2ly est écrit en python, mais probablement pas la version qui est installée sur ton ordi...).
E.
Personnellement je trouve que la plupart du temps je vais plus vite à saisir directos qu'à corriger les conneries.
Je jetterai un oeil à ton midi po, quand j'ai un moment, voir si y'a moyen de sortir un truc propre d'entrée de jeu.
Dickie, tes problèmes d'éxécution de midi2ly semblent dus à un conflit de version de python (midi2ly est écrit en python, mais probablement pas la version qui est installée sur ton ordi...).
E.
« Finalement, j’ai rencontré une brouette, et j’ai pensé qu’elle me prêterait une oreille attentive. » Lewis Carroll