guitar_pro_parser 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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