Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env perl
- # Decode a Google Les Paul Guitar Doodle Thing's "tune" string, e.g.:
- # IAYxigFHKIUCIJRIilA*
- my $decoder = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_*";
- my %decoder;
- for(my $i=0;$i<length($decoder);$i++) {
- my $c = substr($decoder, $i, 1);
- $decoder{$c} = $i;
- }
- # the order of the notes is not in C-major scale order; this is the permutation
- # table to put it in scale order
- my @permute = qw(2 6 3 0 7 1 8 4 9 5);
- # 0123456789
- # note: 0010000000 5-bit duration 0
- # note: 0000001000 5-bit duration 6
- # note: 0001000000 5-bit duration 5
- # note: 1000000000 5-bit duration 5
- # note: 0000000100 5-bit duration 5
- # note: 0100000000 5-bit duration 5
- # note: 0000000010 5-bit duration 4
- # note: 0000100000 5-bit duration 5
- # note: 0000000001 5-bit duration 4
- # note: 0000010000 5-bit duration 5
- my $input = <>;
- chomp($input);
- my @out;
- for(my $i=0;$i<length($input);$i += 4) {
- my $a = $decoder{substr($input, $i, 1)};
- my $b = $decoder{substr($input, $i+1, 1)};
- my $c = $decoder{substr($input, $i+2, 1)};
- my $d = $decoder{substr($input, $i+3, 1)};
- # fixme: handle *
- # aaaaaabb bbbbcccc ccdddddd
- my $A = ($a<<2)|($b>>4);
- my $B = (($b&15)<<4)|($c>>2);
- my $C = (($c&3)<<6)|($d);
- push @out, ($A, $B, $C);
- }
- my ($outidx,$outbit) = (0,0x80);
- sub getbit
- {
- my $bit = ($out[$outidx] & $outbit) ? 1 : 0;
- $outbit >>= 1;
- if(!$outbit) {
- $outidx++;
- $outbit = 0x80;
- }
- return $bit;
- }
- sub getbits
- {
- my ($n) = @_;
- my $e = 1;
- my $x = 0;
- while($n--) { $x |= $e*getbit(); $e <<= 1;}
- return $x;
- }
- print(join(" ", map { sprintf("%02x", $_) } @out) . "\n");
- while($outidx < scalar @out) {
- my $notetype = getbit();
- if($notetype) {
- print("chord: ");
- my @notes = map { getbit() } (0..9);
- printf("%d", $notes[$permute[$_]]) for(0..9);
- } else {
- printf("note: ");
- my $note = getbits(4);
- printf("%d", $permute[$_] == $note ? 1 : 0) for(0..9);
- }
- print(" ");
- my $durtype = getbit();
- if($durtype) {
- printf("20-bit duration %d\n", getbits(20));
- } else {
- printf("5-bit duration %d\n", getbits(5));
- }
- }
Add Comment
Please, Sign In to add comment