------ art_2992_17423903.1147884607507
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Here's my short solution. It just assumes any set of 6 equal-length lines
starting with ('A'..'G') are a tab, and ignores the rest of the file.
It passes everything it finds on the tab lines to the guitar, since I was
hoping to improve guitar.rb to handle hammers and slides and such..
Unfortunately, real life just takes too much time...
---begin player.rb ------
require 'guitar.rb'
tuningMap = {
'EADGBE' => Guitar::EADGBE,
'DADGBE' => Guitar::DADGBE,
'DGCFAD'=> Guitar::DGCFAD
}
puts "usage: Player.rb tabfile" or exit if ARGV.size < 1
lines,lastlength=[],nil
until ARGF.eof do
lines << ARGF.gets.chomp.split('');
#read until we find 6 lines of same length
if lastlength and lastlength != lines[-1].length
#throw away nonmatching lines
lines.shift while lines.size > 1
end
lastlength = lines[-1].length
if lines.size == 6
sig = lines.inject([]){|a,l| a <<l.shift}
#make sure it has a key signature
if !sig.find{|e| !e or !(("A".."G").include?(e.upcase))}
#create a guitar in the key of the first tab found.
g ||= Guitar.new(Guitar::NYLON_ACOUSTIC,
tuningMap[sig.reverse.join.upcase])
until (lines[0].empty?)
note = lines.inject([]){|a,l| a << l.shift}
if (note[0]!='|')
p note.join if $DEBUG
g.play(note.join)
end
end
end
lines.clear
end
end
File.open("tab.mid","wb") {|f| f.write(g.dump)}
----
-Adam
On 5/17/06, Ross Bamford <rossrt / roscopeco.co.uk> wrote:
>
> This is the 'proof of concept' solution I wrote for this quiz. It just
> uses a regexp approach to extract whatever tab it can find from the
> input, and it has the limitations mentioned in the quiz (9 frets, etc).
>
> #!/usr/local/bin/ruby
> #
> # This is a very simple solution to this quiz, using
> # the simple software guitar supplied. Run e.g:
> #
> # ./playtab.rb sometab.tab | timidity -Os -
> #
> # Using the correct -O (s is ALSA - see --help for more).
> # Alternatively, file the output and load it in your
> # midi player.
> #
> require 'guitar'
>
> tabre = /(([eADGBE]\|?
> [\-0-9~xhpbrBend\(\)\[\]\{\}=*|#]+
> [.\r\n]*){6})/x
> tabs = []
>
> ARGF.read.scan(tabre) {
> tab = $1.split
> tabs << tab if tab.all? { |line| line.length == tab[0].length }
> }
>
> axe = Guitar.new(Guitar::CLEAN_ELECTRIC)
> tabs.inject([[]]) do |bars,t|
> (t[0].length - 2).times do |i|
> notes = t.inject("") { |s,line| s << line[i+2] }.reverse
> if notes =~ /[|*]{6}/
> bars << []
> else
> bars.last << notes
> end
> end
> bars
> end.reject { |a| a.empty? }.each do |bar|
> bar.each do |notes|
> axe.play(notes)
> end
> end
>
> $stdout.write(axe.dump)
>
> --
> Ross Bamford - rosco / roscopeco.REMOVE.co.uk
>
>
>
------ art_2992_17423903.1147884607507--