/// <summary> /// Searches the cache for a particular phrase. /// </summary> /// <param name="phrase">The phrase information.</param> /// <returns>The phrase information if found in the cache or <c>null</c>.</returns> /// <exception cref="ArgumentNullException">Thrown if <pararef name="phrase" /> is <c>null</c>.</exception> /// <exception cref="InvalidOperationException">Thrown if the cache has been stopped.</exception> public Phrase FindPhrase(Phrase phrase) { Phrase existing; if (phrase == null) { throw new ArgumentNullException("phrase"); } // The requested voice might not exist, so get the actual // voice that can be used. phrase.ActualVoice = SpeechEngine.GetVoice(phrase.Voice); if (phrase.ActualVoice == null) { return(null); // No installed voices } lock (syncLock) { if (!isRunning) { throw new InvalidOperationException("[PhraseCache] is stopped."); } if (index.TryGetValue(GetCacheKey(phrase), out existing)) { return(existing); } else { return(null); } } }
/// <summary> /// Handles background activities. /// </summary> /// <param name="state">Not used.</param> private void OnBkTimer(object state) { // Update performance counters. CorePerf.Runtime.RawValue = (int)(DateTime.UtcNow - startTime).TotalMinutes; // Handle global background activities. SpeechEngine.OnBkTask(); }
/// <summary> /// Adds the genrated phrase audio file passed to the cache. /// </summary> /// <param name="phrase">The phrase being added.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="phrase" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException">Thrown if the <paramref name="phrase" />.<see cref="Path"/> property is <c>null</c>.</exception> /// <exception cref="InvalidOperationException">Thrown if the cache has been stopped or if a one-time phrase is passed.</exception> public void AddPhrase(Phrase phrase) { Phrase existing; if (phrase == null) { throw new ArgumentNullException("phrase"); } if (phrase.Path == null) { throw new ArgumentException("[Path] property cannot be NULL.", "phrase"); } if (phrase.IsOneTime) { throw new InvalidOperationException("[AddPhrase] cannot accept a one-time phrase."); } phrase = phrase.Clone(); // The requested voice might not exist, so get the actual // voice that can be used. phrase.ActualVoice = SpeechEngine.GetVoice(phrase.Voice); if (phrase.ActualVoice == null) { return; // No installed voices } lock (syncLock) { if (!isRunning) { throw new InvalidOperationException("[PhraseCache] is stopped."); } phrase.LastAccessUtc = DateTime.UtcNow; if (index.TryGetValue(GetCacheKey(phrase), out existing)) { // The phrase is already in the index. existing.LastAccessUtc = phrase.LastAccessUtc; } else { index.Add(GetCacheKey(phrase), phrase); } } }
/// <summary> /// Called by NeonSwitch to execute a synchronous subcommand. /// </summary> /// <param name="args">The command execution context including the arguments.</param> /// <remarks> /// <note> /// Implementations can use the various <see cref="ExecuteEventArgs.Write(string)"/> method /// overloads in <see cref="ExecuteEventArgs"/> to stream text back to the caller. /// </note> /// </remarks> public void Execute(ExecuteEventArgs args) { try { var phrase = Phrase.Decode(args.SubcommandArgs); args.Write(SpeechEngine.SpeakToFile(phrase)); } catch (Exception e) { SysLog.LogException(e); args.Write(SpeechEngine.ErrorAudioPath); } }
/// <summary> /// Starts the service, associating it with an <see cref="IServiceHost" /> instance. /// </summary> /// <param name="serviceHost">The service user interface.</param> /// <param name="args">Command line arguments.</param> public void Start(IServiceHost serviceHost, string[] args) { lock (syncLock) { if (router != null) { return; // Already started } // Global initialization startTime = DateTime.UtcNow; NetTrace.Start(); CoreApp.InstallPerfCounters(); // Service initialization this.serviceHost = serviceHost; try { SysLog.LogInformation("NeonSwitch v{0} Start", Helper.GetVersionString()); router = new LeafRouter(); router.Start(); state = ServiceState.Running; bkTimer = new GatedTimer(OnBkTimer, null, CoreApp.BkTaskInterval); SpeechEngine.Start(SpeechEngineSettings.LoadConfig("NeonSwitch.Speech")); #if DEBUG // $todo(jeff.lill): Delete this. SwitchTest.Test(); #endif // Indicate that the switch core service is open for business. NeonSwitch // application instance loaders will spin, waiting for this to be set before // calling the application's main function. Switch.SetGlobal(SwitchGlobal.NeonSwitchReady, "true"); } catch (Exception e) { SpeechEngine.Stop(); if (bkTimer != null) { bkTimer.Dispose(); bkTimer = null; } if (router != null) { router.Stop(); router = null; } SysLog.LogException(e); throw; } } }