Scheme : récupérer des valeurs de propriété

Bonjour.

Je suis en train de me faire un série d'exercices Scheme consistant à écrire en Scheme des fonctions toutes faites de Lily (ce qui fera l'objet de quelques pages web sur mon futur blog, sans doute).

En ce moment, je souhaite écrire une fonction qui augmente de 1 degré une note.
J'ai besoin de récupérer le b de 'pitch
(ly:make-pitch a b c))
de façon à l'augmenter de 1 pour le réinjecter dans la note passée en argument.

Ma fonction débute ainsi :

ajouterundegre = #(define-music-function (parser location note)(ly:music?)
"ajoute 1 au second chiffre du pitch"
(let ((result-note (ly:music-deep-copy note))) ;copie locale de la note argument
((result-pitch (ly:music-property (first (ly:music-property result-note 'elements)) 'pitch))) ;copie locale du pitch de result-note

Comment faire pour récupérer le chiffre b du pitch, svp ?
La solution me permettrait d'étendre ce concept à bien d'autres fonctions. J'avoue ne pas avoir vu passer ce truc dans la doc : j'ai dû cligner des yeux au mauvais endroit !

Bonne soirée !

JMarc

J'ai besoin de récupérer le b de 'pitch
(ly:make-pitch a b c))
de façon à l'augmenter de 1 pour le réinjecter dans la note passée en argument.

(ly:pitch-octave result-pitch ) récupère a
(ly:pitch-notename result-pitch ) récupère b
(ly:pitch-alteration result-pitch ) récupère c
Toutes les fonctions de pitch (sauf ly:make-pitch) commence par ly:pitch

Bonne fin de semaine

Gilles

Merci pour cette réponse qui confirme ce que j'ai glané aujourd'hui dans la doc Notation... Le fait est que j'aimerais savoir où trouver ce type de renseignement... ça doit bien être qque part ! :wink:
Quand tu m'écris : "Toutes les fonctions de pitch (sauf ly:make-pitch) commence par ly:pitch", en fait, j'aimerais avoir la liste de ces fonctions de pitch, parce que c'est pas évident à inventer! :stuck_out_tongue:

Bon, ça avance quand-même ! J'en suis donc là de ma fonction :

\version "2.13"

%le pitch est une propriété appartenant au 'NoteEvent, de la forme (ly:make-pitch a b c)
%où a = n° d'octave (zéro pour c'), b = n° du degré (zéro pour le c), c = 1/2 (dièse) ou -1/2 (bémol)
%a=pitch-octave, b=pitch-notename, c=pitch-alteration

ajouteundegre = #(define-music-function
(parser location note)(ly:music?)
"augmente d'un degré une note en ajoutant 1 au pitch-notename"
(let
(
(result-note (ly:music-deep-copy note))
(p (ly:music-property result-note 'pitch))
(o (ly:pitch-octave pitch))
(n (ly:pitch-octave pitch))
(a (ly:pitch-alteration pitch))
)
(set! p (ly:make-pitch o (+ 1 n) a))
(set! (ly:music-property result-note 'pitch) p)
result-note
)
)
\score{
\ajouteundegre c4
}

J'aurais pu mettre, à la place de la ligne en gras :
(ly:music-set-property! result-note 'pitch p)
ce qui aurait donné la même chose.

Bon d'abord, je reçois un message de Lily, pas content, qui me dit :

"While evaluating arguments to ly:music-property in expression (ly:music-property result-note (quote pitch)): Unbound variable: result-note
interruption avec le code 1.

Je ne comprends pas pourquoi il trouve que ma belle variable locale result-note est unbound ?
Si ça se trouve, c'est une bête histoire de parenthèses : j'ai bcp de mal avec ces bouzins dans tous les sens !

Bonne fin de semaine à toute la troupe !

JMarc

Merci pour cette réponse qui confirme ce que j'ai glané aujourd'hui dans la doc Notation... Le fait est que j'aimerais savoir où trouver ce type de renseignement... ça doit bien être qque part ! :wink:
Quand tu m'écris : "Toutes les fonctions de pitch (sauf ly:make-pitch) commence par ly:pitch", en fait, j'aimerais avoir la liste de ces fonctions de pitch, parce que c'est pas évident à inventer! :stuck_out_tongue:

http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Scheme-functions#Scheme-functions

Pour la version 2.13 je sais pas.

%le pitch est une propriété appartenant au 'NoteEvent, de la forme (ly:make-pitch a b c)
%où a = n° d'octave (zéro pour c'), b = n° du degré (zéro pour le c), c = 1/2 (dièse) ou -1/2 (bémol)
%a=pitch-octave, b=pitch-notename, c=pitch-alteration

ajouteundegre = #(define-music-function
(parser location note)(ly:music?)
"augmente d'un degré une note en ajoutant 1 au pitch-notename"
(let
(
(result-note (ly:music-deep-copy note))
(p (ly:music-property result-note 'pitch))
(o (ly:pitch-octave pitch))
(n (ly:pitch-octave pitch))
(a (ly:pitch-alteration pitch))
)
(set! p (ly:make-pitch o (+ 1 n) a))
(set! (ly:music-property result-note 'pitch) p)
result-note
)
)
\score{
\ajouteundegre c4
}

J'aurais pu mettre, à la place de la ligne en gras :
(ly:music-set-property! result-note 'pitch p)
ce qui aurait donné la même chose.

Bon d'abord, je reçois un message de Lily, pas content, qui me dit :

"While evaluating arguments to ly:music-property in expression (ly:music-property result-note (quote pitch)): Unbound variable: result-note
interruption avec le code 1.

Je ne comprends pas pourquoi il trouve que ma belle variable locale result-note est unbound ?
Si ça se trouve, c'est une bête histoire de parenthèses : j'ai bcp de mal avec ces bouzins dans tous les sens !

Bonne fin de semaine à toute la troupe !

JMarc

Il y a 3 petites erreurs, dont 1 d'étourderie
1-
Si tu fais :
\ajouteundegre \displayMusic c4

tu obtiens :
(make-music
'EventChord
'elements
(list (make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1 1)
'pitch
(ly:make-pitch -1 0 0))))

Tu n'obtiens pas une note ( 'NoteEvent ), mais un 'EventChord. Donc l'extraction du pitch est un peu moins direct
(voir ci-dessous )

2- l'erreur d'étourderie :
Tu appelles p le (ly:music-property result-note 'pitch), puis dans les lignes suivantes tu l'appelles pitch !

3-
En scheme, dans une instruction let, chaque "variable" doivent être indépendante les unes des autres. Si tu veux utiliser le resultat d'une ligne1 dans la ligne 2, tu dois utiliser let* à la place.

Donc ça donne un truc comme ça :

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ajouteundegre = #(define-music-function (parser location note)(ly:music?)
"augmente d'un degré une note en ajoutant 1 au pitch-notename"
(let*
(
(result-chord (ly:music-deep-copy note))
(result-note (car (ly:music-property result-chord 'elements)))
(p (ly:music-property result-note 'pitch))
(o (ly:pitch-octave p))
(n (ly:pitch-octave p))
(a (ly:pitch-alteration p))
)
(set! p (ly:make-pitch o (+ 1 n) a))
(set! (ly:music-property result-note 'pitch) p)
result-note
)
)
\score{
\ajouteundegre c'4
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Bon courage.

Gilles

Quand tu m'écris : "Toutes les fonctions de pitch (sauf ly:make-pitch) commence par ly:pitch", en fait, j'aimerais avoir la liste de ces fonctions de pitch, parce que c'est pas évident à inventer!

Pour la version 2.13 je sais pas.

Houlla, ça, ça veut dire que je trouverai jamais .... :cry:

Il y a 3 petites erreurs, dont 1 d'étourderie
1-
Si tu fais :
\ajouteundegre \displayMusic c4

tu obtiens :
(make-music
'EventChord
'elements
(list (make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1 1)
'pitch
(ly:make-pitch -1 0 0))))

Tu n'obtiens pas une note ( 'NoteEvent ), mais un 'EventChord. Donc l'extraction du pitch est un peu moins direct
(voir ci-dessous )

ZE piège... je m'emmelle les pinceaux dans les niveaux... c'est le but de mes exercices...

2- l'erreur d'étourderie :
Tu appelles p le (ly:music-property result-note 'pitch), puis dans les lignes suivantes tu l'appelles pitch !

Et c'est parti pour 2 heures de flagellation avec nerf de boeuf clouté... c'est le tarif à la maison ! :stuck_out_tongue:

3-
En scheme, dans une instruction let, chaque "variable" doivent être indépendante les unes des autres. Si tu veux utiliser le resultat d'une ligne1 dans la ligne 2, tu dois utiliser let* à la place.

Ah ça aussi il va falloir que je creuse : les !, les *, et quand il n'y a rien. J'ai survolé le tuto scheme de lily, donc punition ! Nerf de boeuf + 1 heure...

Donc ça donne un truc comme ça :

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ajouteundegre = #(define-music-function (parser location note)(ly:music?)
"augmente d'un degré une note en ajoutant 1 au pitch-notename"
(let*
(
(result-chord (ly:music-deep-copy note))
(result-note (car (ly:music-property result-chord 'elements)))
(p (ly:music-property result-note 'pitch))
(o (ly:pitch-octave p))
(n (ly:pitch-octave p))
(a (ly:pitch-alteration p))
)
(set! p (ly:make-pitch o (+ 1 n) a))
(set! (ly:music-property result-note 'pitch) p)
result-note
)
)
\score{
\ajouteundegre c'4
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Bon courage.

Gilles

Champion du monde ! En plus j'ai bien tout compris ! :sunglasses:
Merci pour tout, je viens de faire un grand pas dans le monde souterrain de lilyScheme...

JMarc

Ah ça aussi il va falloir que je creuse : les !, les *, et quand il n'y a rien. J'ai survolé le tuto scheme de lily, donc punition ! Nerf de boeuf + 1 heure...

Le guide de référence se trouve ici :
http://www.gnu.org/software/guile/manual/guile.html
et en particulier le chapitre 5 :
http://www.gnu.org/software/guile/manual/guile.html#API-Reference
C'est très spartiate ( pas de tuto), c'est en anglais, mais ça a le mérite d'exister.
Pour les let et let* par exemple tu as une explication succinte ici :
http://www.gnu.org/software/guile/manual/guile.html#Local-Bindings

Champion du monde !

Euh en fait j'ai fait une erreur dans la dernière ligne. Il faut mettre, je pense, result-chord et non result-note comme resultat de la fonction. On voit ici que Lilypond a immédiatement corriger en englobant le result-note dans un 'EventChord pour que le code reste valide. ( il suffit de faire un \displayMusic \ajouteundegre c'4 pour s'en assurrer ). Pas mal fait ce programe Lilypond !
Bonne soirée.

Gilles

Euh en fait j'ai fait une erreur dans la dernière ligne.

Oups.J'ai trouvé une autre erreur d'étourderie à la ligne où n est déclaré (n (ly:pitch-notename p)) et non (n (ly:pitch-octave p)).
Du coups c'était un hasard si ça marchait avec do ...
Cette version devrait marcher avec toutes les notes.

%%%%%%%%%%%%%%%
ajouteundegre = #(define-music-function (parser location note)(ly:music?)
"augmente d'un degré une note en ajoutant 1 au pitch-notename"
(let*
(
(result-chord (ly:music-deep-copy note))
(result-note (car (ly:music-property result-chord 'elements)))
(p (ly:music-property result-note 'pitch))
(o (ly:pitch-octave p))
(n (ly:pitch-notename p))
(a (ly:pitch-alteration p))
)
(set! p (ly:make-pitch o (+ 1 n) a))
(set! (ly:music-property result-note 'pitch) p)
result-chord
)
)
\score{
\ajouteundegre c'4
}
%%%%%%%%%%%%%%%%%

Bon j'arrête pour ce soir.

Gilles