Skip to content

Commit

Permalink
change everything
Browse files Browse the repository at this point in the history
  • Loading branch information
spannerisms committed Jul 10, 2024
1 parent 7dd4663 commit a1f4d22
Show file tree
Hide file tree
Showing 38 changed files with 4,011 additions and 904 deletions.
20 changes: 20 additions & 0 deletions Aubio/Aubio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
global using System.Runtime.InteropServices;

namespace Aubio;

public static unsafe class Aubio {
internal const string dll = "libaubio-5.dll";
internal const CharSet CharEnc = CharSet.Ansi;

public static float DetectPitch(WaveContainer wave, PitchDetectionAlgorithm method = PitchDetectionAlgorithm.Default, float? tolerance = null) {
int hopSize = wave.SampleCount;

using var tmp = new PitchDetect(method, (uint) hopSize, (uint) hopSize, (uint) wave.SampleRate);

if (tolerance is float tolf) {
tmp.Tolerance = tolf;
}

return tmp.Do(wave);
}
}
55 changes: 55 additions & 0 deletions Aubio/Fvec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.Diagnostics.CodeAnalysis;

namespace Aubio;

[StructLayout(LayoutKind.Sequential)]
internal abstract unsafe class FvecBase : IDisposable {
public readonly uint Count;
public readonly nint ptr;
private bool amDead;

protected FvecBase(uint count, nint size) {
Count = count;
ptr = Marshal.AllocHGlobal(size);
}

~FvecBase() {
Dispose(false);
}

protected virtual void Dispose(bool disposing) {
if (!amDead) {
if (disposing) {
Marshal.FreeHGlobal(ptr);
}

amDead = true;
}
}

public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}

[StructLayout(LayoutKind.Sequential)]
internal unsafe sealed class FvecRet : FvecBase {
public FvecRet() : base(1, sizeof(float)) {
}

// again, this is just a float
public static implicit operator float(FvecRet f) => ((float*) f.ptr)[0];
}

[StructLayout(LayoutKind.Sequential)]
internal unsafe class FvecSamples : FvecBase {

public FvecSamples(WaveContainer samples) : base((uint) samples.SampleCount, samples.SampleCount * sizeof(float)) {
float* fsamps = (float*) ptr;

for (int i = 0; i < Count; i++) {
fsamps[i] = samples[i];
}
}
}
131 changes: 131 additions & 0 deletions Aubio/PitchDetect.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
namespace Aubio;

public sealed unsafe partial class PitchDetect : IDisposable {
private readonly PitchT* _cstruct;

public int Type => _cstruct->type;
public int Mode => _cstruct->mode;

public float Silence {
get => _cstruct->silence;
set => _cstruct->silence = Math.Clamp(value, -200F, 0F);
}

private string _pitchUnit = "Hz";
public string PitchUnit {
get => _pitchUnit;
set {
string clean = value?.ToLowerInvariant() switch {
"hz" or
"hertz" or
"frequency" or
"freq" => "Hz",

"midi" => "midi",

"cent" or
"cents" => "cent",

"bin" => "bin",

_ => throw new ArgumentException($"Invalid unit: {value}")
};

_pitchUnit = clean;
aubio_pitch_set_unit(_cstruct, _pitchUnit);

//[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_set_unit", StringMarshalling = StringMarshalling.Utf8)]
[DllImport(Aubio.dll, EntryPoint = "aubio_pitch_set_unit", CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool aubio_pitch_set_unit(PitchT* t, string s);
}
}

private uint _toleranceError = 0;
private bool meGone;

public float Tolerance {
get {
return aubio_pitch_get_tolerance(_cstruct);

//[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_get_tolerance")]
[DllImport(Aubio.dll, EntryPoint = "aubio_pitch_get_tolerance")]
[return: MarshalAs(UnmanagedType.R4)]
static extern float aubio_pitch_get_tolerance(PitchT* p);
}
set {
_toleranceError = aubio_pitch_set_tolerance(_cstruct, value);

//[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_set_tolerance")]
[DllImport(Aubio.dll, EntryPoint = "aubio_pitch_set_tolerance")]
[return: MarshalAs(UnmanagedType.U4)]
static extern uint aubio_pitch_set_tolerance(PitchT* p, float v);
}
}


/// <summary>
/// Pitch Detective
/// </summary>
public PitchDetect(PitchDetectionAlgorithm method, uint bufferSize, uint hopSize, uint sampleRate) {
_cstruct = new_aubio_pitch(method.GetToken(), bufferSize, hopSize, sampleRate);
}

[LibraryImport(Aubio.dll, EntryPoint = "new_aubio_pitch", StringMarshalling = StringMarshalling.Utf8)]
private static partial PitchT* new_aubio_pitch(string method, uint bufferSize, uint hopSize, uint sampleRate);

public float Do(WaveContainer w) {
using FvecRet ret = new();
using FvecSamples samps = new(w);
aubio_pitch_do(_cstruct, samps, ret);

return ret;

//[LibraryImport(Aubio.dll, EntryPoint = "aubio_pitch_do")]
[DllImport(Aubio.dll, EntryPoint = "aubio_pitch_do")]
static extern void aubio_pitch_do(PitchT* p, FvecSamples ptr, FvecRet retPtr);
}

~PitchDetect() {
Dispose(false);
}

private void Dispose(bool disposing) {
if (!meGone) {
if (disposing) {
del_aubio_pitch(_cstruct);

//[LibraryImport(Aubio.dll, EntryPoint = "del_aubio_pitch")]
[DllImport(Aubio.dll, EntryPoint = "del_aubio_pitch")]
static extern void del_aubio_pitch(PitchT* p);
}

meGone = true;
}
}

public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}

// This should never actually be created as a managed struct
// it only exists as a wrapper for member access to the unmanaged memory created by the aubio library
[StructLayout(LayoutKind.Sequential)]
private unsafe struct PitchT {
public int type;
public int mode;
public uint samplerate;
public uint bufsize;
public void* pobject;
public void* filter;
public void* filtered;
public void* pv;
public void* fftgrain;
public void* buf;
public void* detect_cb;
public void* conv_cb;
public void* conf_cb;
public float silence;
}
}
41 changes: 41 additions & 0 deletions Aubio/PitchDetectionAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace Aubio;

public enum PitchDetectionAlgorithm {
Default = 0,

YIN,
YINFast,
Schmitt,

// TODO these aren't actually implemented in the current dll this calls
FComb,
MComb,
YINFFT,
SpecAcf
}

public static class PitchDetectionAlgorithmExtensions {
public static string GetToken(this PitchDetectionAlgorithm p) => p switch {
PitchDetectionAlgorithm.Default or
PitchDetectionAlgorithm.YIN => "yin",
PitchDetectionAlgorithm.YINFast => "yinfast",
PitchDetectionAlgorithm.Schmitt => "schmitt",
PitchDetectionAlgorithm.FComb => "fcomb",
PitchDetectionAlgorithm.MComb => "mcomb",
PitchDetectionAlgorithm.YINFFT => "yinfft",
PitchDetectionAlgorithm.SpecAcf => "specacf",
_ => throw new ArgumentException($"Not a valid {nameof(PitchDetectionAlgorithm)}!"),
};

public static string GetName(this PitchDetectionAlgorithm p) => p switch {
PitchDetectionAlgorithm.Default => "Default algorithm",
PitchDetectionAlgorithm.YIN => "YIN",
PitchDetectionAlgorithm.YINFast => "YIN but fast",
PitchDetectionAlgorithm.Schmitt => "Schmitt trigger",
PitchDetectionAlgorithm.FComb => "Fast comb filter",
PitchDetectionAlgorithm.MComb => "Multi-comb filter",
PitchDetectionAlgorithm.YINFFT => "Spectral YIN",
PitchDetectionAlgorithm.SpecAcf => "Spectral autocorrelation",
_ => throw new ArgumentException($"Not a valid {nameof(PitchDetectionAlgorithm)}!"),
};
}
7 changes: 7 additions & 0 deletions BRRSuiteGUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
</PropertyGroup>

<ItemGroup>
<None Remove="Resources\brrsuiteengine.bin" />
<None Remove="version.xml" />
</ItemGroup>

Expand Down Expand Up @@ -65,6 +66,9 @@
</ItemGroup>

<ItemGroup>
<None Update="libaubio-5.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
Expand All @@ -78,6 +82,9 @@
<None Update="Resources\logofull.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="testengine.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
30 changes: 30 additions & 0 deletions Controls/RoundedUpDown.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.ComponentModel;

namespace BRRSuiteGUI;

[DefaultProperty(nameof(Value))]
[DefaultEvent(nameof(ValueChanged))]
[DefaultBindingProperty(nameof(Value))]
internal class RoundedUpDown : NumericUpDown {
public RoundedUpDown() : base() { }

[Bindable(true)]
public new decimal Value {
get => base.Value;
set => base.Value = decimal.Round(value, DecimalPlaces, MidpointRounding.ToZero);
}

protected override void OnMouseWheel(MouseEventArgs e) {
if (e is HandledMouseEventArgs f) {
f.Handled = true;
}

if (e.Delta > 0) {
UpButton();
} else if (e.Delta < 0) {
DownButton();
}

base.OnMouseWheel(e);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private void LinkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs
Process.Start("explorer.exe", "https://github.com/tewtal/mITroid/blob/master/mITroid/NSPC/BRR.cs/");
}

private void pictureBox1_Click(object sender, EventArgs e) {
private void IClickedTheLogo(object sender, EventArgs e) {
Process.Start("explorer.exe", "https://github.com/spannerisms/BRRSuiteGUI/");
}
}
File renamed without changes.
Loading

0 comments on commit a1f4d22

Please sign in to comment.