guitar_pro_parser 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,17 +2,12 @@ module GuitarProParser
2
2
 
3
3
  # This class represents bars as containers of notes.
4
4
  #
5
- # == Attributes
6
- #
7
- # All attributes are read-only
8
- #
9
- # * +voices+ (hash) Voices of this bar.
10
- # Guitar Pro 5 files has :lead and :bass voices.
11
- # Guitar Pro 4 and less files has only :lead voice.
12
- #
13
- #
14
5
  class Bar
15
6
 
7
+ # Hash of voices of this bar.
8
+ # Guitar Pro 5 files has :lead and :bass voices.
9
+ # Guitar Pro 4 and less files has only :lead voice.
10
+ # Each voice is array of beats.
16
11
  attr_accessor :voices
17
12
 
18
13
  def initialize
@@ -4,7 +4,7 @@ module GuitarProParser
4
4
  #
5
5
  # == Attributes
6
6
  #
7
- # *+new_time_signature+* (hash) Info about new time signature in format
7
+ # * +new_time_signature+ (hash) Info about new time signature in format
8
8
  # { numerator: 4, denominator: 4, beam_eight_notes_by_values: [2, 2, 2, 2] }
9
9
  # or nil if doesn't present
10
10
  #
@@ -2,12 +2,49 @@ module GuitarProParser
2
2
 
3
3
  class ChordDiagram
4
4
 
5
- attr_accessor :name, :start_fret, :frets
5
+ attr_accessor :name,
6
+ :base_fret,
7
+ :frets,
8
+ :display_as,
9
+ :root,
10
+ :type
11
+
12
+ # Determines if the chord goes until the ninth, the eleventh, or the thirteenth.
13
+ attr_accessor :nine_eleven_thirteen
14
+
15
+ attr_accessor :bass,
16
+ :tonality,
17
+ :add,
18
+ :fifth_tonality,
19
+ :ninth_tonality,
20
+ :eleventh_tonality,
21
+ :barres,
22
+ :intervals,
23
+ :fingers,
24
+ :display_fingering
6
25
 
7
26
  def initialize
8
27
  @name = ''
9
- @start_fret = 0
28
+ @base_fret = 0
10
29
  @frets = []
30
+ @display_as = :sharp
31
+ @root = nil
32
+ @type = 'M'
33
+ @nine_eleven_thirteen = 0
34
+ @bass = nil
35
+ @tonality = :perfect
36
+ @add = false
37
+ @fifth_tonality = :perfect
38
+ @ninth_tonality = :perfect
39
+ @eleventh_tonality = :perfect
40
+ @barres = []
41
+ @intervals = []
42
+ @fingers = []
43
+ @display_fingering = false
44
+ end
45
+
46
+ def add_barre(fret, start_string, end_string)
47
+ @barres << { fret: fret, start_string: start_string, end_string: end_string }
11
48
  end
12
49
 
13
50
  end
@@ -1,5 +1,19 @@
1
1
  module GuitarProHelper
2
2
 
3
+ # Possible versions of Guitar Pro file
4
+ VERSIONS = { 'FICHIER GUITARE PRO v1' => 1.0,
5
+ 'FICHIER GUITARE PRO v1.01' => 1.01,
6
+ 'FICHIER GUITARE PRO v1.02' => 1.02,
7
+ 'FICHIER GUITARE PRO v1.03' => 1.03,
8
+ 'FICHIER GUITARE PRO v1.04' => 1.04,
9
+ 'FICHIER GUITAR PRO v2.20' => 2.2,
10
+ 'FICHIER GUITAR PRO v2.21' =>2.21,
11
+ 'FICHIER GUITAR PRO v3.00' => 3.0,
12
+ 'FICHIER GUITAR PRO v4.00' => 4.0,
13
+ 'FICHIER GUITAR PRO v4.06' => 4.06,
14
+ 'FICHIER GUITAR PRO L4.06' => 4.06,
15
+ 'FICHIER GUITAR PRO v5.10' => 5.1 }
16
+
3
17
  NOTES = %w(C C# D D# E F F# G G# A A# B)
4
18
  VOICES = [:lead, :bass]
5
19
  FINGERS = [:thumb, :index, :middle, :ring, :pinky]
@@ -33,10 +47,23 @@ module GuitarProHelper
33
47
 
34
48
  SLIDE_TYPES = [:no_slide, :shift_slide, :legato_slide, :slide_out_and_downwards, :slide_out_and_upwards, :slide_in_from_below, :slide_in_from_above]
35
49
  MAP_SLIDE_TYPES_GP5 = { '0'=>0, '1'=>1, '2'=>2, '4'=>3, '8'=>4, '16'=>5, '32'=>6 }
36
- MAP_SLIDE_TYPES_GP4 = { '-2'=>0, '-1'=>1, '0'=>2, '1'=>3, '2'=>4, '3'=>5, '4'=>6 }
37
-
50
+ MAP_SLIDE_TYPES_GP4 = { '-2'=>6, '-1'=>5, '0'=>0, '1'=>1, '2'=>2, '3'=>3, '4'=>4 }
51
+
38
52
  HARMONIC_TYPES = [:none, :natural, :artificial, :tapped, :pinch, :semi]
39
- TRILL_PERIODS = [4, 8, 16]
53
+ TRILL_PERIODS = { '1' => 4, '2' => 8, '3' => 16 }
54
+ CHORD_TYPES = %w(M 7 7M 6 m m7 m7M m6 sus2 sus4 7sus2 7sus4 dim aug 5)
55
+ NINE_ELEVEN_THIRTEEN = [0, 9, 11, 13]
56
+
57
+ # Strange moment here. In format specification is written:
58
+ # 0: perfect
59
+ # 1: augmented
60
+ # 2: diminished
61
+ # But actually (after tests) it seems to be:
62
+ # 0: perfect
63
+ # 1: diminished
64
+ # 2: augmented
65
+ CHORD_TONALITIES = [:perfect, :diminished, :augmented]
66
+
40
67
 
41
68
  # Macros to create boolean instance variables' getters like this:
42
69
  # attr_boolean :complete
@@ -69,9 +69,8 @@ module GuitarProParser
69
69
  def read_version
70
70
  length = @input.read_byte
71
71
  version_string = @input.read_string length
72
- # TODO: Change a way to get value from string
73
- version_string['FICHIER GUITAR PRO v'] = ''
74
- @version = version_string.to_f
72
+ # TODO: Raise exception for unsupported or wrong versions here
73
+ @version = GuitarProHelper::VERSIONS.fetch(version_string)
75
74
  @song.version = @version
76
75
 
77
76
  # Skip first 31 bytes that are reserved for version data
@@ -273,7 +272,7 @@ module GuitarProParser
273
272
  bits = @input.read_bitmask
274
273
  bits.count.times { |i| bars_settings.alternate_endings << (i+1) if bits[i] }
275
274
  else
276
- bars_settings.alternate_endings << @input.read_byte
275
+ bars_settings.alternate_endings << @input.read_byte
277
276
  end
278
277
  end
279
278
 
@@ -398,7 +397,7 @@ module GuitarProParser
398
397
  beat.rest = GuitarProHelper::REST_TYPES.fetch(@input.read_byte.to_s) if is_rest
399
398
  beat.duration = GuitarProHelper::DURATIONS.fetch(@input.read_signed_byte.to_s)
400
399
  beat.tuplet = @input.read_integer if is_tuplet
401
- read_chord_diagram(track) if has_chord_diagram
400
+ read_chord_diagram(beat, track.strings.count) if has_chord_diagram
402
401
  beat.text = @input.read_chunk if has_text
403
402
  read_beat_effects(beat) if has_effects
404
403
  read_mix_table(beat) if has_mix_table_change
@@ -439,19 +438,84 @@ module GuitarProParser
439
438
  end
440
439
  end
441
440
 
442
- def read_chord_diagram(track)
441
+ def read_chord_diagram(beat, strings_count)
443
442
  beat.chord_diagram = ChordDiagram.new
444
443
 
445
- format = @input.read_byte
446
-
447
- if format == 0 # Guitar Pro 3 format
444
+ format = @input.read_bitmask
445
+ if format[0] == false # Guitar Pro 3 format
448
446
  beat.chord_diagram.name = @input.read_chunk
449
- beat.chord_diagram.start_fret = @input.read_integer
450
- unless beat.chord_diagram.start_fret.zero?
451
- track.strings.count.times { beat.chord_diagram.frets << @input.read_integer }
447
+ beat.chord_diagram.base_fret = @input.read_integer
448
+ unless beat.chord_diagram.base_fret.zero?
449
+ strings_count.times { beat.chord_diagram.frets << @input.read_integer }
452
450
  end
453
- else # Guitar Pro 4 format
454
- @input.increment_offset(105) # TODO: Write reading logic here
451
+ else # Guitar Pro 4 and 5 format
452
+ beat.chord_diagram.display_as = @input.read_boolean ? :sharp : :flat
453
+ @input.increment_offset(3)
454
+
455
+ root = @input.read_byte
456
+ beat.chord_diagram.root = GuitarProHelper::NOTES[root] unless root == 12
457
+
458
+ beat.chord_diagram.type = GuitarProHelper::CHORD_TYPES[@input.read_byte]
459
+ beat.chord_diagram.nine_eleven_thirteen = GuitarProHelper::NINE_ELEVEN_THIRTEEN.fetch(@input.read_byte)
460
+
461
+ bass = @input.read_integer
462
+ beat.chord_diagram.bass = GuitarProHelper::NOTES[bass] if bass >= 0
463
+
464
+ beat.chord_diagram.tonality = GuitarProHelper::CHORD_TONALITIES[@input.read_integer]
465
+ beat.chord_diagram.add = @input.read_boolean
466
+
467
+ name_length = @input.read_byte
468
+ beat.chord_diagram.name = @input.read_string(name_length)
469
+ @input.increment_offset(20 - name_length) if name_length < 20
470
+
471
+ @input.increment_offset(2)
472
+ beat.chord_diagram.fifth_tonality = GuitarProHelper::CHORD_TONALITIES[@input.read_byte]
473
+ beat.chord_diagram.ninth_tonality = GuitarProHelper::CHORD_TONALITIES[@input.read_byte]
474
+ beat.chord_diagram.eleventh_tonality = GuitarProHelper::CHORD_TONALITIES[@input.read_byte]
475
+
476
+ beat.chord_diagram.base_fret = @input.read_integer
477
+
478
+ strings_count.times { beat.chord_diagram.frets << @input.read_integer }
479
+ (7 - strings_count).times { @input.skip_integer }
480
+
481
+ barres_count = @input.read_byte
482
+ barres_frets = []
483
+ barres_starts = []
484
+ barres_ends = []
485
+ 5.times { barres_frets << @input.read_byte }
486
+ 5.times { barres_starts << @input.read_byte }
487
+ 5.times { barres_ends << @input.read_byte }
488
+ barres_count.times do |i|
489
+ beat.chord_diagram.add_barre(barres_frets[i],
490
+ barres_starts[i],
491
+ barres_ends[i])
492
+ end
493
+
494
+ # TODO: I don't know why but it looks inverted
495
+ beat.chord_diagram.intervals << 1 if @input.read_byte == 0x01
496
+ beat.chord_diagram.intervals << 3 if @input.read_byte == 0x01
497
+ beat.chord_diagram.intervals << 5 if @input.read_byte == 0x01
498
+ beat.chord_diagram.intervals << 7 if @input.read_byte == 0x01
499
+ beat.chord_diagram.intervals << 9 if @input.read_byte == 0x01
500
+ beat.chord_diagram.intervals << 11 if @input.read_byte == 0x01
501
+ beat.chord_diagram.intervals << 13 if @input.read_byte == 0x01
502
+ @input.skip_byte
503
+
504
+ strings_count.times do |i|
505
+ finger_id = @input.read_signed_byte
506
+ finger = nil
507
+ if finger_id == -2
508
+ finger = :unknown
509
+ elsif finger_id == -1
510
+ finger = :no
511
+ else
512
+ finger = GuitarProHelper::FINGERS[finger_id]
513
+ end
514
+ beat.chord_diagram.fingers << finger
515
+ end
516
+ @input.increment_offset(7 - strings_count) if strings_count < 7
517
+
518
+ beat.chord_diagram.display_fingering = @input.read_boolean
455
519
  end
456
520
  end
457
521
 
@@ -622,11 +686,11 @@ module GuitarProParser
622
686
  note.fret = @input.read_byte
623
687
 
624
688
  if has_fingering
625
- left_finger = @input.read_byte
626
- right_finger = @input.read_byte
689
+ left_finger = @input.read_signed_byte
690
+ right_finger = @input.read_signed_byte
627
691
 
628
- note.add_left_hand_finger(FINGERS.fetch(left_finger)) unless left_finger == -1
629
- note.add_right_hand_finger(FINGERS.fetch(right_finger)) unless right_finger == -1
692
+ note.add_left_hand_finger(GuitarProHelper::FINGERS.fetch(left_finger)) unless left_finger == -1
693
+ note.add_right_hand_finger(GuitarProHelper::FINGERS.fetch(right_finger)) unless right_finger == -1
630
694
  end
631
695
 
632
696
  # Ignore time-independed duration data for Guitar Pro 5
@@ -688,16 +752,19 @@ module GuitarProParser
688
752
  note.add_tremolo(GuitarProHelper::TREMOLO_PICKING_SPEEDS.fetch(@input.read_byte.to_s)) if has_tremolo
689
753
 
690
754
  if has_slide
691
- value = @input.read_byte.to_s
692
- # TODO: Check if there is difference between GP4 and GP5
693
- note.slide = GuitarProHelper::SLIDE_TYPES.fetch(GuitarProHelper::MAP_SLIDE_TYPES_GP5.fetch(value))
755
+ value = @input.read_signed_byte.to_s
756
+ if @version >= 5.0
757
+ note.slide = GuitarProHelper::SLIDE_TYPES.fetch(GuitarProHelper::MAP_SLIDE_TYPES_GP5.fetch(value))
758
+ else
759
+ note.slide = GuitarProHelper::SLIDE_TYPES.fetch(GuitarProHelper::MAP_SLIDE_TYPES_GP4.fetch(value))
760
+ end
694
761
  end
695
762
 
696
763
  read_harmonic(note) if has_harmonic
697
764
 
698
765
  if has_trill
699
766
  fret = @input.read_byte
700
- period = GuitarProHelper::TRILL_PERIODS.fetch(@input.read_byte)
767
+ period = GuitarProHelper::TRILL_PERIODS.fetch(@input.read_byte.to_s)
701
768
  note.add_trill(fret, period)
702
769
  end
703
770
  end
@@ -3,69 +3,108 @@ require 'guitar_pro_parser/io/reader'
3
3
  module GuitarProParser
4
4
 
5
5
  # This class represents the content of Guitar Pro file.
6
- # It can be initialized by path to .gp[3,4,5] file. The it will automatically parse its data.
6
+ # It can be initialized by path to .gp[3,4,5] file. Then it will automatically parse its data.
7
7
  # Or it can be just instantiated with default values of the attributes.
8
8
  #
9
- # == Attributes
10
- #
11
- #
12
- # * +version+ (float) Version of Guitar Pro
13
- # * +title+ (string)
14
- # * +subtitle+ (string)
15
- # * +artist+ (string)
16
- # * +album+ (string)
17
- # * +lyricist+ (string) Author of lyrics (>= 5.0 only)
18
- # * +composer+ (string) Author of music
19
- # * +copyright+ (string)
20
- # * +transcriber+ (string) Author of tabulature
21
- # * +instructions+ (string)
22
- # * +notices+ (array) Array of notices (each notice is a string)
23
- # * +triplet_feel+ (boolean) Shuffle rhythm feel (< 5.0 only)
24
- # * +lyrics_track+ (integer) Associated track for the lyrics (>= 4.0 only)
25
- # * +lyrics+ (array) Lyrics data represented as array of hashes with 5 elements
26
- # (for lyrics lines from 1 to 5). Each line has lyrics' text
27
- # and number of bar where it starts: {text: "Some text", bar: 1}
28
- # (>= 4.0 only)
29
- # * +master_volume+ (integer) Master volume (value from 0 - 200, default is 100) (>= 5.0 only)
30
- # * +equalizer+ (array) Array of equalizer settings.
31
- # Each one is represented as number of increments of .1dB the volume for
32
- # 32Hz band is lowered
33
- # 60Hz band is lowered
34
- # 125Hz band is lowered
35
- # 250Hz band is lowered
36
- # 500Hz band is lowered
37
- # 1KHz band is lowered
38
- # 2KHz band is lowered
39
- # 4KHz band is lowered
40
- # 8KHz band is lowered
41
- # 16KHz band is lowered
42
- # overall volume is lowered (gain)
43
- # * +page_setup+ (object) Object of PageSetup class that contains data about page setup (>= 5.0 only)
44
- # * +tempo+ (string) Tempo as string
45
- # * +bpm+ (integer) Tempo as beats per minute
46
- # * +key+ (integer) #TODO: convert digit to something readable (has different format for GP3 and GP4/5)
47
- # * +octave+ (integer) (>= 4.0 only)
48
- # * +channels+ (array) Table of midi channels. There are 4 ports and 16 channels, the channels are stored in this order:
49
- # port1/channel1 - port1/channel2 ... port1/channel16 - port2/channel1 ...
50
- # * +musical_directions+ (hash) Hash of musical directions definitions.
51
- # Each symbol is represented as the bar number at which it is placed.
52
- # If the symbol is not presented its value is nil.
53
- # There is full list of supported symbols in GuitarProHelper::MUSICAL_DIRECTIONS array (>= 5.0 only)
54
- # * +master_reverb+ (integer) Selected master reverb setting (in Score information, value from 0 to 60) (>= 5.0 only) #TODO represent as names
55
- # * +bars_settings+ (array) Array of settings of bars. Doesn't represent bars as containers for notes (look at Bar class for it)
56
- # * +tracks+ (array) Array of tracks
57
- #
58
9
  class Song
59
10
 
60
11
  include GuitarProHelper
61
12
 
62
- attr_accessor :version, :title, :subtitle, :artist, :album, :lyricist, :composer, :copyright,
63
- :transcriber, :instructions, :notices, :triplet_feel, :lyrics_track, :lyrics,
64
- :master_volume, :equalizer, :page_setup, :tempo, :bpm, :key, :octave, :channels,
65
- :musical_directions, :master_reverb, :bars_settings, :tracks
13
+ # Guitar Pro version
14
+ attr_accessor :version
15
+
16
+ # Song information
17
+ attr_accessor :title, :subtitle, :artist, :album, :lyricist,
18
+ :composer, :copyright, :transcriber, :instructions
19
+
20
+ # Array of notices
21
+ attr_accessor :notices
22
+
23
+ # (Boolean) Shuffle rhythm feel. < 5.0 only.
24
+ # In version 5 of the format it is true when
25
+ # there is at least 1 bar with triplet feel.
26
+ attr_accessor :triplet_feel
27
+
28
+ # Associated track for the lyrics (>= 4.0 only)
29
+ attr_accessor :lyrics_track
30
+
31
+ # Lyrics represented as array of hashes with 5 elements
32
+ # (for lyrics lines from 1 to 5).
33
+ # Each line has lyrics' text and number of bar where it starts
34
+ # {text: "Some text", bar: 1}
35
+ # (>= 4.0 only)
36
+ attr_accessor :lyrics
37
+
38
+ # Master volume (value from 0 - 200, default is 100) (>= 5.0 only)
39
+ attr_accessor :master_volume
40
+
41
+ # Array of equalizer settings.
42
+ # Each one is represented as number of increments of .1dB the volume for
43
+ # * 32Hz band is lowered
44
+ # * 60Hz band is lowered
45
+ # * 125Hz band is lowered
46
+ # * 250Hz band is lowered
47
+ # * 500Hz band is lowered
48
+ # * 1KHz band is lowered
49
+ # * 2KHz band is lowered
50
+ # * 4KHz band is lowered
51
+ # * 8KHz band is lowered
52
+ # * 16KHz band is lowered
53
+ # * overall volume is lowered (gain)
54
+ attr_accessor :equalizer
55
+
56
+ # (PageSetup) Data about page setup such as paddings, width, height, etc. (>= 5.0 only)
57
+ attr_accessor :page_setup
66
58
 
59
+ # (String) Tempo text
60
+ attr_accessor :tempo
61
+
62
+ # Tempo as beats per minute
63
+ attr_accessor :bpm
64
+
65
+ # Key (signature) at the beginning of the piece.
66
+ # It is encoded as:
67
+ # * ...
68
+ # * -1: F (b)
69
+ # * 0: C
70
+ # * 1: G (#)
71
+ # * 2: D (##)
72
+ # * ...
73
+ # TODO: convert digit to something readable
74
+ attr_accessor :key
75
+
76
+ # Octave. Default value is 0.
77
+ # It becomes 8 if the sheet is to be played one octave higher (8va).
78
+ attr_accessor :octave
79
+
80
+ # Table of midi channels. There are 4 ports and 16 channels, the channels are stored in this order:
81
+ # port1/channel1 - port1/channel2 ... port1/channel16 - port2/channel1 ...
82
+ # in array with the format:
83
+ # [[1,2,...16], [1,2,...16], [1,2,...16], [1,2,...16]]
84
+ attr_accessor :channels
85
+
86
+ # (Hash) Musical directions definitions.
87
+ # Each symbol is represented as the bar number at which it is placed.
88
+ # If the symbol is not presented its value is nil.
89
+ # There is full list of supported symbols in GuitarProHelper::MUSICAL_DIRECTIONS array (>= 5.0 only)
90
+ attr_accessor :musical_directions
91
+
92
+ # Selected master reverb setting (in Score information, value from 0 to 60) (>= 5.0 only)
93
+ # TODO: Represent as names
94
+ attr_accessor :master_reverb
95
+
96
+ # Array of settings of bars. Doesn't represent bars as containers for notes (look at Bar class for it)
97
+ attr_accessor :bars_settings
98
+
99
+ # Array of tracks
100
+ attr_accessor :tracks
101
+
102
+ # Initializes new Song instance.
103
+ # Parameters:
104
+ # (String) +file_path+ Path to file to read. If is not specified default song instance will be created.
105
+ # (Boolean) +headers_only+ Read only headers information from file if true (much faster than reading every note)
67
106
  def initialize(file_path = nil, headers_only = false)
68
- # Initialize variables by default values
107
+ @version = 5.1
69
108
  @title = ''
70
109
  @title = ''
71
110
  @subtitle = ''
@@ -90,11 +129,10 @@ module GuitarProParser
90
129
  @channels = []
91
130
  @musical_directions = Hash[GuitarProHelper::MUSICAL_DIRECTIONS.collect { |elem| [elem, nil] }]
92
131
  @master_reverb = 0
93
-
94
132
  @bars_settings = []
95
133
  @tracks = []
96
134
 
97
- # Read data from file
135
+ # Read data from file if it is specified
98
136
  Reader.new(self, file_path, headers_only) unless file_path.nil?
99
137
  end
100
138
 
@@ -1,3 +1,3 @@
1
1
  module GuitarProParser
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -20,7 +20,7 @@ describe GuitarProParser::Beat do
20
20
  test_beat :first
21
21
 
22
22
  its(:dotted) { should == false }
23
- its(:chord_diagram) { should be_nil }
23
+ its(:chord_diagram) { should be_kind_of GuitarProParser::ChordDiagram }
24
24
  its(:tuplet) { should be_nil }
25
25
  its(:rest) { should be_nil }
26
26
 
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe GuitarProParser::ChordDiagram do
4
+
5
+ shared_examples 'any Guitar Pro version' do
6
+ context 'F#m11/9-' do
7
+ subject { song.tracks[0].bars[0].get_beat(0).chord_diagram }
8
+ its(:name) { should == 'F#m11/9-' }
9
+ its(:base_fret) { should == 1 }
10
+ its(:frets) { should == [3, 2, 4, 2, 0, 2] }
11
+ its(:display_as) { should == :sharp }
12
+ its(:root) { should == 'F#' }
13
+ its(:type) { should == 'm' }
14
+ its(:nine_eleven_thirteen) { should == 11 }
15
+ its(:bass) { should == 'F#' }
16
+ its(:tonality) { should == :perfect }
17
+ its(:add) { should == false }
18
+ its(:fifth_tonality) { should == :perfect }
19
+ its(:ninth_tonality) { should == :diminished }
20
+ its(:eleventh_tonality) { should == :perfect }
21
+ its(:barres) { should == [{ fret: 2, start_string: 1, end_string: 4 }] }
22
+ its(:intervals) { should == [13] }
23
+ its(:fingers) { should == [:ring, :middle, :pinky, :middle, :no, :index] }
24
+ its(:display_fingering) { should == true }
25
+ end
26
+
27
+ context 'Asus2add13' do
28
+ subject { song.tracks[0].bars[0].get_beat(4).chord_diagram }
29
+ its(:name) { should == 'Asus2add13' }
30
+ its(:base_fret) { should == 1 }
31
+ its(:frets) { should == [2, 0, 2, 2, 2, -1] }
32
+ its(:display_as) { should == :sharp }
33
+ its(:root) { should == 'A' }
34
+ its(:type) { should == 'sus2' }
35
+ its(:nine_eleven_thirteen) { should == 13 }
36
+ its(:bass) { should == 'B' }
37
+ its(:tonality) { should == :perfect }
38
+ its(:add) { should == true }
39
+ its(:fifth_tonality) { should == :perfect }
40
+ its(:ninth_tonality) { should == :perfect }
41
+ its(:eleventh_tonality) { should == :perfect }
42
+ its(:barres) { should == [] }
43
+ its(:intervals) { should == [7, 9, 11] }
44
+ its(:fingers) { should == [:pinky, :no, :ring, :middle, :index, :no] }
45
+ its(:display_fingering) { should == true }
46
+ end
47
+
48
+ context 'C7M13+/9-/11-' do
49
+ subject { song.tracks[0].bars[1].get_beat(0).chord_diagram }
50
+ its(:name) { should == 'C7M13+/9-/11-' }
51
+ its(:base_fret) { should == 8 }
52
+ its(:frets) { should == [9, 11, 9, 9, 10, 8] }
53
+ its(:display_as) { should == :sharp }
54
+ its(:root) { should == 'C' }
55
+ its(:type) { should == '7M' }
56
+ its(:nine_eleven_thirteen) { should == 13 }
57
+ its(:bass) { should == 'C' }
58
+ its(:tonality) { should == :augmented }
59
+ its(:add) { should == false }
60
+ its(:fifth_tonality) { should == :perfect }
61
+ its(:ninth_tonality) { should == :diminished }
62
+ its(:eleventh_tonality) { should == :diminished }
63
+ its(:barres) { should == [{ fret: 9, start_string: 1, end_string: 4 }] }
64
+ its(:intervals) { should == [] }
65
+ its(:fingers) { should == [:middle, :pinky, :middle, :middle, :ring, :index] }
66
+ its(:display_fingering) { should == true }
67
+ end
68
+ end
69
+
70
+ context 'Guitar Pro 5' do
71
+ subject(:song) { GuitarProParser::Song.new test_tab_path 5 }
72
+ it_behaves_like 'any Guitar Pro version'
73
+ end
74
+
75
+ context 'Guitar Pro 4' do
76
+ subject(:song) { GuitarProParser::Song.new test_tab_path 4 }
77
+ it_behaves_like 'any Guitar Pro version'
78
+ end
79
+
80
+
81
+ end
@@ -1,19 +1,27 @@
1
1
  require 'spec_helper'
2
2
 
3
- # TODO: Rewrite these test when it will be possible to read all the beats and notes.
3
+ # TODO: It would be nice to add more tests for notes and test :bass voice
4
4
 
5
5
  def test_note(type)
6
- refs = {
7
- first: [0, '5']
6
+ notes = {
7
+ first: [0, 0, 0, '5'],
8
+ legato_slide: [0, 15, 0, '2'],
9
+ shift_slide: [0, 15, 2, '2'],
10
+ slide_in_from_below: [0, 15, 4, '2'],
11
+ slide_in_from_above: [0, 15, 5, '2'],
12
+ slide_out_and_downwards: [0, 15, 6, '2'],
13
+ slide_out_and_upwards: [0, 15, 7, '2'],
8
14
  }
9
- beat_number = refs.fetch(type).fetch(0)
10
- string_number = refs.fetch(type).fetch(1)
11
- subject { song.tracks[0].bars[0].get_beat(beat_number).strings[string_number] }
15
+ note = notes.fetch(type)
16
+ track_number = note[0]
17
+ bar_number = note[1]
18
+ beat_number = note[2]
19
+ string_number = note[3]
20
+ subject { song.tracks[track_number].bars[bar_number].get_beat(beat_number).strings[string_number] }
12
21
  end
13
22
 
14
23
  describe GuitarProParser::Note do
15
24
 
16
-
17
25
  shared_examples 'any Guitar Pro version' do
18
26
 
19
27
  context 'note of the 1 beat, 1 bar, 1 track' do
@@ -39,6 +47,36 @@ describe GuitarProParser::Note do
39
47
  its(:trill) { should be_nil }
40
48
  end
41
49
 
50
+ context 'legato slide' do
51
+ test_note :legato_slide
52
+ its(:slide) { should == :legato_slide }
53
+ end
54
+
55
+ context 'shift slide' do
56
+ test_note :shift_slide
57
+ its(:slide) { should == :shift_slide }
58
+ end
59
+
60
+ context 'slide in from below' do
61
+ test_note :slide_in_from_below
62
+ its(:slide) { should == :slide_in_from_below }
63
+ end
64
+
65
+ context 'slide in from above' do
66
+ test_note :slide_in_from_above
67
+ its(:slide) { should == :slide_in_from_above }
68
+ end
69
+
70
+ context 'slide out and downwards' do
71
+ test_note :slide_out_and_downwards
72
+ its(:slide) { should == :slide_out_and_downwards }
73
+ end
74
+
75
+ context 'slide out and upwards' do
76
+ test_note :slide_out_and_upwards
77
+ its(:slide) { should == :slide_out_and_upwards }
78
+ end
79
+
42
80
  end
43
81
 
44
82
  context 'Guitar Pro 5' do
@@ -50,6 +88,5 @@ describe GuitarProParser::Note do
50
88
  subject(:song) { GuitarProParser::Song.new test_tab_path 4 }
51
89
  it_behaves_like 'any Guitar Pro version'
52
90
  end
53
-
54
91
 
55
92
  end
data/spec/tabs/tab.gp4 CHANGED
Binary file
data/spec/tabs/tab.gp5 CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guitar_pro_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-24 00:00:00.000000000 Z
12
+ date: 2013-07-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -90,6 +90,7 @@ files:
90
90
  - spec/lib/guitar_pro_parser/bar_settings_spec.rb
91
91
  - spec/lib/guitar_pro_parser/beat_spec.rb
92
92
  - spec/lib/guitar_pro_parser/channel_spec.rb
93
+ - spec/lib/guitar_pro_parser/chord_diagram_spec.rb
93
94
  - spec/lib/guitar_pro_parser/guitar_pro_helper_spec.rb
94
95
  - spec/lib/guitar_pro_parser/io/input_stream_spec.rb
95
96
  - spec/lib/guitar_pro_parser/note_spec.rb
@@ -131,6 +132,7 @@ test_files:
131
132
  - spec/lib/guitar_pro_parser/bar_settings_spec.rb
132
133
  - spec/lib/guitar_pro_parser/beat_spec.rb
133
134
  - spec/lib/guitar_pro_parser/channel_spec.rb
135
+ - spec/lib/guitar_pro_parser/chord_diagram_spec.rb
134
136
  - spec/lib/guitar_pro_parser/guitar_pro_helper_spec.rb
135
137
  - spec/lib/guitar_pro_parser/io/input_stream_spec.rb
136
138
  - spec/lib/guitar_pro_parser/note_spec.rb