feat: allow volume control and more audio types

Also allow choosing audio output device.
This commit is contained in:
Anna 2020-08-24 13:13:42 -04:00
parent 4eaa0e5169
commit 8475b7effb
5 changed files with 79 additions and 18 deletions

View File

@ -36,6 +36,8 @@ namespace PeepingTom {
public bool FocusTargetOnHover { get; set; } = true;
public bool PlaySoundOnTarget { get; set; } = false;
public string SoundPath { get; set; } = null;
public float SoundVolume { get; set; } = 1f;
public int SoundDevice { get; set; } = -1;
public float SoundCooldown { get; set; } = 10f;
public bool PlaySoundWhenClosed { get; set; } = false;

View File

@ -48,6 +48,9 @@
<Reference Include="ImGuiScene">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\ImGuiScene.dll</HintPath>
</Reference>
<Reference Include="NAudio, Version=1.10.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NAudio.1.10.0\lib\net35\NAudio.dll</HintPath>
</Reference>
<Reference Include="SharpDX.Mathematics, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1" />
<Reference Include="System" />
<Reference Include="System.Core" />

View File

@ -4,6 +4,7 @@ using Dalamud.Game.Chat.SeStringHandling.Payloads;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Actors.Types;
using ImGuiNET;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
@ -89,8 +90,8 @@ namespace PeepingTom {
private void ShowSettings() {
// 700x250 if setting a size
ImGui.SetNextWindowSize(new Vector2(700, 250));
if (ImGui.Begin($"{this.plugin.Name} settings", ref this._settingsOpen)) {
ImGui.SetNextWindowSize(new Vector2(700, 275));
if (ImGui.Begin($"{this.plugin.Name} settings", ref this._settingsOpen, ImGuiWindowFlags.NoResize)) {
if (ImGui.BeginTabBar("##settings-tabs")) {
if (ImGui.BeginTabItem("Markers")) {
bool markTargeted = this.plugin.Config.MarkTargeted;
@ -178,7 +179,7 @@ namespace PeepingTom {
}
string path = this.plugin.Config.SoundPath ?? "";
if (ImGui.InputText("Path to WAV file", ref path, 1_000)) {
if (ImGui.InputText("Path to audio file", ref path, 1_000)) {
path = path.Trim();
this.plugin.Config.SoundPath = path.Length == 0 ? null : path;
this.plugin.Config.Save();
@ -186,6 +187,41 @@ namespace PeepingTom {
ImGui.Text("Leave this blank to use a built-in sound.");
float volume = this.plugin.Config.SoundVolume * 100f;
if (ImGui.DragFloat("Volume of sound", ref volume, .1f, 0f, 100f, "%.1f%%")) {
this.plugin.Config.SoundVolume = Math.Max(0f, Math.Min(1f, volume / 100f));
this.plugin.Config.Save();
}
int soundDevice = this.plugin.Config.SoundDevice;
string name;
if (soundDevice == -1) {
name = "Default";
} else if (soundDevice > -1 && soundDevice < WaveOut.DeviceCount) {
var caps = WaveOut.GetCapabilities(soundDevice);
name = caps.ProductName;
} else {
name = "Invalid device";
}
if (ImGui.BeginCombo("Output device", name)) {
if (ImGui.Selectable("Default")) {
this.plugin.Config.SoundDevice = -1;
this.plugin.Config.Save();
}
ImGui.Separator();
for (int deviceNum = -1; deviceNum < WaveOut.DeviceCount; deviceNum++) {
var caps = WaveOut.GetCapabilities(deviceNum);
if (ImGui.Selectable(caps.ProductName)) {
this.plugin.Config.SoundDevice = deviceNum;
this.plugin.Config.Save();
}
}
ImGui.EndCombo();
}
float soundCooldown = this.plugin.Config.SoundCooldown;
if (ImGui.DragFloat("Cooldown for sound (seconds)", ref soundCooldown, .01f, 0f, 30f)) {
soundCooldown = Math.Max(0f, soundCooldown);
@ -357,7 +393,7 @@ namespace PeepingTom {
}
actors = dict;
}
ImGuiWindowFlags flags = ImGuiWindowFlags.None;
if (!this.plugin.Config.AllowMovement) {
flags |= ImGuiWindowFlags.NoMove;

View File

@ -4,6 +4,7 @@ using Dalamud.Game.Chat.SeStringHandling.Payloads;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.Internal;
using Dalamud.Plugin;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -12,6 +13,7 @@ using System.Linq;
using System.Media;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace PeepingTom {
class TargetWatcher : IDisposable {
@ -188,28 +190,45 @@ namespace PeepingTom {
}
private void PlaySound() {
SoundPlayer player;
if (this.plugin.Config.SoundPath == null) {
player = new SoundPlayer(Properties.Resources.Target);
} else {
player = new SoundPlayer(this.plugin.Config.SoundPath);
int soundDevice = this.plugin.Config.SoundDevice;
if (soundDevice < -1 || soundDevice > WaveOut.DeviceCount) {
soundDevice = -1;
}
using (player) {
new Thread(new ThreadStart(() => {
WaveStream reader;
try {
player.Play();
} catch (FileNotFoundException e) {
this.SendError($"Could not play sound: {e.Message}");
} catch (InvalidOperationException e) {
this.SendError($"Could not play sound: {e.Message}");
if (this.plugin.Config.SoundPath == null) {
reader = new WaveFileReader(Properties.Resources.Target);
} else {
reader = new AudioFileReader(this.plugin.Config.SoundPath);
}
#pragma warning disable CA1031 // Do not catch general exception types
} catch (Exception e) {
#pragma warning restore CA1031 // Do not catch general exception types
this.SendError($"Could not play sound file: {e.Message}");
return;
}
}
using (reader) {
using (var output = new WaveOutEvent() { DeviceNumber = soundDevice }) {
output.Init(reader);
output.Volume = this.plugin.Config.SoundVolume;
output.Play();
while (output.PlaybackState == PlaybackState.Playing) {
Thread.Sleep(500);
}
}
}
})).Start();
}
private void SendError(string message) {
Payload[] payloads = { new TextPayload($"[Who's Looking] {message}") };
Payload[] payloads = { new TextPayload($"[{this.plugin.Name}] {message}") };
this.plugin.Interface.Framework.Gui.Chat.PrintChat(new XivChatEntry {
MessageBytes = new SeString(payloads).Encode(),
Type = XivChatType.ErrorMessage
Type = XivChatType.ErrorMessage,
});
}

View File

@ -5,4 +5,5 @@
<package id="Microsoft.CodeQuality.Analyzers" version="2.9.6" targetFramework="net48" developmentDependency="true" />
<package id="Microsoft.NetCore.Analyzers" version="2.9.6" targetFramework="net48" developmentDependency="true" />
<package id="Microsoft.NetFramework.Analyzers" version="2.9.6" targetFramework="net48" developmentDependency="true" />
<package id="NAudio" version="1.10.0" targetFramework="net48" />
</packages>