Skip to content

Commit bad6a66

Browse files
committed
power chords and chord parser added
1 parent 64efbc8 commit bad6a66

File tree

2 files changed

+240
-0
lines changed

2 files changed

+240
-0
lines changed

chords.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
package guitar
22

3+
import (
4+
"strconv"
5+
"strings"
6+
)
7+
8+
func ParseChord(chordTab string) []NotePositioner {
9+
notes := strings.Split(chordTab, " ")
10+
chord := []NotePositioner{}
11+
12+
for i, note := range notes {
13+
num, err := strconv.Atoi(note)
14+
if err != nil {
15+
if note != "-" {
16+
return []NotePositioner{}
17+
}
18+
continue
19+
}
20+
chord = append(chord, Note{Fret: num, String: i})
21+
}
22+
23+
return chord
24+
}
25+
326
const (
427
// A
528
// e|0
@@ -295,6 +318,95 @@ const (
295318
// A|0
296319
// E|3
297320
Gmaj7
321+
322+
// C5
323+
// e|-
324+
// B|-
325+
// G|-
326+
// D|5
327+
// A|3
328+
// E|-
329+
PowerC5
330+
// D5
331+
// e|-
332+
// B|-
333+
// G|-
334+
// D|7
335+
// A|5
336+
// E|-
337+
PowerD5
338+
// Db5
339+
// e|-
340+
// B|-
341+
// G|-
342+
// D|6
343+
// A|4
344+
// E|-
345+
PowerDb5
346+
// Eb5
347+
// e|-
348+
// B|-
349+
// G|-
350+
// D|3
351+
// A|1
352+
// E|-
353+
PowerEb5
354+
// E5
355+
// e|-
356+
// B|-
357+
// G|-
358+
// D|-
359+
// A|2
360+
// E|0
361+
PowerE5
362+
// F5
363+
// e|-
364+
// B|-
365+
// G|-
366+
// D|-
367+
// A|3
368+
// E|1
369+
PowerF5
370+
// Gb5
371+
// e|-
372+
// B|-
373+
// G|-
374+
// D|-
375+
// A|4
376+
// E|2
377+
PowerGb5
378+
// G5
379+
// e|-
380+
// B|-
381+
// G|-
382+
// D|-
383+
// A|5
384+
// E|3
385+
PowerG5
386+
// A5
387+
// e|-
388+
// B|-
389+
// G|-
390+
// D|-
391+
// A|7
392+
// E|5
393+
PowerA5
394+
// Bb5
395+
// e|-
396+
// B|-
397+
// G|-
398+
// D|3
399+
// A|1
400+
// E|-
401+
PowerBb5
402+
// B5
403+
// e|-
404+
// B|-
405+
// G|-
406+
// D|4
407+
// A|2
408+
// E|-
409+
PowerB5
298410
)
299411

300412
func GetChord(chordNum int) []NotePositioner {
@@ -601,6 +713,61 @@ func GetChord(chordNum int) []NotePositioner {
601713
Note{Fret: 0, String: 4},
602714
Note{Fret: 3, String: 5},
603715
}
716+
case PowerC5:
717+
return []NotePositioner{
718+
Note{Fret: 5, String: 3},
719+
Note{Fret: 3, String: 4},
720+
}
721+
case PowerD5:
722+
return []NotePositioner{
723+
Note{Fret: 7, String: 3},
724+
Note{Fret: 5, String: 4},
725+
}
726+
case PowerDb5:
727+
return []NotePositioner{
728+
Note{Fret: 6, String: 3},
729+
Note{Fret: 4, String: 4},
730+
}
731+
case PowerEb5:
732+
return []NotePositioner{
733+
Note{Fret: 3, String: 3},
734+
Note{Fret: 1, String: 4},
735+
}
736+
case PowerE5:
737+
return []NotePositioner{
738+
Note{Fret: 2, String: 4},
739+
Note{Fret: 0, String: 5},
740+
}
741+
case PowerF5:
742+
return []NotePositioner{
743+
Note{Fret: 3, String: 4},
744+
Note{Fret: 1, String: 5},
745+
}
746+
case PowerGb5:
747+
return []NotePositioner{
748+
Note{Fret: 4, String: 4},
749+
Note{Fret: 2, String: 5},
750+
}
751+
case PowerG5:
752+
return []NotePositioner{
753+
Note{Fret: 5, String: 4},
754+
Note{Fret: 3, String: 5},
755+
}
756+
case PowerA5:
757+
return []NotePositioner{
758+
Note{Fret: 7, String: 4},
759+
Note{Fret: 5, String: 5},
760+
}
761+
case PowerBb5:
762+
return []NotePositioner{
763+
Note{Fret: 3, String: 3},
764+
Note{Fret: 1, String: 4},
765+
}
766+
case PowerB5:
767+
return []NotePositioner{
768+
Note{Fret: 4, String: 3},
769+
Note{Fret: 2, String: 4},
770+
}
604771
default:
605772
return []NotePositioner{}
606773
}

chords_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package guitar
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestParseChord(t *testing.T) {
10+
testCases := []struct {
11+
name string
12+
chordTab string
13+
expected []NotePositioner
14+
expectError bool
15+
}{
16+
{
17+
name: "Standard A chord",
18+
chordTab: "0 2 2 2 0 -",
19+
expected: []NotePositioner{
20+
Note{Fret: 0, String: 0},
21+
Note{Fret: 2, String: 1},
22+
Note{Fret: 2, String: 2},
23+
Note{Fret: 2, String: 3},
24+
Note{Fret: 0, String: 4},
25+
},
26+
},
27+
{
28+
name: "Power chord E5",
29+
chordTab: "- - - 2 0 -",
30+
expected: []NotePositioner{
31+
Note{Fret: 2, String: 3},
32+
Note{Fret: 0, String: 4},
33+
},
34+
},
35+
{
36+
name: "Chord with skipped strings (mixed)",
37+
chordTab: "3 - 0 1 - 3",
38+
expected: []NotePositioner{
39+
Note{Fret: 3, String: 0},
40+
Note{Fret: 0, String: 2},
41+
Note{Fret: 1, String: 3},
42+
Note{Fret: 3, String: 5},
43+
},
44+
},
45+
{
46+
name: "Invalid character (letters)",
47+
chordTab: "a b c 1 2 3",
48+
expectError: true,
49+
},
50+
{
51+
name: "Empty input",
52+
chordTab: "",
53+
expectError: true,
54+
},
55+
}
56+
57+
for _, tc := range testCases {
58+
t.Run(tc.name, func(t *testing.T) {
59+
result := ParseChord(tc.chordTab)
60+
61+
if tc.expectError {
62+
assert.Empty(t, result, "Expected error but got notes")
63+
return
64+
}
65+
66+
assert.Equal(t, len(tc.expected), len(result), "Number of parsed notes mismatch")
67+
for i, note := range tc.expected {
68+
assert.Equal(t, note.FretPosition(), result[i].FretPosition(), "Fret mismatch")
69+
assert.Equal(t, note.StringPosition(), result[i].StringPosition(), "String mismatch")
70+
}
71+
})
72+
}
73+
}

0 commit comments

Comments
 (0)