Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multi-select, pick random sound #6

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions UI/Components/SoundComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private void State_OnSplit(object sender, EventArgs e)
}
else
{
var path = string.Empty;
var path = new string[] { };
int volume = Settings.SplitVolume;

var splitIndex = State.CurrentSplitIndex - 1;
Expand Down Expand Up @@ -127,7 +127,7 @@ private void State_OnSplit(object sender, EventArgs e)
}
}

if (string.IsNullOrEmpty(path))
if (path == null || path.Length == 0)
path = Settings.Split;

PlaySound(path, volume);
Expand Down Expand Up @@ -160,28 +160,37 @@ private void State_OnReset(object sender, TimerPhase e)
PlaySound(Settings.Reset, Settings.ResetVolume);
}

private void PlaySound(string location, int volume)
private void PlaySound(string[] location, int volume)
{
Player.Stop();

if (Activated && File.Exists(location))

if (location != null && location.Length != 0)
{
Task.Factory.StartNew(() =>
var rnd = new Random();
int lIndex = rnd.Next(0, location.Length);

var soundLocation = location[lIndex];

if (Activated && File.Exists(soundLocation))
{
try
Task.Factory.StartNew(() =>
{
AudioFileReader audioFileReader = new AudioFileReader(location);
audioFileReader.Volume = (volume / 100f) * (Settings.GeneralVolume / 100f);
try
{
AudioFileReader audioFileReader = new AudioFileReader(soundLocation);
audioFileReader.Volume = (volume / 100f) * (Settings.GeneralVolume / 100f);

Player.DeviceNumber = Settings.OutputDevice;
Player.Init(audioFileReader);
Player.Play();
}
catch (Exception e)
{
Log.Error(e);
}
});
Player.DeviceNumber = Settings.OutputDevice;
Player.Init(audioFileReader);
Player.Play();
}
catch (Exception e)
{
Log.Error(e);
}
});
}
}
}

Expand Down
144 changes: 82 additions & 62 deletions UI/Components/SoundSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,35 @@ namespace LiveSplit.UI.Components
{
public partial class SoundSettings : UserControl
{
public string Split { get; set; }
public string SplitAheadGaining { get; set; }
public string SplitAheadLosing { get; set; }
public string SplitBehindGaining { get; set; }
public string SplitBehindLosing { get; set; }
public string BestSegment { get; set; }
public string UndoSplit { get; set; }
public string SkipSplit { get; set; }
public string PersonalBest { get; set; }
public string NotAPersonalBest { get; set; }
public string Reset { get; set; }
public string Pause { get; set; }
public string Resume { get; set; }
public string StartTimer { get; set; }
public string[] Split { get; set; }
public string SplitText { get { return string.Join(",", Split); } set { Split = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] SplitAheadGaining { get; set; }
public string SplitAheadGainingText { get { return string.Join(",", SplitAheadGaining); } set { SplitAheadGaining = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] SplitAheadLosing { get; set; }
public string SplitAheadLosingText { get { return string.Join(",", SplitAheadLosing); } set { SplitAheadLosing = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] SplitBehindGaining { get; set; }
public string SplitBehindGainingText { get { return string.Join(",", SplitBehindGaining); } set { SplitBehindGaining = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] SplitBehindLosing { get; set; }
public string SplitBehindLosingText { get { return string.Join(",", SplitBehindLosing); } set { SplitBehindLosing = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] BestSegment { get; set; }
public string BestSegmentText { get { return string.Join(",", BestSegment); } set { BestSegment = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] UndoSplit { get; set; }
public string UndoSplitText { get { return string.Join(",", UndoSplit); } set { UndoSplit = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] SkipSplit { get; set; }
public string SkipSplitText { get { return string.Join(",", SkipSplit); } set { SkipSplit = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] PersonalBest { get; set; }
public string PersonalBestText { get { return string.Join(",", PersonalBest); } set { PersonalBest = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] NotAPersonalBest { get; set; }
public string NotAPersonalBestText { get { return string.Join(",", NotAPersonalBest); } set { NotAPersonalBest = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] Reset { get; set; }
// Uses different name because ResetText hides Control.ResetText otherwise.
public string ResetSoundText { get { return string.Join(",", Reset); } set { Reset = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] Pause { get; set; }
public string PauseText { get { return string.Join(",", Pause); } set { Pause = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] Resume { get; set; }
public string ResumeText { get { return string.Join(",", Resume); } set { Resume = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }
public string[] StartTimer { get; set; }
public string StartTimerText { get { return string.Join(",", StartTimer); } set { StartTimer = value.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); } }

public int OutputDevice { get; set; }

Expand Down Expand Up @@ -57,7 +72,7 @@ public SoundSettings()
Reset =
Pause =
Resume =
StartTimer = "";
StartTimer = new string[] { "" };

OutputDevice = 0;

Expand All @@ -80,20 +95,20 @@ public SoundSettings()
for (int i = 0; i < WaveOut.DeviceCount; ++i)
cbOutputDevice.Items.Add(WaveOut.GetCapabilities(i));

txtSplitPath.DataBindings.Add("Text", this, "Split");
txtSplitAheadGaining.DataBindings.Add("Text", this, "SplitAheadGaining");
txtSplitAheadLosing.DataBindings.Add("Text", this, "SplitAheadLosing");
txtSplitBehindGaining.DataBindings.Add("Text", this, "SplitBehindGaining");
txtSplitBehindLosing.DataBindings.Add("Text", this, "SplitBehindLosing");
txtBestSegment.DataBindings.Add("Text", this, "BestSegment");
txtUndo.DataBindings.Add("Text", this, "UndoSplit");
txtSkip.DataBindings.Add("Text", this, "SkipSplit");
txtPersonalBest.DataBindings.Add("Text", this, "PersonalBest");
txtNotAPersonalBest.DataBindings.Add("Text", this, "NotAPersonalBest");
txtReset.DataBindings.Add("Text", this, "Reset");
txtPause.DataBindings.Add("Text", this, "Pause");
txtResume.DataBindings.Add("Text", this, "Resume");
txtStartTimer.DataBindings.Add("Text", this, "StartTimer");
txtSplitPath.DataBindings.Add("Text", this, "SplitText");
txtSplitAheadGaining.DataBindings.Add("Text", this, "SplitAheadGainingText");
txtSplitAheadLosing.DataBindings.Add("Text", this, "SplitAheadLosingText");
txtSplitBehindGaining.DataBindings.Add("Text", this, "SplitBehindGainingText");
txtSplitBehindLosing.DataBindings.Add("Text", this, "SplitBehindLosingText");
txtBestSegment.DataBindings.Add("Text", this, "BestSegmentText");
txtUndo.DataBindings.Add("Text", this, "UndoSplitText");
txtSkip.DataBindings.Add("Text", this, "SkipSplitText");
txtPersonalBest.DataBindings.Add("Text", this, "PersonalBestText");
txtNotAPersonalBest.DataBindings.Add("Text", this, "NotAPersonalBestText");
txtReset.DataBindings.Add("Text", this, "ResetSoundText");
txtPause.DataBindings.Add("Text", this, "PauseText");
txtResume.DataBindings.Add("Text", this, "ResumeText");
txtStartTimer.DataBindings.Add("Text", this, "StartTimerText");

cbOutputDevice.DataBindings.Add("SelectedIndex", this, "OutputDevice");

Expand All @@ -118,20 +133,20 @@ public void SetSettings(XmlNode node)
{
var element = (XmlElement)node;

Split = SettingsHelper.ParseString(element["Split"]);
SplitAheadGaining = SettingsHelper.ParseString(element["SplitAheadGaining"]);
SplitAheadLosing = SettingsHelper.ParseString(element["SplitAheadLosing"]);
SplitBehindGaining = SettingsHelper.ParseString(element["SplitBehindGaining"]);
SplitBehindLosing = SettingsHelper.ParseString(element["SplitBehindLosing"]);
BestSegment = SettingsHelper.ParseString(element["BestSegment"]);
UndoSplit = SettingsHelper.ParseString(element["UndoSplit"]);
SkipSplit = SettingsHelper.ParseString(element["SkipSplit"]);
PersonalBest = SettingsHelper.ParseString(element["PersonalBest"]);
NotAPersonalBest = SettingsHelper.ParseString(element["NotAPersonalBest"]);
Reset = SettingsHelper.ParseString(element["Reset"]);
Pause = SettingsHelper.ParseString(element["Pause"]);
Resume = SettingsHelper.ParseString(element["Resume"]);
StartTimer = SettingsHelper.ParseString(element["StartTimer"]);
Split = SettingsHelper.ParseString(element["Split"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
SplitAheadGaining = SettingsHelper.ParseString(element["SplitAheadGaining"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
SplitAheadLosing = SettingsHelper.ParseString(element["SplitAheadLosing"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
SplitBehindGaining = SettingsHelper.ParseString(element["SplitBehindGaining"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
SplitBehindLosing = SettingsHelper.ParseString(element["SplitBehindLosing"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
BestSegment = SettingsHelper.ParseString(element["BestSegment"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
UndoSplit = SettingsHelper.ParseString(element["UndoSplit"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
SkipSplit = SettingsHelper.ParseString(element["SkipSplit"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
PersonalBest = SettingsHelper.ParseString(element["PersonalBest"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
NotAPersonalBest = SettingsHelper.ParseString(element["NotAPersonalBest"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
Reset = SettingsHelper.ParseString(element["Reset"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
Pause = SettingsHelper.ParseString(element["Pause"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
Resume = SettingsHelper.ParseString(element["Resume"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
StartTimer = SettingsHelper.ParseString(element["StartTimer"]).Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);

OutputDevice = SettingsHelper.ParseInt(element["OutputDevice"]);

Expand Down Expand Up @@ -167,20 +182,20 @@ public int GetSettingsHashCode()
private int CreateSettingsNode(XmlDocument document, XmlElement parent)
{
return SettingsHelper.CreateSetting(document, parent, "Version", "1.6") ^
SettingsHelper.CreateSetting(document, parent, "Split", Split) ^
SettingsHelper.CreateSetting(document, parent, "SplitAheadGaining", SplitAheadGaining) ^
SettingsHelper.CreateSetting(document, parent, "SplitAheadLosing", SplitAheadLosing) ^
SettingsHelper.CreateSetting(document, parent, "SplitBehindGaining", SplitBehindGaining) ^
SettingsHelper.CreateSetting(document, parent, "SplitBehindLosing", SplitBehindLosing) ^
SettingsHelper.CreateSetting(document, parent, "BestSegment", BestSegment) ^
SettingsHelper.CreateSetting(document, parent, "UndoSplit", UndoSplit) ^
SettingsHelper.CreateSetting(document, parent, "SkipSplit", SkipSplit) ^
SettingsHelper.CreateSetting(document, parent, "PersonalBest", PersonalBest) ^
SettingsHelper.CreateSetting(document, parent, "NotAPersonalBest", NotAPersonalBest) ^
SettingsHelper.CreateSetting(document, parent, "Reset", Reset) ^
SettingsHelper.CreateSetting(document, parent, "Pause", Pause) ^
SettingsHelper.CreateSetting(document, parent, "Resume", Resume) ^
SettingsHelper.CreateSetting(document, parent, "StartTimer", StartTimer) ^
SettingsHelper.CreateSetting(document, parent, "Split", string.Join(",", Split)) ^
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'd want to store the multiple paths as child XML elements instead of having a comma separated list.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wanting this functionality, but unsure how the SettingsHelper works. Are you suggesting looping over Split and adding each to "Split1", "Split2", or something similar?

Copy link
Author

@FrozenSake FrozenSake Aug 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a refactor that I could potentially look in to, but honestly since it takes ~5-6 months per review, and I do not program in C# any more, I've largely given up on this pull request.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I held off on making changes too, in hopes my comment would lead to more info. It seems the maintainers have other plans than getting this and the other PRs ready. Understandable, everyone's busy these days 🤷

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest bumping the PR (by leaving a comment and tagging me) to get quicker reviews. But yeah, I've been pretty busy with other stuff recently.

I was hoping the XML would look something like this:

<Split>
  <Sound>my sound 1</Sound>
  <Sound>my sound 2</Sound>
</Split>

I'm not entirely sure how you do that with the SettingsHelper, but it should be possible. The Splits component might be a good reference, since that component has a list of columns in its settings.

SettingsHelper.CreateSetting(document, parent, "SplitAheadGaining", string.Join(",", SplitAheadGaining)) ^
SettingsHelper.CreateSetting(document, parent, "SplitAheadLosing", string.Join(",", SplitAheadLosing)) ^
SettingsHelper.CreateSetting(document, parent, "SplitBehindGaining", string.Join(",", SplitBehindGaining)) ^
SettingsHelper.CreateSetting(document, parent, "SplitBehindLosing", string.Join(",", SplitBehindLosing)) ^
SettingsHelper.CreateSetting(document, parent, "BestSegment", string.Join(",", BestSegment)) ^
SettingsHelper.CreateSetting(document, parent, "UndoSplit", string.Join(",", UndoSplit)) ^
SettingsHelper.CreateSetting(document, parent, "SkipSplit", string.Join(",", SkipSplit)) ^
SettingsHelper.CreateSetting(document, parent, "PersonalBest", string.Join(",", PersonalBest)) ^
SettingsHelper.CreateSetting(document, parent, "NotAPersonalBest", string.Join(",", NotAPersonalBest)) ^
SettingsHelper.CreateSetting(document, parent, "Reset", string.Join(",", Reset)) ^
SettingsHelper.CreateSetting(document, parent, "Pause", string.Join(",", Pause)) ^
SettingsHelper.CreateSetting(document, parent, "Resume", string.Join(",", Resume)) ^
SettingsHelper.CreateSetting(document, parent, "StartTimer", string.Join(",", StartTimer)) ^
SettingsHelper.CreateSetting(document, parent, "OutputDevice", OutputDevice) ^
SettingsHelper.CreateSetting(document, parent, "SplitVolume", SplitVolume) ^
SettingsHelper.CreateSetting(document, parent, "SplitAheadGainingVolume", SplitAheadGainingVolume) ^
Expand All @@ -199,24 +214,29 @@ private int CreateSettingsNode(XmlDocument document, XmlElement parent)
SettingsHelper.CreateSetting(document, parent, "GeneralVolume", GeneralVolume);
}

protected string BrowseForPath(TextBox textBox, Action<string> callback)
protected string[] BrowseForPath(TextBox textBox, Action<string[]> callback)
{
var path = textBox.Text;
var pathArray = new string[] { "" };
var fileDialog = new OpenFileDialog()
{
FileName = path,
Filter = "Audio Files|*.mp3;*.wav;*.aiff;*.wma|All Files|*.*"
Filter = "Audio Files|*.mp3;*.wav;*.aiff;*.wma|All Files|*.*",
Multiselect = true
};

var result = fileDialog.ShowDialog();

if (result == DialogResult.OK)
path = fileDialog.FileName;
path = String.Join(",", fileDialog.FileNames);
pathArray = fileDialog.FileNames;
if (path == null || path.Length == 0)
path = "";

textBox.Text = path;
callback(path);
callback(pathArray);

return path;
return pathArray;
}

private void btnSplit_Click(object sender, EventArgs e)
Expand Down