O que eu acabei de tocar? Traduzir dedilhados de guitarra em acordes

22

Relacionados: Música: o que há nesse acorde? , Notas para tablatura , geração de abas de guitarra , Traduzir pares de números para notas de guitarra

Dado um toque de guitarra, produza o acorde que ele representa. Você pode usar entrada e saída padrão ou escrever uma função que retorne uma sequência.

Os dedilhados de entrada serão classificados como um dos seguintes acordes, a serem expressos da seguinte forma (se a nota principal for C):

  • tríade principal: C
  • tríade menor: Cm
  • (dominante) sétimo: C7
  • sétima menor: Cm7

O acorde pode estar invertido, portanto você não pode confiar na nota mais baixa como raiz. Você também não pode confiar que este é um dedilhado fácil ou comum no mundo real. De maneira mais geral, a saída do programa deve ignorar as oitavas dos arremessos e tratar todos os arremessos que correspondem à mesma nota musical (ou seja A) igual.

Isso é , então o código mais curto em bytes vence.

Formato de entrada

A entrada é uma série de 6 valores que indicam, para cada corda de um violão de 6 cordas na afinação padrão (EADGBE), na qual a guitarra será tocada. Também pode indicar que a corda não é tocada. O traste "zeroth" também é conhecido como posição aberta, e os números do traste são contados a partir daí. Suponha que o violão tenha 21 posições de traste, de modo que a posição mais alta seja o número 20.

Por exemplo, a entrada X 3 2 0 1 0significa colocar os dedos nas seguintes posições na parte superior do pescoço do violão:

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

e dedilhando da 2ª à 6ª cordas. Corresponde a esta guia ASCII :

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

Você tem alguma flexibilidade na escolha do tipo de entrada que deseja: cada posição do traste pode ser expressa como uma string ou um número. As cordas da guitarra que não são tocadas são comumente indicadas com um X, mas você pode escolher um valor de sentinela diferente se isso facilitar as coisas para você (como -1se você estivesse usando números). A série de 6 posições de traste pode ser inserida como qualquer lista, matriz ou tipo de sequência, uma única sequência separada por espaço ou como entrada padrão - mais uma vez, sua escolha.

Você pode confiar na entrada correspondente a um dos quatro tipos de acordes mencionados acima.

Por favor, explique em sua postagem que forma de entrada sua solução leva.

Formato de saída

Você deve retornar ou imprimir na saída padrão uma sequência que descreva o acorde para o qual o dedilhado se destina. Essa sequência é composta por duas partes concatenadas juntas. Problemas de capitalização. Espaço em branco à direita é permitido.

A primeira parte indica a nota raiz , um de A, A#/ Bb, B, C, C#/ Db, D, D#/ Eb, E, F, F#/ Gb, G, ou G#/ Ab. (Estou usando #, em vez de , e bem vez de , para evitar que requer Unicode.) Notas de raiz que podem ser expressos sem um sustenido ou bemol deve ser expressa sem eles (nunca de saída B#, Fbou Dbb); aqueles que não podem devem ser expressos com um único símbolo pontiagudo ou plano (ou seja , um C#ou Db, mas nunca B##). Em outras palavras, você deve minimizar o número de acidentes (objetos cortantes ou rasos) no nome da nota.

A segunda parte indica o tipo de acorde, vazio para uma tríade maior, mpara uma tríade menor, 7para a sétima dominante ou m7para a sétima menor. Portanto, um Sol maior é produzido simplesmente como G, enquanto um sétimo D menor pode ser produzido como um D#m7ou outro Ebm7. Mais exemplos podem ser encontrados nos casos de teste no final.

Teoria e dicas

Notas musicais

A escala cromática tem 12 arremessos por oitava. Quando sintonizados com o mesmo temperamento, cada um desses tons fica igualmente distante dos vizinhos 1 . Os arremessos separados por 12 semitons (uma oitava) são considerados a mesma nota musical. Isso significa que podemos tratar notas como números inteiros módulo 12, de 0 a 11. Sete delas recebem nomes de letras 2 de A a G. Isso não é suficiente para nomear todas as 12 notas, mas adicionar acidentalmente corrige isso: adicionar a ♯ ( nítida) a uma nota o torna um semitom mais alto e a adição de ♭ (plano) o torna um semitom mais baixo.

Acordes

Um acorde é de 2 ou mais notas tocadas juntas. O tipo de acorde depende das relações entre as notas, que podem ser determinadas pelas distâncias entre elas. Um acorde tem uma nota raiz, como mencionado anteriormente. Trataremos a nota raiz como 0 nesses exemplos, mas isso é arbitrário e tudo o que importa neste desafio é a distância entre as notas na aritmética do módulo. Sempre haverá um tipo de acorde exclusivo para a resposta, uma tríade ou um sétimo . A nota principal nem sempre será o tom de menor frequência; escolha a nota raiz para poder descrever o acorde como um dos quatro tipos de acordes a seguir:

  • Uma tríade principal é um acorde com as notas 0 4 7.
  • Uma tríade menor é um acorde com as notas 0 3 7.
  • Um sétimo acorde dominante (ou maior / menor) possui as notas 0 4 7 10.
  • Um sétimo acorde menor (ou menor / menor) possui as notas 0 3 7 10. 3

Afinação de guitarra

A afinação padrão em uma guitarra de 6 cordas começa com E na corda mais baixa e, em seguida, toca notas em intervalos de 5, 5, 5, 4 e 5 semitons subindo as cordas. Tomando o E mais baixo como 0, isso significa tocar todas as cordas do violão, dando-lhe notas numeradas 0 5 10 15 19 24, às quais o módulo 12 é equivalente 0 5 10 3 7 0ou as notas E A D G B E.

Exemplos trabalhados

Se sua entrada é 0 2 2 0 0 0, isso corresponde às notas E B E G B E, então apenas E, B e G. Elas formam o acorde Em, que pode ser visto numerando-as com a raiz como E, fornecendo-nos 0 3 7. (O resultado seria o mesmo para X 2 X 0 X 0, ou 12 14 14 12 12 12.)

Se sua entrada for 4 4 6 4 6 4, numerá-las com uma raiz de C♯ fornece 7 0 7 10 4 7, ou 0 4 7 10, então a resposta é C#7(ou Db7). Se fosse 4 4 6 4 5 4, a numeração daria 7 0 7 10 3 7, ou 0 3 7 10, qual é C#m7(ou Dbm7).

Casos de teste

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 pelos logaritmos de suas frequências

2 ou, em solfège , nomes como do, re, mi . Nesse desafio, use os nomes das letras.

3 Isso também pode ser chamado de sexto acorde principal, com uma escolha diferente de nota raiz. Neste desafio, chame-o pelo seu sétimo nome menor.

Dan Getz
fonte
3
Grande desafio!
Luis Mendo
1
Tentados a perto como um joguete do meu desafio futuro: D (eu tinha um desafio muito semelhante em mente, mas você estava obvously mais rápido.)
flawr
O espaço em branco à direita é permitido na string de saída?
Luis Mendo
@LuisMendo sure; isso é bom.
Dan Getz
1
@officialaimm não, você não precisa lidar com outras situações. Você pode assumir que sempre será um desses 4 tipos de acordes. Em outras palavras, seu código pode fazer o que você quiser (incluindo erro ou dar uma resposta errada) se tiver um acorde diferente.
Dan Getz

Respostas:

9

MATL , 115 114 bytes

[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

O formato de entrada é [N 3 2 0 1 0]onde Nindica a sequência não utilizada.

A string de saída sempre usa #, não b.

Experimente online! Ou verifique todos os casos de teste, em duas partes, para evitar o tempo limite do compilador online:

Explicação

[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
Luis Mendo
fonte
4

Arquivo .com do MS-DOS (179 bytes)

O arquivo (aqui exibido como 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

A entrada é dada via linha de comando. Entrada inválida levará a um comportamento inválido do programa!

O código do assembler fica assim:

.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

Casos de teste:

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

Eu já vi dois pianistas tocando juntos "quatro mãos" em um piano.

Este caso de teste é a primeira vez que li sobre guitarristas fazendo isso!

Mesmo com o toque da mão direita, você não pode tocar um cabo como este!

Martin Rosenau
fonte
Hmm, talvez uma lula possa tocar esse acorde? Eu acho que é um dos que encontrei por uma pesquisa aleatória para que possa haver alguns casos de teste "difíceis".
Dan Getz
3

Ruby, 129 bytes

Como versão anterior, mas usa um loop único, com operador ternário para sequenciar entre a etapa de análise e a etapa de saída. Algumas outras pequenas modificações foram necessárias para fazer esse trabalho.

->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])}}

Ruby, 136 bytes

A função Llamda aceita uma matriz de 6 números como argumento e gera saída para stdout. Cadeia de caracteres não utilizada é representada por um valor falso (os únicos valores falsificados em ruby ​​são nile 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}}

Explicação

Eu uso uma representação dos 12 arremessos com base no círculo dos quintos . Isso significa que cada tom é seguido pelo tom 7 semitons mais alto (ou 5 semitons mais baixo), fornecendo a sequência F C G D A E B F# C# G# D# A#. Existem 2 vantagens nisso. Uma é que todos os objetos cortantes aparecem juntos. A outra é que as notas de corda aberta do baixo de 5 cordas aparecem juntas: GDAEB (a guitarra está relacionada, mas um pouco mais complexa, veja abaixo).

O primeiro loop é executado 6 vezes. A expressão 6--~j%5(equivalente 6-(j+1)%5) dá os valores de nota para as cordas abertas: E=5 A=4 D=3 G=2 B=6 E=5. Para isso, adicionamos o número do traste multiplicado por 7 (como pode ser visto acima, adicionar um semitom nos move 7 lugares adiante na sequência.) Em seguida, pegamos a coisa toda no módulo 12 e fazemos um bitmap das notas que estão presentes (nós use 4097<<note valuepara fornecer 2 oitavas consecutivas.)

Depois de compor o bitmap, estamos prontos para pesquisar o acorde e produzi-lo.

Estamos interessados ​​nas seguintes notas:

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

Começando pela verificação do acorde F, testamos para ver se a raiz e o quinto estão presentes: bits 0 e 1 (contando desde os menos significativos: bits do 1 e do 2). Para rejeitar o sexto acorde, também precisamos verificar se o sexto está ausente: bit 3 (bit de 8). portanto, verificamos isso r&&11==3e, se sim, imprimimos o acorde.

Ignoramos o terço maior e confiamos inteiramente no bit 9 (terço menor) e no bit 10 (sétimo menor) para calcular o tipo de acorde. A expressão r>>9&3é usada para escolher o tipo de acorde correto de uma matriz.

No final do ciclo, mudamos o bitmap caminho certo bit r/=2para testar as possíveis raízes de acordes em seqüência: F C G D A E B F# C# G# D# A#.

Ungolfed in program program

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
Level River St
fonte
2

Javascript (ES6), 335 333 bytes

Adoro este desafio e PPCG SE! Este é o meu primeiro golfe - sugestões são bem-vindas, pois tenho certeza de que poderia melhorar muito. (tirei 2 bytes como eu incluíra f = na contagem)

A função fpega uma matriz de strings, representando números e 'X', como f(['X','3','2','0','1','0'])e retorna um acorde (natural ou nítido) E#m7. Novas linhas adicionadas para maior clareza (não incluídas na contagem de bytes)

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]

Exemplo de uso:

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

Para executar casos de teste:

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))}`)
})

Versão ungolfed com explicação:

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 */
}
Chris M
fonte
1
Bem vindo ao site! Fico feliz em ouvir que você goste. :) Infelizmente, eu não conheço JS, então não tenho dicas, mas você pode encontrar algumas aqui
DJMcMayhem