Skip to content

Commit 87d129a

Browse files
committed
Major refactoring: making audio sources and NoteFinders instantiable, and adding the ability for there to be more than 1 running at a time. This means several breaking API changes, and a ton of changes throughout, but opens the door to some new capabilities I look forward to using.
1 parent 1ccd825 commit 87d129a

40 files changed

+600
-469
lines changed

ColorChord.NET-API/ColorChordAPI.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public static class ColorChordAPI
66
{
77
/// <summary>Use this version as return value for <see cref="Extensions.IExtension.APIVersion"/> in your extension.</summary>
88
/// <remarks>This allows ColorChord.NET to know if the installed version of your extension is compatible.</remarks>
9-
public const uint APIVersion = 21;
9+
public const uint APIVersion = 22;
1010

1111
public static IConfigurer Configurer;
1212
}

ColorChord.NET-API/Config/ConfigNames.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,31 @@
44
/// <remarks>Using these helps prevent different classes having different config names for the same options.</remarks>
55
public static class ConfigNames
66
{
7+
public const string SECTION_SOURCE = "Source";
8+
public const string SECTION_SOURCE_ARR = "Sources";
9+
public const string SECTION_NOTE_FINDER = "NoteFinder";
10+
public const string SECTION_NOTE_FINDER_ARR = "NoteFinders";
11+
public const string SECTION_VISUALIZER = "Visualizer";
12+
public const string SECTION_VISUALIZER_ARR = "Visualizers";
13+
public const string SECTION_OUTPUT = "Output";
14+
public const string SECTION_OUTPUT_ARR = "Outputs";
15+
public const string SECTION_CONTROLLER = "Controller";
16+
public const string SECTION_CONTROLLER_ARR = "Controllers";
17+
718
public const string TYPE = "Type";
819
public const string NAME = "Name";
920
public const string ENABLE = "Enable";
1021
public const string TARGET = "Target";
1122
public const string LED_COUNT = "LEDCount";
23+
24+
/// <summary>Used as the key for when a component needs to know the name of a <see cref="ColorChord.NET.API.Sources.IAudioSource"/> to reference.</summary>
25+
public const string SOURCE_NAME = "SourceName";
26+
/// <summary>Used as the key for when a component needs to know the name of a <see cref="ColorChord.NET.API.NoteFinder.NoteFinderCommon"/> to reference.</summary>
27+
public const string NOTE_FINDER_NAME = "NoteFinderName";
28+
/// <summary>Used as the key for when a component needs to know the name of a <see cref="ColorChord.NET.API.Outputs.IOutput"/> to reference.</summary>
29+
public const string OUTPUT_NAME = "OutputName";
30+
/// <summary>Used as the key for when a component needs to know the name of a <see cref="ColorChord.NET.API.Visualizers.IVisualizer"/> to reference.</summary>
31+
public const string VIZ_NAME = "VisualizerName";
32+
/// <summary>Used as the key for when a component needs to know the name of a <see cref="ColorChord.NET.API.Controllers.Controller"/> to reference.</summary>
33+
public const string CONTROLLER_NAME = "ControllerName";
1234
}

ColorChord.NET-API/Config/IConfigurer.cs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
using ColorChord.NET.API.Outputs;
1+
using ColorChord.NET.API.Controllers;
2+
using ColorChord.NET.API.NoteFinder;
3+
using ColorChord.NET.API.Outputs;
4+
using ColorChord.NET.API.Sources;
25
using ColorChord.NET.API.Visualizers;
6+
using ColorChord.NET.API.Visualizers.Formats;
37

48
namespace ColorChord.NET.API.Config;
59

@@ -15,16 +19,38 @@ public interface IConfigurer
1519
/// <exception cref="NotImplementedException">If the attribute is one that is not yet supported.</exception>
1620
public bool Configure(object targetObj, Dictionary<string, object> config, bool warnAboutRemainder = true);
1721

18-
/// <summary>Used by outputs. Reads the config, and finds the visualizer instance that this output should attach to.</summary>
19-
/// <param name="target">The output that will attach to the visualizer.</param>
20-
/// <param name="config">The config entries which will be used in finding the appropriate visualizer.</param>
21-
/// <returns>The visualizer that this output should attach to.</returns>
22-
public IVisualizer? FindVisualizer(IOutput target, Dictionary<string, object> config);
22+
/// <summary>Reads the given config and finds the corresponding loaded <see cref="IAudioSource"/> instance.</summary>
23+
/// <remarks>Intended to be used by <see cref="NoteFinderCommon"/> instances to find their audio source to attach to.</remarks>
24+
/// <param name="config">The config section of a component which needs to find an audio source, the <see cref="ConfigNames.SOURCE_NAME"/> key will be used to find it by name. If the key is missing and there is only one audio source present, it is returned.</param>
25+
/// <returns>The audio source instance if it was found, null otherwise.</returns>
26+
public IAudioSource? FindSource(Dictionary<string, object> config);
27+
28+
/// <summary>Reads the given config and finds the corresponding loaded <see cref="NoteFinderCommon"/> instance.</summary>
29+
/// <remarks>Intended to be used by <see cref="IVisualizer"/> instances to find their NoteFinder to attach to.</remarks>
30+
/// <param name="config">The config section of a component which needs to find a NoteFinder, the <see cref="ConfigNames.NOTE_FINDER_NAME"/> key will be used to find it by name. If the key is missing and there is only one NoteFinder present, it is returned.</param>
31+
/// <returns>The NoteFinder instance if it was found, null otherwise.</returns>
32+
public NoteFinderCommon? FindNoteFinder(Dictionary<string, object> config);
33+
34+
/// <summary>Reads the given config and finds the corresponding loaded <see cref="IVisualizer"/> instance.</summary>
35+
/// <remarks>Intended to be used by <see cref="IOutput"/> instances to find their visualizer to attach to.</remarks>
36+
/// <param name="config">The config section of a component which needs to find a visualizer, the <see cref="ConfigNames.VIZ_NAME"/> key will be used to find it by name.</param>
37+
/// <returns>The visualizer instance if it was found, null otherwise.</returns>
38+
public IVisualizer? FindVisualizer(Dictionary<string, object> config);
2339

2440
/// <summary>Used by outputs. Reads the config, and finds the visualizer instance that this output should attach to.</summary>
2541
/// <param name="target">The output that will attach to the visualizer.</param>
2642
/// <param name="config">The config entries which will be used in finding the appropriate visualizer.</param>
2743
/// <param name="acceptableFormat">The <see cref="IVisualizerFormat"/> type that is accepted by this output.</param>
28-
/// <returns>The visualizer that this output should attach to.</returns>
44+
/// <returns>The visualizer that this output should attach to if it was found, null otherwise.</returns>
2945
public IVisualizer? FindVisualizer(IOutput target, Dictionary<string, object> config, Type acceptableFormat);
46+
47+
/// <summary>Reads the given config and finds the corresponding loaded <see cref="IOutput"/> instance.</summary>
48+
/// <param name="config">The config section of a component which needs to find an output, the <see cref="ConfigNames.OUTPUT_NAME"/> key will be used to find it by name.</param>
49+
/// <returns>The output instance if it was found, null otherwise.</returns>
50+
public IOutput? FindOutput(Dictionary<string, object> config);
51+
52+
/// <summary>Reads the given config and finds the corresponding loaded <see cref="Controller"/> instance.</summary>
53+
/// <param name="config">The config section of a component which needs to find a controller, the <see cref="ConfigNames.CONTROLLER_NAME"/> key will be used to find it by name.</param>
54+
/// <returns>The controller instance if it was found, null otherwise.</returns>
55+
public Controller? FindController(Dictionary<string, object> config);
3056
}

ColorChord.NET-API/NoteFinder/NoteFinderCommon.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ namespace ColorChord.NET.API.NoteFinder;
55

66
public abstract class NoteFinderCommon : IConfigurableAttr
77
{
8+
public abstract string Name { get; protected init; }
9+
810
/// <summary> When data was last added to the buffer. Used to detect idle state. </summary>
9-
public static DateTime LastDataAdd { get; set; }
11+
public DateTime LastDataAdd { get; private set; }
1012

1113
/// <summary> The speed (in ms between runs) at which the note finder needs to run, set by the fastest visualizer. </summary>
12-
public static uint ShortestPeriod { get; protected set; } = 100;
14+
public uint ShortestPeriod { get; protected set; } = 100;
1315

1416
/// <summary> The frequency spectrum data, before folding into a single octave. </summary>
1517
public abstract ReadOnlySpan<float> AllBinValues { get; }
@@ -23,7 +25,7 @@ public abstract class NoteFinderCommon : IConfigurableAttr
2325
/// <summary> Used to keep track of locations of notes that stay between frames in <see cref="Notes"/>, as that array's order may change. </summary>
2426
public abstract ReadOnlySpan<int> PersistentNoteIDs { get; }
2527

26-
public static AutoResetEvent InputDataEvent { get; protected set; } = new(false);
28+
public AutoResetEvent InputDataEvent { get; protected set; } = new(false);
2729

2830
/// <summary>How many note slots there are. Usually not all are in use.</summary>
2931
public abstract int NoteCount { get; } // TODO: Finish docs
@@ -41,10 +43,10 @@ public abstract class NoteFinderCommon : IConfigurableAttr
4143

4244

4345
private const int INTERMEDIATE_BUFFER_COUNT = 4;
44-
private static readonly IntermediateBuffer[] IntermediateBuffers = new IntermediateBuffer[INTERMEDIATE_BUFFER_COUNT];
45-
private static readonly int[] IntermediateBuffersToRead = new int[INTERMEDIATE_BUFFER_COUNT];
46+
private readonly IntermediateBuffer[] IntermediateBuffers = new IntermediateBuffer[INTERMEDIATE_BUFFER_COUNT];
47+
private readonly int[] IntermediateBuffersToRead = new int[INTERMEDIATE_BUFFER_COUNT];
4648

47-
public static void SetupBuffers()
49+
public void SetupBuffers()
4850
{
4951
for (int i = 0; i < INTERMEDIATE_BUFFER_COUNT; i++)
5052
{
@@ -53,7 +55,7 @@ public static void SetupBuffers()
5355
}
5456
}
5557

56-
public static short[]? GetBufferToWrite(out int bufferRef)
58+
public short[]? GetBufferToWrite(out int bufferRef)
5759
{
5860
for (int i = 0; i < INTERMEDIATE_BUFFER_COUNT; i++)
5961
{
@@ -68,7 +70,7 @@ public static void SetupBuffers()
6870
return null;
6971
}
7072

71-
public static short[]? GetBufferToRead(out int bufferRef, out uint amountToRead, out bool moreAvailable)
73+
public short[]? GetBufferToRead(out int bufferRef, out uint amountToRead, out bool moreAvailable)
7274
{
7375
lock (IntermediateBuffersToRead)
7476
{
@@ -91,7 +93,7 @@ public static void SetupBuffers()
9193
}
9294
}
9395

94-
public static bool IsBufferAvailableToWrite()
96+
public bool IsBufferAvailableToWrite()
9597
{
9698
for (int i = 0; i < INTERMEDIATE_BUFFER_COUNT; i++)
9799
{
@@ -100,16 +102,17 @@ public static bool IsBufferAvailableToWrite()
100102
return false;
101103
}
102104

103-
public static void FinishBufferRead(int bufferRef)
105+
public void FinishBufferRead(int bufferRef)
104106
{
105107
IntermediateBuffers[bufferRef].ReadMode = false;
106108
}
107109

108-
public static void FinishBufferWrite(int bufferRef, uint amountWritten)
110+
public void FinishBufferWrite(int bufferRef, uint amountWritten)
109111
{
110112
if (bufferRef == -1) { return; }
111113
IntermediateBuffers[bufferRef].DataCount = amountWritten;
112114
IntermediateBuffers[bufferRef].ReadMode = true;
115+
this.LastDataAdd = DateTime.UtcNow;
113116
lock (IntermediateBuffersToRead)
114117
{
115118
for (int i = 0; i < INTERMEDIATE_BUFFER_COUNT; i++)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
using ColorChord.NET.API.Config;
2+
using ColorChord.NET.API.NoteFinder;
23

34
namespace ColorChord.NET.API.Sources;
45

56
public interface IAudioSource : IConfigurableAttr
67
{
8+
string Name { get; }
79
void Start();
810
void Stop();
11+
uint GetSampleRate();
12+
void AttachNoteFinder(NoteFinderCommon noteFinder);
913
}

ColorChord.NET-API/ThreadedInstanceAttribute.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace ColorChord.NET.API.Utility;
2+
3+
public interface IThreadedInstance
4+
{
5+
/// <summary> This method is called on the managed instance thread after the constructor is finished. </summary>
6+
/// <remarks> For example, this is useful if you need to run a continued loop on the instance thread. </remarks>
7+
public void InstThreadPostInit();
8+
}

ColorChord.NET-API/Visualizers/IVisualizer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using ColorChord.NET.API.Config;
2+
using ColorChord.NET.API.NoteFinder;
23
using ColorChord.NET.API.Outputs;
34

45
namespace ColorChord.NET.API.Visualizers;
56

67
public interface IVisualizer : IConfigurableAttr
78
{
89
string Name { get; }
10+
NoteFinderCommon? NoteFinder { get; }
911
void Start();
1012
void Stop();
1113
void AttachOutput(IOutput output);

0 commit comments

Comments
 (0)