Skip to content

Instantly share code, notes, and snippets.

@jbarrett
Last active April 26, 2024 09:28
Show Gist options
  • Save jbarrett/370c7480ecbc6bca6b60f36927c023a8 to your computer and use it in GitHub Desktop.
Save jbarrett/370c7480ecbc6bca6b60f36927c023a8 to your computer and use it in GitHub Desktop.
Sox-based multichannel wav splitter
#!/usr/bin/env perl
# usage:
# ./wavsplitter.pl [--channels=number of channels in output] [--sox=path to sox] file-list
#
# Back up your files before use, provided as-is, no warranty etc.
use strict;
use warnings;
use experimental qw/ signatures /;
use Getopt::Long qw/ :config pass_through /;
use File::Path qw/ make_path /;
my $output_channels = 2;
chomp( my $sox = `which sox` );
GetOptions (
"channels|c=i" => \$output_channels,
"sox|s" => \$sox
);
die "No sox in path or specified sox not found" unless -e $sox;
my @files = map { glob( $_ ) } @ARGV;
die "No files specified" unless @files;
sub input_channels( $file ) {
for ( `$sox --i $file` ) {
next unless s/^Channels\s+:\s+([0-9]+).*/$1/;
return $_;
}
return 0;
}
for my $file ( @files ) {
my $channel = 1;
my $input_channels = input_channels( $file );
if ( ! $input_channels ) {
warn "Unable to determine channel count for $file - skipping";
next;
}
if ( $input_channels <= $output_channels ) {
warn "Not enough channels to split in $file - skipping";
next;
}
my $name = $file =~ s/\.\w+$//r;
my $dir = "${file}_split_" . time;
make_path $dir;
while ( $channel < $input_channels ) {
my @remix_channels = $output_channels > 1
# remix 1-2 style had mixed (heh) results - list all channels separately
? map { $channel + $_ } 0..$output_channels - 1
: ( $output_channels );
my $out = "$dir/$name-" . join( '-', @remix_channels ) . ".wav" =~ s/\s+/-/gr;
system( $sox, $file, $out, 'remix', @remix_channels );
$channel += $output_channels;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment