Guest User

google guitar doodle decoder

a guest
Jun 10th, 2011
425
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.17 KB | None | 0 0
  1. #!/usr/bin/env perl
  2.  
  3. # Decode a Google Les Paul Guitar Doodle Thing's "tune" string, e.g.:
  4.  
  5. # IAYxigFHKIUCIJRIilA*
  6.  
  7. my $decoder = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_*";
  8. my %decoder;
  9. for(my $i=0;$i<length($decoder);$i++) {
  10.   my $c = substr($decoder, $i, 1);
  11.   $decoder{$c} = $i;
  12. }
  13.  
  14. # the order of the notes is not in C-major scale order; this is the permutation
  15. # table to put it in scale order
  16. my @permute = qw(2 6 3 0 7 1 8 4 9 5);
  17.  
  18. #        0123456789
  19. # note:  0010000000 5-bit duration 0
  20. # note:  0000001000 5-bit duration 6
  21. # note:  0001000000 5-bit duration 5
  22. # note:  1000000000 5-bit duration 5
  23. # note:  0000000100 5-bit duration 5
  24. # note:  0100000000 5-bit duration 5
  25. # note:  0000000010 5-bit duration 4
  26. # note:  0000100000 5-bit duration 5
  27. # note:  0000000001 5-bit duration 4
  28. # note:  0000010000 5-bit duration 5
  29.  
  30. my $input = <>;
  31. chomp($input);
  32. my @out;
  33. for(my $i=0;$i<length($input);$i += 4) {
  34.   my $a = $decoder{substr($input, $i, 1)};
  35.   my $b = $decoder{substr($input, $i+1, 1)};
  36.   my $c = $decoder{substr($input, $i+2, 1)};
  37.   my $d = $decoder{substr($input, $i+3, 1)};
  38.  
  39.   # fixme: handle *
  40.  
  41.   # aaaaaabb bbbbcccc ccdddddd
  42.   my $A = ($a<<2)|($b>>4);
  43.   my $B = (($b&15)<<4)|($c>>2);
  44.   my $C = (($c&3)<<6)|($d);
  45.   push @out, ($A, $B, $C);
  46. }
  47.  
  48. my ($outidx,$outbit) = (0,0x80);
  49. sub getbit
  50. {
  51.   my $bit = ($out[$outidx] & $outbit) ? 1 : 0;
  52.   $outbit >>= 1;
  53.   if(!$outbit) {
  54.     $outidx++;
  55.     $outbit = 0x80;
  56.   }
  57.   return $bit;
  58. }
  59.  
  60. sub getbits
  61. {
  62.   my ($n) = @_;
  63.   my $e = 1;
  64.   my $x = 0;
  65.   while($n--) { $x |= $e*getbit(); $e <<= 1;}
  66.   return $x;
  67. }
  68.  
  69. print(join(" ", map { sprintf("%02x", $_) } @out) . "\n");
  70.  
  71. while($outidx < scalar @out) {
  72.   my $notetype = getbit();
  73.   if($notetype) {
  74.     print("chord: ");
  75.     my @notes = map { getbit() } (0..9);
  76.     printf("%d", $notes[$permute[$_]]) for(0..9);
  77.   } else {
  78.     printf("note:  ");
  79.     my $note = getbits(4);
  80.     printf("%d", $permute[$_] == $note ? 1 : 0) for(0..9);
  81.   }
  82.   print(" ");
  83.   my $durtype = getbit();
  84.   if($durtype) {
  85.     printf("20-bit duration %d\n", getbits(20));
  86.   } else {
  87.     printf("5-bit duration %d\n", getbits(5));
  88.   }
  89. }
Add Comment
Please, Sign In to add comment