Open jgarte opened 1 year ago
A third implementation is to use the abjad library to render the twelve-tone row.
I think this is our best option to easily support features I have mentioned here and in other issues #31 #29 #30 #32 .
Using abjad will make it very easy to generate a twelve-tone row:
>>> import abjad
>>> numbers = [1, 11, 9, 3, 6, 7, 5, 4, 10, 2, 8, 0]
>>> row = abjad.TwelveToneRow(numbers)
>>> row.as_midi(row, "row.midi")
>>> print(row)
PC<1, 11, 9, 3, 6, 7, 5, 4, 10, 2, 8, 0>
>>> # row is an object with methods
>>> row.
row.count( row.index( row.items row.retrograde( row.to_pitches( row.voice_vertically(
row.from_selection( row.invert( row.multiply( row.rotate( row.transpose(
row.has_duplicates( row.item_class row.permute( row.to_pitch_classes( row.voice_horizontally(
>>> row.to_pitch_classes()
TwelveToneRow([1, 11, 9, 3, 6, 7, 5, 4, 10, 2, 8, 0])
>>> abjad.persist.as_midi(row, "row.midi")
('row.midi', 0.007839679718017578, 9.847418308258057, True)
>>> abjad.persist.as_png(row, "row.png")
(('row.png',), 0.008437156677246094, 2.8052899837493896, True)
>>> abjad.persist.as_ly(row, "row.ly")
('row.ly', 0.008110284805297852)
abjad uses lilypond to produce the midi file. We would be able to drop numpy and miditime as dependencies of python-twelve-tone if we use abjad.
abjad is also smaller as a library than numpy but we'll be getting a lot more use out of it than using numpy and as shown in these examples..
%! abjad.LilyPondFile._get_format_pieces()
\version "2.24.1"
%! abjad.LilyPondFile._get_format_pieces()
\language "english"
\layout {
\accidentalStyle forget
indent = 0
\context {
\Score
\override BarLine.transparent = ##t
\override BarNumber.stencil = ##f
\override Beam.stencil = ##f
\override Flag.stencil = ##f
\override Stem.stencil = ##f
\override TimeSignature.stencil = ##f
proportionalNotationDuration = #(ly:make-moment 1 12)
}
}
\paper {
markup-system-spacing.padding = 8
system-system-spacing.padding = 10
top-markup-spacing.padding = 4
}
\new Score
<<
\new Staff
{
\new Voice
{
cs'8
b'8
a'8
ef'8
fs'8
g'8
f'8
e'8
bf'8
d'8
af'8
c'8
%! SCORE_1
\bar "|."
\override Score.BarLine.transparent = ##f
}
}
>>
With the below png output we could add a feature to render the musical score fragment of the twelve-tone row in the terminal with terminal-img, for example.
from image import DrawImage
# feeding it the png output from abjad
image = DrawImage("row.png")
The score fragment output can be easily styled to not produce the footer.
@accraze Would you like me to draft a PR using abjad/lilypond to update the MIDI functionality mentioned in #31?
I can close #29 and #32 as well in this PR.
I would not be implementing the row score image terminal rendering mentioned above in this PR but I would be happy to do that in a near future PR.
Hi,
What do you think if we were to re-implement a twelve tone matrix without needing to use numpy.zeros?
For example we could generate the 12X12 matrix like this:
We can then proceed to implement the
compose
function in terms of mutating the abovematrix
list variable to produce a matrix with the canonical row forms:P
,R
,I
, andRI
.One possible algorithm:
We can loosely implement the steps as described in this instructable:
https://www.instructables.com/Create-a-Twelve-Tone-melody-with-a-Twelve-Tone-Mat/
List[int]
variables created in steps 1 and 2 to mutate/compute the rest of the 12 X 12List[List[int]]
.Another alternative could be to outsource the matrix generation logic to the music21 library:
https://web.mit.edu/music21/doc/moduleReference/moduleSerial.html?highlight=row#music21.serial.ToneRow.row
Using music21 would be an implementation detail of
twelve-tone
.The cool thing that might arise from using music21 is that we could piggyback on its features to add/invent CLI flags for
twelve-tone
such as--historical
that let's the user ask for a historical tone row, which is kind of cute:twelve-tone using music21's
getHistoricalRowByName
methodor with
--verbose