[prev in list] [next in list] [prev in thread] [next in thread] 

List:       lilypond-user
Subject:    Scheme experts, please help me improve my code
From:       Manuela <manuela-g () gmx ! at>
Date:       2016-03-27 0:10:34
Message-ID: trinity-18a3bb0e-5838-4520-bd69-684ab4d0e573-1459037434585 () 3capp-gmx-bs13
[Download RAW message or body]

[Attachment #2 (text/html)]

<html><head></head><body><div style="font-family: Verdana;font-size: 12.0px;"><div>
<div>Hi altogether,</div>

<div>some time ago I had the idea to write a kind of harmony analyzer. It works in \
the following manner: you enter some notes (<span style="font-family:courier \
new,courier,monospace;">myMusik) </span>and you get a list of chords which contain \
these notes.<br/> I had no idea of Scheme, so I studies several manuals, and Harm \
from the German Lilypond forum helped me a lot but still I am sometimes lost in \
parentheses. The code as it is now is working and I am very glad about that. But \
there is much room for improvement, and the chordNameExceptions don&#39;t work, so I \
ask for your help</div>

<div>Basically I would prefer to enter a list of chords like I do in Lilypond, such \
as c:7 c:m7 c:maj7 ... and the program should do the rest, create list etc. My scheme \
knowledge is not good enough for that.</div>

<div>Please excuse the German comments.</div>

<div>&nbsp;</div>

<div>Here is the code:</div>

<div>&nbsp;</div>

<div>
<div>Hi altogether,</div>

<div>some time ago I had the idea to write a kind of harmony analyzer. It works in \
the following manner: you enter some notes and you get a list of chords which contain \
these notes.<br/> I had no idea of Scheme, so I studies several manuals, and Harm \
from the German Lilypond forum helped me a lot but still I am sometimes lost in \
parentheses. The code as it is now is working and I am very glad about that. But \
there is much room for improvement, and the chordNameExceptions don&#39;t work, so I \
ask for your help</div>

<div>Basically I would prefer to enter a list of chords like I do in Lilypond, such \
as c:7 c:m7 c:maj7 ... and the program should do the rest, create list etc. My scheme \
knowledge is not good enough for that.</div>

<div>Please excuse the German comments.</div>

<div>Here is the code:</div>

<div>&nbsp;</div>

<div><span style="font-family:courier new,courier,monospace;">&#92;version \
&quot;2.19.37&quot;</span></div>

<div><span style="font-family:courier new,courier,monospace;">&#92;language \
&quot;deutsch&quot;</span></div>

<div><span style="font-family:courier new,courier,monospace;">myMusik= &lt; c&#39; \
e&#39; &gt;1_&quot;Input&quot;<br/> Tonleitern=&lt; c des d es e f fis ges g as a b h \
&gt;</span></div>

<div><span style="font-family:courier new,courier,monospace;">chExceptionMusic = \
{<br/> &nbsp; &lt;c es ges&gt;1-&#92;markup { &#92;super &quot;dim&quot; }<br/>
&nbsp; &lt;c e gis&gt;1-&#92;markup { &#92;super &quot;maj&quot; }<br/>
&nbsp; &lt;c e geses&gt;1-&#92;markup { &#92;super &quot;ddim&quot; }<br/>
&nbsp; &lt;c eses ges &gt;1-&#92;markup { &#92;super &quot;dddim&quot; }<br/>
&nbsp; &lt;c e g h&gt;1-&#92;markup { &#92;super &quot;maj7&quot; }<br/>
&nbsp; &lt;c es g h&gt;1-&#92;markup { &quot;m&quot; &#92;super &quot;maj7&quot; \
}<br/> &nbsp; &lt;c es ges h&gt;1-&#92;markup { &quot;m&quot; &#92;super { \
&quot;maj7&quot; &#92;flat &quot;5&quot; } }<br/> &nbsp; &lt;c e&nbsp; ges \
h&gt;1-&#92;markup { &#92;super { &quot;maj7&quot; &#92;flat &quot;5&quot; } }<br/> \
&nbsp; &lt;c es ges heses&gt;1-&#92;markup { &#92;super &quot;dim7&quot; }<br/> \
&nbsp; &lt;c e g h d&#39;&gt;1-&#92;markup { &#92;super &quot;maj9&quot; }<br/> \
&nbsp; &lt;c e g b d&#39; f a&#39; &gt;1-&#92;markup { &#92;super &quot;13&quot; \
}<br/> &nbsp; %&lt;c e g&nbsp; d&#39; &gt;1-&#92;markup { &#92;super &quot;add9&quot; \
}<br/> &nbsp; &lt;c e g b des&#39; as&#39; &gt;1-&#92;markup { &#92;super {&nbsp; \
&#92;flat &quot;9&quot;&nbsp; &#92;flat 13 } }<br/> &nbsp; &lt;c e g b d&#39; a&#39; \
&gt;1-&#92;markup { &#92;super &quot;13&quot; }<br/> &nbsp; &lt;c e g a \
d&#39;&gt;1-&#92;markup { &#92;super &quot;6(add9)&quot; }<br/> }</span></div>

<div><span style="font-family:courier new,courier,monospace;">% Convert music to list \
and prepend to existing exceptions.<br/> chExceptions = #( append<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
( sequential-music-to-chord-exceptions chExceptionMusic #t)<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ignatzekExceptions)</span></div>

<div><span style="font-family:courier new,courier,monospace;">chExceptions = #( \
append<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
( sequential-music-to-chord-exceptions chExceptionMusic #t)<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ignatzekExceptions)</span></div>

<div><span style="font-family:courier new,courier,monospace;">ChordI = &#92;chordmode \
{ &#92;germanChords<br/> &nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = \
#chExceptions c:1 }<br/> ChordII = &#92;chordmode {&nbsp; &#92;germanChords<br/>
&nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = #chExceptions c:2 }<br/>
ChordIII = &#92;chordmode { &#92;germanChords<br/>
&nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = #chExceptions c:3 }<br/>
ChordIV = &#92;chordmode { &#92;germanChords<br/>
&nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = #chExceptions c:4 }<br/>
ChordV = &#92;chordmode { &#92;germanChords<br/>
&nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = #chExceptions c:5 }<br/>
ChordVI = &#92;chordmode { &#92;germanChords<br/>
&nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = #chExceptions c:6 }<br/>
ChordVII = &#92;chordmode { &#92;germanChords<br/>
&nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = #chExceptions c:7 }<br/>
ChordVIII = &#92;chordmode { &#92;germanChords<br/>
&nbsp;&nbsp;&nbsp; &#92;set chordNameExceptions = #chExceptions c:8 }</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define MusLis \
(list<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordI<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordII<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordIII<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordIV<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordV<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordVI<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordVII<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
ChordVIII<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
))</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define (pitch-equals? \
p1 p2)<br/> &nbsp;&nbsp; (and<br/>
&nbsp;&nbsp;&nbsp; (= (ly:pitch-alteration p1) (ly:pitch-alteration p2))<br/>
&nbsp;&nbsp;&nbsp; (= (ly:pitch-notename p1) (ly:pitch-notename p2))))</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define myInput (sort \
(music-pitches myMusik) ly:pitch&lt;?) )</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define mk-pitch<br/>
&nbsp;&nbsp; ;; wir erschaffen eine Pitchliste aus der Musikliste<br/>
&nbsp;&nbsp; (lambda (ls)<br/>
&nbsp;&nbsp;&nbsp;&nbsp; (cond<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wir haben fertig, wenn Liste leer ist<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((null? ls) &#39;())</span></div>

<div><span style="font-family:courier \
new,courier,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wenn das Listenelement ein \
g&uuml;ltiger Musikausdruck ist<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; dann \
f&uuml;gen wir die sortierte Pitchliste als Listenelement hinzu<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((ly:music? (car ls))<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (cons (sort (music-pitches (car ls) ) \
ly:pitch&lt;?)<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;(cons (car l2) \
(vvv l1 (cdr l2)))<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (mk-pitch \
(cdr ls)))<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; ansonsten machen wir mit dem Rest der Liste \
weiter<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (else (mk-pitch (cdr ls)))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp; )</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define is-in?<br/>
&nbsp;&nbsp; ;; wir versuchen zu eruieren<br/>
&nbsp;&nbsp; ;; ob alle Elemente der Liste l1 in l2 enthalten sind<br/>
&nbsp;&nbsp; ;; genauer gesagt m&uuml;ssen nur notename und alteration stimmen<br/>
&nbsp;&nbsp; ;; die Oktavlage interessiert uns nicht<br/>
&nbsp;&nbsp; (lambda ( l1 l2 )<br/>
&nbsp;&nbsp;&nbsp;&nbsp; ( cond<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; zun&auml;chst pr&uuml;fen wir, ob die \
Testliste bereits ersch&ouml;pft ist<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; \
wenn ja dann ist es wahr<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((null? l1) \
#t<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wenn die Zielliste ersch&ouml;pft ist<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; ist es falsch<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((null? l2) #f<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wir &uuml;berpr&uuml;fen das erste Element \
der Testliste<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wenn es gleich dem ersten \
Element der Zielliste ist<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; dann \
k&ouml;nnen wir mit dem restlichen Teil der Testliste fortsetzen<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((pitch-equals? (car l1) (car l2))<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (is-in? (cdr l1) l2)<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;&#39;equalPitch<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; ansonsten versuchen wir es mit dem folgenden \
Element der Zielliste<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (else (is-in? l1 (cdr \
l2))<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp; )</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(begin<br/>
&nbsp; (define (ist-in? l1 l2)<br/>
&nbsp;&nbsp;&nbsp; (every (lambda (x) (-&gt;bool (member x l2 pitch-equals?))) \
l1)<br/> &nbsp;&nbsp;&nbsp; )<br/>
&nbsp; )</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define www<br/>
&nbsp;&nbsp; ;; wir wollen jetzt die Musikausdr&uuml;cke in eine Liste \
h&auml;ngen<br/> &nbsp;&nbsp; ;; l1 ist unsere Testliste<br/>
&nbsp;&nbsp; ;; l2 enth&auml;lt die Pitches<br/>
&nbsp;&nbsp; ;; l3 enth&auml;lt die Musik (in diesem Fall die Akkorde bzw. \
Akkordnamen</span></div>

<div><span style="font-family:courier new,courier,monospace;">&nbsp;&nbsp; (lambda \
(l1 l2 l3)<br/> &nbsp;&nbsp;&nbsp;&nbsp; ( cond<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wenn die Akkordliste leer ist, dann \
verabschieden wir uns<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((null? l2) \
&#39;()<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wenn die Testliste leer ist, dann ist es auch \
aus<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((null? l1) &#39;() )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wenn die Noten der Testliste im ersten Akkord \
enthalten sind,<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wird der Akkord \
hinzugef&uuml;gt<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((is-in? l1 (car l2))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (cons (car l3) (www l1 (cdr l2) (cdr \
l3)))<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; wenn die Noten von l1 nicht im ersten Akkort \
enthalten sind<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;; machen wir mit der \
restlichen Akkordliste weiter<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (else (www l1 \
(cdr l2) (cdr l3))<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp; )</span></div>

<div><span style="font-family:courier new,courier,monospace;">%% Liste der \
transponierten AKkorde<br/> %% in zwei Stufen<br/>
%% die innere Funktion durchl&auml;uft die Akkordliste<br/>
%% die &auml;u&szlig;ere die Tonleiterliste<br/>
%% das hat den Sinn, dass ich die Liste der Akkorde insgesamt transponieren will<br/>
%% und nicht jeden Akkord in alle Tonarten und dann den n&auml;chsten Akkord \
etc.</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define ( \
Akkorde-in-allen-Tonleitern Pitch Musik)<br/> &nbsp;&nbsp; (append-map<br/>
&nbsp;&nbsp;&nbsp; (lambda (p)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (map<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (lambda (music)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #{ { &#92;transpose c &#36;p \
&#36;music } #})<br/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Musik<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp;&nbsp; (event-chord-pitches Pitch)<br/>
&nbsp;&nbsp;&nbsp; )<br/>
&nbsp;&nbsp; )</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define MusikListe \
(Akkorde-in-allen-Tonleitern Tonleitern MusLis))</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define PitLis \
(mk-pitch MusikListe))</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(define Ergebnis (www \
myInput PitLis MusikListe )) % just for interest</span></div>

<div><span style="font-family:courier new,courier,monospace;">#(display (length \
Ergebnis))</span></div>

<div><span style="font-family:courier new,courier,monospace;">&#92;score {<br/>
&nbsp; &#92;new Staff<br/>
&nbsp; &lt;&lt;<br/>
&nbsp;&nbsp;&nbsp; &#92;new Voice &#36;(make-sequential-music&nbsp; (append (list \
myMusik) Ergebnis))<br/> &nbsp;&nbsp;&nbsp; &#92;new ChordNames {<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#36;(make-sequential-music Ergebnis)<br/>
&nbsp;&nbsp;&nbsp; }<br/>
&nbsp; &gt;&gt;<br/>
}</span></div>
</div>
</div></div></body></html>


["Analysator.png" (image/png)]

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic