aboutsummaryrefslogtreecommitdiff
path: root/audiocue2bincue
blob: 84c15823b1645496e12c9e3fd5ae54d94b03eed8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env perl -w

# Convert an audio file based CD image into a raw bin/cue.
# Uses libsndfile to do the audio file decoding and conversion,
# except for mp3 files (use lame for those).

# Please don't try to convince me to use CPAN modules for things like
# cue sheets or audio format conversions. This is me using perl as a
# 'glue' language, not an 'enterprise applications platform'.

($self = $0) =~ s,.*/,,;

if(!@ARGV || $ARGV[0] eq '--help') {
	print <<EOF;
Usage: $self [-s] [input.cue] [output.cue]
See man page for details.
EOF
	exit 0
}

if($ARGV[0] eq '-s') {
	$swapbytes = 1;
	shift @ARGV;
}

if($ARGV[1] && $ARGV[1] ne '-') {
	open $out, ">", $ARGV[1];
	select $out;
}

# Everyone always complains about regex looking like gibberish,
# so here's my attempt at writing a readable(ish) one.
$match_file = qr{
   ^\s*        # optional leading space/tabs
      FILE     # required token
   \s+         # required one or more spaces before the filename
   "?          # optional quote (spec doesn't require it)
      ([^"]+)  # actual filename goes in $1
   "?          # optional quote afterwards
   \s+         # required space(s) before the type
   (\w+)       # type (BINARY, WAVE, MP3 maybe, etc) goes in $2
}x;

@ARGV = ($ARGV[0]);

%audiofiles = ();

while(<>) {
	if(/$match_file/) {
		my ($file, $type) = ($1, $2);
		$audiofiles{$file}++;
		print fix_line($_, $file, $type);
	} else {
		print;
	}
}

for(keys %audiofiles) {
	my $newfilename = $new_filenames{$_};
	(my $rawfilename = $newfilename) =~ s/\.bin$/.raw/;

	my @cmd = ();

	if($_ =~ /mp3$/i) {
		@cmd = ( "lame", "-t", "--quiet", "--decode" );
		push @cmd, "-x" if $swapbytes;
		push @cmd, ( $_, $rawfilename );
	} else {
		my $endarg = "-endian=" . ($swapbytes ? "big" : "little");
		@cmd = ( "sndfile-convert", "-pcm16", $endarg, $_, $rawfilename );
	}

	warn "Converting $_ to raw .bin with $cmd[0]\n";
	system(@cmd);
	rename($rawfilename, $newfilename);
}

sub fix_line {
	my ($line, $filename, $type) = @_;
	my $newfilename;

	if($type eq 'BINARY') {
		warn "$filename is already type BINARY, leaving as-is\n";
		return $line;
	}

	($newfilename = $filename) =~ s/(?:\.\w+)?$/.bin/;
	$new_filenames{$filename} = $newfilename;
	return "FILE \"$newfilename\" BINARY\r\n";
}