Во что я только что играл? Перевести гитарные аппликации в аккорды

22

Связанный: Музыка: что в этом аккорде? , Заметки к табулатуре , Создание гитарных вкладок? , Переведите пары чисел в гитарные ноты

Учитывая гитару, выведите аккорд, который он представляет. Вы можете использовать стандартный ввод и вывод или написать функцию, которая возвращает строку.

Входные отпечатки будут классифицироваться как один из следующих аккордов, который будет выражаться следующим образом (если корневая нота была C):

  • главная триада: C
  • второстепенная триада: Cm
  • (доминирующий) седьмой: C7
  • младший седьмой: Cm7

Аккорд может быть перевернут, поэтому нельзя полагаться на низшую ноту, являющуюся корнем. Вы также не можете полагаться на то, что это легкая или обычная аппликатура в реальном мире. В более общем случае выходные данные вашей программы должны игнорировать октавы высот и обрабатывать все высотные отметки, которые соответствуют одной и той же музыкальной ноте (т.е. A), как равные.

Это , поэтому выигрывает самый короткий код в байтах.

Формат ввода

Входные данные представляют собой последовательность из 6 значений, которые указывают для каждой струны 6-струнной гитары в стандартной настройке (EADGBE), на которой будет раздражаться эта строка. Это также может указывать на то, что строка не воспроизводится вообще. «Нулевой» лад также известен как открытая позиция, и отсюда начинаются числа ладов. Предположим, что у гитары 21 позиция ладов, так что самая высокая позиция ладов - номер 20.

Например, ввод X 3 2 0 1 0означает размещение пальцев в следующих положениях в верхней части шеи гитары:

(6th) |---|---|---|---|---
      |-X-|---|---|---|---
      |---|---|---|---|---
      |---|-X-|---|---|---
      |---|---|-X-|---|---
(1st) |---|---|---|---|---

и играет на 2-й и 6-й струнах. Это соответствует этой вкладке ASCII :

e |-0-|
B |-1-|
G |-0-|
D |-2-|
A |-3-|
E |---|

У вас есть некоторая гибкость в выборе типа ввода, который вы хотите: каждая позиция раздражения может быть выражена в виде строки или числа. Гитарные струны, которые не воспроизводятся, обычно обозначаются знаком X, но вы можете выбрать другое значение часового значения, если это облегчит вам задачу (например, -1если вы используете числа). Последовательность из 6 позиций ладов может быть введена в виде любого списка, массива или типа последовательности, отдельной строки через пробел или в качестве стандартного ввода - еще раз, на ваш выбор.

Вы можете положиться на вход, соответствующий одному из 4 типов аккордов, упомянутых выше.

Пожалуйста, объясните в своем посте, какую форму ввода использует ваше решение.

Выходной формат

Вы должны либо вернуть, либо вывести на стандартный вывод строку, описывающую аккорд, для которого предназначена аппликатура. Эта строка состоит из двух частей, соединенных вместе. Вопросы капитализации. Конечный пробел разрешен.

Первая часть указывает на основную ноту , один из A, A#/ Bb, B, C, C#/ Db, D, D#/ Eb, E, F, F#/ Gb, Gили G#/ Ab. (Я использую #вместо , и bвместо того , чтобы избежать требует Unicode.) Корневые заметки , которые могут быть выражены без резких или квартиры должны быть выражены без них (никогда не выход B#, Fbили Dbb); те, которые не могут быть обозначены одним острым или плоским символом (т. е. или C#или Db, но никогда B##). Другими словами, вы должны минимизировать количество случайных (острых предметов или квартир) в имени заметки.

Вторая часть указывает тип аккорда, либо пустой для большой триады, mдля малой триады, 7для доминирующей седьмой или m7для младшей седьмой. Таким образом , в G мажоре выводится просто G, в то время как незначительные седьмой D♯ может быть выход или как D#m7или Ebm7. Больше примеров можно найти в тестовых примерах в конце.

Теория и советы

Музыкальные ноты

Хроматическая шкала имеет 12 шагов на октаву. При настройке на одинаковый темперамент каждый из этих шагов одинаково удален от своих соседей 1 . Высота тона, составляющая 12 полутонов (октава), считается одной и той же музыкальной нотой. Это означает, что мы можем рассматривать заметки как целые числа по модулю 12, от 0 до 11. Семь из них имеют буквенные имена 2 от A до G. Этого недостаточно, чтобы назвать все 12 тонов, но добавление случайных ошибок исправляет следующее: добавление ♯ ( от резкой) к ноте делает его на полтона выше, а добавление flat (плоского) делает его на полтона ниже.

Аккорды

Аккорд - это две или более нот, сыгранных вместе. Тип аккорда зависит от отношений между нотами, которые могут быть определены расстояниями между ними. Аккорд имеет корневую ноту, как упоминалось ранее. Мы будем рассматривать корневую заметку как 0 в этих примерах, но это произвольно, и все, что имеет значение в этой задаче, - это расстояние между заметками в арифметике по модулю. Для ответа всегда будет один уникальный тип аккордов: триада или седьмой аккорд . Корневая нота не всегда будет самой низкой частотой звука; выберите основную ноту так, чтобы вы могли описать аккорд как один из четырех следующих типов аккордов:

  • Мажорное трезвучие это аккорд с нотами 0 4 7.
  • Незначительная триада является хордой с примечаниями 0 3 7.
  • Доминирующий (или крупный / минор) седьмой аккорд имеет ноты 0 4 7 10.
  • У младшего (или младшего / младшего) седьмого аккорда есть ноты 0 3 7 10. 3

Гитара тюнинг

Стандартная настройка на 6-струнной гитаре начинается с E на самой нижней струне, а затем нажимает ноты с интервалами 5, 5, 5, 4, а затем на 5 полутонов, идущих вверх по струнам. Принимая самое низкое E за 0, это означает, что удар по всем струнам гитары дает вам пронумерованные высоты 0 5 10 15 19 24, которые по модулю 12 эквивалентны 0 5 10 3 7 0, или ноты E A D G B E.

Отработанные примеры

Если вы вводите 0 2 2 0 0 0, это соответствует примечаниям E B E G B E, так что только E, B и G. Они образуют аккорд Em, который можно увидеть, пронумеровав их корнем как E, что дает нам 0 3 7. (Результат будет таким же для X 2 X 0 X 0или 12 14 14 12 12 12.)

Если вы вводите 4 4 6 4 6 4, нумерация их с корнем C♯ дает 7 0 7 10 4 7, или 0 4 7 10, поэтому ответ C#7(или Db7). Если бы это было вместо этого 4 4 6 4 5 4, нумерация дала бы 7 0 7 10 3 7, или 0 3 7 10, который C#m7(или Dbm7).

Контрольные примеры

X 3 2 0 1 0  --->  C
0 2 2 0 0 0  --->  Em
X 2 X 0 X 0  --->  Em
4 4 6 4 6 4  --->  C#7  (or Db7)
4 4 6 4 5 4  --->  C#m7 (or Dbm7)
0 2 2 1 0 0  --->  E
0 0 2 2 2 0  --->  A
X X 4 3 2 2  --->  F#   (or Gb)
3 2 0 0 0 1  --->  G7
X X 0 2 1 1  --->  Dm7
3 3 5 5 5 3  --->  C
4 6 6 5 4 4  --->  G#   (or Ab)
2 2 4 4 4 5  --->  B7
0 7 5 5 5 5  --->  Am7
7 6 4 4 X X  --->  B
8 6 1 X 1 3  --->  Cm
8 8 10 10 9 8 -->  Fm
0 19 5 16 8 7 -->  Em
6 20 0 3 11 6 -->  A#   (or Bb)
X 14 9 1 16 X -->  G#m  (or Abm)
12 14 14 12 12 12 --> Em
15 14 12 12 12 15 --> G
20 X 20 20 20 20  --> Cm7
X 13 18 10 11 10  --> A#7 (or Bb7)

1 по логарифмам их частот

2 или, в solfège , такие имена, как do, re, mi . В этом вызове используйте буквенные имена.

3 Это также можно назвать мажорным шестым аккордом с другим выбором основной ноты. В этом вызове назовите его вторым седьмым именем.

Дэн Гетц
источник
3
Отличный вызов!
Луис Мендо
1
Соблазн закрыться как дурак от моего будущего вызова: D (У меня был очень похожий вызов, но ты был намного быстрее.)
flawr
Разрешены ли в конце строки конечные пробелы?
Луис Мендо
@ LuisMendo уверен; отлично.
Дан Гетц
1
@officialaimm нет, вам не нужно разбираться с другими ситуациями. Вы можете предположить, что это всегда будет один из тех 4 типов аккордов. Другими словами, ваш код может делать все, что вы хотите (включая ошибку или давать неправильный ответ), если он получает другой аккорд.
Дан Гетц

Ответы:

9

MATL , 115 114 байт

[OAXICO]+tZN~)Y@!"@t1)XH- 12\XzXJK7hm?O.]JI7hm?'m'.]J[KCX]m?'7'.]J[ICX]m?'m7'.]]'FF#GG#AA#BCC#DD#E'l2741B~QY{HX)wh

Формат ввода - [N 3 2 0 1 0]где Nуказывается неиспользуемая строка.

Выходная строка всегда использует #, а не b.

Попробуйте онлайн! Или проверьте все контрольные примеры в двух частях, чтобы избежать тайм-аута онлайн-компилятора:

объяснение

[OAXICO]            % Push [0 5 10 3 7 0]. This represents the pitch of each open
                    % string relative to the lowest string, modulo 12
+                   % Add to implicit input. May contain NaN's, for unused strings
tZN~)               % Remove NaN's
Y@!                 % Matrix of all permutations, each in a column
"                   % For each column
  @                 %   Push current column
  t1)               %   Duplicate and get first entry
  XH                %   Copy into clipboard H
  - 12\             %   Subtract. This amounts to considering that the first note
                    %   of the current permutation is the root, and computing
                    %   all intervals with respect to that
  12\               %   Modulo 12
  Xz                %   Remove zeros
  XJ                %   Copy into clipboard J
  K7hm?             %   Are all intervals 4 or 7? If so: it's a major chord
    O               %     Push 0 (will become space when converted to char)
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  I7hm?             %   Are all intervals 3 or 7? If so: it's a minor chord
    'm'             %     Push this string
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  [KCX]m?           %   Are all intervals 4, 7 or 10? If so: it's a dominant-7th
                    %   chord
    '7'             %     Push this string
    .               %     Break for loop
  ]                 %   End if
  J                 %   Push array of nonzero intervals again
  [ICX]m?           %   Are all intervals 3, 7 or 10? If so: it's a minor 7th chord
    'm7'            %     Push this string
    .               %     Break for loop
  ]                 %   End if
]                   % End for. The loop is always exited via one of the 'break'
                    % statements. When that happens, the stack contains 0, 'm',
                    % '7' or 'm7', indicating the type of chord; and clipboard H
                    % contains a number that tells the root note using the lowest 
                    % string as base (1 is F, 2 is F# etc)
'FF#GG#AA#BCC#DD#E' % Push this string. Will be split into strings of length 1 or 2
l                   % Push 1
2741B~Q             % Push [1 2 1 2 1 2 1 1 2 1 2 1] (obtained as 2741 in binary,
                    % negated, plus 1)
Y{                  % Split string using those lengths. Gives a cell array of
                    % strings: {'F', 'F#', ..., 'E'}
H                   % Push the identified root note
X)                  % Index into cell array of strings
wh                  % Swap and concatenate. Implicitly display
Луис Мендо
источник
4

Файл MS-DOS .COM (179 байт)

Файл (здесь отображается как HEX):

fc be 81 00 bf 72 01 31 db b9 06 00 51 e8 73 00
59 e2 f9 b9 0c 00 be 48 01 ad 39 c3 74 0d 40 75
f8 d1 fb 73 03 80 c7 08 e2 ec c3 31 db 88 cb 8a
87 59 01 e8 42 00 8a 87 65 01 e8 3b 00 81 c6 08
00 ac e8 33 00 ac eb 30 91 00 89 00 91 04 89 04
ff ff 00 00 6d 00 37 00 6d 37 42 41 41 47 47 46
46 45 44 44 43 43 00 23 00 23 00 23 00 00 23 00
23 00 04 09 02 07 0b 04 84 c0 74 06 b4 02 88 c2
cd 21 c3 8a 0d 47 ac 3c 20 76 fb 30 ed 3c 41 73
22 2c 30 72 0b 86 c5 b4 0a f6 e4 00 c5 ac eb ed
88 e8 00 c8 30 e4 b1 0c f6 f1 88 e1 b8 01 00 d3
e0 09 c3

Ввод осуществляется через командную строку. Неверный ввод приведет к некорректному поведению программы!

Код на ассемблере выглядит так:

.text
.code16
ComFileStart:
    cld
    mov $0x81, %si
    mov $(TuneTable-ComFileStart+0x100), %di
    xor %bx, %bx
    # 6 strings: Build the mask of played tones
    mov $6, %cx
NextStringRead:
    push %cx
    call InsertIntoMask
    pop %cx
    loop NextStringRead

    # Check all base tones...
    mov $12, %cx
TestNextTone:
    mov $0x100+ChordTable-ComFileStart, %si
TestNextChord:
    lodsw
    # Is it the chord we are searching for?
    cmp %ax, %bx
    je FoundChord 
    # Is it the end of the table?
    inc %ax
    jnz TestNextChord
    # Transpose the chord we really play
    # and go to the next tone
    # This code rotates the low 12 bits of
    # BX one bit right
    sar $1, %bx
    jnc NoToneRotated
    add $8, %bh
NoToneRotated:
    loop TestNextTone
EndOfProgram:
    ret

FoundChord:
    # Get and print the tone name
    xor %bx, %bx
    mov %cl, %bl
    mov (ToneNamesTable+0x100-1-ComFileStart)(%bx),%al
    call printChar
    mov (ToneNamesTable+0x100+12-1-ComFileStart)(%bx),%al
    call printChar
    # Get the chord name suffix and print it
    add $(ChordNamesTable-ChordTable-2),%si
    lodsb
    call printChar
    lodsb
    # Note: Under MS-DOS 0x0000 is the first word on
    # the stack so the "RET" of printChar will jump
    # to address 0x0000 which contains an "INT $0x21"
    # (end of program) instruction
    jmp printChar

ChordTable:
    # Major, Minor, Major-7, Minor-7
    .word 0x91, 0x89, 0x491, 0x489, 0xFFFF
ChordNamesTable:
    .byte 0,0,'m',0,'7',0,'m','7'
ToneNamesTable:
    .ascii "BAAGGFFEDDCC"
    .byte 0,'#',0,'#',0,'#',0,0,'#',0,'#',0
TuneTable:
    .byte 4,9,2,7,11,4

#
# Subfunction: Print character AL;
#              Do nothing if AL=0
#
printChar:
    test %al, %al
    jz noPrint
    mov $2, %ah
    mov %al, %dl
    int $0x21
noPrint:
    ret

#
# Subfunction: Get one finger position
#              and insert it into a bit mask
#              of tones being played
#
# Input:
#
#   [DS:DI] = 
#        Tuning of current string (0=C, 1=C#, ..., 11=B)
#        Actually only 2=D, 4=E, 7=G, 9=A and 11=B are used
#
#   DS:SI = Next character to read
#
#   DF = Clear
#
# Input and Output:
#
#    BX = Bit mask
#    DI = Will be incremented
#
# Destroys nearly all registers but SI and BX
#
InsertIntoMask:
    mov (%di), %cl
    inc %di
SkipSpaces:
    lodsb
    cmp $' ', %al
    jbe SkipSpaces
# Now evaluate each digit
    xor %ch, %ch
GetNextDigit:
    # Number = 10*Number+Digit
    cmp $'A', %al
    jae DigitIsX
    sub $'0', %al
    jb DigitsDone
    xchg %al, %ch
    mov $10, %ah
    mul %ah
    add %al, %ch
    lodsb
    jmp GetNextDigit
DigitsDone:
    # Add the tune of the string
    # and perform modulus 12
    mov %ch, %al
    add %cl, %al
    xor %ah, %ah
    mov $12, %cl
    div %cl
    mov %ah, %cl
    mov $1, %ax
    shl %cl, %ax
    or %ax, %bx
DigitIsX:
    ret

Тестовые случаи:

6 20 0 3 11 6 -->  A#   (or Bb)

Я уже видел двух пианистов, играющих вместе на фортепиано в четыре руки.

Этот тестовый пример - первый раз, когда я читаю о гитаристах, делающих это!

Даже с правым постукиванием вы не можете разыграть такой шнур!

Мартин Розенау
источник
Хм, может кальмар может сыграть этот аккорд? Я думаю, что это один из тех, которые я нашел при случайном поиске, так что могут быть некоторые "сложные" тестовые случаи.
Дэн Гетц
3

Рубин, 129 байт

Как и в предыдущей версии, но используется один цикл с троичным оператором для последовательности между этапом синтаксического анализа и этапом вывода. Некоторые другие незначительные изменения были необходимы, чтобы сделать эту работу.

->a{r=0
18.times{|j|j<6?a[j]&&r|=8194<<(6--~j%5+a[j]*7)%12:(r/=2)&11==3&&puts("CGDAEBF"[j%7]+?#*(j/13)+['',?m,?7,'m7'][r>>9&3])}}

Рубин, 136 байт

Функция Llamda принимает массив из 6 чисел в качестве аргумента и выводит на стандартный вывод. Неиспользуемая строка представляется ложным значением (единственными ложными значениями в ruby ​​являются nilи false.)

->a{r=0
6.times{|j|a[j]&&r|=4097<<(6--~j%5+a[j]*7)%12}
12.times{|j|r&11==3&&puts("FCGDAEB"[j%7]+?#*(j/7)+['',?m,?7,'m7'][r>>9&3]);r/=2}}

объяснение

Я использую представление 12 шагов на основе круга пятых . Это означает, что за каждой высотой звука следует высота на 7 полутонов (или на 5 полутонов ниже), что дает последовательность F C G D A E B F# C# G# D# A#. В этом есть два преимущества. Во-первых, все острые предметы появляются вместе. Другое состоит в том, что открытые струнные ноты 5-струнного баса появляются вместе: GDAEB (гитара связана, но немного более сложна, см. Ниже).

Первый цикл выполняется 6 раз. Выражение 6--~j%5(эквивалентно 6-(j+1)%5) дает значение ноты для открытых струн: E=5 A=4 D=3 G=2 B=6 E=5. К этому мы добавляем число ладов, умноженное на 7 (как видно выше, добавление одного полутона перемещает нас на 7 позиций вперед в последовательности.) Затем мы берем все это по модулю 12 и делаем растровое изображение из присутствующих нот (мы используйте, 4097<<note valueчтобы дать 2 последовательных октавы.)

Составив растровое изображение, мы готовы искать аккорд и выводить его.

Нас интересуют следующие заметки:

Note       position in      position in             Note      position in 
           semitone domain  circle of fifths                  circle of fifths 
Root       0                0                       Root      0
Minor 3rd  3                9                       Fifth     1
Major 3rd  4                4                       Sixth     3
Fifth      7                1                       Major 3rd 4
Sixth      9                3                       Minor 3rd 9
Minor 7th  10               10                      Minor 7th 10

Начав с проверки аккорда F, мы проверяем, присутствуют ли корень и пятый: биты 0 и 1 (считая от наименее значимого: биты 1 и 2). Чтобы отклонить шестой аккорд, нам также необходимо проверить, что шестой отсутствует: бит 3 (бит 8), поэтому мы проверяем это, r&&11==3и если это так, мы печатаем аккорд.

Мы игнорируем основную треть и полностью полагаемся на бит 9 (младшая треть) и бит 10 (младшая 7-я) для определения типа аккорда. Выражение r>>9&3используется для выбора правильного типа аккорда из массива.

В конце цикла, мы сдвинуть растровый вправо на один бит , r/=2чтобы проверить возможные корни аккордов в следующей последовательности: F C G D A E B F# C# G# D# A#.

Неуправляемый в тестовой программе

f=->a{                            #Accept array of 6 numbers as argument.
  r=0                             #Setup an empty bitmap.

  6.times{|j|                     #For each string
    a[j]&&                        #if the fret value is truthy (not nil or false)
    r|=4097<<(6--~j%5+a[j]*7)%12  #calculate the note value in the circle of fifths and add to the bitmap.
  }

  12.times{|j|                    #For each possible root note
    r&11==3&&                     #if root and fifth are present (bits 0 and 1) and sixth is absent (bit 3) 
    puts("FCGDAEB"[j%7]+?#*(j/7)+ #output the note name and a sharp symbol if necessary, followed by
    ['',?m,?7,'m7'][r>>9&3])      #m and/or 7 as indicate by bits 9 and 10.
    r/=2
  }
}

print 1;f[[nil,3,2,0,1,0]]       #  C
print 2;f[[0,2,2,0,0,0]]         #  Em
print 3;f[[nil,2,nil,0,nil,0]]   #  Em
print 4;f[[4,4,6,4,6,4]]         #  C#7 
print 5;f[[4,4,6,4,5,4]]         #  C#m7 
print 6;f[[0,2,2,1,0,0]]         #  E
print 7;f[[0,0,2,2,2,0]]         #  A
print 8;f[[nil,nil,4,3,2,2]]     #  F#  
print 9;f[[3,2,0,0,0,1]]         #  G7
print 10;f[[nil,nil,0,2,1,1]]    #  Dm7
print 11;f[[3,3,5,5,5,3]]        #  C
print 12;f[[4,6,6,5,4,4]]        #  G#  
print 13;f[[2,2,4,4,4,5]]        #  B7
print 14;f[[0,7,5,5,5,5]]        #  Am7
print 15;f[[7,6,4,4,nil,nil]]    #  B
print 16;f[[8,6,1,nil,1,3]]      #  Cm
print 17;f[[8,8,10,10,9,8]]      #  Fm
print 18;f[[0,19,5,16,8,7]]      #  Em
print 19;f[[6,20,0,3,11,6]]      #  A#  
print 20;f[[nil,14,9,1,16,nil]]  #  G#m 
print 21;f[[12,14,14,12,12,12]]  #  Em
print 22;f[[15,14,12,12,12,15]]  #  G
print 23;f[[20,nil,20,20,20,20]] #  Cm7
print 24;f[[nil,13,18,10,11,10]] #  A#7
Уровень реки St
источник
2

Javascript (ES6), 335 333 байта

Люблю этот вызов и PPCG SE! Это мой первый гольф - предложения приветствуются, так как я уверен, что это можно улучшить. (сбил 2 байта, так как я включил в счет f =)

Функция fпринимает массив строк, представляющих числа и «X», как f(['X','3','2','0','1','0'])и возвращает аккорд (натуральный или резкий), как E#m7. Новые строки добавлены для ясности (не включены в число байтов)

f=c=>[s=new Map([[435,''],[345,'m'],[4332,7],[3432,'m7']]),
n=[...new Set(c.map((e,i)=>e?(+e+[0,5,10,3,7,0][i])%12:-1)
.filter(e=>++e).sort((a,b)=>a>b))],d=[...n,n[0]+12].reduce(
(a,c,i)=>i?[...a,(c-n[i-1]+12)%12]:[],0).join``.repeat(2),
m=+d.match(/(34|43)(5|32)/g)[0],'E0F0F#0G0G#0A0A#0B0C0C#0D0D#'
.split(0)[n[d.indexOf(m)]]+s.get(m)][4]

Пример использования:

console.log(f(['0','2','2','0','0','0'])); // Em

Для запуска тестовых случаев:

tests=`X 3 2 0 1 0 ---> C
0 2 2 0 0 0 ---> Em
X 2 X 0 X 0 ---> Em
4 4 6 4 6 4 ---> C#7 (or Db7)
4 4 6 4 5 4 ---> C#m7 (or Dbm7)`; // and so on...

tests.split`\n`.forEach(e=>{
    console.log(`Test: ${e}
      Result: ${f(e.split(' ').slice(0,6))}`)
})

Неуправляемая версия с объяснением:

f = (c) => {
    s = new Map([
        [435,''], [345,'m'], [4332,7], [3432,'m7'] 
    ]) /* Each key in s describes the intervals (semitones)
          between consecutive notes in a chord, when it is
          reduced to a single octave, including the interval
          from highest back to lowest. The values describe
          the corresponding chord suffix. E.g. C-E-G has
          intervals C-4-E-3-G-5-C. 435=major=no suffix. */

    n = [ ...new Set(
        c.map( 
         (e,i) => e ? ( +e + [0,5,10,3,7,0][i] )%12 : -1 
         ).filter( (e) => ++e ).sort( (a,b) => a>b )
        ) ] /* take the input array, c, and transform each fret
               position into a note. remove non-notes (-1), sort
               in tone order, remove duplicates. An input of
               positions X 13 18 10 11 10 becomes notes
               (-1) 6 4 1 6 10 then 1 4 6 10. */

    d = [ ...n, n[0] + 12 ].reduce(
        (a,c,i) => i ? [ ...a, (c - n[i-1] + 12)%12 ] : [], 0
    ).join``.repeat(2)
    /* convert the note array, n, into an interval string, d,
       including the lowest note repeated above it to capture
       all intervals. Repeat it twice so that, regardless of the
       inversion played, the intervals will appear in root order
       somewhere. E.g. notes 1-4-6-10 and 13 (1+12)
       become intervals 3 2 4 3, and string for searching
       32433243 */

    m = +d.match( /(34|43)(5|32)/g )[0];
      /* m is the matched chord pattern. In this case, 4332. */

    return 'E0F0F#0G0G#0A0A#0B0C0C#0D0D#'.split(0)[
    n[ d.indexOf(m) ]
    /* get the position in the interval string where the root
       interval first occurs. this corresponds to the position
       of the chord root note in the note array, n. convert this
       number 0-12 to a note name E - D# */
    ] + s.get(m)
       /* add the suffix corresponding to the matched
       chord interval pattern */
}
Крис М
источник
1
Добро пожаловать на сайт! Я рад слышать, что вам это нравится. :) К сожалению, я не знаю JS, поэтому у меня нет никаких советов, но вы можете найти их здесь
DJMcMayhem