HiveBrain v1.2.0
Get Started
← Back to all entries
patternModerate

From sounds (Hz and seconds) to musical theory

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
musicaltheorysecondssoundsandfrom

Problem

The following procedures are an attempt to connect some physical aspects of the sound (frequency and duration) to traditional music theory.

Each procedure is accompanied by one or more examples.

The names of the procedures are in Italian, but thanks to the examples should be understandable to those who have a basic knowledge of music.

`to accordoDaListaAltezze :lista_altezze
localmake "lista_note map [daAltezzaANota ?] :lista_altezze
OP accordoDaListaNote :lista_note
; es. accordoDaListaAltezze [do4 sol5 mi3 la4] -> [la do mi sol]
; es. accordoDaListaAltezze [dob4 sol#5 mi3 labb4] -> [labb dob mi sol#]
end

to accordoDaListaNote :lista_note
localmake "note remdup :lista_note
if (count :note) [la do mi sol]
end

to accordoDelGradoDelModoNote :grado :num_note :modo_note
localmake "modo_base_note daModoAModoBase :modo_note
if or (:num_note 7) [OP [il numero di note deve essere compreso tra 3 e 7]]
localmake "fondamentale item :grado :modo_base_note
localmake "seq prendi :num_note sequenzaPerGenerareAccordi
OP map [succCircolareEnnesimo ? :fondamentale :modo_base_note] :seq
; es. accordoDelGradoDelModoNote 2 5 [sib do re mib fa sol la sib]
; es. accordoDelGradoDelModoNote 5 4 (daModoAModoNomi "do modoMaggioreAscendente)
; es. accordoDelGradoDelModoNote 2 3 (daModoAModoNomi "do modoMaggioreDiscendente)
; es. accordoDelGradoDelModoNote 5 4 (daModoAModoNomi "sib modoMaggioreAscendente)
end

to accordoListaAltezze? :lista_altezze
localmake "lista_note map [daAltezzaANota ?] :lista_altezze
OP accordoListaNote? :lista_note
; es. accordoListaAltezze? [do4 sol5 mi3 la4] -> true
end

to accordoListaNote? :lista_note
localmake "note remdup :lista_note
if (count :note) true
end

to aDistanzaDiTerzaDa? :nota1 :nota2
localmake "nota_base_1 daNotaANotaBase :nota1
localmake "nota_base_2 daNotaANotaBase :nota2
OP or ((succCircolareEnnesimo 2 :nota_base_1 nomiNoteBase) = :nota_base_2) ~
((predCircolareEnnesimo 2 :no

Solution

The examples you included with nearly every procedure are very helpful. Nevertheless, this is a large library of about 100 procedures, which makes it hard to learn. Some simplifying strategies include:

  • Writing a synopsis or demo. A couple of interesting use cases, written as comments or unit tests, would help to give an overview of the goals of the library and how everything fits together.



-
Organizing the procedures by theme, and making an index. I see at least the following categories:

  • Generic helper functions (e.g. logBase, concatena, posizione, prendi, prendiSottostringa, predCircolare, …)



  • Note naming (e.g. alterazioneDaSpostamentoInSemitoni, altezzaPrecedente, altezzeDo0Si8, nomiNoteBase, nomiNoteConDiesis, doNotaANoteBase, …)



  • Intervals (e.g. daInteroAToniESemitoni, distanzaInSemitoniDaDo0, aDistanzaDiTerzaDa?, terzaAscendente?, spostamentoAssolutoInSemitoni, …)



  • Modes (e.g. baseModo, gradiModo, modoMaggioreAscendente, rappresentazioneTradizionaleDelModo, …)



  • Chords (e.g. accordoDaListaAltezze, accordoDaListaNote, notaDellAccordo?, noteDellAccordo?, promuoviCandidate, sequenzaPerGenerareAccordi, …)



  • Standard frequencies (diapason, do3, do5, la4, la#4, sib3, frequenzeDo0Si8)



  • Frequencies and scales (daModoAScalaAltezze, daScalaAltezzeAModoNote, semitoni, scala, scala2, scala4, scalaMaggioreLa4La5)



  • Audio (suonaFrequenze, suonaFrequenzeConDurata)



  • Examples (esempio, …, esempio7)



-
Reducing special notes. I can understand the need for diapason (aliased to la4), because that is the standard frequency upon which all tuning is based. I could also understand do4 (261.626 Hz, "middle do"). But do3, do5, la#4, and sib3? Those look like clutter to me.

Along those lines, you have procedures named distanzaInSemitoniDaDo0, distanzaInSemitoniDaDo0DaAltezza, and distanzaInSemitoniDelLa4DaDo0. Why isn't there just a single procedure distanzaInSemitoni :altezzaDiReferenza :altezza?

-
Eliminating trivially derived procedures. For each procedure that returns a mode (modoMaggioreAscendente, modoMinoreArmonicoAscendente, modoMinoreMelodicoAscendente, …), you also have a corresponding …Discendente procedure. I would prefer shorter procedure names (such as modoMaggiore), with the understanding that it's easy to call reverse on the result if I want the descending scale.

Similarly, there is little point in defining daAltezzeAFrequenze that is just a plural version of daAltezzaAFrequenza. You only need to offer one or the other. Bloating the library's interface for a little bit of convenience isn't worth it.

-
Eliminating redundancy and applying consistent naming. Some of your procedures are named according to the scheme daCosaXACosaY; others are just CosaYDaCosaX. One such redundant pair is daAltezzaAFrequenza and frequenzaDellAltezza — they appear to be independently implemented ways to achieve the same result.

By the way, daAltezzaAFrequenza is broken: - distanzaInSemitoniDelLa4DaDo0Da should be - distanzaInSemitoniDelLa4DaDo0.

I am also puzzled by the pair daAltezzaANomeNota and daAltezzaANota. The comments suggest that they behave identically.

  • Marking helper functions as such. Some functions, such as prendiSottostringa, altezzaPrecedenteScomposta, and daInteroAToniESemitoni, don't appear to be part of your library's interface. You could use some naming convention to indicate that these are "private" procedures.



I'm a bit confused by what exactly you consider a "nota". In daNotaANotaBase, for example, it's clear that "nota" means a note name including any accidental (♮, ♯, ♭, , ), whereas "nota base" refers to the name with accidentals stripped off. On the other hand, why does the procedure altezzaPrecedente :nota :alterazione :ottava :spostamento_in_semitoni accept an :alterazione parameter separately from the :nota?

Despite the criticisms above, the functionality does seem reasonably clear for the most part, thanks to the long explicit names for procedures and parameters, along with the examples accompanying each procedure.

Context

StackExchange Code Review Q#84346, answer score: 11

Revisions (0)

No revisions yet.