Compare commits
2 Commits
8da46c0511
...
5daee1a01a
Author | SHA1 | Date | |
---|---|---|---|
5daee1a01a | |||
2d5d305528 |
@@ -1,5 +1,9 @@
|
|||||||
|
using Cryville.EEW.Core;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Cryville.EEW.Unity {
|
namespace Cryville.EEW.Unity {
|
||||||
@@ -8,12 +12,17 @@ namespace Cryville.EEW.Unity {
|
|||||||
float SeverityColorMappingLuminanceMultiplier,
|
float SeverityColorMappingLuminanceMultiplier,
|
||||||
bool UseContinuousColor,
|
bool UseContinuousColor,
|
||||||
string ColorScheme,
|
string ColorScheme,
|
||||||
|
string LocationNamer,
|
||||||
|
|
||||||
string OverrideTimeZone,
|
string OverrideTimeZone,
|
||||||
bool DoDisplayTimeZone,
|
bool DoDisplayTimeZone,
|
||||||
bool DoSwitchBackToHistory,
|
bool DoSwitchBackToHistory,
|
||||||
|
|
||||||
|
string NowcastWarningDelayTolerance,
|
||||||
|
|
||||||
string OverrideDisplayCulture,
|
string OverrideDisplayCulture,
|
||||||
|
IReadOnlyCollection<TTSCultureConfig> TTSCultures,
|
||||||
|
bool DoIgnoreLanguageVariant,
|
||||||
|
|
||||||
IReadOnlyCollection<EventSourceConfig> EventSources
|
IReadOnlyCollection<EventSourceConfig> EventSources
|
||||||
) {
|
) {
|
||||||
@@ -22,12 +31,17 @@ namespace Cryville.EEW.Unity {
|
|||||||
1f,
|
1f,
|
||||||
false,
|
false,
|
||||||
"Default",
|
"Default",
|
||||||
|
"FERegionLong",
|
||||||
|
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
|
||||||
|
"1:00:00",
|
||||||
|
|
||||||
"",
|
"",
|
||||||
|
new List<TTSCultureConfig> { new(SharedCultures.CurrentUICulture) },
|
||||||
|
true,
|
||||||
|
|
||||||
new List<EventSourceConfig> {
|
new List<EventSourceConfig> {
|
||||||
new JMAAtomEventSourceConfig(Array.Empty<string>()),
|
new JMAAtomEventSourceConfig(Array.Empty<string>()),
|
||||||
@@ -61,6 +75,20 @@ namespace Cryville.EEW.Unity {
|
|||||||
record WolfxEventSourceConfig(IReadOnlyCollection<string> Filter = null, bool IsFilterWhitelist = false, bool UseRawCENCLocationName = false) : EventSourceConfig;
|
record WolfxEventSourceConfig(IReadOnlyCollection<string> Filter = null, bool IsFilterWhitelist = false, bool UseRawCENCLocationName = false) : EventSourceConfig;
|
||||||
|
|
||||||
[JsonSerializable(typeof(Config))]
|
[JsonSerializable(typeof(Config))]
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(Converters = new Type[] { typeof(CultureInfoConverter) }, WriteIndented = true)]
|
||||||
sealed partial class ConfigSerializationContext : JsonSerializerContext { }
|
sealed partial class ConfigSerializationContext : JsonSerializerContext { }
|
||||||
|
|
||||||
|
sealed class CultureInfoConverter : JsonConverter<CultureInfo> {
|
||||||
|
public override CultureInfo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
|
||||||
|
Debug.Assert(typeToConvert == typeof(CultureInfo));
|
||||||
|
var value = reader.GetString();
|
||||||
|
if (value == null) return CultureInfo.InvariantCulture;
|
||||||
|
if (value == "") return SharedCultures.CurrentUICulture;
|
||||||
|
return SharedCultures.Get(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, CultureInfo value, JsonSerializerOptions options) {
|
||||||
|
writer.WriteStringValue(value.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,12 +26,12 @@ namespace Cryville.EEW.Unity {
|
|||||||
public IColorScheme ColorScheme { get; private set; } = new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.Instance);
|
public IColorScheme ColorScheme { get; private set; } = new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.Instance);
|
||||||
public ISubColorScheme BorderColorScheme { get; private set; } = new WrappedColorScheme(new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.SecondaryInstance));
|
public ISubColorScheme BorderColorScheme { get; private set; } = new WrappedColorScheme(new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.SecondaryInstance));
|
||||||
public ISubColorScheme TextColorScheme { get; private set; } = new DefaultTextColorScheme(Color.White, Color.Black);
|
public ISubColorScheme TextColorScheme { get; private set; } = new DefaultTextColorScheme(Color.White, Color.Black);
|
||||||
public TimeSpan NowcastWarningDelayTolerance => TimeSpan.FromMinutes(60); // TODO TTS
|
public TimeSpan NowcastWarningDelayTolerance { get; private set; } = TimeSpan.FromMinutes(60);
|
||||||
|
|
||||||
public CultureInfo RVMCulture { get; private set; } = SharedCultures.CurrentUICulture;
|
public CultureInfo RVMCulture { get; private set; } = SharedCultures.CurrentUICulture;
|
||||||
readonly int _infoLocationSpecificity = 3;
|
readonly int _infoLocationSpecificity = 3;
|
||||||
readonly int _ttsLocationSpecificity = 3;
|
readonly int _ttsLocationSpecificity = 3;
|
||||||
readonly LocationNamer _locationNamer = new() { Namer = new FERegionLongNamer() }; // TODO TTS
|
readonly LocationNamer _locationNamer = new() { Namer = new FERegionLongNamer() };
|
||||||
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name, out int specificity) {
|
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name, out int specificity) {
|
||||||
specificity = _ttsLocationSpecificity;
|
specificity = _ttsLocationSpecificity;
|
||||||
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
|
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
|
||||||
@@ -41,6 +41,9 @@ namespace Cryville.EEW.Unity {
|
|||||||
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
|
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IReadOnlyCollection<TTSCultureConfig> TTSCultures { get; private set; }
|
||||||
|
public bool DoIgnoreLanguageVariant { get; private set; }
|
||||||
|
|
||||||
public TimeZoneInfo OverrideTimeZone { get; private set; }
|
public TimeZoneInfo OverrideTimeZone { get; private set; }
|
||||||
public bool DoDisplayTimeZone { get; private set; } = true;
|
public bool DoDisplayTimeZone { get; private set; } = true;
|
||||||
public bool DoSwitchBackToHistory { get; private set; } = true;
|
public bool DoSwitchBackToHistory { get; private set; } = true;
|
||||||
@@ -114,12 +117,20 @@ namespace Cryville.EEW.Unity {
|
|||||||
"SREV" => new DefaultTextColorScheme(Color.White, Color.FromArgb(28, 28, 28), 0.555f),
|
"SREV" => new DefaultTextColorScheme(Color.White, Color.FromArgb(28, 28, 28), 0.555f),
|
||||||
_ => new DefaultTextColorScheme(Color.White, Color.Black),
|
_ => new DefaultTextColorScheme(Color.White, Color.Black),
|
||||||
};
|
};
|
||||||
|
_locationNamer.Namer = config.LocationNamer switch {
|
||||||
|
"FERegionShort" => new FERegionShortNamer(),
|
||||||
|
_ => new FERegionLongNamer(),
|
||||||
|
};
|
||||||
|
if (config.NowcastWarningDelayTolerance is string nowcastWarningDelayTolerance)
|
||||||
|
NowcastWarningDelayTolerance = TimeSpan.Parse(nowcastWarningDelayTolerance, CultureInfo.InvariantCulture);
|
||||||
OverrideTimeZone = ParseTimeZone(config.OverrideTimeZone);
|
OverrideTimeZone = ParseTimeZone(config.OverrideTimeZone);
|
||||||
DoDisplayTimeZone = config.DoDisplayTimeZone;
|
DoDisplayTimeZone = config.DoDisplayTimeZone;
|
||||||
DoSwitchBackToHistory = config.DoSwitchBackToHistory;
|
DoSwitchBackToHistory = config.DoSwitchBackToHistory;
|
||||||
RVMCulture = config.OverrideDisplayCulture is string rvmCulture
|
RVMCulture = config.OverrideDisplayCulture is string rvmCulture
|
||||||
? (string.IsNullOrEmpty(rvmCulture) ? SharedCultures.CurrentUICulture : SharedCultures.Get(rvmCulture))
|
? (string.IsNullOrEmpty(rvmCulture) ? SharedCultures.CurrentUICulture : SharedCultures.Get(rvmCulture))
|
||||||
: CultureInfo.InvariantCulture;
|
: CultureInfo.InvariantCulture;
|
||||||
|
TTSCultures = config.TTSCultures ?? new List<TTSCultureConfig> { new(CultureInfo.InvariantCulture) };
|
||||||
|
DoIgnoreLanguageVariant = config.DoIgnoreLanguageVariant;
|
||||||
EventSources = config.EventSources;
|
EventSources = config.EventSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using SpeechLib;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -5,7 +6,14 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Cryville.EEW.Unity {
|
namespace Cryville.EEW.Unity {
|
||||||
class TTSWorker : Core.Audio.TTSWorker {
|
class TTSWorker : Core.Audio.TTSWorker {
|
||||||
public TTSWorker() : base(CreateSoundPlayer()) { }
|
readonly SpVoiceClass _voice;
|
||||||
|
|
||||||
|
public TTSWorker() : base(CreateSoundPlayer()) {
|
||||||
|
try {
|
||||||
|
_voice = new SpVoiceClass();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
static SoundPlayer CreateSoundPlayer() {
|
static SoundPlayer CreateSoundPlayer() {
|
||||||
try {
|
try {
|
||||||
@@ -16,10 +24,24 @@ namespace Cryville.EEW.Unity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool IsSpeaking() => false;
|
protected override bool IsSpeaking() {
|
||||||
|
if (_voice == null) return false;
|
||||||
|
_voice.GetStatus(out var status, out _);
|
||||||
|
return (status.dwRunningState & (uint)SpeechRunState.SRSEIsSpeaking) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected override Task Speak(CultureInfo culture, string content, CancellationToken cancellationToken) => Task.CompletedTask;
|
protected override Task Speak(CultureInfo culture, string content, CancellationToken cancellationToken) {
|
||||||
|
if (_voice == null) return Task.CompletedTask;
|
||||||
|
_voice.Speak(
|
||||||
|
string.Format(CultureInfo.InvariantCulture, "<LANG LANGID=\"{0:x}\">{1}</LANG>", culture.LCID, content),
|
||||||
|
SpeechVoiceSpeakFlags.SVSFlagsAsync | SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak
|
||||||
|
);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void StopCurrent() { }
|
protected override void StopCurrent() {
|
||||||
|
if (_voice == null) return;
|
||||||
|
_voice.Skip("SENTENCE", int.MaxValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -65,6 +65,8 @@ namespace Cryville.EEW.Unity {
|
|||||||
_worker.RVMGeneratorContext = SharedSettings.Instance;
|
_worker.RVMGeneratorContext = SharedSettings.Instance;
|
||||||
_worker.TTSMessageGeneratorContext = SharedSettings.Instance;
|
_worker.TTSMessageGeneratorContext = SharedSettings.Instance;
|
||||||
_worker.RVMCulture = SharedSettings.Instance.RVMCulture;
|
_worker.RVMCulture = SharedSettings.Instance.RVMCulture;
|
||||||
|
_worker.SetTTSCultures(SharedSettings.Instance.TTSCultures ?? new TTSCultureConfig[0]);
|
||||||
|
_worker.IgnoreLanguageVariant = SharedSettings.Instance.DoIgnoreLanguageVariant;
|
||||||
_ongoingReportManager.Changed += OnOngoingReported;
|
_ongoingReportManager.Changed += OnOngoingReported;
|
||||||
_worker.Reported += OnReported;
|
_worker.Reported += OnReported;
|
||||||
_grouper.GroupUpdated += OnGroupUpdated;
|
_grouper.GroupUpdated += OnGroupUpdated;
|
||||||
|
BIN
Assets/Plugins/Windows/Interop.SpeechLib.dll
Normal file
BIN
Assets/Plugins/Windows/Interop.SpeechLib.dll
Normal file
Binary file not shown.
76
Assets/Plugins/Windows/Interop.SpeechLib.dll.meta
Normal file
76
Assets/Plugins/Windows/Interop.SpeechLib.dll.meta
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 17df7db50754b8f459aa29934b507000
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
: Any
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
Exclude Android: 1
|
||||||
|
Exclude Editor: 0
|
||||||
|
Exclude Linux64: 1
|
||||||
|
Exclude OSXUniversal: 1
|
||||||
|
Exclude Win: 0
|
||||||
|
Exclude Win64: 0
|
||||||
|
- first:
|
||||||
|
Android: Android
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: ARMv7
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
OS: AnyOS
|
||||||
|
- first:
|
||||||
|
Standalone: Linux64
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: OSXUniversal
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: None
|
||||||
|
- first:
|
||||||
|
Standalone: Win
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings:
|
||||||
|
CPU: x86
|
||||||
|
- first:
|
||||||
|
Standalone: Win64
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings:
|
||||||
|
CPU: x86_64
|
||||||
|
- first:
|
||||||
|
Windows Store Apps: WindowsStoreApps
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
CPU: AnyCPU
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Reference in New Issue
Block a user