Stupid Mac::Glue Tricks: PODxt Sampling
The PODxt guitar amp/fx modeler was recently updated with a bunch of new stuff, including a bass expansion pack. Well, I play bass and guitar, and I liked the idea of not having to buy a Bass PODxt to go with my regular one. So I got the expansion pack to test it out, and wrote this program to do it.
It requires the following steps, apart from having all the proper modules and software installed:
- Create glues for QuickTime Player, MidiPipe, and Sound Studio (the latter only if you want to record the result)
- Set your default audio output to the PODxt
- If recording, set Sound Studio's audio input to the PODxt
- In System Preferences, set the PODxt to do reamping (cmd-3)
- Create a MidiPipe file that has a MIDI In named 'MidiPipe Input 1' and has MIDI Out set to the PODxt, and save it in the same directory as this program, with a '.mipi' extension
- In main_loop(), set the programs you want to try out; the demo here first loops over some programs, then switches to a blank program, then tries out a bunch of different amps by themselves
- If you want each program to be announced with speech, set the $SPEECH variable to true
- Run the program, as 'podxt-soundtest.plx path/to/someaudiofile.aif', where the audio file is a recording of clean guitar/bass; it will save the files in 'path/to/someaudiofile-samples/'
#!/usr/bin/perl
# podxt-soundtest.plx
use strict;
use warnings;
use File::Basename;
use File::Spec::Functions qw(catdir catfile);
use FindBin '$Bin';
use Mac::Errors '$MacError';
use Mac::Glue ':all';
use Mac::Speech;
use Time::HiRes 'sleep';
my $DEBUG = 1;
my $RECORD = 1;
my $SPEECH = 0;
use constant {
CC => 176,
PROGRAM => 192,
AMP_ENABLE => 111,
AMP_SELECT => 11,
};
my @voice = qw(Damien Diane Vicki Victoria);
my $midi_port = 'MidiPipe Input 1';
my $sound_file = shift;
my($sound_name, $sound_dir) = fileparse($sound_file, qr/\..+/);
my($qt_player, $midi_pipe, $sound_studio, $voice, $speech, $recording, $movie, $done);
init();
main_loop();
finish();
sub main_loop {
for my $n (111, 32.. 79) {
doit(program => $n);
}
# blank program
midi({ program => 127 });
for my $n (73.. 100) {
doit(amp => $n);
}
}
sub doit {
my($what, $which) = @_;
get_sound_files();
start_recording();
say($what, $which);
midi({ $what, $which });
play();
stop_recording();
save_recording($what, $which);
}
sub finish {
print "Done.\n";
exit;
}
sub init {
$qt_player = new Mac::Glue 'QuickTime Player';
$midi_pipe = new Mac::Glue 'MidiPipe';
$sound_studio = new Mac::Glue 'Sound Studio' if $RECORD;
if ($SPEECH) {
my $V;
for (@voice) {
last if $V = $Mac::Speech::Voice{$_};
}
$speech = NewSpeechChannel( $V );
}
if ($DEBUG) {
$qt_player->ERRORS(1);
$midi_pipe->ERRORS(1);
$sound_studio->ERRORS(1) if $RECORD;
}
$sound_studio->launch if $RECORD;
my($pipe) = fileparse($0, qr/\..+/);
$midi_pipe->open(catfile($Bin, $pipe . '.mipi'));
$qt_player->activate;
open_sound_file();
# preload voice
if ($SPEECH) {
SpeakText($speech, '');
sleep 0.1 while SpeechBusy();
}
$movie = $qt_player->obj(movie => 1, window => 1);
$done = $movie->prop('done');
}
sub midi {
my($params) = @_;
my $opts = {
toPort => $midi_port
};
if (defined $params->{program}) {
$opts->{withData} = [ PROGRAM, $params->{program} ];
} elsif (defined $params->{amp}) {
$opts->{withData} = [ CC, AMP_ENABLE, 0 ];
$midi_pipe->MIDISend(%$opts);
$opts->{withData} = [ CC, AMP_SELECT, $params->{amp} ];
}
$midi_pipe->MIDISend(%$opts);
}
sub say {
return unless $SPEECH;
my($what, $which) = @_;
my $text = "$what number $which";
print "$text\n";
midi({ program => 127 });
SpeakText($speech, $text);
sleep 0.1 while SpeechBusy();
}
sub play {
$movie->start;
while (1) {
last if $done->get;
sleep 0.5;
}
sleep 1.5;
}
sub get_sound_files {
if ($RECORD) {
$recording = $sound_studio->make(new => 'document');
}
open_sound_file();
}
sub open_sound_file {
$qt_player->obj(file => $sound_file)->open;
}
sub start_recording {
return unless $RECORD;
$recording->record;
}
sub stop_recording {
return unless $RECORD;
$recording->stop;
}
sub save_recording {
return unless $RECORD;
my($what, $which) = @_;
my $dir = catdir($sound_dir, $sound_name . '-samples');
mkdir $dir;
sleep 5;
$recording->save(
in => $recording->obj(file => catfile($dir, "$what-$which.aiff")),
as => enum('AIFF')
);
sleep 5;
$recording->close;
}
Leave a comment