Procházet zdrojové kódy

Use the new standardized QT_PLAYER interface

Zachary Kotlarek před 13 roky
rodič
revize
505504efde

+ 145 - 216
dmx/Audio.pm

@@ -2,17 +2,22 @@
 use strict;
 use warnings;
 use POSIX;
-use File::Touch;
 use File::Basename;
-use Time::HiRes qw( usleep sleep time );
 use IPC::System::Simple;
+use Time::HiRes qw( usleep sleep time );
 
 # Package name
 package Audio;
 
 # Config
 my $MEDIA_PATH = `~/bin/video/mediaPath`;
-my %FILES      = ();
+
+# App config
+my $DATA_DIR   = DMX::dataDir();
+my $QT_FILE    = $DATA_DIR . 'QT_PLAYER';
+my $QT_SOCK    = $QT_FILE . '.socket';
+my $WAIT_DELAY = 0.1;
+my $MAX_WAIT   = 5 / $WAIT_DELAY;
 
 # Debug
 my $DEBUG = 0;
@@ -20,131 +25,82 @@ if ($ENV{'DEBUG'}) {
 	$DEBUG = 1;
 }
 
-# Execute the provided string with osascript
-sub runApplescript($) {
-	my ($script) = @_;
-	if ($DEBUG) {
-		print STDERR 'AppleScript: ' . $script . "\n";
-	}
-
-	my $retval = IPC::System::Simple::capture('osascript', '-e', $script);
-	$retval =~ s/[\r\n]$//;
-	if ($DEBUG) {
-		print STDERR "\tAppleScript result: " . $retval . "\n";
-	}
+# State
+my %FILES = ();
+my $SOCK  = undef();
 
-	return $retval;
-}
+# Send the provided arguments to the QT socket
+sub sendCmd(@) {
 
-# Set or get the system output volume
-sub systemVolume($) {
-	my ($new) = @_;
-	if ($DEBUG) {
-		print STDERR "Audio::systemVolume()\n";
+	# Connect the socket as needed
+	if (!$SOCK) {
+		$SOCK = DMX::clientSock($QT_SOCK);
 	}
 
-	if ($new) {
-		runApplescript('set volume output volume ' . $new);
-	} else {
-		return runApplescript('get output volume of (get volume settings)');
+	# Ensure the data is compatible with the encoding scheme
+	foreach my $part (@_) {
+		if ($part =~ /\|/) {
+			die('Invalid QT command component: ' . $part . "\n");
+		}
 	}
-}
 
-# Set or get a document's volume
-sub volume($$) {
-	my ($name, $new) = @_;
+	# Build the command stirng
+	my $str = join('|', @_);
 	if ($DEBUG) {
-		print STDERR 'Audio::volume(): ' . $name . "\n";
-	}
-	if (!loaded($name)) {
-		die('Invalid QT document: ' . $name . "\n");
+		print STDERR 'Sending QT_PLAYER command: ' . $str . "\n";
 	}
 
-	if ($new) {
-		runApplescript('tell application "QuickTime Player" to set audio volume of document ' . $FILES{$name}->{'name'} . ' to ' . $new);
-	} else {
-		return runApplescript('tell application "QuickTime Player" to get audio volume of document ' . $FILES{$name}->{'name'});
-	}
+	# Send the command
+	$SOCK->send($str)
+	  or die("Unable to send to QT socket\n");
 }
 
-# Add an load a document
-sub addLoad($$) {
-	my ($name, $path) = @_;
+# Execute the provided string with osascript
+sub runApplescript($) {
+	my ($script) = @_;
 	if ($DEBUG) {
-		print STDERR 'Audio::addLoad(): ' . $name . "\n";
+		print STDERR 'AppleScript: ' . $script . "\n";
 	}
-	add($name, $path);
-	load($name);
-}
 
-# Add a document to the available list
-sub add($$) {
-	my ($name, $path) = @_;
+	my $retval = IPC::System::Simple::capture('osascript', '-e', $script);
+	$retval =~ s/[\r\n]$//;
 	if ($DEBUG) {
-		print STDERR 'Audio::add(): ' . $name . ', ' . $path . "\n";
-	}
-
-	# Construct an absolute file path
-	if (!($path =~ /^\//)) {
-		$path = $MEDIA_PATH . '/' . $path;
-	}
-
-	# Validate
-	if (!-r $path) {
-		die('Invalid audio path: ' . $path . "\n");
+		print STDERR "\tAppleScript result: " . $retval . "\n";
 	}
 
-	# We only support one document per name
-	drop($name);
-
-	# Append the array
-	my %tmp = ('path' => $path);
-	$FILES{$name} = \%tmp;
+	return $retval;
 }
 
-# Drop a document from the available list, unloaded as necessary
-sub drop($) {
-	my ($name) = @_;
-	if ($DEBUG) {
-		print STDERR 'Audio::drop(): ' . $name . "\n";
-	}
-
-	# Stop and unload as necessary
-	if (loaded($name)) {
-		stop($name);
-		unload($name);
-	}
+# Load a document
+sub load($$) {
+	my ($name, $path) = @_;
+	sendCmd('LOAD', $name, $path);
 
-	# Drop as necessary
-	if (available($name)) {
-		delete($FILES{$name});
+	# Wait for the file to load
+	my $count = 0;
+	while (!loaded($name)) {
+		sleep($WAIT_DELAY);
+		$count++;
+		if ($count > $MAX_WAIT) {
+			die('Unable to open file: ' . $name . "\n");
+		}
 	}
 }
 
 # Is the named document loaded?
 sub loaded($) {
 	my ($name) = @_;
-	if ($DEBUG) {
-		print STDERR 'Audio::loaded(): ' . $name . "\n";
-	}
-
-	if (available($name) && defined($FILES{$name}->{'name'})) {
-		return 1;
-	}
-	return 0;
+	parseList();
+	return exists($FILES{$name});
 }
 
-# Is the named document configured?
-sub available($) {
+# Unload the named document
+sub unload($) {
 	my ($name) = @_;
 	if ($DEBUG) {
-		print STDERR 'Audio::available(): ' . $name . "\n";
-	}
-
-	if (defined($name) && defined($FILES{$name})) {
-		return 1;
+		print STDERR 'Audio::loadAudio(): ' . $name . "\n";
 	}
-	return 0;
+	sendCmd('UNLOAD', $name);
 }
 
 # Play the named document, waiting for completion
@@ -154,12 +110,12 @@ sub play($) {
 		print STDERR 'Audio::play(): ' . $name . "\n";
 	}
 
-	# Start playback
-	background($name);
+	# Ensure the file is loaded
+	dieUnloaded($name);
 
-	# Wait for it to complete
 	my @cmd = ('tell application "QuickTime Player"');
-	push(@cmd, 'repeat while playing of document ' . $FILES{$name}->{'name'} . ' = true');
+	push(@cmd, 'play document ' . $FILES{$name});
+	push(@cmd, 'repeat while playing of document ' . $FILES{$name} . ' = true');
 	push(@cmd, 'delay 0.1');
 	push(@cmd, 'end repeat');
 	push(@cmd, 'end tell');
@@ -172,12 +128,39 @@ sub background($) {
 	if ($DEBUG) {
 		print STDERR 'Audio::background(): ' . $name . "\n";
 	}
-	if (!loaded($name)) {
-		die('Invalid QT document: ' . $name . "\n");
+
+	# Ensure the file is loaded
+	dieUnloaded($name);
+
+	runApplescript('tell application "QuickTime Player" to play document ' . $FILES{$name});
+}
+
+# Pause the named document
+sub pause($) {
+	my ($name) = @_;
+	if ($DEBUG) {
+		print STDERR 'Audio::pause(): ' . $name . "\n";
+	}
+
+	# Ensure the file is loaded
+	dieUnloaded($name);
+
+	runApplescript('tell application "QuickTime Player" to pause document ' . $FILES{$name});
+}
+
+# Stop playback of the named document
+sub stop($) {
+	my ($name) = @_;
+	if ($DEBUG) {
+		print STDERR "Audio::stopAudio()\n";
 	}
 
-	# Start playback
-	runApplescript('tell application "QuickTime Player" to play document ' . $FILES{$name}->{'name'});
+	# Ensure the file is loaded
+	dieUnloaded($name);
+
+	# Stop and rewind
+	runApplescript('tell application "QuickTime Player" to stop document ' . $FILES{$name});
+	runApplescript('tell application "QuickTime Player" to set current time of document ' . $FILES{$name} . ' to 0');
 }
 
 # Is the named document playing?
@@ -187,8 +170,10 @@ sub playing($) {
 		print STDERR 'Audio::playing(): ' . $name . "\n";
 	}
 
-	# Ask QT if the document is playing
-	# Note that while QT has a "playing" property it is only true when rate == 1.0
+	# Ensure the file is loaded
+	dieUnloaded($name);
+
+	# QT has a "playing" property but it is only true when rate == 1.0
 	my $rate = rate($name);
 	if ($rate > 0) {
 		return 1;
@@ -202,14 +187,14 @@ sub position($$) {
 	if ($DEBUG) {
 		print STDERR 'Audio::position(): ' . $name . "\n";
 	}
-	if (!loaded($name)) {
-		die('Invalid QT document: ' . $name . "\n");
-	}
+
+	# Ensure the file is loaded
+	dieUnloaded($name);
 
 	if ($new) {
-		runApplescript('tell application "QuickTime Player" to set current time of document ' . $FILES{$name}->{'name'} . ' to ' . $new);
+		runApplescript('tell application "QuickTime Player" to set current time of document ' . $FILES{$name} . ' to ' . $new);
 	} else {
-		return runApplescript('tell application "QuickTime Player" to get current time of document ' . $FILES{$name}->{'name'});
+		return runApplescript('tell application "QuickTime Player" to get current time of document ' . $FILES{$name});
 	}
 }
 
@@ -219,134 +204,78 @@ sub rate($$) {
 	if ($DEBUG) {
 		print STDERR 'Audio::rate(): ' . $name . "\n";
 	}
-	if (!loaded($name)) {
-		die('Invalid QT document: ' . $name . "\n");
-	}
+
+	# Ensure the file is loaded
+	dieUnloaded($name);
 
 	if ($new) {
-		runApplescript('tell application "QuickTime Player" to set rate of document ' . $FILES{$name}->{'name'} . ' to ' . $new);
+		runApplescript('tell application "QuickTime Player" to set rate of document ' . $FILES{$name} . ' to ' . $new);
 	} else {
-		return runApplescript('tell application "QuickTime Player" to get rate of document ' . $FILES{$name}->{'name'});
+		return runApplescript('tell application "QuickTime Player" to get rate of document ' . $FILES{$name});
 	}
 }
 
-# Pause the named document
-sub pause($) {
-	my ($name) = @_;
+# Set or get a document's volume
+sub volume($$) {
+	my ($name, $new) = @_;
 	if ($DEBUG) {
-		print STDERR 'Audio::pause(): ' . $name . "\n";
-	}
-	if (!loaded($name)) {
-		die('Invalid QT document: ' . $name . "\n");
+		print STDERR 'Audio::volume(): ' . $name . "\n";
 	}
 
-	# Pause playback
-	runApplescript('tell application "QuickTime Player" to pause document ' . $FILES{$name}->{'name'});
-}
+	# Ensure the file is loaded
+	dieUnloaded($name);
 
-# Stop playback of the named document or all documents
-sub stop($) {
-	my ($name) = @_;
-	if ($DEBUG) {
-		print STDERR "Audio::stopAudio()\n";
-	}
-
-	# Allow control of all documents or a specific document
-	my $doc = 'every document';
-	if (loaded($name)) {
-		$doc = 'document ' . $FILES{$name}->{'name'};
+	if ($new) {
+		runApplescript('tell application "QuickTime Player" to set audio volume of document ' . $FILES{$name} . ' to ' . $new);
+	} else {
+		return runApplescript('tell application "QuickTime Player" to get audio volume of document ' . $FILES{$name});
 	}
-
-	# Stop and rewind all QT documents
-	runApplescript('tell application "QuickTime Player" to stop ' . $doc);
-	runApplescript('tell application "QuickTime Player" to set current time of ' . $doc . ' to 0');
-
-	# Bring Plex back to the front
-	runApplescript('tell application "Plex" to activate');
 }
 
-# Unload the named document
-sub unload($) {
-	my ($name) = @_;
+# Set or get the system output volume
+sub systemVolume($) {
+	my ($new) = @_;
 	if ($DEBUG) {
-		print STDERR 'Audio::loadAudio(): ' . $name . "\n";
-	}
-	if (!available($name)) {
-		die('Invalid QT document: ' . $name . "\n");
+		print STDERR "Audio::systemVolume()\n";
 	}
 
-	# Nothing to do if the file isn't loaded
-	if (!loaded($name)) {
-		return;
+	if ($new) {
+		runApplescript('set volume output volume ' . $new);
+	} else {
+		return runApplescript('get output volume of (get volume settings)');
 	}
-
-	# Close to document
-	runApplescript('tell application "QuickTime Player" to close document ' . $FILES{$name}->{'name'});
-
-	# Delete our local handle
-	delete($FILES{$name}->{'name'});
 }
 
-# Load the named document
-sub load($) {
-	my ($name) = @_;
-	if ($DEBUG) {
-		print STDERR 'Audio::loadAudio(): ' . $name . "\n";
-	}
-	if (!available($name)) {
-		die('Invalid QT document: ' . $name . "\n");
-	}
-
-	# Unload first, if we're already loaded
-	if (loaded($name)) {
-		unload($name);
-	}
-
-	# Find out how many files are already open
-	my $count = runApplescript('tell application "QuickTime Player" to count items of every document');
-
-	# Open the file
-	IPC::System::Simple::system('open', '-a', 'QuickTime Player', $FILES{$name}->{'path'});
-
-	# Wait for QT to load the new file
-	my @cmd = ('tell application "QuickTime Player"');
-	push(@cmd, 'set endDate to current date + (3/60 * minutes)');
-	push(@cmd, 'repeat while (count items of every document) <= ' . $count . ' and current date < endDate');
-	push(@cmd, 'delay 0.1');
-	push(@cmd, 'end repeat');
-	push(@cmd, 'get document 1');
-	push(@cmd, 'end tell');
-	my $doc = runApplescript(join("\n", @cmd));
-
-	# Clean up the document name
-	$doc =~ s/^\s*document //;
-	$doc =~ s/\s+$//;
-	$doc =~ s/\"/\\\"/g;
-	$doc = '"' . $doc . '"';
+# Stop playback on all documents
+sub stopAll() {
+	sendCmd('STOP');
+}
 
-	# Save the document handle
-	$FILES{$name}->{'name'} = $doc;
+# Reset the entire QT Player process
+sub reset() {
+	sendCmd('RESET');
+}
 
-	# Bring Plex back to the front
-	runApplescript('tell application "Plex" to activate');
+# Read and parse the qt_player file list
+sub parseList() {
+	%FILES = ();
+	open(my $fh, $QT_FILE)
+	  or die('Unable to open QT_PLAYER file: ' . $! . "\n");
+	while (<$fh>) {
+		my ($name, $handle) = $_ =~ /^([^|]+)\|\s*(\".+\")\s*$/;
+		if (!$name || !$handle) {
+			die('Invalid QT_PLAYER line: ' . $_);
+		}
+		$FILES{$name} = $handle;
+	}
+	close($fh);
 }
 
-# Get things into a reasonable state
-sub init() {
-	if ($DEBUG) {
-		print STDERR "Audio::init()\n";
+sub dieUnloaded($) {
+	my ($name) = @_;
+	if (!loaded($name)) {
+		die('File not loaded: ' . $name . "\n");
 	}
-
-	# Close all QT documents and relaunch QT Player
-	runApplescript('tell application "QuickTime Player" to close every document');
-	runApplescript('tell application "QuickTime Player" to quit');
-	sleep(1);
-	IPC::System::Simple::system('open', '-a', 'QuickTime Player');
-
-	# Always load and play the SILENCE file (for sanity and general init)
-	add('SILENCE', 'DMX/Silence.wav');
-	load('SILENCE');
-	play('SILENCE');
 }
 
 # Always return true

+ 2 - 0
dmx/launchd/com.uberzach.ola.rave.plist

@@ -23,6 +23,8 @@
 		<dict>
 			<key>com.uberzach.state</key>
 			<true/>
+			<key>com.uberzach.qt_player</key>
+			<true/>
 		</dict>
 	</dict>
 	<key>ProgramArguments</key>

+ 42 - 0
dmx/launchd/com.uberzach.qt_player.plist

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>LimitLoadToSessionType</key>
+	<string>Aqua</string>
+	<key>LimitLoadToHosts</key>
+	<array>
+		<string>Loki.local</string>
+		<string>loki.uberzach.com</string>
+		<string>Beddy.local</string>
+		<string>beddy.uberzach.com</string>
+		<string>Heady.local</string>
+		<string>heady.uberzach.com</string>
+	</array>
+	<key>RunAtLoad</key>
+	<true/>
+	<key>Label</key>
+	<string>com.uberzach.qt_player</string>
+	<key>KeepAlive</key>
+	<dict>
+		<key>OtherJobEnabled</key>
+		<dict>
+			<key>com.uberzach.state</key>
+			<true/>
+		</dict>
+	</dict>
+	<key>ProgramArguments</key>
+	<array>
+		<string>/Users/tv/bin/video/dmx/qt_player.pl</string>
+	</array>
+	<!--
+		<key>EnvironmentVariables</key>
+		<dict>
+			<key>DEBUG</key>
+			<string>1</string>
+		</dict>
+		<key>StandardErrorPath</key>
+		<string>/Users/tv/com.uberzach.qt_player_errlog.txt</string>
+	-->
+</dict>
+</plist>

+ 1 - 1
dmx/launchd/com.uberzach.rifftrax.plist

@@ -23,7 +23,7 @@
 		<dict>
 			<key>com.uberzach.state</key>
 			<true/>
-			<key>com.uberzach.ola.rave</key>
+			<key>com.uberzach.qt_player</key>
 			<true/>
 		</dict>
 	</dict>

+ 225 - 0
dmx/qt_player.pl

@@ -0,0 +1,225 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use File::Basename;
+use IPC::System::Simple;
+
+# Local modules
+use Cwd qw(abs_path);
+use File::Basename qw(dirname);
+use lib dirname(abs_path($0));
+use DMX;
+use Audio;
+
+# User config
+my $MEDIA_PATH = `~/bin/video/mediaPath`;
+my %FILES      = ();
+
+# Prototypes
+sub init();
+sub load($$);
+sub unload($);
+sub stop();
+sub filesMatch($$);
+sub dieUnloaded($);
+
+# App config
+my $DATA_DIR    = DMX::dataDir();
+my $OUTPUT_FILE = $DATA_DIR . 'QT_PLAYER';
+my $STATE_SOCK  = $OUTPUT_FILE . '.socket';
+my $DELAY       = 10;
+my $MAX_CMD_LEN = 16384;
+
+# Debug
+my $DEBUG = 0;
+if ($ENV{'DEBUG'}) {
+	$DEBUG = 1;
+}
+
+# Reset QT Player
+init();
+
+# Clear our output file
+if (-e $OUTPUT_FILE) {
+	unlink($OUTPUT_FILE);
+}
+
+# Sockets
+my $SELECT = DMX::selectSock($STATE_SOCK);
+
+# Loop forever
+while (1) {
+
+	# Save the last file list
+	my %lastFiles = %FILES;
+
+	# Wait for commands
+	{
+		my @ready_clients = $SELECT->can_read($DELAY);
+		foreach my $fh (@ready_clients) {
+
+			# Ensure we won't block on recv()
+			$fh->blocking(0);
+
+			# Read
+			while (defined($fh->recv(my $text, $MAX_CMD_LEN))) {
+
+				# Parse
+				my @argv = split(/\|/, $text);
+
+				# Ignore empty commands
+				if (scalar(@argv) < 1) {
+					next;
+				}
+
+				# Dispatch commands
+				my $cmd = shift(@argv);
+				if ($cmd eq 'LOAD' && scalar(@argv) == 2) {
+					load($argv[0], $argv[1]);
+				} elsif ($cmd eq 'UNLOAD' && scalar(@argv) == 1) {
+					unload($argv[0]);
+				} elsif ($cmd eq 'STOP') {
+					stop();
+				} elsif ($cmd eq 'RESET') {
+					init();
+				} else {
+					warn('Ignored invalid command: ' . $text . "\n");
+				}
+			}
+		}
+	}
+	
+	# Ensure "silence" is always available
+	if (!exists($FILES{'SILENCE'})) {
+		init();
+	}
+
+	# Publish the file list whenever it changes, or if the output file does not exist
+	if (filesMatch(\%lastFiles, \%FILES) || !-r $OUTPUT_FILE) {
+		my ($fh, $tmp) = File::Temp::tempfile($OUTPUT_FILE . '.XXXXXXXX', 'UNLINK' => 0);
+		foreach my $file (keys(%FILES)) {
+			print $fh $file . '|' . $FILES{$file} . "\n";
+		}
+		close($fh);
+		rename($tmp, $OUTPUT_FILE);
+	}
+}
+
+# Get things into a reasonable state
+sub init() {
+	if ($DEBUG) {
+		print STDERR "init()\n";
+	}
+
+	# Reset our local state
+	%FILES = ();
+
+	# Close all QT documents and relaunch QT Player
+	Audio::runApplescript('tell application "QuickTime Player" to close every document');
+	Audio::runApplescript('tell application "QuickTime Player" to quit');
+	sleep(1);
+	IPC::System::Simple::system('open', '-a', 'QuickTime Player');
+
+	# Always load and play the SILENCE file (for sanity and general init)
+	load('SILENCE', 'DMX/Silence.wav');
+
+	# Bring Plex back to the front
+	Audio::runApplescript('tell application "Plex" to activate');
+}
+
+# Open the named file and record the handle
+sub load($$) {
+	my ($name, $path) = @_;
+	if ($DEBUG) {
+		print STDERR 'load(): ' . $name . ', ' . $path . "\n";
+	}
+
+	# Build a reasonable path
+	if (!($path =~ /^\//)) {
+		$path = $MEDIA_PATH . '/' . $path;
+	}
+
+	# Ensure the file exists
+	if (!-r $path) {
+		warn('Invalid audio file path: ' . $path . "\n");
+		return;
+	}
+
+	# Reload as needed
+	if (exists($FILES{$name})) {
+		unload($name);
+	}
+
+	# Find out how many files are already open
+	my $count = Audio::runApplescript('tell application "QuickTime Player" to count items of every document');
+
+	# Open the file
+	# It would be nice to use AppleScript here, so we can get a more definitive name, but the open() call is borked
+	IPC::System::Simple::system('open', '-a', 'QuickTime Player', $path);
+
+	# Wait for QT to load the new file
+	# To avoid indefinate hangs this will give up after 5 seconds. When it does the results are undefined.
+	my @cmd = ('tell application "QuickTime Player"');
+	push(@cmd, 'set endDate to current date + (5/60 * minutes)');
+	push(@cmd, 'repeat while (count items of every document) <= ' . $count . ' and current date < endDate');
+	push(@cmd, 'delay 0.1');
+	push(@cmd, 'end repeat');
+	push(@cmd, 'get document 1');
+	push(@cmd, 'end tell');
+	my $doc = Audio::runApplescript(join("\n", @cmd));
+
+	# Clean up the document name
+	$doc =~ s/^\s*document //;
+	$doc =~ s/\s+$//;
+	$doc =~ s/\"/\\\"/g;
+	$doc = '"' . $doc . '"';
+
+	# Save the document handle
+	$FILES{$name} = $doc;
+
+	# Bring Plex back to the front
+	Audio::runApplescript('tell application "Plex" to activate');
+}
+
+# Close the named file
+sub unload($) {
+	my ($name) = @_;
+	if ($DEBUG) {
+		print STDERR 'unload(): ' . $name . "\n";
+	}
+
+	# Ignore files that don't exist
+	if (!exists($FILES{$name})) {
+		warn('No such file loaded: ' . $name . "\n");
+		return;
+	}
+
+	# Close to document
+	Audio::runApplescript('tell application "QuickTime Player" to close document ' . $FILES{$name});
+
+	# Delete our handle
+	delete($FILES{$name});
+}
+
+# Stop and rewind all QT documents
+sub stop() {
+	Audio::runApplescript('tell application "QuickTime Player" to stop every document');
+	Audio::runApplescript('tell application "QuickTime Player" to set current time of every document to 0');
+}
+
+# Determine if anything has changed
+sub filesMatch($$) {
+	my ($old, $new) = @_;
+	if (scalar(keys(%{$old})) != scalar(keys(%{$new}))) {
+		return 0;
+	}
+	foreach my $name (keys(%{$old})) {
+		if (!exists($new->{$name})) {
+			return 0;
+		}
+		if ($old->{$name} ne $new->{$name}) {
+			return 0;
+		}
+	}
+	return 1;
+}

+ 1 - 2
dmx/rave.pl

@@ -67,7 +67,6 @@ if ($ENV{'DEBUG'}) {
 }
 
 # Load all our audio files
-Audio::init();
 foreach my $file (keys(%FILES)) {
 	Audio::addLoad($file, $FILES{$file});
 }
@@ -130,7 +129,7 @@ while (1) {
 			if ($DEBUG) {
 				print STDERR "Ending background processing\n";
 			}
-			Audio::stop(undef());
+			Audio::stopAll();
 			kill(SIGTERM, $PID);
 		}
 

+ 2 - 2
dmx/rifftrax.pl

@@ -154,7 +154,7 @@ while (1) {
 			Audio::systemVolume($VOLUME_STD);
 
 			# Close the audio file
-			Audio::drop('RIFF');
+			Audio::unload('RIFF');
 			$riff = 0;
 
 			# Warm fuzzies
@@ -176,7 +176,7 @@ while (1) {
 			DMX::say('RiffTrax initiated');
 
 			# Load and start the audio file
-			Audio::addLoad('RIFF', $RIFFS{$riff}->{'file'});
+			Audio::load('RIFF', $RIFFS{$riff}->{'file'});
 			playRiff();
 
 			# Set volume when we load -- riffs should be louder than normal system sounds