//public static void PostProcessSound() //{ } public static bool ShouldPlaySound(SingleSound singleSound, SoundMetadata soundMetadata) { if (PlaybackModerator.crewChief != null && !PlaybackModerator.crewChief.running) { PlaybackModerator.Trace(string.Format("Sound {0} rejected because main thread is shutting down", singleSound.fullPath)); return(false); } int messageId = soundMetadata == null ? 0 : soundMetadata.messageId; if (PlaybackModerator.lastBlockedMessageId == messageId) { PlaybackModerator.Trace(string.Format("Sound {0} rejected because other members of the same message have been blocked", singleSound.fullPath)); return(false); } if (PlaybackModerator.rejectMessagesWhenTalking && soundMetadata.type != SoundType.VOICE_COMMAND_RESPONSE && SpeechRecogniser.waitingForSpeech && MainWindow.voiceOption != MainWindow.VoiceOptionEnum.ALWAYS_ON) { PlaybackModerator.Trace(string.Format("Sound {0} rejected because we're in the middle of a voice command", singleSound.fullPath)); if (messageId != 0) { PlaybackModerator.lastBlockedMessageId = messageId; } return(false); } if (PlaybackModerator.minPriorityForInterrupt != SoundType.OTHER && PlaybackModerator.CanInterrupt(soundMetadata)) { SoundType mostImportantTypeInImmediateQueue = PlaybackModerator.audioPlayer.getPriortyOfFirstWaitingImmediateMessage(); if (mostImportantTypeInImmediateQueue <= PlaybackModerator.minPriorityForInterrupt) { PlaybackModerator.Trace(string.Format("Blocking queued messasge {0} because at least 1 {1} message is waiting", singleSound.fullPath, mostImportantTypeInImmediateQueue)); PlaybackModerator.Trace("Messages triggering block logic: " + audioPlayer.getMessagesBlocking(minPriorityForInterrupt)); if (messageId != 0) { PlaybackModerator.lastBlockedMessageId = messageId; } // ensure the blocking message won't expire var firstWaitingMessage = PlaybackModerator.audioPlayer.getFirstWaitingImmediateMessage(mostImportantTypeInImmediateQueue); if (firstWaitingMessage != null && firstWaitingMessage.expiryTime > 0) { firstWaitingMessage.expiryTime = firstWaitingMessage.expiryTime + 2000; } return(false); } } return(true); }
public static void PreProcessSound(SingleSound sound, SoundMetadata soundMetadata) { if (PlaybackModerator.audioPlayer == null) { return; } //PlaybackModerator.Trace($"Pre-Processing sound: {sound.fullPath} isSpotter: {sound.isSpotter} isBleep: {sound.isBleep} "); PlaybackModerator.InjectBeepOutIn(sound, soundMetadata); PlaybackModerator.lastSoundPreProcessed = sound; }
private static void InjectBeepOutIn(SingleSound sound, SoundMetadata soundMetadata) { Debug.Assert(PlaybackModerator.audioPlayer != null, "audioPlayer is not set."); // Only consider injection is preference is set and Spotter and Chief are different personas. if (!PlaybackModerator.IsFakeBleepInjectionEnabled()) { return; } // Skip bleep sounds. if (sound.isBleep) { return; } // Inject bleep out/in if needed. var isSpotterSound = sound.isSpotter; // Alternatively, we could assign a role to each queued sound. We'll need this if we get more "personas" than Chief and Spotter. if (((!PlaybackModerator.lastSoundWasSpotter && isSpotterSound) || // If we are flipping from the Chief to Spotter (PlaybackModerator.lastSoundWasSpotter && !isSpotterSound)) && // Or from the Spotter to Chief PlaybackModerator.audioPlayer.isChannelOpen() && // And, channel is still open (PlaybackModerator.lastSoundPreProcessed == null || !PlaybackModerator.lastSoundPreProcessed.isBleep)) // and the last sound wasn't also a beep (to stop the spotter kicking off with a double-beep) { // Ok, so idea here is that Chief and Spotter have different bleeps. So we use opposing sets. string keyBleepOut = null; string keyBleepIn = null; string traceMsgPostfix = null; if (isSpotterSound) { // Spotter uses opposite blips. keyBleepOut = "end_bleep"; // Chief uses regular bleeps. keyBleepIn = "alternate_short_start_bleep"; traceMsgPostfix = "Spotter interrupted Chief."; } else // Chief comes in. { keyBleepOut = "alternate_end_bleep"; // Spotter uses alternate bleeps keyBleepIn = "short_start_bleep"; traceMsgPostfix = "Chief interrupted Spotter."; } PlaybackModerator.Trace(string.Format("Injecting: {0} and {1} messages. {2}", keyBleepOut, keyBleepIn, traceMsgPostfix)); // insert bleep out/in if (PlaybackModerator.insertBeepOutBetweenSpotterAndChief) { PlaybackModerator.audioPlayer.getSoundCache().Play(keyBleepOut, soundMetadata); } // would be nice to have some slight random silence here if (PlaybackModerator.insertBeepInBetweenSpotterAndChief) { PlaybackModerator.audioPlayer.getSoundCache().Play(keyBleepIn, soundMetadata); } } PlaybackModerator.lastSoundWasSpotter = isSpotterSound; }
/* * CanInterrupt will be true for regular messages triggered by the app's normal event logic. When a message * is played from the 'immediate' queue this will be false (spotter calls, command responses, some edge cases * where the message is time-critical). If this flag is true the presence of a message in the immediate queue * will make the app skip this sound if immediate_messages_block_other_messages is enabled. */ private static Boolean CanInterrupt(SoundMetadata metadata) { // is this sufficient? Should the spotter be able to interrupt voice comm responses? return(metadata.type == SoundType.REGULAR_MESSAGE); }