Sfoglia il codice sorgente

Move audio output functionality to its own daemon, separate from the amplifierPower daemon. Add support for manually selecting the main amp as an output device.

Zachary Kotlarek 13 anni fa
parent
commit
b29d786871
5 ha cambiato i file con 135 aggiunte e 82 eliminazioni
  1. 0 24
      dmx/amplifierPower.pl
  2. 129 0
      dmx/audio.pl
  3. 0 53
      dmx/audioOutput.pl
  4. 4 4
      dmx/launchd/com.uberzach.audio.plist
  5. 2 1
      dmx/state.pl

+ 0 - 24
dmx/amplifierPower.pl

@@ -9,12 +9,6 @@ use File::Basename qw(dirname);
 use lib dirname(abs_path($0));
 use DMX;
 
-# Config
-my $USB_DEV     = 'USB Audio CODEC ';
-my $AMP_DEV     = 'Built-in Output';
-my $DEFAULT_DEV = $USB_DEV;
-my $RAVE_DEV    = $AMP_DEV;
-
 # App config
 my $DATA_DIR     = DMX::dataDir();
 my $OUTPUT_FILE  = $DATA_DIR . 'AMPLIFIER_POWER';
@@ -23,8 +17,6 @@ my $AMP_SOCK     = $DATA_DIR . 'AMPLIFIER.socket';
 my $PUSH_TIMEOUT = 20;
 my $PULL_TIMEOUT = $PUSH_TIMEOUT * 3;
 my $DELAY        = $PULL_TIMEOUT / 2;
-my $START_DELAY  = 3.5;
-my @AUDIO_SET    = ('/Users/tv/bin/SwitchAudioSource', '-s');
 
 # Debug
 my $DEBUG = 0;
@@ -41,7 +33,6 @@ my $amp = DMX::clientSock($AMP_SOCK);
 my $state     = 'OFF';
 my $mode      = 'SURROUND';
 my $input     = 'TV';
-my $output    = $DEFAULT_DEV;
 my $stateLast = $state;
 my %exists    = ();
 my $pushLast  = 0;
@@ -85,13 +76,6 @@ while (1) {
 		$mode = 'SURROUND';
 	}
 
-	# Calculate the output device
-	if ($state eq 'RAVE') {
-		$output = $RAVE_DEV;
-	} else {
-		$output = $DEFAULT_DEV;
-	}
-
 	# Force updates on a periodic basis
 	if (!$update && time() - $pushLast > $PUSH_TIMEOUT) {
 
@@ -138,14 +122,6 @@ while (1) {
 		  or die('Unable to write command to amp socket: ' . $input . ": ${!}\n");
 	}
 
-	# Update the output device as needed
-	if ($exists{'AUDIO_OUTPUT'} ne $output) {
-		if ($DEBUG) {
-			print STDERR 'Setting output to: ' . $output . "\n";
-		}
-		system(@AUDIO_SET, $output);
-	}
-
 	# Update the amp
 	if ($update) {
 

+ 129 - 0
dmx/audio.pl

@@ -0,0 +1,129 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use File::Temp qw( tempfile );
+use Time::HiRes qw( usleep sleep time );
+use IPC::System::Simple qw( system capture );
+
+# Local modules
+use Cwd qw(abs_path);
+use File::Basename qw(dirname);
+use lib dirname(abs_path($0));
+use DMX;
+
+# Config
+my $USB_DEV     = 'USB Audio CODEC ';
+my $AMP_DEV     = 'Built-in Output';
+my $DEFAULT_DEV = $USB_DEV;
+
+# App config
+my $DATA_DIR     = DMX::dataDir();
+my $OUTPUT_FILE  = $DATA_DIR . 'AUDIO';
+my $STATE_SOCK   = $OUTPUT_FILE . '.socket';
+my $PUSH_TIMEOUT = 20;
+my $PULL_TIMEOUT = $PUSH_TIMEOUT * 3;
+my $DELAY        = 1;
+my @AUDIO_CMD    = ('/Users/tv/bin/SwitchAudioSource');
+my @AUDIO_GET    = (@AUDIO_CMD, '-c');
+my @AUDIO_SET    = (@AUDIO_CMD, '-s');
+
+# Debug
+my $DEBUG = 0;
+if ($ENV{'DEBUG'}) {
+	$DEBUG = 1;
+}
+
+# Sockets
+DMX::stateSocket($STATE_SOCK);
+DMX::stateSubscribe($STATE_SOCK);
+
+# State
+my $state      = 'OFF';
+my $device     = $DEFAULT_DEV;
+my $deviceLast = '';
+my $cmdDevice  = $device;
+my %exists     = ();
+my $pushLast   = 0;
+my $pullLast   = time();
+my $update     = 0;
+
+# Always force the output to default at launch
+system(@AUDIO_SET, $DEFAULT_DEV);
+
+# Loop forever
+while (1) {
+
+	# Grab the current audio output device
+	$deviceLast = $device;
+	$device     = capture(@AUDIO_GET);
+	$device =~ s/\n$//;
+
+	# If the device has changed, save the state to disk
+	if ($deviceLast ne $device) {
+		if ($DEBUG) {
+			print STDERR 'New output device: ' . $deviceLast . ' => ' . $device . "\n";
+		}
+		my ($fh, $tmp) = tempfile($OUTPUT_FILE . '.XXXXXXXX', 'UNLINK' => 0);
+		print $fh $device . "\n";
+		close($fh);
+		rename($tmp, $OUTPUT_FILE);
+	}
+
+	# State is calculated; use newState to gather data
+	my $newState = $state;
+
+	# Wait for state updates
+	my $cmdState = DMX::readState($DELAY, \%exists, undef(), undef());
+	if (defined($cmdState)) {
+		$newState = $cmdState;
+		$pullLast = time();
+	}
+
+	# Die if we don't see regular updates
+	if (time() - $pullLast > $PULL_TIMEOUT) {
+		die('No update on state socket in past ' . $PULL_TIMEOUT . " seconds. Exiting...\n");
+	}
+
+	# Calculate the new state
+	if ($exists{'RAVE'}) {
+		$cmdDevice = $AMP_DEV;
+	} elsif ($exists{'AUDIO_AMP'}) {
+		$cmdDevice = $AMP_DEV;
+	} else {
+		$cmdDevice = $DEFAULT_DEV;
+	}
+
+	# Force updates on a periodic basis
+	if (!$update && time() - $pushLast > $PUSH_TIMEOUT) {
+
+		# Not for the audio output device
+		#if ($DEBUG) {
+		#	print STDERR "Forcing periodic update\n";
+		#}
+		#$update = 1;
+	}
+
+	# Force updates when there is a physical state mistmatch
+	if (!$update && $cmdDevice ne $device) {
+		if ($DEBUG) {
+			print STDERR 'State mismatch: ' . $device . ' => ' . $cmdDevice . "\n";
+		}
+		$update = 1;
+	}
+
+	# Update the audio output device
+	if ($update) {
+
+		# Update
+		if ($DEBUG) {
+			print STDERR 'Setting output to: ' . $cmdDevice . "\n";
+		}
+		system(@AUDIO_SET, $cmdDevice);
+
+		# Update the push time
+		$pushLast = time();
+
+		# Clear the update flag
+		$update = 0;
+	}
+}

+ 0 - 53
dmx/audioOutput.pl

@@ -1,53 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use File::Temp qw( tempfile );
-use Time::HiRes qw( usleep sleep time );
-use IPC::System::Simple qw( system capture );
-
-# Local modules
-use Cwd qw(abs_path);
-use File::Basename qw(dirname);
-use lib dirname(abs_path($0));
-use DMX;
-
-# App config
-my $DATA_DIR    = DMX::dataDir();
-my $OUTPUT_FILE = $DATA_DIR . 'AUDIO_OUTPUT';
-my $DELAY       = 1;
-my @AUDIO_GET   = ('/Users/tv/bin/SwitchAudioSource', '-c');
-
-# Debug
-my $DEBUG = 0;
-if ($ENV{'DEBUG'}) {
-	$DEBUG = 1;
-}
-
-# State
-my $device     = '';
-my $deviceLast = $device;
-
-# Loop forever
-while (1) {
-
-	# Save the last output device
-	$deviceLast = $device;
-
-	# Grab the current audio output device
-	$device = capture(@AUDIO_GET);
-	$device =~ s/\n$//;
-
-	# If something has changed, save the state to disk
-	if ($device ne $deviceLast) {
-		if ($DEBUG) {
-			print STDERR 'New output device: ' . $deviceLast . ' => ' . $device . "\n";
-		}
-		my ($fh, $tmp) = tempfile($OUTPUT_FILE . '.XXXXXXXX', 'UNLINK' => 0);
-		print $fh $device . "\n";
-		close($fh);
-		rename($tmp, $OUTPUT_FILE);
-	}
-
-	# Wait between updates
-	sleep($DELAY);
-}

+ 4 - 4
dmx/launchd/com.uberzach.audioOutput.plist → dmx/launchd/com.uberzach.audio.plist

@@ -12,7 +12,7 @@
 	<key>RunAtLoad</key>
 	<true/>
 	<key>Label</key>
-	<string>com.uberzach.audioOutput</string>
+	<string>com.uberzach.audio</string>
 	<key>KeepAlive</key>
 	<dict>
 		<key>OtherJobEnabled</key>
@@ -25,7 +25,7 @@
 	</dict>
 	<key>ProgramArguments</key>
 	<array>
-		<string>/Users/tv/bin/video/dmx/audioOutput.pl</string>
+		<string>/Users/tv/bin/video/dmx/audio.pl</string>
 	</array>
 	<!--
 		<key>EnvironmentVariables</key>
@@ -34,9 +34,9 @@
 			<string>1</string>
 		</dict>
 		<key>StandardOutPath</key>
-		<string>/Users/tv/com.uberzach.audioOutput_log.txt</string>
+		<string>/Users/tv/com.uberzach.audio_log.txt</string>
 		<key>StandardErrorPath</key>
-		<string>/Users/tv/com.uberzach.audioOutput_errlog.txt</string>
+		<string>/Users/tv/com.uberzach.audio_errlog.txt</string>
 	-->
 </dict>
 </plist>

+ 2 - 1
dmx/state.pl

@@ -29,10 +29,11 @@ my %MON_FILES     = (
 	'FAN_CMD'         => 'EXISTS_ON',
 	'LIGHTS'          => 'EXISTS_ON',
 	'STEREO_CMD'      => 'EXISTS_ON',
+	'AUDIO_AMP'       => 'EXISTS_ON',
 	'AMPLIFIER_VOL'   => 'STATUS_VALUE',
 	'AMPLIFIER_MODE'  => 'STATUS_VALUE',
 	'AMPLIFIER_INPUT' => 'STATUS_VALUE',
-	'AUDIO_OUTPUT'    => 'STATUS_VALUE',
+	'AUDIO'           => 'STATUS_VALUE',
 
 	'/mnt/media/DMX/cmd/GARAGE_CMD' => 'EXISTS_CLEAR',
 );