From 9054f529a0681ed1be0636597a36c42484071797 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Thu, 20 Mar 2014 20:23:47 +0100 Subject: [PATCH 01/34] Change CPortAudioCommon to be static class only to allow inheritance in record and playback classes (later) --- Vocaluxe/GlobalSuppressions.cs | 20 +--------- Vocaluxe/Lib/Sound/CPortAudioCommon.cs | 40 +++++++++---------- .../Playback/PortAudio/CPortAudioStream.cs | 22 +++++----- .../Record/PortAudio/CPortAudioRecord.cs | 14 +++---- 4 files changed, 39 insertions(+), 57 deletions(-) diff --git a/Vocaluxe/GlobalSuppressions.cs b/Vocaluxe/GlobalSuppressions.cs index da284174..8a667a11 100644 --- a/Vocaluxe/GlobalSuppressions.cs +++ b/Vocaluxe/GlobalSuppressions.cs @@ -38,9 +38,6 @@ using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Objekte verwerfen, bevor Bereich verloren geht", Scope = "member", Target = "Vocaluxe.Lib.Draw.CDirect3D.#CopyScreen()") ] [assembly: SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Scope = "type", Target = "Vocaluxe.Lib.Input.WiiMote.InputReport")] -[assembly: SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Scope = "type", Target = "PortAudioSharp.PortAudio+PaDeviceIndex")] -[assembly: SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Scope = "type", Target = "PortAudioSharp.PortAudio+PaSampleFormat")] -[assembly: SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Scope = "type", Target = "PortAudioSharp.PortAudio+PaStreamCallbackFlags")] [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "Vocaluxe.Lib.Video.Gstreamer.CGstreamerVideoWrapper.#GetFrame(System.Int32,System.Single)")] @@ -49,19 +46,4 @@ using System.Diagnostics.CodeAnalysis; Target = "Vocaluxe.Lib.Input.CHIDAPI.#ReadTimeout(System.IntPtr,System.Byte[]&,System.Int32,System.Int32)")] [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", - Target = "Vocaluxe.Lib.Input.CHIDAPI.#Read(System.IntPtr,System.Byte[]&,System.Int32)")] -[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "PortAudioSharp.PortAudio.#Pa_GetVersionText()")] -[assembly: - SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", - Target = "PortAudioSharp.PortAudio.#Pa_GetErrorText(PortAudioSharp.PortAudio+PaError)")] -[assembly: - SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", - Target = "PortAudioSharp.PortAudio.#Pa_GetHostApiInfo(System.Int32)")] -[assembly: - SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "PortAudioSharp.PortAudio.#Pa_GetLastHostErrorInfo()")] -[assembly: - SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", - Target = "PortAudioSharp.PortAudio.#Pa_GetDeviceInfo(System.Int32)")] -[assembly: - SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", - Target = "PortAudioSharp.PortAudio.#Pa_GetStreamInfo(System.IntPtr)")] \ No newline at end of file + Target = "Vocaluxe.Lib.Input.CHIDAPI.#Read(System.IntPtr,System.Byte[]&,System.Int32)")] \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/CPortAudioCommon.cs b/Vocaluxe/Lib/Sound/CPortAudioCommon.cs index d3584860..a3233047 100644 --- a/Vocaluxe/Lib/Sound/CPortAudioCommon.cs +++ b/Vocaluxe/Lib/Sound/CPortAudioCommon.cs @@ -12,7 +12,7 @@ namespace Vocaluxe.Lib.Sound /// DO NEVER use following Pa_* functions other than the ones from this class: /// Initialize, Terminate, OpenStream, CloseStream /// - abstract class CPortAudioCommon + static class CPortAudioCommon { private static int _RefCount; private static readonly object _Mutex = new object(); @@ -22,13 +22,13 @@ namespace Vocaluxe.Lib.Sound /// MUST call CloseDriver when done /// /// True on success, falso if not initialized (log written) - protected static bool _InitDriver() + public static bool InitDriver() { lock (_Mutex) { if (_RefCount == 0) { - if (_CheckError("Initialize", PortAudio.Pa_Initialize())) + if (CheckError("Initialize", PortAudio.Pa_Initialize())) return false; } _RefCount++; @@ -40,7 +40,7 @@ namespace Vocaluxe.Lib.Sound /// Safe method to close PortAudio /// MUST be called _exactly_ once after successfull InitDriver call /// - protected static void _CloseDriver() + public static void CloseDriver() { lock (_Mutex) { @@ -51,9 +51,9 @@ namespace Vocaluxe.Lib.Sound } } - protected static PortAudio.PaError _OpenStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, ref PortAudio.PaStreamParameters? outputParameters, - double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, - PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) + public static PortAudio.PaError OpenStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, ref PortAudio.PaStreamParameters? outputParameters, + double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, + PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) { lock (_Mutex) { @@ -72,14 +72,14 @@ namespace Vocaluxe.Lib.Sound /// /// /// True on success - protected static bool _OpenInputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, - double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, - PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) + public static bool OpenInputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, + double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, + PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) { PortAudio.PaStreamParameters? outputParameters = null; return - !_CheckError("OpenInputStream", - _OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData)); + !CheckError("OpenInputStream", + OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData)); } /// @@ -93,17 +93,17 @@ namespace Vocaluxe.Lib.Sound /// /// /// True on success - protected static bool _OpenOutputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? outputParameters, - double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, - PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) + public static bool OpenOutputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? outputParameters, + double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, + PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) { PortAudio.PaStreamParameters? inputParameters = null; return - !_CheckError("OpenOutputStream", - _OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData)); + !CheckError("OpenOutputStream", + OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData)); } - protected static void _CloseStream(IntPtr stream) + public static void CloseStream(IntPtr stream) { lock (_Mutex) { @@ -118,7 +118,7 @@ namespace Vocaluxe.Lib.Sound /// Action identifier (E.g. openStream) /// Result returned by Pa_* call /// True on error - protected static bool _CheckError(String action, PortAudio.PaError errorCode) + public static bool CheckError(String action, PortAudio.PaError errorCode) { if (errorCode != PortAudio.PaError.paNoError) { @@ -140,7 +140,7 @@ namespace Vocaluxe.Lib.Sound /// Selects the most appropriate host api /// /// The most appropriate host api - protected static int _GetHostApi() + public static int GetHostApi() { //Caller has to hold a reference anyway so no locking needed if (_RefCount < 1) diff --git a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs index 6d372560..62a2f9f4 100644 --- a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs +++ b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs @@ -8,7 +8,7 @@ using VocaluxeLib; namespace Vocaluxe.Lib.Sound.Playback.PortAudio { - class CPortAudioStream : CPortAudioCommon, IDisposable + class CPortAudioStream : IDisposable { private const long _Bufsize = 1000000L; private const long _Beginrefill = 800000L; @@ -187,12 +187,12 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio { Paused = false; _AfterFadeAction = EStreamAction.Nothing; - _CheckError("StartStream", PortAudioSharp.PortAudio.Pa_StartStream(_Stream)); + CPortAudioCommon.CheckError("StartStream", PortAudioSharp.PortAudio.Pa_StartStream(_Stream)); } public void Stop() { - _CheckError("StopStream (playback)", PortAudioSharp.PortAudio.Pa_StopStream(_Stream)); + CPortAudioCommon.CheckError("StopStream (playback)", PortAudioSharp.PortAudio.Pa_StopStream(_Stream)); Skip(0f); } @@ -213,11 +213,11 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio bool driverInitialized = false; try { - if (!_InitDriver()) + if (!CPortAudioCommon.InitDriver()) return false; driverInitialized = true; - int hostApi = _GetHostApi(); + int hostApi = CPortAudioCommon.GetHostApi(); _ApiInfo = PortAudioSharp.PortAudio.Pa_GetHostApiInfo(hostApi); _OutputDeviceInfo = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(_ApiInfo.defaultOutputDevice); if (_OutputDeviceInfo.defaultLowOutputLatency < 0.1) @@ -228,7 +228,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio catch (Exception) { if (driverInitialized) - _CloseDriver(); + CPortAudioCommon.CloseDriver(); CLog.LogError("Error Init PortAudio Playback"); return false; } @@ -240,7 +240,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio SFormatInfo format = _Decoder.GetFormatInfo(); if (format.SamplesPerSecond == 0) { - _CloseDriver(); + CPortAudioCommon.CloseDriver(); _Decoder.Close(); _Decoder = null; CLog.LogError("Error Init PortAudio Playback (samples=0)"); @@ -262,7 +262,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio hostApiSpecificStreamInfo = IntPtr.Zero }; - if (!_OpenOutputStream( + if (!CPortAudioCommon.OpenOutputStream( out _Stream, ref outputParams, format.SamplesPerSecond, @@ -271,7 +271,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio _PaStreamCallback, IntPtr.Zero) || _Stream == IntPtr.Zero) { - _CloseDriver(); + CPortAudioCommon.CloseDriver(); _Decoder.Close(); _Decoder = null; return false; @@ -410,8 +410,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio private void _DoFree() { - _CloseStream(_Stream); - _CloseDriver(); + CPortAudioCommon.CloseStream(_Stream); + CPortAudioCommon.CloseDriver(); _Decoder.Close(); _Closeproc(ID); diff --git a/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs b/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs index 914435f8..5515b8b9 100644 --- a/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs +++ b/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs @@ -24,7 +24,7 @@ using Vocaluxe.Base; namespace Vocaluxe.Lib.Sound.Record.PortAudio { - class CPortAudioRecord : CPortAudioCommon, IRecord + class CPortAudioRecord : IRecord { private bool _Initialized; private readonly List _Devices = new List(); @@ -52,11 +52,11 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio try { - if (!_InitDriver()) + if (!CPortAudioCommon.InitDriver()) return false; _Devices.Clear(); - int hostAPI = _GetHostApi(); + int hostAPI = CPortAudioCommon.GetHostApi(); int numDevices = PortAudioSharp.PortAudio.Pa_GetDeviceCount(); for (int i = 0; i < numDevices; i++) { @@ -128,7 +128,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio suggestedLatency = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(_Devices[dev].ID).defaultLowInputLatency, hostApiSpecificStreamInfo = IntPtr.Zero }; - if (!_OpenInputStream( + if (!CPortAudioCommon.OpenInputStream( out _RecHandle[dev], ref inputParams, 44100, @@ -138,7 +138,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio new IntPtr(dev))) return false; - if (_CheckError("Start Stream (rec)", PortAudioSharp.PortAudio.Pa_StartStream(_RecHandle[dev]))) + if (CPortAudioCommon.CheckError("Start Stream (rec)", PortAudioSharp.PortAudio.Pa_StartStream(_RecHandle[dev]))) return false; } } @@ -168,8 +168,8 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio return; foreach (IntPtr handle in _RecHandle) - _CloseStream(handle); - _CloseDriver(); + CPortAudioCommon.CloseStream(handle); + CPortAudioCommon.CloseDriver(); _Initialized = false; From 3bc8fd516f89d9179037ddd8f626dfa6f579c2aa Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 21 Mar 2014 20:36:36 +0100 Subject: [PATCH 02/34] Add a base record class to handle common functions (avoid duplicate code) --- ...PortAudioCommon.cs => CPortAudioHandle.cs} | 98 ++++++++--- .../Playback/PortAudio/CPortAudioStream.cs | 33 ++-- Vocaluxe/Lib/Sound/Record/CRecordBase.cs | 148 ++++++++++++++++ .../Record/DirectSound/CDirectSoundRecord.cs | 140 ++------------- .../Record/PortAudio/CPortAudioRecord.cs | 165 +++--------------- Vocaluxe/Vocaluxe.csproj | 3 +- 6 files changed, 277 insertions(+), 310 deletions(-) rename Vocaluxe/Lib/Sound/{CPortAudioCommon.cs => CPortAudioHandle.cs} (61%) create mode 100644 Vocaluxe/Lib/Sound/Record/CRecordBase.cs diff --git a/Vocaluxe/Lib/Sound/CPortAudioCommon.cs b/Vocaluxe/Lib/Sound/CPortAudioHandle.cs similarity index 61% rename from Vocaluxe/Lib/Sound/CPortAudioCommon.cs rename to Vocaluxe/Lib/Sound/CPortAudioHandle.cs index a3233047..0406055e 100644 --- a/Vocaluxe/Lib/Sound/CPortAudioCommon.cs +++ b/Vocaluxe/Lib/Sound/CPortAudioHandle.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using PortAudioSharp; using Vocaluxe.Base; @@ -8,40 +9,53 @@ namespace Vocaluxe.Lib.Sound /// /// PortAudio can be used for record and playback /// So do some common stuff here and make sure those 2 do not interfere + /// Basic lifetime: On Init() get a new handle, close/dispose it in your close/dispose /// /// DO NEVER use following Pa_* functions other than the ones from this class: /// Initialize, Terminate, OpenStream, CloseStream /// - static class CPortAudioCommon + class CPortAudioHandle : IDisposable { private static int _RefCount; private static readonly object _Mutex = new object(); + private bool _Disposed; + private readonly List _Streams = new List(); + /// - /// Safe method to init PortAudio (adds a reference) - /// MUST call CloseDriver when done + /// Initializes PortAudio library (if required) /// - /// True on success, falso if not initialized (log written) - public static bool InitDriver() + public CPortAudioHandle() { lock (_Mutex) { if (_RefCount == 0) { if (CheckError("Initialize", PortAudio.Pa_Initialize())) - return false; + throw new Exception(); } _RefCount++; } - return true; } - /// - /// Safe method to close PortAudio - /// MUST be called _exactly_ once after successfull InitDriver call - /// - public static void CloseDriver() + ~CPortAudioHandle() { + _Dispose(false); + } + + private void _Dispose(bool disposing) + { + if (_Disposed) + return; + if (!disposing) + CLog.LogDebug("Did not close CPortAudioHandle"); + //Make sure we do not leek any streams as we may keep PA open + if (_Streams.Count > 0) + { + CLog.LogDebug("Did not close " + _Streams.Count + "PortAudio-Stream(s)"); + while (_Streams.Count > 0) + CloseStream(_Streams[0]); + } lock (_Mutex) { Debug.Assert(_RefCount > 0); @@ -49,15 +63,37 @@ namespace Vocaluxe.Lib.Sound if (_RefCount == 0) PortAudio.Pa_Terminate(); } + _Disposed = true; } - public static PortAudio.PaError OpenStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, ref PortAudio.PaStreamParameters? outputParameters, - double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, - PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) + public void Dispose() { + _Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Close the PortAudio handle once you are done + /// + public void Close() + { + Dispose(); + } + + public PortAudio.PaError OpenStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, ref PortAudio.PaStreamParameters? outputParameters, + double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, + PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) + { + if (_Disposed) + throw new ObjectDisposedException("PortAudioHandle already disposed"); + lock (_Mutex) { - return PortAudio.Pa_OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData); + PortAudio.PaError res = PortAudio.Pa_OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, + userData); + if (res == PortAudio.PaError.paNoError) + _Streams.Add(stream); + return res; } } @@ -72,9 +108,9 @@ namespace Vocaluxe.Lib.Sound /// /// /// True on success - public static bool OpenInputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, - double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, - PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) + public bool OpenInputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, + double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, + PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) { PortAudio.PaStreamParameters? outputParameters = null; return @@ -93,9 +129,9 @@ namespace Vocaluxe.Lib.Sound /// /// /// True on success - public static bool OpenOutputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? outputParameters, - double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, - PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) + public bool OpenOutputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? outputParameters, + double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, + PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) { PortAudio.PaStreamParameters? inputParameters = null; return @@ -103,11 +139,15 @@ namespace Vocaluxe.Lib.Sound OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData)); } - public static void CloseStream(IntPtr stream) + public void CloseStream(IntPtr stream) { + if (_Disposed) + throw new ObjectDisposedException("PortAudioHandle already disposed"); + lock (_Mutex) { PortAudio.Pa_CloseStream(stream); + _Streams.Remove(stream); } } @@ -118,8 +158,11 @@ namespace Vocaluxe.Lib.Sound /// Action identifier (E.g. openStream) /// Result returned by Pa_* call /// True on error - public static bool CheckError(String action, PortAudio.PaError errorCode) + public bool CheckError(String action, PortAudio.PaError errorCode) { + if (_Disposed) + throw new ObjectDisposedException("PortAudioHandle already disposed"); + if (errorCode != PortAudio.PaError.paNoError) { CLog.LogError(action + " error: " + PortAudio.Pa_GetErrorText(errorCode)); @@ -140,11 +183,10 @@ namespace Vocaluxe.Lib.Sound /// Selects the most appropriate host api /// /// The most appropriate host api - public static int GetHostApi() + public int GetHostApi() { - //Caller has to hold a reference anyway so no locking needed - if (_RefCount < 1) - return -1; + if (_Disposed) + throw new ObjectDisposedException("PortAudioHandle already disposed"); int selectedHostApi = PortAudio.Pa_GetDefaultHostApi(); int apiCount = PortAudio.Pa_GetHostApiCount(); diff --git a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs index 62a2f9f4..cd2328e2 100644 --- a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs +++ b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs @@ -15,6 +15,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio public readonly int ID; private readonly Closeproc _Closeproc; + private CPortAudioHandle _PaHandle; private readonly CSyncTimer _SyncTimer; private int _ByteCount = 4; @@ -187,12 +188,12 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio { Paused = false; _AfterFadeAction = EStreamAction.Nothing; - CPortAudioCommon.CheckError("StartStream", PortAudioSharp.PortAudio.Pa_StartStream(_Stream)); + _PaHandle.CheckError("StartStream", PortAudioSharp.PortAudio.Pa_StartStream(_Stream)); } public void Stop() { - CPortAudioCommon.CheckError("StopStream (playback)", PortAudioSharp.PortAudio.Pa_StopStream(_Stream)); + _PaHandle.CheckError("StopStream (playback)", PortAudioSharp.PortAudio.Pa_StopStream(_Stream)); Skip(0f); } @@ -210,14 +211,11 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio if (!File.Exists(fileName)) return false; - bool driverInitialized = false; try { - if (!CPortAudioCommon.InitDriver()) - return false; - driverInitialized = true; + _PaHandle = new CPortAudioHandle(); - int hostApi = CPortAudioCommon.GetHostApi(); + int hostApi = _PaHandle.GetHostApi(); _ApiInfo = PortAudioSharp.PortAudio.Pa_GetHostApiInfo(hostApi); _OutputDeviceInfo = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(_ApiInfo.defaultOutputDevice); if (_OutputDeviceInfo.defaultLowOutputLatency < 0.1) @@ -227,8 +225,11 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio } catch (Exception) { - if (driverInitialized) - CPortAudioCommon.CloseDriver(); + if (_PaHandle != null) + { + _PaHandle.Close(); + _PaHandle = null; + } CLog.LogError("Error Init PortAudio Playback"); return false; } @@ -240,7 +241,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio SFormatInfo format = _Decoder.GetFormatInfo(); if (format.SamplesPerSecond == 0) { - CPortAudioCommon.CloseDriver(); + _PaHandle.Close(); + _PaHandle = null; _Decoder.Close(); _Decoder = null; CLog.LogError("Error Init PortAudio Playback (samples=0)"); @@ -262,7 +264,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio hostApiSpecificStreamInfo = IntPtr.Zero }; - if (!CPortAudioCommon.OpenOutputStream( + if (!_PaHandle.OpenOutputStream( out _Stream, ref outputParams, format.SamplesPerSecond, @@ -271,7 +273,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio _PaStreamCallback, IntPtr.Zero) || _Stream == IntPtr.Zero) { - CPortAudioCommon.CloseDriver(); + _PaHandle.Close(); + _PaHandle = null; _Decoder.Close(); _Decoder = null; return false; @@ -410,9 +413,11 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio private void _DoFree() { - CPortAudioCommon.CloseStream(_Stream); - CPortAudioCommon.CloseDriver(); + _PaHandle.CloseStream(_Stream); + _PaHandle.Close(); + _PaHandle = null; _Decoder.Close(); + _Decoder = null; _Closeproc(ID); } diff --git a/Vocaluxe/Lib/Sound/Record/CRecordBase.cs b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs new file mode 100644 index 00000000..78630c90 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs @@ -0,0 +1,148 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Vocaluxe.Base; + +namespace Vocaluxe.Lib.Sound.Record +{ + /// + /// Base class to implement common functionality for Record classes + /// + abstract class CRecordBase + { + private bool _Initialized; + protected List _Devices; + protected CBuffer[] _Buffer; + + /// + /// Init recording + /// Child class should overwrite this to list devices + /// + /// true if success + public virtual bool Init() + { + if (_Initialized) + return false; + + _Devices = new List(); + _Buffer = new CBuffer[CSettings.MaxNumPlayer]; + for (int i = 0; i < _Buffer.Length; i++) + _Buffer[i] = new CBuffer(); + + _Initialized = true; + + return true; + } + + /// + /// Stop all voice capturing streams and terminates recording freeing resources + /// + public virtual void Close() + { + if (!_Initialized) + return; + + _Devices = null; + if (_Buffer != null) + { + foreach (CBuffer buffer in _Buffer) + buffer.Dispose(); + _Buffer = null; + } + + _Initialized = false; + } + + /// + /// Procedure to be called by descendent classes with data that got recorded + /// + /// Device from which the data was recorded + /// Recorded samples, assume Int16 and interleaved for multi-channels + protected void _HandleData(CRecordDevice device, byte[] data) + { + byte[] leftBuffer; + byte[] rightBuffer; + + if (device.Channels == 2) + { + leftBuffer = new byte[data.Length / 2]; + rightBuffer = new byte[data.Length / 2]; + //[]: Sample, L: Left channel R: Right channel + //[LR][LR][LR][LR][LR][LR] + //The data is interleaved and needs to be demultiplexed + for (int i = 0; i < data.Length / 4; i++) + { + leftBuffer[i * 2] = data[i * 4]; + leftBuffer[i * 2 + 1] = data[i * 4 + 1]; + rightBuffer[i * 2] = data[i * 4 + 2]; + rightBuffer[i * 2 + 1] = data[i * 4 + 3]; + } + } + else + leftBuffer = rightBuffer = data; + + if (device.PlayerChannel1 > 0) + _Buffer[device.PlayerChannel1 - 1].ProcessNewBuffer(leftBuffer); + + if (device.PlayerChannel2 > 0) + _Buffer[device.PlayerChannel2 - 1].ProcessNewBuffer(rightBuffer); + } + + /// + /// Detect Pitch and Volume of the newest voice buffer + /// + /// + public void AnalyzeBuffer(int player) + { + if (!_Initialized) + return; + + _Buffer[player].AnalyzeBuffer(); + } + + public int GetToneAbs(int player) + { + if (!_Initialized) + return 0; + + return _Buffer[player].ToneAbs; + } + + public int GetTone(int player) + { + return _Initialized ? _Buffer[player].Tone : 0; + } + + public void SetTone(int player, int tone) + { + if (!_Initialized) + return; + + _Buffer[player].Tone = tone; + } + + public float GetMaxVolume(int player) + { + return _Initialized ? _Buffer[player].MaxVolume : 0f; + } + + public bool ToneValid(int player) + { + return _Initialized && _Buffer[player].ToneValid; + } + + public int NumHalfTones() + { + return CBuffer.NumHalfTones; + } + + public float[] ToneWeigth(int player) + { + return _Initialized ? _Buffer[player].ToneWeigth : null; + } + + public ReadOnlyCollection RecordDevices() + { + return (_Initialized && _Devices.Count > 0) ? _Devices.AsReadOnly() : null; + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/DirectSound/CDirectSoundRecord.cs b/Vocaluxe/Lib/Sound/Record/DirectSound/CDirectSoundRecord.cs index e0a37e8e..61b54b23 100644 --- a/Vocaluxe/Lib/Sound/Record/DirectSound/CDirectSoundRecord.cs +++ b/Vocaluxe/Lib/Sound/Record/DirectSound/CDirectSoundRecord.cs @@ -23,39 +23,28 @@ using Vocaluxe.Base; namespace Vocaluxe.Lib.Sound.Record.DirectSound { - class CDirectSoundRecord : IRecord + class CDirectSoundRecord : CRecordBase, IRecord { private bool _Initialized; - private List _Devices; + private List _Sources; - private readonly CBuffer[] _Buffer; - - public CDirectSoundRecord() + public override bool Init() { - _Buffer = new CBuffer[CSettings.MaxNumPlayer]; - for (int i = 0; i < _Buffer.Length; i++) - _Buffer[i] = new CBuffer(); + if (!base.Init()) + return false; - Init(); - } - - public bool Init() - { - DeviceCollection devices = DirectSoundCapture.GetDevices(); - _Devices = new List(); _Sources = new List(); - int id = 0; + DeviceCollection devices = DirectSoundCapture.GetDevices(); + foreach (DeviceInformation dev in devices) { using (var ds = new DirectSoundCapture(dev.DriverGuid)) { - var device = new CRecordDevice(id, dev.DriverGuid.ToString(), dev.Description, ds.Capabilities.Channels); + var device = new CRecordDevice(_Devices.Count, dev.DriverGuid.ToString(), dev.Description, ds.Capabilities.Channels); _Devices.Add(device); - - id++; } } @@ -64,14 +53,11 @@ namespace Vocaluxe.Lib.Sound.Record.DirectSound return true; } - public void Close() + public override void Close() { - if (_Initialized) - { - Stop(); - _Initialized = false; - } - //System.IO.File.WriteAllBytes("test0.raw", _Buffer[0].Buffer); + Stop(); + _Initialized = false; + base.Close(); } public bool Start() @@ -112,81 +98,6 @@ namespace Vocaluxe.Lib.Sound.Record.DirectSound return true; } - public void AnalyzeBuffer(int player) - { - if (!_Initialized) - return; - - _Buffer[player].AnalyzeBuffer(); - } - - public int GetToneAbs(int player) - { - if (!_Initialized) - return 0; - - return _Buffer[player].ToneAbs; - } - - public int GetTone(int player) - { - if (!_Initialized) - return 0; - - return _Buffer[player].Tone; - } - - public void SetTone(int player, int tone) - { - if (!_Initialized) - return; - - _Buffer[player].Tone = tone; - } - - public float GetMaxVolume(int player) - { - if (!_Initialized) - return 0f; - - return _Buffer[player].MaxVolume; - } - - public bool ToneValid(int player) - { - if (!_Initialized) - return false; - - return _Buffer[player].ToneValid; - } - - public ReadOnlyCollection RecordDevices() - { - if (!_Initialized) - return null; - - if (_Devices.Count == 0) - return null; - - return _Devices.AsReadOnly(); - } - - public int NumHalfTones() - { - if (!_Initialized) - return 0; - - return CBuffer.NumHalfTones; - } - - public float[] ToneWeigth(int player) - { - if (!_Initialized) - return null; - - return _Buffer[player].ToneWeigth; - } - private void _OnDataReady(object sender, CSampleDataEventArgs e) { if (!_Initialized) @@ -194,32 +105,7 @@ namespace Vocaluxe.Lib.Sound.Record.DirectSound CRecordDevice dev = _Devices.FirstOrDefault(device => device.Driver == e.Guid); if (dev == null) return; - byte[] leftBuffer; - byte[] rightBuffer; - - if (dev.Channels == 2) - { - leftBuffer = new byte[e.Data.Length / 2]; - rightBuffer = new byte[e.Data.Length / 2]; - //[]: Sample, L: Left channel R: Right channel - //[LR][LR][LR][LR][LR][LR] - //The data is interleaved and needs to be demultiplexed - for (int i = 0; i < e.Data.Length / 4; i++) - { - leftBuffer[i * 2] = e.Data[i * 4]; - leftBuffer[i * 2 + 1] = e.Data[i * 4 + 1]; - rightBuffer[i * 2] = e.Data[i * 4 + 2]; - rightBuffer[i * 2 + 1] = e.Data[i * 4 + 3]; - } - } - else - leftBuffer = rightBuffer = e.Data; - - if (dev.PlayerChannel1 > 0) - _Buffer[dev.PlayerChannel1 - 1].ProcessNewBuffer(leftBuffer); - - if (dev.PlayerChannel2 > 0) - _Buffer[dev.PlayerChannel2 - 1].ProcessNewBuffer(rightBuffer); + _HandleData(dev, e.Data); } } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs b/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs index 5515b8b9..76b952da 100644 --- a/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs +++ b/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs @@ -16,47 +16,33 @@ #endregion using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Runtime.InteropServices; using System.Threading; using Vocaluxe.Base; namespace Vocaluxe.Lib.Sound.Record.PortAudio { - class CPortAudioRecord : IRecord + class CPortAudioRecord : CRecordBase, IRecord { private bool _Initialized; - private readonly List _Devices = new List(); - + private CPortAudioHandle _PaHandle; private PortAudioSharp.PortAudio.PaStreamCallbackDelegate _MyRecProc; private IntPtr[] _RecHandle; - private readonly CBuffer[] _Buffer; - - public CPortAudioRecord() - { - _Buffer = new CBuffer[CSettings.MaxNumPlayer]; - for (int i = 0; i < _Buffer.Length; i++) - _Buffer[i] = new CBuffer(); - } - /// /// Init PortAudio and list record devices /// /// true if success - public bool Init() + public override bool Init() { - if (_Initialized) + if (!base.Init()) return false; try { - if (!CPortAudioCommon.InitDriver()) - return false; + _PaHandle = new CPortAudioHandle(); - _Devices.Clear(); - int hostAPI = CPortAudioCommon.GetHostApi(); + int hostAPI = _PaHandle.GetHostApi(); int numDevices = PortAudioSharp.PortAudio.Pa_GetDeviceCount(); for (int i = 0; i < numDevices; i++) { @@ -69,9 +55,6 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio } } - foreach (CBuffer buffer in _Buffer) - buffer.Reset(); - _RecHandle = new IntPtr[_Devices.Count]; _MyRecProc = _MyPaStreamCallback; _Initialized = true; @@ -80,6 +63,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio { _Initialized = false; CLog.LogError("Error initializing PortAudio: " + e.Message); + Close(); return false; } @@ -95,9 +79,6 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio if (!_Initialized) return false; - if (_RecHandle == null || _RecHandle.Length == 0) - return false; - Stop(); foreach (IntPtr handle in _RecHandle) @@ -128,7 +109,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio suggestedLatency = PortAudioSharp.PortAudio.Pa_GetDeviceInfo(_Devices[dev].ID).defaultLowInputLatency, hostApiSpecificStreamInfo = IntPtr.Zero }; - if (!CPortAudioCommon.OpenInputStream( + if (!_PaHandle.OpenInputStream( out _RecHandle[dev], ref inputParams, 44100, @@ -138,7 +119,7 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio new IntPtr(dev))) return false; - if (CPortAudioCommon.CheckError("Start Stream (rec)", PortAudioSharp.PortAudio.Pa_StartStream(_RecHandle[dev]))) + if (_PaHandle.CheckError("Start Stream (rec)", PortAudioSharp.PortAudio.Pa_StartStream(_RecHandle[dev]))) return false; } } @@ -162,97 +143,25 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio /// /// Stop all voice capturing streams and terminate PortAudio /// - public void Close() + public override void Close() { - if (!_Initialized) - return; - - foreach (IntPtr handle in _RecHandle) - CPortAudioCommon.CloseStream(handle); - CPortAudioCommon.CloseDriver(); + if (_RecHandle != null) + { + foreach (IntPtr handle in _RecHandle) + { + if (handle != IntPtr.Zero) + _PaHandle.CloseStream(handle); + } + } + if (_PaHandle != null) + { + _PaHandle.Close(); + _PaHandle = null; + } _Initialized = false; - //System.IO.File.WriteAllBytes("test0.raw", _Buffer[0].Buffer); - } - - /// - /// Detect Pitch and Volume of the newest voice buffer - /// - /// - public void AnalyzeBuffer(int player) - { - if (!_Initialized) - return; - - _Buffer[player].AnalyzeBuffer(); - } - - public int GetToneAbs(int player) - { - if (!_Initialized) - return 0; - - return _Buffer[player].ToneAbs; - } - - public int GetTone(int player) - { - if (!_Initialized) - return 0; - - return _Buffer[player].Tone; - } - - public void SetTone(int player, int tone) - { - if (!_Initialized) - return; - - _Buffer[player].Tone = tone; - } - - public float GetMaxVolume(int player) - { - if (!_Initialized) - return 0f; - - return _Buffer[player].MaxVolume; - } - - public bool ToneValid(int player) - { - if (!_Initialized) - return false; - - return _Buffer[player].ToneValid; - } - - public int NumHalfTones() - { - if (!_Initialized) - return 0; - - return CBuffer.NumHalfTones; - } - - public float[] ToneWeigth(int player) - { - if (!_Initialized) - return null; - - return _Buffer[player].ToneWeigth; - } - - public ReadOnlyCollection RecordDevices() - { - if (!_Initialized) - return null; - - if (_Devices.Count == 0) - return null; - - return _Devices.AsReadOnly(); + base.Close(); } private PortAudioSharp.PortAudio.PaStreamCallbackResult _MyPaStreamCallback( @@ -275,34 +184,10 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio numBytes = frameCount * 2; byte[] recbuffer = new byte[numBytes]; - byte[] leftBuffer; - byte[] rightBuffer; // copy from managed to unmanaged memory Marshal.Copy(input, recbuffer, 0, (int)numBytes); - if (dev.Channels == 2) - { - leftBuffer = new byte[numBytes / 2]; - rightBuffer = new byte[numBytes / 2]; - //[]: Sample, L: Left channel R: Right channel - //[LR][LR][LR][LR][LR][LR] - //The data is interleaved and needs to be demultiplexed - for (int i = 0; i < frameCount; i++) - { - leftBuffer[i * 2] = recbuffer[i * 4]; - leftBuffer[i * 2 + 1] = recbuffer[i * 4 + 1]; - rightBuffer[i * 2] = recbuffer[i * 4 + 2]; - rightBuffer[i * 2 + 1] = recbuffer[i * 4 + 3]; - } - } - else - leftBuffer = rightBuffer = recbuffer; - - if (dev.PlayerChannel1 > 0) - _Buffer[dev.PlayerChannel1 - 1].ProcessNewBuffer(leftBuffer); - - if (dev.PlayerChannel2 > 0) - _Buffer[dev.PlayerChannel2 - 1].ProcessNewBuffer(rightBuffer); + _HandleData(dev, recbuffer); } } catch (Exception e) diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 0dc33afe..fcf7e6f6 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -222,7 +222,7 @@ - + @@ -264,6 +264,7 @@ + From 15e08ca8314e4813455415c3b4e2a473d9cab624 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 22 Mar 2014 01:40:35 +0100 Subject: [PATCH 03/34] Fix wrong initial values for weights Add a test for pitch detection accuracy and performance --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 80 ++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 5 deletions(-) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index c3db3e72..dd264249 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -1,12 +1,21 @@ -using System; +//#define TEST_PITCH + +using System; using System.IO; +#if TEST_PITCH +using System.Diagnostics; +using VocaluxeLib; + +#endif + namespace Vocaluxe.Lib.Sound.Record { class CBuffer : IDisposable { //Half tones: C C♯ D Eb E F F♯ G G♯ A Bb B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) + private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) public const int NumHalfTones = 17; //Number of halftone to analyze C2-E3 (TODO: use more/full octaves?) private const int _AnalysisBufLen = 4096; @@ -27,17 +36,18 @@ namespace Vocaluxe.Lib.Sound.Record { MinVolume = 0.02f; ToneWeigth = new float[NumHalfTones]; - for (int i = 0; i < ToneWeigth.Length; i++) - ToneWeigth[i] = 0.99f; + Reset(); +#if TEST_PITCH + _TestPitchDetection(); +#endif } static CBuffer() { - const double halftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) //Init Array to avoid costly calculations for (int toneIndex = 0; toneIndex < NumHalfTones; toneIndex++) { - double freq = _BaseToneFreq * Math.Pow(halftoneBase, toneIndex); + double freq = _BaseToneFreq * Math.Pow(_HalftoneBase, toneIndex); _SamplesPerPeriodPerTone[toneIndex] = (int)Math.Round(44100.0 / freq); // samples in one period } } @@ -70,6 +80,8 @@ namespace Vocaluxe.Lib.Sound.Record ToneValid = false; ToneAbs = 0; Tone = 0; + for (int i = 0; i < ToneWeigth.Length; i++) + ToneWeigth[i] = 0f; } private void _Add(byte[] bytes) @@ -212,5 +224,63 @@ namespace Vocaluxe.Lib.Sound.Record } GC.SuppressFinalize(this); } + +#if TEST_PITCH + private static bool _PitchTestRun; + + private string _ToneToNote(int tone, bool withOctave = true) + { + string[] notes = {"C", "C♯", "D", "Eb", "E", "F", "F♯", "G", "G♯", "A", "Bb", "B"}; + string result = notes[tone % 12]; + if (withOctave) + result += (tone / 12) + 2; + return result; + } + + private void _TestPitchDetection() + { + if (_PitchTestRun) + return; + _PitchTestRun = true; + const int toneFrom = 0; + const int tontTo = 47; + Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(tontTo)); + byte[] data; + for (int tone = toneFrom; tone <= tontTo; tone++) + { + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, out data); + ProcessNewBuffer(data); + AnalyzeBuffer(); + if (!ToneValid) + CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " not detected"); + else if (Tone != tone % 12) + CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " wrongly detected as " + _ToneToNote(Tone, false)); + } + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, out data); + Stopwatch sw = new Stopwatch(); + sw.Start(); + for (int i = 0; i < 10000; i++) + { + // ProcessNewBuffer(data); + // AnalyzeBuffer(); + _FindMaxVolume(); + _AnalyzeByAutocorrelation(); + } + sw.Stop(); + Console.WriteLine("Analysing took " + sw.ElapsedMilliseconds + "ms"); + Reset(); + } + + private void _GetSineWave(double freq, int sampleRate, out byte[] data) + { + const short max = short.MaxValue; + const int len = _AnalysisBufLen; //sampleRate * durationMs / 1000; + short[] data16Bit = new short[len]; + for (int i = 0; i < len; i++) + data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq) * max); + data = new byte[data16Bit.Length * 2]; + Buffer.BlockCopy(data16Bit, 0, data, 0, data.Length); + } +#endif } } \ No newline at end of file From dbde93d50c9e02626e50aca579bf84028fd3377e Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 22 Mar 2014 19:22:01 +0100 Subject: [PATCH 04/34] Add auto-correlation function for sound detection Update test-code to check also mixed sounds --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 127 ++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 24 deletions(-) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index dd264249..fe9b150c 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -5,6 +5,7 @@ using System.IO; #if TEST_PITCH using System.Diagnostics; +//using System.Windows.Forms; using VocaluxeLib; #endif @@ -13,10 +14,18 @@ namespace Vocaluxe.Lib.Sound.Record { class CBuffer : IDisposable { + public enum EAnalyzeFunction + { + AutoCorrelation, //Faster but strict (All right in set range, more resistent to noise, but does not detect tones outside the range) + Amdf //Average magnitude difference, slower and more heuristic (false detections in set range but also right detections outside) + } + + private delegate double DAnalyzeTone(int tone); + //Half tones: C C♯ D Eb E F F♯ G G♯ A Bb B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) - public const int NumHalfTones = 17; //Number of halftone to analyze C2-E3 (TODO: use more/full octaves?) + public const int NumHalfTones = 24; //Number of halftone to analyze C2-B4 private const int _AnalysisBufLen = 4096; private const int _AnalysisByteBufLen = _AnalysisBufLen * 2; @@ -26,6 +35,16 @@ namespace Vocaluxe.Lib.Sound.Record private static readonly int[] _SamplesPerPeriodPerTone = new int[NumHalfTones]; //Precalculated table holding sample# per period for each tone private readonly float[] _TmpWeight = new float[NumHalfTones]; //tmp buffer for weights (gets copied to ToneWeight when checked) + // ReSharper disable MemberCanBePrivate.Global + // ReSharper disable ConvertToConstant.Global + // ReSharper disable FieldCanBeMadeReadOnly.Global + public static EAnalyzeFunction AnalyzeFunction = EAnalyzeFunction.AutoCorrelation; + // ReSharper restore FieldCanBeMadeReadOnly.Global + // ReSharper restore ConvertToConstant.Global + // ReSharper restore MemberCanBePrivate.Global + // ReSharper disable FieldCanBeMadeReadOnly.Local + private DAnalyzeTone _AnalyzeToneFunc; + // ReSharper restore FieldCanBeMadeReadOnly.Local private double _MaxVolume; private bool _NewSamples; @@ -37,6 +56,10 @@ namespace Vocaluxe.Lib.Sound.Record MinVolume = 0.02f; ToneWeigth = new float[NumHalfTones]; Reset(); + if (AnalyzeFunction == EAnalyzeFunction.Amdf) + _AnalyzeToneFunc = _GetAmdf; + else if (AnalyzeFunction == EAnalyzeFunction.AutoCorrelation) + _AnalyzeToneFunc = _GetAutoCorrelation; #if TEST_PITCH _TestPitchDetection(); #endif @@ -128,7 +151,7 @@ namespace Vocaluxe.Lib.Sound.Record _FindMaxVolume(); if (MaxVolume >= MinVolume) - _AnalyzeByAutocorrelation(); + _AnalyzeTones(); else ToneValid = false; } @@ -156,7 +179,7 @@ namespace Vocaluxe.Lib.Sound.Record _MaxVolume = (double)maxVolume / Int16.MaxValue; } - private void _AnalyzeByAutocorrelation() + private void _AnalyzeTones() { // prepare to analyze double maxWeight = -1.0; @@ -169,7 +192,7 @@ namespace Vocaluxe.Lib.Sound.Record // too few samples -> use a bigger buffer-size for (int toneIndex = 0; toneIndex < NumHalfTones; toneIndex++) { - double curWeight = _AnalyzeAutocorrelationTone(toneIndex); + double curWeight = _AnalyzeToneFunc(toneIndex); if (curWeight > maxWeight) { @@ -195,7 +218,28 @@ namespace Vocaluxe.Lib.Sound.Record ToneValid = false; } - private double _AnalyzeAutocorrelationTone(int tone) + private double _GetAutoCorrelation(int tone) + { + int samplesPerPeriod = _SamplesPerPeriodPerTone[tone]; // samples in one period + + double accumDist = 0; // accumulated distances + + // compare correlating samples + int sampleIndex = 0; // index of sample to analyze + // Start value= index of sample one period ahead + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) + { + // calc distance to corresponding sample in next period (lower means more distant) + double dist = _AnalysisBuffer[sampleIndex] * _AnalysisBuffer[correlatingSampleIndex]; + accumDist += dist; + } + + //Using _AnalysisBufLen here makes it return correct values among all analyzed frequencies + const double scaleValue = (double)Int16.MaxValue * (double)Int16.MaxValue * _AnalysisBufLen; + return accumDist / scaleValue; + } + + private double _GetAmdf(int tone) { int samplesPerPeriod = _SamplesPerPeriodPerTone[tone]; // samples in one period @@ -206,12 +250,11 @@ namespace Vocaluxe.Lib.Sound.Record // Start value= index of sample one period ahead for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) { - // calc distance (correlation: 1-dist/IntMax) to corresponding sample in next period - // distance (0=equal .. IntMax=totally different) between correlated samples + // calc distance (correlation: 1-dist/IntMax*2) to corresponding sample in next period (0=equal .. IntMax*2=totally different) int dist = Math.Abs(_AnalysisBuffer[sampleIndex] - _AnalysisBuffer[correlatingSampleIndex]); accumDist += dist; } - + //Use analyzed sample count here. BufLen yields more errors return 1.0 - (double)accumDist / Int16.MaxValue / sampleIndex; } @@ -228,7 +271,7 @@ namespace Vocaluxe.Lib.Sound.Record #if TEST_PITCH private static bool _PitchTestRun; - private string _ToneToNote(int tone, bool withOctave = true) + private static string _ToneToNote(int tone, bool withOctave = true) { string[] notes = {"C", "C♯", "D", "Eb", "E", "F", "F♯", "G", "G♯", "A", "Bb", "B"}; string result = notes[tone % 12]; @@ -243,35 +286,71 @@ namespace Vocaluxe.Lib.Sound.Record return; _PitchTestRun = true; const int toneFrom = 0; - const int tontTo = 47; + const int tontTo = 48; Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(tontTo)); byte[] data; - for (int tone = toneFrom; tone <= tontTo; tone++) + int ok = 0; + for (int distort = 0; distort < 5; distort++) { - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, out data); - ProcessNewBuffer(data); - AnalyzeBuffer(); - if (!ToneValid) - CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " not detected"); - else if (Tone != tone % 12) - CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " wrongly detected as " + _ToneToNote(Tone, false)); + for (int tone = toneFrom; tone <= tontTo; tone++) + { + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, out data); + for (int i = 0; i < distort; i++) + _Distort(data, tone + 2 + i * 2); + + ProcessNewBuffer(data); + AnalyzeBuffer(); + if (!ToneValid) + CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " not detected (Distortion: " + distort + ")"); + else if (Tone != tone % 12) + CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " wrongly detected as " + _ToneToNote(Tone, false) + " (Distortion: " + distort + ")"); + else + ok++; + } } _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, out data); + ProcessNewBuffer(data); + AnalyzeBuffer(); Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 10000; i++) { - // ProcessNewBuffer(data); - // AnalyzeBuffer(); - _FindMaxVolume(); - _AnalyzeByAutocorrelation(); + ProcessNewBuffer(data); + AnalyzeBuffer(); + // _FindMaxVolume(); + // _AnalyzeTones(); } sw.Stop(); - Console.WriteLine("Analysing took " + sw.ElapsedMilliseconds + "ms"); + string msg = "Analyser: Errors: " + ((tontTo - toneFrom + 1) * 5 - ok) + "; Speed: " + + (int)(10000.0 / (sw.ElapsedMilliseconds / 1000.0)) + " buffers/s"; + Console.WriteLine(msg); + //MessageBox.Show(msg); Reset(); } - private void _GetSineWave(double freq, int sampleRate, out byte[] data) + private static void _Distort(byte[] data, int tone) + { + short[] sdata = new short[data.Length / 2]; + Buffer.BlockCopy(data, 0, sdata, 0, data.Length); + short[] sdata2 = new short[data.Length / 2]; + if (tone < 4) + { + byte[] data2; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, out data2); + Buffer.BlockCopy(data2, 0, sdata2, 0, data.Length); + } + else + { + Random r = new Random(0xBEEF); + for (int i = 0; i < sdata.Length; i++) + sdata2[i] = (short)(r.Next() - Int16.MinValue); + } + for (int i = 0; i < sdata.Length; i++) + sdata[i] = (short)(sdata[i] * 4.0 / 5.0 + sdata2[i] / 5.0); + Buffer.BlockCopy(sdata, 0, data, 0, data.Length); + } + + private static void _GetSineWave(double freq, int sampleRate, out byte[] data) { const short max = short.MaxValue; const int len = _AnalysisBufLen; //sampleRate * durationMs / 1000; From 2d441c347384a8cbc39fba4776037019fb545ea4 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 23 Mar 2014 01:06:58 +0100 Subject: [PATCH 05/34] Improve detection by interpolating and fix test case --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 165 ++++++++++++++++++--------- 1 file changed, 114 insertions(+), 51 deletions(-) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index fe9b150c..880f819b 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -5,7 +5,7 @@ using System.IO; #if TEST_PITCH using System.Diagnostics; -//using System.Windows.Forms; +using System.Windows.Forms; using VocaluxeLib; #endif @@ -16,8 +16,8 @@ namespace Vocaluxe.Lib.Sound.Record { public enum EAnalyzeFunction { - AutoCorrelation, //Faster but strict (All right in set range, more resistent to noise, but does not detect tones outside the range) - Amdf //Average magnitude difference, slower and more heuristic (false detections in set range but also right detections outside) + AutoCorrelation, //Faster, more resistent to noise, good value for HalfToneMax=38 (higher->wrong results in test case, WHY?) with 38 no wrong values in test case + Amdf //Average magnitude difference, slower, detects everything in range -> HalfToneMax=45 } private delegate double DAnalyzeTone(int tone); @@ -25,15 +25,18 @@ namespace Vocaluxe.Lib.Sound.Record //Half tones: C C♯ D Eb E F F♯ G G♯ A Bb B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) - public const int NumHalfTones = 24; //Number of halftone to analyze C2-B4 + private const int _HalfToneMin = 0; // C2 + private const int _HalfToneMax = 38; //45; // inclusive, 38=D5; 45=A5 + public const int NumHalfTones = _HalfToneMax - _HalfToneMin + 1; //Number of halftones to analyze private const int _AnalysisBufLen = 4096; private const int _AnalysisByteBufLen = _AnalysisBufLen * 2; - private readonly Int16[] _AnalysisBuffer = new Int16[_AnalysisBufLen]; + private readonly short[] _AnalysisBuffer = new short[_AnalysisBufLen]; private readonly byte[] _AnalysisByteBuffer = new byte[_AnalysisByteBufLen]; //tmp buffer (stream->tmpBuffer->(Int16)AnalysisBuffer) - private static readonly int[] _SamplesPerPeriodPerTone = new int[NumHalfTones]; //Precalculated table holding sample# per period for each tone + //Precalculated table holding sample# per period for each tone (actually we may not use the lower few entries, but keep it to avoid index modification + private static readonly double[] _SamplesPerPeriodPerTone = new double[_HalfToneMax + 1]; private readonly float[] _TmpWeight = new float[NumHalfTones]; //tmp buffer for weights (gets copied to ToneWeight when checked) // ReSharper disable MemberCanBePrivate.Global // ReSharper disable ConvertToConstant.Global @@ -68,10 +71,10 @@ namespace Vocaluxe.Lib.Sound.Record static CBuffer() { //Init Array to avoid costly calculations - for (int toneIndex = 0; toneIndex < NumHalfTones; toneIndex++) + for (int toneIndex = 0; toneIndex <= _HalfToneMax; toneIndex++) { double freq = _BaseToneFreq * Math.Pow(_HalftoneBase, toneIndex); - _SamplesPerPeriodPerTone[toneIndex] = (int)Math.Round(44100.0 / freq); // samples in one period + _SamplesPerPeriodPerTone[toneIndex] = 44100.0 / freq; // samples in one period } } @@ -161,18 +164,16 @@ namespace Vocaluxe.Lib.Sound.Record private void _FindMaxVolume() { short maxVolume = 0; - for (int i = 0; i < _AnalysisBuffer.Length / 4; i++) + for (int i = 0; i < _AnalysisBufLen / 4; i++) { short volume = _AnalysisBuffer[i]; - if (volume < 0) + if (volume == Int16.MinValue) { - if (volume == Int16.MinValue) - { - maxVolume = Int16.MaxValue; - break; - } - volume = (short)-volume; + maxVolume = Int16.MaxValue; + break; } + if (volume < 0) + volume = (short)-volume; if (volume > maxVolume) maxVolume = volume; } @@ -186,11 +187,12 @@ namespace Vocaluxe.Lib.Sound.Record double minWeight = 1.0; int maxTone = -1; + // analyze halftones // Note: at the lowest tone (~65Hz) and a buffer-size of 4096 // at 44.1 (or 48kHz) only 6 (or 5) samples are compared, this might be // too few samples -> use a bigger buffer-size - for (int toneIndex = 0; toneIndex < NumHalfTones; toneIndex++) + for (int toneIndex = _HalfToneMin; toneIndex <= _HalfToneMax; toneIndex++) { double curWeight = _AnalyzeToneFunc(toneIndex); @@ -203,14 +205,15 @@ namespace Vocaluxe.Lib.Sound.Record if (curWeight < minWeight) minWeight = curWeight; - _TmpWeight[toneIndex] = (float)curWeight; + _TmpWeight[toneIndex - _HalfToneMin] = (float)curWeight; } - if (maxWeight - minWeight > 0.01) + if (maxWeight - minWeight > 0.001) { Array.Copy(_TmpWeight, ToneWeigth, NumHalfTones); ToneAbs = maxTone; + //Console.WriteLine(maxTone); Tone = maxTone % 12; ToneValid = true; } @@ -220,17 +223,22 @@ namespace Vocaluxe.Lib.Sound.Record private double _GetAutoCorrelation(int tone) { - int samplesPerPeriod = _SamplesPerPeriodPerTone[tone]; // samples in one period + double samplesPerPeriodD = _SamplesPerPeriodPerTone[tone]; // samples in one period + int samplesPerPeriod = (int)samplesPerPeriodD; + double fHigh = samplesPerPeriodD - samplesPerPeriod; + double fLow = 1.0 - fHigh; double accumDist = 0; // accumulated distances // compare correlating samples int sampleIndex = 0; // index of sample to analyze // Start value= index of sample one period ahead - for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) { // calc distance to corresponding sample in next period (lower means more distant) - double dist = _AnalysisBuffer[sampleIndex] * _AnalysisBuffer[correlatingSampleIndex]; + double dist = _AnalysisBuffer[sampleIndex] * + (_AnalysisBuffer[correlatingSampleIndex] * fLow + _AnalysisBuffer[correlatingSampleIndex + 1] * fHigh); + //double dist = _AnalysisBuffer[sampleIndex] * _AnalysisBuffer[correlatingSampleIndex]; accumDist += dist; } @@ -241,17 +249,22 @@ namespace Vocaluxe.Lib.Sound.Record private double _GetAmdf(int tone) { - int samplesPerPeriod = _SamplesPerPeriodPerTone[tone]; // samples in one period + double samplesPerPeriodD = _SamplesPerPeriodPerTone[tone]; // samples in one period + int samplesPerPeriod = (int)samplesPerPeriodD; + double fHigh = samplesPerPeriodD - samplesPerPeriod; + double fLow = 1.0 - fHigh; - int accumDist = 0; // accumulated distances + double accumDist = 0; // accumulated distances // compare correlating samples int sampleIndex = 0; // index of sample to analyze // Start value= index of sample one period ahead - for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) { // calc distance (correlation: 1-dist/IntMax*2) to corresponding sample in next period (0=equal .. IntMax*2=totally different) - int dist = Math.Abs(_AnalysisBuffer[sampleIndex] - _AnalysisBuffer[correlatingSampleIndex]); + //int dist = (int)Math.Abs(_AnalysisBuffer[sampleIndex] - _AnalysisBuffer[correlatingSampleIndex]); + double dist = Math.Abs(_AnalysisBuffer[sampleIndex] - + (_AnalysisBuffer[correlatingSampleIndex] * fLow + _AnalysisBuffer[correlatingSampleIndex + 1] * fHigh)); accumDist += dist; } //Use analyzed sample count here. BufLen yields more errors @@ -273,10 +286,11 @@ namespace Vocaluxe.Lib.Sound.Record private static string _ToneToNote(int tone, bool withOctave = true) { + tone += 24; string[] notes = {"C", "C♯", "D", "Eb", "E", "F", "F♯", "G", "G♯", "A", "Bb", "B"}; string result = notes[tone % 12]; if (withOctave) - result += (tone / 12) + 2; + result += (tone / 12); return result; } @@ -285,18 +299,17 @@ namespace Vocaluxe.Lib.Sound.Record if (_PitchTestRun) return; _PitchTestRun = true; - const int toneFrom = 0; - const int tontTo = 48; - Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(tontTo)); + int toneFrom = Math.Max(0, _HalfToneMin); + const int toneTo = 47; //B5 + Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); byte[] data; int ok = 0; - for (int distort = 0; distort < 5; distort++) + for (int distort = 0; distort < 10; distort++) { - for (int tone = toneFrom; tone <= tontTo; tone++) + for (int tone = toneFrom; tone <= toneTo; tone++) { _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, out data); - for (int i = 0; i < distort; i++) - _Distort(data, tone + 2 + i * 2); + _Distort(data, tone, distort); ProcessNewBuffer(data); AnalyzeBuffer(); @@ -313,40 +326,90 @@ namespace Vocaluxe.Lib.Sound.Record AnalyzeBuffer(); Stopwatch sw = new Stopwatch(); sw.Start(); - for (int i = 0; i < 10000; i++) + const int repeats = 2000; + for (int i = 0; i < repeats; i++) { - ProcessNewBuffer(data); - AnalyzeBuffer(); - // _FindMaxVolume(); - // _AnalyzeTones(); + //ProcessNewBuffer(data); + //AnalyzeBuffer(); + _FindMaxVolume(); + _AnalyzeTones(); } sw.Stop(); - string msg = "Analyser: Errors: " + ((tontTo - toneFrom + 1) * 5 - ok) + "; Speed: " + - (int)(10000.0 / (sw.ElapsedMilliseconds / 1000.0)) + " buffers/s"; + string msg = "Analyser: Errors: " + ((toneTo - toneFrom + 1) * 10 - ok) + "; Speed: " + + (int)(repeats / (sw.ElapsedMilliseconds / 1000.0)) + " buffers/s"; Console.WriteLine(msg); - //MessageBox.Show(msg); + MessageBox.Show(msg); Reset(); } - private static void _Distort(byte[] data, int tone) + private static short[] _GetDistort(int len, int tone, int type) { - short[] sdata = new short[data.Length / 2]; - Buffer.BlockCopy(data, 0, sdata, 0, data.Length); - short[] sdata2 = new short[data.Length / 2]; - if (tone < 4) + short[] sdata = new short[len]; + if (type < 9) { + int newTone = 1; + switch (type) + { + case 0: + newTone = 2; + break; + case 1: + newTone = 3; + break; + case 2: + newTone = 6; + break; + case 3: + newTone = 8; + break; + case 4: + newTone = 10; + break; + case 5: + newTone = 15; + break; + case 6: + newTone = 25; + break; + case 7: + newTone = 26; + break; + case 8: + newTone = 29; + break; + } byte[] data2; - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, out data2); - Buffer.BlockCopy(data2, 0, sdata2, 0, data.Length); + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone + newTone), 44100, out data2); + Buffer.BlockCopy(data2, 0, sdata, 0, len * 2); } else { Random r = new Random(0xBEEF); for (int i = 0; i < sdata.Length; i++) - sdata2[i] = (short)(r.Next() - Int16.MinValue); + sdata[i] = (short)(r.Next() - Int16.MinValue); } + return sdata; + } + + private static void _Distort(byte[] data, int tone, int distortCt) + { + if (distortCt < 1) + return; + short[] sdata = new short[data.Length / 2]; + Buffer.BlockCopy(data, 0, sdata, 0, data.Length); + + short[][] distortions = new short[distortCt][]; + for (int i = 0; i < distortCt; i++) + distortions[i] = _GetDistort(data.Length / 2, tone, i); + for (int i = 0; i < sdata.Length; i++) - sdata[i] = (short)(sdata[i] * 4.0 / 5.0 + sdata2[i] / 5.0); + { + double distortion = 0; + for (int j = 0; j < distortCt; j++) + distortion += distortions[j][i]; + distortion /= distortCt; + sdata[i] = (short)(sdata[i] * 4.0 / 5.0 + distortion / 5.0); + } Buffer.BlockCopy(sdata, 0, data, 0, data.Length); } From f6499efd38478d75d71a2e1a6e541f4fcee46ac7 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 23 Mar 2014 01:23:58 +0100 Subject: [PATCH 06/34] Convert to double upfront Introduce property for MinWeightDiff --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 880f819b..7aece259 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -1,8 +1,7 @@ -//#define TEST_PITCH +#define TEST_PITCH using System; using System.IO; - #if TEST_PITCH using System.Diagnostics; using System.Windows.Forms; @@ -32,7 +31,7 @@ namespace Vocaluxe.Lib.Sound.Record private const int _AnalysisBufLen = 4096; private const int _AnalysisByteBufLen = _AnalysisBufLen * 2; - private readonly short[] _AnalysisBuffer = new short[_AnalysisBufLen]; + private readonly double[] _AnalysisBuffer = new double[_AnalysisBufLen]; private readonly byte[] _AnalysisByteBuffer = new byte[_AnalysisByteBufLen]; //tmp buffer (stream->tmpBuffer->(Int16)AnalysisBuffer) //Precalculated table holding sample# per period for each tone (actually we may not use the lower few entries, but keep it to avoid index modification @@ -47,6 +46,7 @@ namespace Vocaluxe.Lib.Sound.Record // ReSharper restore MemberCanBePrivate.Global // ReSharper disable FieldCanBeMadeReadOnly.Local private DAnalyzeTone _AnalyzeToneFunc; + private double _MinWeightDiff; // ReSharper restore FieldCanBeMadeReadOnly.Local private double _MaxVolume; @@ -60,9 +60,15 @@ namespace Vocaluxe.Lib.Sound.Record ToneWeigth = new float[NumHalfTones]; Reset(); if (AnalyzeFunction == EAnalyzeFunction.Amdf) + { _AnalyzeToneFunc = _GetAmdf; + _MinWeightDiff = 0.01; + } else if (AnalyzeFunction == EAnalyzeFunction.AutoCorrelation) + { _AnalyzeToneFunc = _GetAutoCorrelation; + _MinWeightDiff = 0.0001; + } #if TEST_PITCH _TestPitchDetection(); #endif @@ -163,21 +169,16 @@ namespace Vocaluxe.Lib.Sound.Record private void _FindMaxVolume() { - short maxVolume = 0; + double maxVolume = 0; for (int i = 0; i < _AnalysisBufLen / 4; i++) { - short volume = _AnalysisBuffer[i]; - if (volume == Int16.MinValue) - { - maxVolume = Int16.MaxValue; - break; - } + double volume = _AnalysisBuffer[i]; if (volume < 0) - volume = (short)-volume; + volume = -volume; if (volume > maxVolume) maxVolume = volume; } - _MaxVolume = (double)maxVolume / Int16.MaxValue; + _MaxVolume = maxVolume / Int16.MaxValue; } private void _AnalyzeTones() @@ -208,7 +209,7 @@ namespace Vocaluxe.Lib.Sound.Record _TmpWeight[toneIndex - _HalfToneMin] = (float)curWeight; } - if (maxWeight - minWeight > 0.001) + if (maxWeight - minWeight > _MinWeightDiff) { Array.Copy(_TmpWeight, ToneWeigth, NumHalfTones); From 8eb42b5a5f274c1c7fdc3ea5ecfbec031da1cd08 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 23 Mar 2014 21:41:40 +0100 Subject: [PATCH 07/34] Add a native version of the pitch detection algo as C# is to slow for exact real time detection(Speedup: 10) --- .gitignore | 13 +- PitchTracker/PitchTracker.vcxproj | 178 ++++++++++++++++++++++ PitchTracker/PitchTracker.vcxproj.filters | 27 ++++ PitchTracker/pitchTracker.cpp | 115 ++++++++++++++ PitchTracker/pitchTracker.h | 17 +++ Vocaluxe.sln | 23 +++ Vocaluxe/Lib/Sound/Record/CBuffer.cs | 115 +++++++++++--- 7 files changed, 460 insertions(+), 28 deletions(-) create mode 100644 PitchTracker/PitchTracker.vcxproj create mode 100644 PitchTracker/PitchTracker.vcxproj.filters create mode 100644 PitchTracker/pitchTracker.cpp create mode 100644 PitchTracker/pitchTracker.h diff --git a/.gitignore b/.gitignore index 6413e521..a12662d6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,13 +14,13 @@ Output/Songs /*.ctl /Output/Registration.xml /Vocaluxe.suo -/Vocaluxe/Vocaluxe.csproj.user +*.csproj.user +*.vcxproj.user /Output/Config.xml *.ipch *.log /Output/Playlists/*.xml -/Output/x64/gstreamer/GstreamerHelper.dll -/Output/x86/gstreamer/GstreamerHelper.dll +GstreamerHelper.dll *.tlog *.suo *.obj @@ -39,11 +39,7 @@ Output/Songs *.Cache /GstreamerHelper/bin/* /VocaluxeLib/bin -/ClientServerLib/ClientServerLib/ClientServerLib.csproj.user -/ClientServerLib/ClientServerLib/bin/Debug/ClientServerLib.dll -/ClientServerLib/ClientTest/bin/Debug/ClientServerLib.dll -/ClientServerLib/ClientTest/bin/Release/ClientServerLib.dll -/ClientServerLib/ClientServerLib/bin/ClientServerLib.dll +ClientServerLib.dll ClientTest.exe *.vshost.* *.userprefs @@ -63,3 +59,4 @@ Output/Vocaluxe_x64.exe /Output/VocaluxeServerConfig.exe.config /PhoneGap/ /Output/Profiles +PitchTracker.dll diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj new file mode 100644 index 00000000..73e5ca52 --- /dev/null +++ b/PitchTracker/PitchTracker.vcxproj @@ -0,0 +1,178 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {54A48AF7-515C-4EDD-B395-2BFFA096050A} + Win32Proj + PitchTracker + PitchTracker + + + + DynamicLibrary + true + v110_xp + Unicode + + + DynamicLibrary + true + v110_xp + Unicode + + + DynamicLibrary + false + v110_xp + true + Unicode + + + DynamicLibrary + false + v110_xp + true + Unicode + + + + + + + + + + + + + + + + + + + true + bin\$(Configuration).$(Platform)\ + obj\$(Configuration).$(Platform)\ + + + true + bin\$(Configuration).$(Platform)\ + obj\$(Configuration).$(Platform)\ + + + false + bin\$(Configuration).$(Platform)\ + obj\$(Configuration).$(Platform)\ + + + false + bin\$(Configuration).$(Platform)\ + obj\$(Configuration).$(Platform)\ + + + + NotUsing + Level3 + Disabled + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Fast + + + Windows + true + + + xcopy "$(OutDir)*.dll" "$(SolutionDir)Output\x64\" /I /Y + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Fast + + + Windows + true + + + xcopy "$(OutDir)*.dll" "$(SolutionDir)Output\x86\" /I /Y + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Speed + true + Fast + + + Windows + false + true + true + + + xcopy "$(OutDir)*.dll" "$(SolutionDir)Output\x64\" /I /Y + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Speed + Fast + + + Windows + false + true + true + + + xcopy "$(OutDir)*.dll" "$(SolutionDir)Output\x86\" /I /Y + + + + + + + + + + + + \ No newline at end of file diff --git a/PitchTracker/PitchTracker.vcxproj.filters b/PitchTracker/PitchTracker.vcxproj.filters new file mode 100644 index 00000000..aa287032 --- /dev/null +++ b/PitchTracker/PitchTracker.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Quelldateien + + + + + Headerdateien + + + \ No newline at end of file diff --git a/PitchTracker/pitchTracker.cpp b/PitchTracker/pitchTracker.cpp new file mode 100644 index 00000000..72904102 --- /dev/null +++ b/PitchTracker/pitchTracker.cpp @@ -0,0 +1,115 @@ +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . + +#include "pitchTracker.h" +#include +#include +#include +#include + +void doLog(const char* msg,...){ + va_list argptr = NULL; + va_start(argptr, msg); + + char buffer[200]; + vsprintf_s(buffer,msg, argptr); + if(Log) Log(buffer); + va_end(argptr); +} + +void SetLogCallback(LogCallback Callback){ + Log=Callback; +} + +double *SamplesPerPeriodPerTone = NULL; +int MinHalfTone = 0, MaxHalfTone = 38; +const double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) + +void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ + MinHalfTone = minHalfTone; + MaxHalfTone = maxHalfTone; + DeInit(); + if(maxHalfTone <= 0) + return; + SamplesPerPeriodPerTone = (double*) malloc(MaxHalfTone * sizeof(double)); + //Init Array to avoid costly calculations + for (int toneIndex = 0; toneIndex <= MaxHalfTone; toneIndex++) + { + double freq = baseToneFrequency * pow(HalftoneBase, toneIndex); + SamplesPerPeriodPerTone[toneIndex] = 44100.0 / freq; // samples in one period + } +} + +void DeInit(){ + if(SamplesPerPeriodPerTone){ + free(SamplesPerPeriodPerTone); + SamplesPerPeriodPerTone=NULL; + } +} + +static double _AnalyzeToneFunc(double *samples, int sampleCt, int toneIndex){ + double samplesPerPeriodD = SamplesPerPeriodPerTone[toneIndex]; // samples in one period + int samplesPerPeriod = (int)samplesPerPeriodD; + double fHigh = samplesPerPeriodD - samplesPerPeriod; + double fLow = 1.0 - fHigh; + + double accumDist = 0; // accumulated distances + + // compare correlating samples + int sampleIndex = 0; // index of sample to analyze + // Start value= index of sample one period ahead + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < sampleCt; correlatingSampleIndex++, sampleIndex++) + { + // calc distance to corresponding sample in next period (lower means more distant) + double dist = samples[sampleIndex] * (samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh); + accumDist += dist; + } + + //Using _AnalysisBufLen here makes it return correct values among all analyzed frequencies + double scaleValue = 32767.0 * 32767.0 * sampleCt; // Divide also by Int16.MaxValue^2 + return accumDist / scaleValue; +} + +int GetTone(double *samples, int sampleCt, float *weights){ + double maxVolume = 0; + for(int i = 0; i < sampleCt; i++){ + double vol = abs(samples[i]); + if(vol > maxVolume) + maxVolume = vol; + } + double maxWeight = -1; + double minWeight = 1; + int maxTone = -1; + for (int toneIndex = MinHalfTone; toneIndex <= MaxHalfTone; toneIndex++) + { + double curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolume * 32767.0; + + if (curWeight > maxWeight) + { + maxWeight = curWeight; + maxTone = toneIndex; + } + + if (curWeight < minWeight) + minWeight = curWeight; + + weights[toneIndex] = (float) curWeight; + } + + if(maxWeight - minWeight > 0.01){ + return maxTone; + }else return -1; +} + diff --git a/PitchTracker/pitchTracker.h b/PitchTracker/pitchTracker.h new file mode 100644 index 00000000..99b477b0 --- /dev/null +++ b/PitchTracker/pitchTracker.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef dywapitchtrack__H +#define dywapitchtrack__H + +#define DllExport extern "C" __declspec(dllexport) + +DllExport void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); +DllExport void DeInit(); +DllExport int GetTone(double *samples, int sampleCt, float *weights); + +typedef void (__stdcall * LogCallback)(const char* text); +static LogCallback Log; +DllExport void SetLogCallback(LogCallback Callback); + +#endif + diff --git a/Vocaluxe.sln b/Vocaluxe.sln index 347f685a..0298c529 100644 --- a/Vocaluxe.sln +++ b/Vocaluxe.sln @@ -9,6 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocalu {EC5167E4-CCFB-4CEE-987C-CF816F1062A3} = {EC5167E4-CCFB-4CEE-987C-CF816F1062A3} {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} = {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} {5A4053F1-5AD5-441F-B254-D97A088127B6} = {5A4053F1-5AD5-441F-B254-D97A088127B6} + {54A48AF7-515C-4EDD-B395-2BFFA096050A} = {54A48AF7-515C-4EDD-B395-2BFFA096050A} EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VocaluxeLib", "VocaluxeLib\VocaluxeLib.csproj", "{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}" @@ -25,6 +26,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerLib", "ClientServerLi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebserverInitalConfig", "WebserverInitalConfig\WebserverInitalConfig.csproj", "{55F89808-4E79-4FFE-BC13-48258913F5C9}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PitchTracker", "PitchTracker\PitchTracker.vcxproj", "{54A48AF7-515C-4EDD-B395-2BFFA096050A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution DebugLinux|x64 = DebugLinux|x64 @@ -191,6 +194,26 @@ Global {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x64.Build.0 = Release|Any CPU {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x86.ActiveCfg = Release|Any CPU {55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x86.Build.0 = Release|Any CPU + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x64.ActiveCfg = Debug|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x64.Build.0 = Debug|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x86.ActiveCfg = Debug|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugLinux|x86.Build.0 = Debug|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x64.ActiveCfg = Debug|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x64.Build.0 = Debug|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x86.ActiveCfg = Debug|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.DebugWin|x86.Build.0 = Debug|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x64.ActiveCfg = Release|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x64.Build.0 = Release|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x86.ActiveCfg = Release|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.InstallerWin|x86.Build.0 = Release|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x64.ActiveCfg = Release|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x64.Build.0 = Release|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x86.ActiveCfg = Release|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseLinux|x86.Build.0 = Release|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x64.ActiveCfg = Release|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x64.Build.0 = Release|x64 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x86.ActiveCfg = Release|Win32 + {54A48AF7-515C-4EDD-B395-2BFFA096050A}.ReleaseWin|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 7aece259..70334af4 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -1,9 +1,29 @@ -#define TEST_PITCH +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +#define TEST_PITCH +#define USE_NATIVE_DETECTION +//If defined, it uses a library with native code that speeds up detection by a factor of 10 using System; using System.IO; #if TEST_PITCH using System.Diagnostics; +using System.Runtime.InteropServices; using System.Windows.Forms; using VocaluxeLib; @@ -11,16 +31,29 @@ using VocaluxeLib; namespace Vocaluxe.Lib.Sound.Record { +#if USE_NATIVE_DETECTION + static class CPitchTracker + { + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void DeInit(); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetTone(double[] samples, int sampleCt, float[] weights); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate void LogCallback(string message); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void SetLogCallback(LogCallback c); + } +#endif + class CBuffer : IDisposable { - public enum EAnalyzeFunction - { - AutoCorrelation, //Faster, more resistent to noise, good value for HalfToneMax=38 (higher->wrong results in test case, WHY?) with 38 no wrong values in test case - Amdf //Average magnitude difference, slower, detects everything in range -> HalfToneMax=45 - } - - private delegate double DAnalyzeTone(int tone); - + private static int _InitCount; //Half tones: C C♯ D Eb E F F♯ G G♯ A Bb B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) @@ -34,9 +67,18 @@ namespace Vocaluxe.Lib.Sound.Record private readonly double[] _AnalysisBuffer = new double[_AnalysisBufLen]; private readonly byte[] _AnalysisByteBuffer = new byte[_AnalysisByteBufLen]; //tmp buffer (stream->tmpBuffer->(Int16)AnalysisBuffer) - //Precalculated table holding sample# per period for each tone (actually we may not use the lower few entries, but keep it to avoid index modification + private readonly float[] _TmpWeights = new float[NumHalfTones]; //tmp buffer for weights (gets copied to ToneWeight when checked) +#if !USE_NATIVE_DETECTION + //Precalculated table holding sample# per period for each tone (actually we may not use the lower few entries, but keep it to avoid index modification private static readonly double[] _SamplesPerPeriodPerTone = new double[_HalfToneMax + 1]; - private readonly float[] _TmpWeight = new float[NumHalfTones]; //tmp buffer for weights (gets copied to ToneWeight when checked) + + public enum EAnalyzeFunction + { + AutoCorrelation, //Faster, more resistent to noise, good value for HalfToneMax=38 (higher->wrong results in test case, WHY?) with 38 no wrong values in test case + Amdf //Average magnitude difference, slower, detects everything in range -> HalfToneMax=45 + } + private delegate double DAnalyzeTone(int tone); + // ReSharper disable MemberCanBePrivate.Global // ReSharper disable ConvertToConstant.Global // ReSharper disable FieldCanBeMadeReadOnly.Global @@ -48,7 +90,7 @@ namespace Vocaluxe.Lib.Sound.Record private DAnalyzeTone _AnalyzeToneFunc; private double _MinWeightDiff; // ReSharper restore FieldCanBeMadeReadOnly.Local - +#endif private double _MaxVolume; private bool _NewSamples; @@ -56,9 +98,11 @@ namespace Vocaluxe.Lib.Sound.Record public CBuffer() { + _Init(); MinVolume = 0.02f; ToneWeigth = new float[NumHalfTones]; Reset(); +#if !USE_NATIVE_DETECTION if (AnalyzeFunction == EAnalyzeFunction.Amdf) { _AnalyzeToneFunc = _GetAmdf; @@ -69,19 +113,32 @@ namespace Vocaluxe.Lib.Sound.Record _AnalyzeToneFunc = _GetAutoCorrelation; _MinWeightDiff = 0.0001; } +#endif #if TEST_PITCH _TestPitchDetection(); #endif } - static CBuffer() + ~CBuffer() { - //Init Array to avoid costly calculations + _Dispose(); + } + + private static void _Init() + { + _InitCount++; + if (_InitCount > 1) + return; //Do init only once +#if USE_NATIVE_DETECTION + CPitchTracker.Init(_BaseToneFreq, _HalfToneMin, _HalfToneMax); +#else + //Init Array to avoid costly calculations for (int toneIndex = 0; toneIndex <= _HalfToneMax; toneIndex++) { double freq = _BaseToneFreq * Math.Pow(_HalftoneBase, toneIndex); _SamplesPerPeriodPerTone[toneIndex] = 44100.0 / freq; // samples in one period } +#endif } public int ToneAbs { get; private set; } @@ -98,7 +155,7 @@ namespace Vocaluxe.Lib.Sound.Record public float[] ToneWeigth { get; private set; } /// - /// Minimum volume for a tone to be valid + /// Minimum volume for a tone to be valid /// public float MinVolume { get; set; } @@ -183,7 +240,11 @@ namespace Vocaluxe.Lib.Sound.Record private void _AnalyzeTones() { - // prepare to analyze +#if USE_NATIVE_DETECTION + int maxTone = CPitchTracker.GetTone(_AnalysisBuffer, _AnalysisBufLen, _TmpWeights); + if (maxTone >= 0) +#else + // prepare to analyze double maxWeight = -1.0; double minWeight = 1.0; int maxTone = -1; @@ -206,12 +267,13 @@ namespace Vocaluxe.Lib.Sound.Record if (curWeight < minWeight) minWeight = curWeight; - _TmpWeight[toneIndex - _HalfToneMin] = (float)curWeight; + _TmpWeights[toneIndex - _HalfToneMin] = (float)curWeight; } if (maxWeight - minWeight > _MinWeightDiff) +#endif { - Array.Copy(_TmpWeight, ToneWeigth, NumHalfTones); + Array.Copy(_TmpWeights, ToneWeigth, NumHalfTones); ToneAbs = maxTone; //Console.WriteLine(maxTone); @@ -222,6 +284,7 @@ namespace Vocaluxe.Lib.Sound.Record ToneValid = false; } +#if !USE_NATIVE_DETECTION private double _GetAutoCorrelation(int tone) { double samplesPerPeriodD = _SamplesPerPeriodPerTone[tone]; // samples in one period @@ -269,17 +332,29 @@ namespace Vocaluxe.Lib.Sound.Record accumDist += dist; } //Use analyzed sample count here. BufLen yields more errors - return 1.0 - (double)accumDist / Int16.MaxValue / sampleIndex; + return 1.0 - accumDist / Int16.MaxValue / sampleIndex; } +#endif public void Dispose() + { + _Dispose(); + GC.SuppressFinalize(this); + } + + private void _Dispose() { if (_Stream != null) { _Stream.Dispose(); _Stream = null; } - GC.SuppressFinalize(this); +#if USE_NATIVE_DETECTION + Debug.Assert(_InitCount > 0); + _InitCount--; + if (_InitCount == 0) + CPitchTracker.DeInit(); +#endif } #if TEST_PITCH From d67d58cbc3bab9ff1b3dd9ebc45fdce8ab271741 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 23 Mar 2014 22:34:22 +0100 Subject: [PATCH 08/34] Change note names --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 70334af4..b7f84c54 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -54,7 +54,7 @@ namespace Vocaluxe.Lib.Sound.Record class CBuffer : IDisposable { private static int _InitCount; - //Half tones: C C♯ D Eb E F F♯ G G♯ A Bb B + //Half tones: C C♯ D D# E F F♯ G G♯ A A# B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) private const int _HalfToneMin = 0; // C2 @@ -363,7 +363,7 @@ namespace Vocaluxe.Lib.Sound.Record private static string _ToneToNote(int tone, bool withOctave = true) { tone += 24; - string[] notes = {"C", "C♯", "D", "Eb", "E", "F", "F♯", "G", "G♯", "A", "Bb", "B"}; + string[] notes = {"C", "C♯", "D", "D#", "E", "F", "F♯", "G", "G♯", "A", "A#", "B"}; string result = notes[tone % 12]; if (withOctave) result += (tone / 12); From cbbed7b4a2a8867f552968bfe3d1af5cbdd26560 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Mon, 24 Mar 2014 01:56:44 +0100 Subject: [PATCH 09/34] Fix using --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index b7f84c54..9c668741 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -15,15 +15,18 @@ // along with Vocaluxe. If not, see . #endregion -#define TEST_PITCH +//#define TEST_PITCH #define USE_NATIVE_DETECTION //If defined, it uses a library with native code that speeds up detection by a factor of 10 using System; using System.IO; -#if TEST_PITCH using System.Diagnostics; +#if USE_NATIVE_DETECTION using System.Runtime.InteropServices; + +#endif +#if TEST_PITCH using System.Windows.Forms; using VocaluxeLib; From 64b4f15281ec9e390f56c9eb3a7e91ddb2d03fd6 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Mon, 24 Mar 2014 02:00:41 +0100 Subject: [PATCH 10/34] Fix wrong array bounds --- PitchTracker/pitchTracker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PitchTracker/pitchTracker.cpp b/PitchTracker/pitchTracker.cpp index 72904102..31e82059 100644 --- a/PitchTracker/pitchTracker.cpp +++ b/PitchTracker/pitchTracker.cpp @@ -43,7 +43,7 @@ void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ DeInit(); if(maxHalfTone <= 0) return; - SamplesPerPeriodPerTone = (double*) malloc(MaxHalfTone * sizeof(double)); + SamplesPerPeriodPerTone = (double*) malloc((MaxHalfTone + 1) * sizeof(double)); //Init Array to avoid costly calculations for (int toneIndex = 0; toneIndex <= MaxHalfTone; toneIndex++) { @@ -105,7 +105,7 @@ int GetTone(double *samples, int sampleCt, float *weights){ if (curWeight < minWeight) minWeight = curWeight; - weights[toneIndex] = (float) curWeight; + weights[toneIndex - MinHalfTone] = (float) curWeight; } if(maxWeight - minWeight > 0.01){ From 94c7f6868859e0cd901421ae08f1f572f92f6fb8 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Tue, 25 Mar 2014 18:10:41 +0100 Subject: [PATCH 11/34] Add another pitch detection algorithm (from Performous) and wrapped everything in c++/cli classes --- PitchTracker/Helper.h | 61 ++++ PitchTracker/License.txt | 2 + PitchTracker/Performous.txt | 346 ++++++++++++++++++++++ PitchTracker/PitchTracker.vcxproj | 25 ++ PitchTracker/PitchTracker.vcxproj.filters | 32 ++ PitchTracker/PitchWrapper.cpp | 92 ++++++ PitchTracker/PitchWrapper.h | 62 ++++ PitchTracker/compatibility.cpp | 30 ++ PitchTracker/compatibility.h | 17 ++ PitchTracker/libda/fft.hpp | 84 ++++++ PitchTracker/libda/sample.hpp | 82 +++++ PitchTracker/pitch.cc | 233 +++++++++++++++ PitchTracker/pitch.hh | 132 +++++++++ PitchTracker/pitchTracker.cpp | 169 ++++++----- PitchTracker/pitchTracker.h | 22 +- PitchTracker/util.hh | 45 +++ Vocaluxe/Lib/Sound/Record/CBuffer.cs | 37 +-- Vocaluxe/Vocaluxe.csproj | 4 + 18 files changed, 1349 insertions(+), 126 deletions(-) create mode 100644 PitchTracker/Helper.h create mode 100644 PitchTracker/License.txt create mode 100644 PitchTracker/Performous.txt create mode 100644 PitchTracker/PitchWrapper.cpp create mode 100644 PitchTracker/PitchWrapper.h create mode 100644 PitchTracker/compatibility.cpp create mode 100644 PitchTracker/compatibility.h create mode 100644 PitchTracker/libda/fft.hpp create mode 100644 PitchTracker/libda/sample.hpp create mode 100644 PitchTracker/pitch.cc create mode 100644 PitchTracker/pitch.hh create mode 100644 PitchTracker/util.hh diff --git a/PitchTracker/Helper.h b/PitchTracker/Helper.h new file mode 100644 index 00000000..f0416375 --- /dev/null +++ b/PitchTracker/Helper.h @@ -0,0 +1,61 @@ +#pragma once +#include "pitch.hh" +#include "PitchWrapper.h" + +#pragma managed(push, off) + +#include +#include + +float* short2FloatArray(short* in, size_t len){ + const float maxShort = 32768.0; //maximum abs value of a short + + float* result = static_cast(malloc(len * sizeof(float))); + float* curOut = result; + for(int i=0; i(malloc(len * sizeof(double))); + double* curOut = result; + for(int i=0; iFreq = tone.freq; + result->DB = tone.db; + result->Stabledb = tone.stabledb; + result->Age = static_cast(tone.age); + result->NoteExact = 12.0 * std::log(tone.freq / 127.09) / std::log(2.0) + 27.5 - 16; // 16 = C2 + result->Note = static_cast(std::round(result->NoteExact)); + return result; + } + } +} \ No newline at end of file diff --git a/PitchTracker/License.txt b/PitchTracker/License.txt new file mode 100644 index 00000000..0db6541a --- /dev/null +++ b/PitchTracker/License.txt @@ -0,0 +1,2 @@ +Some code is taken from Performous: https://github.com/performous/performous/tree/master/game +From 25.03.2014 \ No newline at end of file diff --git a/PitchTracker/Performous.txt b/PitchTracker/Performous.txt new file mode 100644 index 00000000..5861375b --- /dev/null +++ b/PitchTracker/Performous.txt @@ -0,0 +1,346 @@ +GNU GPLv2 or later. Some parts of the project may have more liberal licenses. +See Authors.txt for information on copyright holders and licenses of specific +parts. Fonts are licensed under SIL OFL. + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj index 73e5ca52..e17ebdcd 100644 --- a/PitchTracker/PitchTracker.vcxproj +++ b/PitchTracker/PitchTracker.vcxproj @@ -167,10 +167,35 @@ + + + + true + true + true + true + false + false + false + false + false + false + Default + Default + + + + + + + + + + diff --git a/PitchTracker/PitchTracker.vcxproj.filters b/PitchTracker/PitchTracker.vcxproj.filters index aa287032..f122cd3f 100644 --- a/PitchTracker/PitchTracker.vcxproj.filters +++ b/PitchTracker/PitchTracker.vcxproj.filters @@ -18,10 +18,42 @@ Quelldateien + + Quelldateien + + + Quelldateien + + + Quelldateien + Headerdateien + + Headerdateien + + + Headerdateien + + + Headerdateien + + + Headerdateien + + + Headerdateien + + + + + Headerdateien + + + Headerdateien + \ No newline at end of file diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp new file mode 100644 index 00000000..6c18714e --- /dev/null +++ b/PitchTracker/PitchWrapper.cpp @@ -0,0 +1,92 @@ +#include "PitchWrapper.h" +#pragma managed(push, off) +#include "pitchTracker.h" +#pragma managed(pop) + +#include "Helper.h" + +namespace Native{ + namespace PitchTracking{ + + //CAnalyzer + + void CAnalyzer::Input(array^ data){ + if(data->Length == 0) + return; + pin_ptr dataPtr = &data[0]; + float* dataPtr2 = dataPtr; + m_analyzer->input(dataPtr2, dataPtr2 + data->Length); + } + + void CAnalyzer::Input(array^ data){ + if(data->Length == 0) + return; + pin_ptr dataPtr = &data[0]; + float* dataFloat = short2FloatArray(dataPtr, data->Length); + m_analyzer->input(dataFloat, dataFloat + data->Length); + freeFloatArray(dataFloat); + } + + void CAnalyzer::Process(){ + m_analyzer->process(); + } + + double CAnalyzer::GetPeak(){ + return m_analyzer->getPeak(); + } + + array^ CAnalyzer::GetTones(){ + Analyzer::tones_t umTones = m_analyzer->getTones(); + array^ tones = gcnew array(static_cast(umTones.size())); + int i = 0; + for(auto it=umTones.begin(); it!=umTones.end(); it++, i++){ + tones[i]=ConvertToneToManaged(*it); + } + return tones; + } + + CTone^ CAnalyzer::FindTone(){ + return FindTone(65.0); + } + + CTone^ CAnalyzer::FindTone(double minFreq){ + return FindTone(minFreq, 1000.0); + } + + CTone^ CAnalyzer::FindTone(double minFreq, double maxFreq){ + const Tone* tone = m_analyzer->findTone(minFreq, maxFreq); + return (tone == NULL) ? nullptr : ConvertToneToManaged(*tone); + } + + void CAnalyzer::Output(array^ data, float rate){ + pin_ptr dataPtr = &data[0]; + m_analyzer->output(dataPtr, dataPtr + data->Length, rate); + } + + String^ CAnalyzer::GetId(){ + return m_id; + } + + + //CPitchTracker + + void CPitchTracker::Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ + PitchTracker::Init(baseToneFrequency, minHalfTone, maxHalfTone); + } + + void CPitchTracker::DeInit(){ + PitchTracker::DeInit(); + } + + int CPitchTracker::GetTone(array^ samples, array^ weights){ + if(samples->Length == 0) + return -1; + pin_ptr dataPtr = &samples[0]; + pin_ptr weightsPtr = &weights[0]; + double* dataDouble = short2DoubleArray(dataPtr, samples->Length, false); + int result = PitchTracker::GetTone(dataDouble, samples->Length, weightsPtr, true); + freeDoubleArray(dataDouble); + return result; + } + } +} \ No newline at end of file diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h new file mode 100644 index 00000000..617c24f3 --- /dev/null +++ b/PitchTracker/PitchWrapper.h @@ -0,0 +1,62 @@ +#pragma once + +#pragma managed(push, off) +#include "pitch.hh" +#pragma managed(pop) + +using namespace System; +using namespace System::Collections::Generic; + +namespace Native{ + namespace PitchTracking{ + public ref class CTone { + public: + static const int MAXHARM = 48; ///< The maximum number of harmonics tracked + static const int MINAGE = 2; ///< The minimum age required for a tone to be output + double Freq; ///< Frequency (Hz) + double DB; ///< Level (dB) + double Stabledb; ///< Stable level, useful for graphics rendering + int Age; ///< How many times the tone has been detected in row + double NoteExact; + int Note; + /// Less-than compare by levels (instead of frequencies like operator< does) + static bool dbCompare(CTone l, CTone r) { return l.DB < r.DB; } + }; + + public ref class CAnalyzer { + public: + CAnalyzer(double rate, String^ id) { + m_analyzer = new Analyzer(rate,""); + m_id = id; + } + CAnalyzer(double rate, String^ id, unsigned step) { + m_analyzer = new Analyzer(rate,"",step); + m_id = id; + } + ~CAnalyzer() { this->!CAnalyzer(); } + !CAnalyzer() { delete m_analyzer; } + + void Input(array^ data); + void Input(array^ data); + void Process(); + double GetPeak(); + array^ GetTones(); + CTone^ FindTone(); + CTone^ FindTone(double minFreq); + CTone^ FindTone(double minFreq, double maxFreq); + void Output(array^ data, float rate); + String^ GetId(); + + private: + Analyzer* m_analyzer; + String^ m_id; + }; + + public ref class CPitchTracker abstract sealed{ + public: + static void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); + static void DeInit(); + static int GetTone(array^ samples, array^ weights); + }; + } +} \ No newline at end of file diff --git a/PitchTracker/compatibility.cpp b/PitchTracker/compatibility.cpp new file mode 100644 index 00000000..207b750d --- /dev/null +++ b/PitchTracker/compatibility.cpp @@ -0,0 +1,30 @@ +#include "compatibility.h" + +#include + +#ifdef _MSC_VER +#if(_MSC_VER < 1800) // < VS2013 +namespace std +{ + float round(float d) + { + return static_cast(floor(d + 0.5)); + } + + double round(double d) + { + return floor(d + 0.5); + } + + long double round(long double d) + { + return floor(d + 0.5); + } + +} + +double remainder(double num, double denom){ + return num - std::round(num/denom) * denom; +} +#endif +#endif \ No newline at end of file diff --git a/PitchTracker/compatibility.h b/PitchTracker/compatibility.h new file mode 100644 index 00000000..ebdf8a88 --- /dev/null +++ b/PitchTracker/compatibility.h @@ -0,0 +1,17 @@ +//Contains some definitions to make the code work with compilers that do not support all feautures + +#pragma once + +#ifdef _MSC_VER + #define constexpr const + #if(_MSC_VER < 1800) // < VS2013 + namespace std + { + float round(float d); + double round(double d); + long double round(long double d); + } + + double remainder(double num, double denom); + #endif +#endif \ No newline at end of file diff --git a/PitchTracker/libda/fft.hpp b/PitchTracker/libda/fft.hpp new file mode 100644 index 00000000..1611c2fb --- /dev/null +++ b/PitchTracker/libda/fft.hpp @@ -0,0 +1,84 @@ +#pragma once + +/** + * @file fft.hpp FFT and related facilities. + */ + +#include "sample.hpp" +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.141592653589793 +#endif + +#define M_TAU (2.0 * M_PI) + +namespace da { + + // With g++ optimization -fcx-limited-range should be used for 5x performance boost. + + // Based on the description of Volodymyr Myrnyy in + // http://www.dspdesignline.com/showArticle.jhtml?printableArticle=true&articleId=199903272 + template struct DanielsonLanczos { + static void apply(std::complex* data) { + constexpr std::size_t N = 1 << P; + constexpr std::size_t M = N / 2; + // Compute even and odd halves + DanielsonLanczos

().apply(data); + DanielsonLanczos

().apply(data + M); + // Combine the results + std::complex w(1.0); + for (std::size_t i = 0; i < M; ++i) { + const std::complex temp = data[i + M] * w; + data[M + i] = data[i] - temp; + data[i] += temp; + w *= std::polar(1.0, -M_TAU / N); + } + } + }; + + template struct DanielsonLanczos<0, T> { static void apply(std::complex*) {} }; + + /** Perform FFT on data. **/ + template void fft(std::complex* data) { + // Perform bit-reversal sorting of sample data. + constexpr std::size_t N = 1 << P; + std::size_t j = 0; + for (std::size_t i = 0; i < N; ++i) { + if (i < j) std::swap(data[i], data[j]); + std::size_t m = N / 2; + while (m > 1 && m <= j) { j -= m; m >>= 1; } + j += m; + } + // Do the actual calculation + DanielsonLanczos::apply(data); + } + + /** Perform FFT on data from floating point iterator, windowing the input. **/ + template std::vector > fft(InIt begin, Window window) { + std::vector > data(1 << P); + // Perform bit-reversal sorting of sample data. + constexpr std::size_t N = 1 << P; + std::size_t j = 0; + for (std::size_t i = 0; i < N; ++i) { + data[j] = *begin++ * window[i]; + std::size_t m = N / 2; + while (m > 1 && m <= j) { j -= m; m >>= 1; } + j += m; + } + // Do the actual calculation + DanielsonLanczos::apply(&data[0]); + return data; + } + + template void ifft(std::complex* data) { + constexpr std::size_t N = 1 << P; + for (std::size_t i = 0; i < N; ++i) data[i] = std::conj(data[i]); // Invert phase so that we can use FFT to do IFFT + fft

(data); + constexpr std::complex scale(1.0/N, 0.0); + for (std::size_t i = 0; i < N; ++i) data[i] = scale * std::conj(data[i]); // Invert back, and apply IFFT scaling + } + +} diff --git a/PitchTracker/libda/sample.hpp b/PitchTracker/libda/sample.hpp new file mode 100644 index 00000000..a09bbcb6 --- /dev/null +++ b/PitchTracker/libda/sample.hpp @@ -0,0 +1,82 @@ +#pragma once + +#include +#include "../compatibility.h" + +/** + * @file sample.hpp Sample format definition and format conversions. + */ + +namespace da { + + using std::round; + + // Should be a floating-point type + typedef float sample_t; + + // A helper function for clamping a value to a certain range + template T clamp(T val, T min, T max) { + if (val < min) val = min; + if (val > max) val = max; + return val; + } + + constexpr sample_t max_s16(32767), min_s16 = -max_s16 - sample_t(1); + constexpr sample_t max_s24(8388607), min_s24 = -max_s24 - sample_t(1); + constexpr sample_t max_s32(2147483647), min_s32= -max_s32 - sample_t(1); + constexpr double tau(6.2831853071795864769252867665590057683943387987502116); ///< One full circle + constexpr double pi = tau / sample_t(2); ///< Half circle + constexpr double eps(1e-10); ///< Tiny positive value + + /// Mathematical sinc function + template static inline Float msinc(Float x) { return std::abs(x) < Float(eps) ? Float(1) : std::sin(x) / x; } + + /// Normalized (signal processing) sinc function + template static inline Float sinc(Float x) { return msinc(Float(pi) * x); } + + /// Lanczos kernel of size A + template static inline Float lanc(Float x) { + return std::abs(x) < A ? sinc(x) * sinc(x / A) : Float(); + } + + // The following conversions provide lossless conversions between floats + // and integers. Be sure to use only these conversions or otherwise the + // conversions may not be lossless, due to different scaling factors being + // used by different libraries. + + // The negative minimum integer value produces sample_t value slightly + // more negative than -1.0 but this is necessary in order to prevent + // clipping in the float-to-int conversions. Now amplitude 1.0 in floating + // point produces -32767 .. 32767 symmetrical non-clipping range in s16. + + static inline sample_t conv_from_s16(int s) { return s / max_s16; } + static inline sample_t conv_from_s24(int s) { return s / max_s24; } + static inline sample_t conv_from_s32(int s) { return s / max_s32; } + // The rounding is strictly not necessary, but it greatly improves + // the error tolerance if any floating point calculations are done. + // The ugly static_casts are required to avoid warnings in MSVC. + static inline int conv_to_s16(sample_t s) { return clamp(static_cast(round(s * max_s16)), static_cast(min_s16), static_cast(max_s16)); } + static inline int conv_to_s24(sample_t s) { return clamp(static_cast(round(s * max_s24)), static_cast(min_s24), static_cast(max_s24)); } + static inline int conv_to_s32(sample_t s) { return static_cast(clamp(round(s * max_s32), min_s32, max_s32 )); } + // Non-rounding non-clamping versions are provided for very low end devices (still lossless) + static inline int conv_to_s16_fast(sample_t s) { return static_cast(s * max_s16); } + static inline int conv_to_s24_fast(sample_t s) { return static_cast(s * max_s24); } + static inline int conv_to_s32_fast(sample_t s) { return static_cast(s * max_s32); } + + template class step_iterator: public std::iterator { + ValueType* m_pos; + std::ptrdiff_t m_step; + public: + step_iterator(ValueType* pos, std::ptrdiff_t step): m_pos(pos), m_step(step) {} + ValueType& operator*() { return *m_pos; } + step_iterator operator+(std::ptrdiff_t rhs) { return step_iterator(m_pos + m_step * rhs, m_step); } + step_iterator& operator++() { m_pos += m_step; return *this; } + step_iterator operator++(int) { step_iterator ret = *this; ++*this; return ret; } + bool operator!=(step_iterator const& rhs) const { return m_pos != rhs.m_pos; } + std::ptrdiff_t operator-(step_iterator const& rhs) const { return (m_pos - rhs.m_pos) / m_step; } + // TODO: more operators + }; + + typedef step_iterator sample_iterator; + typedef step_iterator sample_const_iterator; +} diff --git a/PitchTracker/pitch.cc b/PitchTracker/pitch.cc new file mode 100644 index 00000000..d4b9d9a0 --- /dev/null +++ b/PitchTracker/pitch.cc @@ -0,0 +1,233 @@ +#include "pitch.hh" + +#include "util.hh" +#include "libda/fft.hpp" +#include +#include +#include + +// Limit the range to avoid noise and useless computation +static const double FFT_MINFREQ = 45.0; +static const double FFT_MAXFREQ = 5000.0; + +Tone::Tone(): + freq(0.0), + db(-getInf()), + stabledb(-getInf()), + age() +{ + for (auto& h: harmonics) h = -getInf(); +} + +void Tone::print() const { + if (age < Tone::MINAGE) return; + std::cout << std::fixed << std::setprecision(1) << freq << " Hz, age " << age << ", " << db << " dB:"; + for (std::size_t i = 0; i < 8; ++i) std::cout << " " << harmonics[i]; + std::cout << std::endl; +} + +bool Tone::operator==(double f) const { + return std::abs(freq / f - 1.0) < 0.05; +} + +Analyzer::Analyzer(double rate, std::string id, std::size_t step): + m_step(step), + m_resampleFactor(1.0), + m_resamplePos(), + m_rate(rate), + m_id(id), + m_window(FFT_N), + m_fftLastPhase(FFT_N / 2), + m_peak(0.0), + m_oldfreq(0.0) +{ + if (m_step > FFT_N) throw std::logic_error("Analyzer step is larger that FFT_N (ideally it should be less than a fourth of FFT_N)."); + // Hamming window + for (size_t i=0; i < FFT_N; i++) { + m_window[i] = static_cast(0.53836 - 0.46164 * std::cos(2.0 * M_PI * i / (FFT_N - 1))); + } +} + +void Analyzer::output(float* begin, float* end, double rate) { + constexpr unsigned a = 2; + const unsigned size = m_passthrough.size(); + const unsigned out = static_cast((end - begin) / 2 /* stereo */); + if (out == 0) return; + const unsigned in = static_cast(m_resampleFactor * (m_rate / rate) * out + 2 * a /* lanczos kernel */ + 5 /* safety margin for rounding errors */); + float pcm[m_passthrough.capacity]; + m_passthrough.read(pcm, pcm + in + 4); + for (unsigned i = 0; i < out; ++i) { + double s = 0.0; + unsigned k = static_cast(m_resamplePos); + double x = m_resamplePos - k; + // Lanczos sampling of input at m_resamplePos + for (unsigned j = 0; j <= 2 * a; ++j) s += pcm[k + j] * da::lanc(x - j + a); + s *= 5.0; + begin[i * 2] += (float) s; + begin[i * 2 + 1] += (float) s; + m_resamplePos += m_resampleFactor; + } + unsigned num = static_cast(m_resamplePos); + m_resamplePos -= num; + if (size > 3000) { + // Reset + m_passthrough.pop(m_passthrough.size() - 700); + m_resampleFactor = 1.0; + } else { + m_passthrough.pop(num); + m_resampleFactor = 0.99 * m_resampleFactor + 0.01 * (size > 700 ? 1.02 : 0.98); + } +} + + +namespace { + struct Peak { + double freq; + double db; + bool harm[Tone::MAXHARM]; + Peak(double _freq = 0.0, double _db = -getInf()): + freq(_freq), db(_db) + { + for (auto& h: harm) h = false; + } + void clear() { + freq = 0.0; + db = -getInf(); + } + }; + + Peak& match(std::vector& peaks, std::size_t pos) { + std::size_t best = pos; + if (peaks[pos - 1].db > peaks[best].db) best = pos - 1; + if (peaks[pos + 1].db > peaks[best].db) best = pos + 1; + return peaks[best]; + } +} + +bool Analyzer::calcFFT() { + float pcm[FFT_N]; + // Read FFT_N samples, move forward by m_step samples + if (!m_buf.read(pcm, pcm + FFT_N)) return false; + m_buf.pop(static_cast(m_step)); + // Peak level calculation of the most recent m_step samples (the rest is overlap) + for (float const* ptr = pcm + FFT_N - m_step; ptr != pcm + FFT_N; ++ptr) { + float s = *ptr; + float p = s * s; + if (p > m_peak) m_peak = p; else m_peak *= 0.999; + } + // Calculate FFT + m_fft = da::fft(pcm, m_window); + return true; +} + +void Analyzer::calcTones() { + // Precalculated constants + const double freqPerBin = m_rate / FFT_N; + const double phaseStep = 2.0 * M_PI * m_step / FFT_N; + const double normCoeff = 1.0 / FFT_N; + const double minMagnitude = pow(10, -100.0 / 20.0) / normCoeff; // -100 dB + // Limit frequency range of processing + const size_t kMin = std::max(size_t(1), size_t(FFT_MINFREQ / freqPerBin)); + const size_t kMax = std::min(FFT_N / 2, size_t(FFT_MAXFREQ / freqPerBin)); + std::vector peaks(kMax + 1); // One extra to simplify loops + for (size_t k = 1; k <= kMax; ++k) { + double magnitude = std::abs(m_fft[k]); + double phase = std::arg(m_fft[k]); + // process phase difference + double delta = phase - m_fftLastPhase[k]; + m_fftLastPhase[k] = static_cast(phase); + delta -= k * phaseStep; // subtract expected phase difference + delta = remainder(delta, 2.0 * M_PI); // map delta phase into +/- M_PI interval + delta /= phaseStep; // calculate diff from bin center frequency + double freq = (k + delta) * freqPerBin; // calculate the true frequency + if (freq > 1.0 && magnitude > minMagnitude) { + peaks[k].freq = freq; + peaks[k].db = 20.0 * log10(normCoeff * magnitude); + } + } + // Prefilter peaks + double prevdb = peaks[0].db; + for (size_t k = 1; k < kMax; ++k) { + double db = peaks[k].db; + if (db > prevdb) peaks[k - 1].clear(); + if (db < prevdb) peaks[k].clear(); + prevdb = db; + } + // Find the tones (collections of harmonics) from the array of peaks + tones_t tones; + for (size_t k = kMax - 1; k >= kMin; --k) { + if (peaks[k].db < -70.0) continue; + // Find the best divider for getting the fundamental from peaks[k] + std::size_t bestDiv = 1; + int bestScore = 0; + for (std::size_t div = 2; div <= Tone::MAXHARM && k / div > 1; ++div) { + double freq = peaks[k].freq / div; // Fundamental + int score = 0; + for (std::size_t n = 1; n < div && n < 8; ++n) { + Peak& p = match(peaks, k * n / div); + --score; + if (p.db < -90.0 || std::abs(p.freq / n / freq - 1.0) > .03) continue; + if (n == 1) score += 4; // Extra for fundamental + score += 2; + } + if (score > bestScore) { + bestScore = score; + bestDiv = div; + } + } + // Construct a Tone by combining the fundamental frequency (freq) and all harmonics + Tone t; + std::size_t count = 0; + double freq = peaks[k].freq / bestDiv; + t.db = peaks[k].db; + for (std::size_t n = 1; n <= bestDiv; ++n) { + // Find the peak for n'th harmonic + Peak& p = match(peaks, k * n / bestDiv); + if (std::abs(p.freq / n / freq - 1.0) > .03) continue; // Does it match the fundamental freq? + if (p.db > t.db - 10.0) { + t.db = std::max(t.db, p.db); + ++count; + t.freq += p.freq / n; + } + t.harmonics[n - 1] = p.db; + p.clear(); + } + t.freq /= count; + // If the tone seems strong enough, add it (-3 dB compensation for each harmonic) + if (t.db > -50.0 - 3.0 * count) { + t.stabledb = t.db; + tones.push_back(t); + } + } + mergeWithOld(tones); + m_tones.swap(tones); +} + +void Analyzer::mergeWithOld(tones_t& tones) const { + tones.sort(); + auto it = tones.begin(); + // Iterate over old tones + for (auto const& old: m_tones) { + // Try to find a matching new tone + while (it != tones.end() && *it < old) ++it; + // If match found + if (it != tones.end() && *it == old) { + // Merge the old tone into the new tone + it->age = old.age + 1; + it->stabledb = 0.8 * old.stabledb + 0.2 * it->db; + it->freq = 0.5 * old.freq + 0.5 * it->freq; + } else if (old.db > -80.0) { + // Insert a decayed version of the old tone into new tones + Tone& t = *tones.insert(it, old); + t.db -= 5.0; + t.stabledb -= 0.1; + } + } +} + +void Analyzer::process() { + // Try calculating FFT and calculate tones until no more data in input buffer + while (calcFFT()) calcTones(); +} + + diff --git a/PitchTracker/pitch.hh b/PitchTracker/pitch.hh new file mode 100644 index 00000000..bb543be6 --- /dev/null +++ b/PitchTracker/pitch.hh @@ -0,0 +1,132 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "compatibility.h" + +/// struct to represent tones +struct Tone { + static const std::size_t MAXHARM = 48; ///< The maximum number of harmonics tracked + static const std::size_t MINAGE = 2; ///< The minimum age required for a tone to be output + double freq; ///< Frequency (Hz) + double db; ///< Level (dB) + double stabledb; ///< Stable level, useful for graphics rendering + double harmonics[MAXHARM]; ///< Harmonics' levels + std::size_t age; ///< How many times the tone has been detected in row + Tone(); + void print() const; ///< Prints Tone to std::cout + bool operator==(double f) const; ///< Compare for rough frequency match + /// Less-than compare by levels (instead of frequencies like operator< does) + static bool dbCompare(Tone const& l, Tone const& r) { return l.db < r.db; } +}; + +static inline bool operator==(Tone const& lhs, Tone const& rhs) { return lhs == rhs.freq; } +static inline bool operator!=(Tone const& lhs, Tone const& rhs) { return !(lhs == rhs); } +static inline bool operator<=(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq || lhs == rhs; } +static inline bool operator>=(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq || lhs == rhs; } +static inline bool operator<(Tone const& lhs, Tone const& rhs) { return lhs.freq < rhs.freq && lhs != rhs; } +static inline bool operator>(Tone const& lhs, Tone const& rhs) { return lhs.freq > rhs.freq && lhs != rhs; } + +static const unsigned FFT_P = 10; +static const std::size_t FFT_N = 1 << FFT_P; + +/// Lock-free ring buffer. Discards oldest data on overflow (not strictly thread-safe). +template class RingBuffer { +public: + constexpr static size_t capacity = SIZE; + RingBuffer(): m_read(), m_write() {} ///< Initialize empty buffer + template void insert(InIt begin, InIt end) { + unsigned r = static_cast(m_read); // The read position + unsigned w = static_cast(m_write); // The write position + bool overflow = false; + while (begin != end) { + m_buf[w] = *begin++; // Copy sample + w = modulo(w + 1); // Update cursor + if (w == r) overflow = true; + } + m_write = w; + if (overflow) m_read = modulo(w + 1); // Reset read pointer on overflow + } + /// Read data from current position if there is enough data to fill the range (otherwise return false). Does not move read pointer. + template bool read(OutIt begin, OutIt end) { + unsigned r = static_cast(m_read); + if (modulo(static_cast(m_write) - r) <= end - begin) return false; // Not enough audio available + while (begin != end) *begin++ = m_buf[r++ % SIZE]; // Copy audio to output iterator + return true; + } + void pop(unsigned n) { m_read = modulo(static_cast(m_read + n)); } ///< Move reading pointer forward. + unsigned size() const { return modulo(static_cast(m_write - m_read)); } +private: + static unsigned modulo(unsigned idx) { return (SIZE + idx) % SIZE; } ///< Modulo operation with proper rounding (handles slightly "negative" idx as well) + float m_buf[SIZE]; + volatile size_t m_read, m_write; ///< The indices of the next read/write operations. read == write implies that buffer is empty. +}; + +/// analyzer class + /** class to analyze input audio and transform it into useable data + */ +class Analyzer { +public: + /// fast fourier transform vector + typedef std::vector > fft_t; + /// list of tones + typedef std::list tones_t; + /// constructor + Analyzer(double rate, std::string id, std::size_t step = 200); + /** Add input data to buffer. This is thread-safe (against other functions). **/ + template void input(InIt begin, InIt end) { + m_buf.insert(begin, end); + m_passthrough.insert(begin, end); + } + /** Call this to process all data input so far. **/ + void process(); + /** Get the raw FFT. **/ + fft_t const& getFFT() const { return m_fft; } + /** Get the peak level in dB (negative value, 0.0 = clipping). **/ + double getPeak() const { return 10.0 * log10(m_peak); } + /** Get a list of all tones detected. **/ + tones_t const& getTones() const { return m_tones; } + /** Find a tone within the singing range; prefers strong tones around 200-400 Hz. **/ + Tone const* findTone(double minfreq = 65.0, double maxfreq = 1000.0) const { + if (m_tones.empty()) { m_oldfreq = 0.0; return NULL; } + double db = std::max_element(m_tones.begin(), m_tones.end(), Tone::dbCompare)->db; + Tone const* best = NULL; + double bestscore = 0; + for (tones_t::const_iterator it = m_tones.begin(); it != m_tones.end(); ++it) { + if (it->db < db - 20.0 || it->freq < minfreq || it->age < Tone::MINAGE) continue; + if (it->freq > maxfreq) break; + double score = it->db - std::max(180.0, std::abs(it->freq - 300.0)) / 10.0; + if (m_oldfreq != 0.0 && std::fabs(it->freq/m_oldfreq - 1.0) < 0.05) score += 10.0; + if (best && bestscore > score) break; + best = &*it; + bestscore = score; + } + m_oldfreq = (best ? best->freq : 0.0); + return best; + } + /** Give data away for mic pass-through */ + void output(float* begin, float* end, double rate); + /** Returns the id (color name) of the mic */ + std::string const& getId() const { return m_id; } + +private: + const std::size_t m_step; + RingBuffer<2 * FFT_N> m_buf; // Twice the FFT size should give enough room for sliding window and for engine delays + RingBuffer<4096> m_passthrough; + double m_resampleFactor; + double m_resamplePos; + double m_rate; + std::string m_id; + std::vector m_window; + fft_t m_fft; + std::vector m_fftLastPhase; + double m_peak; + tones_t m_tones; + mutable double m_oldfreq; + bool calcFFT(); + void calcTones(); + void mergeWithOld(tones_t& tones) const; +}; diff --git a/PitchTracker/pitchTracker.cpp b/PitchTracker/pitchTracker.cpp index 31e82059..4d472ee2 100644 --- a/PitchTracker/pitchTracker.cpp +++ b/PitchTracker/pitchTracker.cpp @@ -19,97 +19,102 @@ #include #include -void doLog(const char* msg,...){ - va_list argptr = NULL; - va_start(argptr, msg); +namespace PitchTracker{ - char buffer[200]; - vsprintf_s(buffer,msg, argptr); - if(Log) Log(buffer); - va_end(argptr); -} + static void doLog(const char* msg,...){ + va_list argptr = NULL; + va_start(argptr, msg); -void SetLogCallback(LogCallback Callback){ - Log=Callback; -} - -double *SamplesPerPeriodPerTone = NULL; -int MinHalfTone = 0, MaxHalfTone = 38; -const double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) - -void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ - MinHalfTone = minHalfTone; - MaxHalfTone = maxHalfTone; - DeInit(); - if(maxHalfTone <= 0) - return; - SamplesPerPeriodPerTone = (double*) malloc((MaxHalfTone + 1) * sizeof(double)); - //Init Array to avoid costly calculations - for (int toneIndex = 0; toneIndex <= MaxHalfTone; toneIndex++) - { - double freq = baseToneFrequency * pow(HalftoneBase, toneIndex); - SamplesPerPeriodPerTone[toneIndex] = 44100.0 / freq; // samples in one period - } -} - -void DeInit(){ - if(SamplesPerPeriodPerTone){ - free(SamplesPerPeriodPerTone); - SamplesPerPeriodPerTone=NULL; - } -} - -static double _AnalyzeToneFunc(double *samples, int sampleCt, int toneIndex){ - double samplesPerPeriodD = SamplesPerPeriodPerTone[toneIndex]; // samples in one period - int samplesPerPeriod = (int)samplesPerPeriodD; - double fHigh = samplesPerPeriodD - samplesPerPeriod; - double fLow = 1.0 - fHigh; - - double accumDist = 0; // accumulated distances - - // compare correlating samples - int sampleIndex = 0; // index of sample to analyze - // Start value= index of sample one period ahead - for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < sampleCt; correlatingSampleIndex++, sampleIndex++) - { - // calc distance to corresponding sample in next period (lower means more distant) - double dist = samples[sampleIndex] * (samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh); - accumDist += dist; + char buffer[200]; + vsprintf_s(buffer,msg, argptr); + if(Log) Log(buffer); + va_end(argptr); } - //Using _AnalysisBufLen here makes it return correct values among all analyzed frequencies - double scaleValue = 32767.0 * 32767.0 * sampleCt; // Divide also by Int16.MaxValue^2 - return accumDist / scaleValue; -} - -int GetTone(double *samples, int sampleCt, float *weights){ - double maxVolume = 0; - for(int i = 0; i < sampleCt; i++){ - double vol = abs(samples[i]); - if(vol > maxVolume) - maxVolume = vol; + void SetLogCallback(LogCallback Callback){ + Log=Callback; } - double maxWeight = -1; - double minWeight = 1; - int maxTone = -1; - for (int toneIndex = MinHalfTone; toneIndex <= MaxHalfTone; toneIndex++) - { - double curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolume * 32767.0; - if (curWeight > maxWeight) + double *SamplesPerPeriodPerTone = NULL; + int MinHalfTone = 0, MaxHalfTone = 38; + const double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) + + void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ + MinHalfTone = minHalfTone; + MaxHalfTone = maxHalfTone; + DeInit(); + if(maxHalfTone <= 0) + return; + SamplesPerPeriodPerTone = (double*) malloc((MaxHalfTone + 1) * sizeof(double)); + //Init Array to avoid costly calculations + for (int toneIndex = 0; toneIndex <= MaxHalfTone; toneIndex++) { - maxWeight = curWeight; - maxTone = toneIndex; + double freq = baseToneFrequency * pow(HalftoneBase, toneIndex); + SamplesPerPeriodPerTone[toneIndex] = 44100.0 / freq; // samples in one period + } + } + + void DeInit(){ + if(SamplesPerPeriodPerTone){ + free(SamplesPerPeriodPerTone); + SamplesPerPeriodPerTone=NULL; + } + } + + static double _AnalyzeToneFunc(double *samples, int sampleCt, int toneIndex){ + double samplesPerPeriodD = SamplesPerPeriodPerTone[toneIndex]; // samples in one period + int samplesPerPeriod = (int)samplesPerPeriodD; + double fHigh = samplesPerPeriodD - samplesPerPeriod; + double fLow = 1.0 - fHigh; + + double accumDist = 0; // accumulated distances + + // compare correlating samples + int sampleIndex = 0; // index of sample to analyze + // Start value= index of sample one period ahead + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < sampleCt; correlatingSampleIndex++, sampleIndex++) + { + // calc distance to corresponding sample in next period (lower means more distant) + double dist = samples[sampleIndex] * (samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh); + accumDist += dist; } - if (curWeight < minWeight) - minWeight = curWeight; - - weights[toneIndex - MinHalfTone] = (float) curWeight; + //Using _AnalysisBufLen here makes it return correct values among all analyzed frequencies + double scaleValue = sampleCt; // Divide also by Int16.MaxValue^2 + return accumDist / scaleValue; } - if(maxWeight - minWeight > 0.01){ - return maxTone; - }else return -1; -} + int GetTone(double *samples, int sampleCt, float *weights, bool scale){ + double maxVolume = 0; + for(int i = 0; i < sampleCt; i++){ + double vol = abs(samples[i]); + if(vol > maxVolume) + maxVolume = vol; + } + double maxWeight = -1; + double minWeight = 1; + int maxTone = -1; + for (int toneIndex = MinHalfTone; toneIndex <= MaxHalfTone; toneIndex++) + { + double curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolume; + if(scale) + curWeight /= 32768.0; //maximum abs value of a short, would actually need to scale by MaxValue^2 but we already scaled by maxVolume + if (curWeight > maxWeight) + { + maxWeight = curWeight; + maxTone = toneIndex; + } + + if (curWeight < minWeight) + minWeight = curWeight; + + weights[toneIndex - MinHalfTone] = (float) curWeight; + } + + if(maxWeight - minWeight > 0.01){ + return maxTone; + }else return -1; + } + +} \ No newline at end of file diff --git a/PitchTracker/pitchTracker.h b/PitchTracker/pitchTracker.h index 99b477b0..961c436c 100644 --- a/PitchTracker/pitchTracker.h +++ b/PitchTracker/pitchTracker.h @@ -1,17 +1,11 @@ #pragma once -#ifndef dywapitchtrack__H -#define dywapitchtrack__H - -#define DllExport extern "C" __declspec(dllexport) - -DllExport void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); -DllExport void DeInit(); -DllExport int GetTone(double *samples, int sampleCt, float *weights); - -typedef void (__stdcall * LogCallback)(const char* text); -static LogCallback Log; -DllExport void SetLogCallback(LogCallback Callback); - -#endif +namespace PitchTracker{ + void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); + void DeInit(); + int GetTone(double *samples, int sampleCt, float *weights, bool scale = false); + typedef void (__stdcall * LogCallback)(const char* text); + static LogCallback Log; + void SetLogCallback(LogCallback Callback); +} diff --git a/PitchTracker/util.hh b/PitchTracker/util.hh new file mode 100644 index 00000000..f07753d4 --- /dev/null +++ b/PitchTracker/util.hh @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include + +/** Limit val to range [min, max] **/ +template T clamp(T val, T min = 0, T max = 1) { + if (min > max) throw std::logic_error("min > max"); + if (val < min) return min; + if (val > max) return max; + return val; +} + +template struct MinMax { + Numeric min, max; + explicit MinMax(Numeric min = std::numeric_limits::min(), Numeric max = std::numeric_limits::max()): min(min), max(max) {} + bool matches(Numeric val) const { return val >= min && val <= max; } +}; + +/** A convenient way for getting NaNs **/ +static inline double getNaN() { return std::numeric_limits::quiet_NaN(); } + +/** A convenient way for getting infs **/ +static inline double getInf() { return std::numeric_limits::infinity(); } + +static inline bool isPow2(unsigned int val) { + if (val == 0) return false; + if ((val & (val-1)) == 0) return true; // From Wikipedia: Power_of_two + return false; +} + +static inline unsigned int nextPow2(unsigned int val) { + unsigned int ret = 1; + while (ret < val) ret *= 2; + return ret; +} + +static inline unsigned int prevPow2(unsigned int val) { + unsigned int ret = 1; + while ((ret*2) < val) ret *= 2; + return ret; +} + diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 9c668741..46c3c59a 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -23,8 +23,7 @@ using System; using System.IO; using System.Diagnostics; #if USE_NATIVE_DETECTION -using System.Runtime.InteropServices; - +using Native.PitchTracking; #endif #if TEST_PITCH using System.Windows.Forms; @@ -34,26 +33,6 @@ using VocaluxeLib; namespace Vocaluxe.Lib.Sound.Record { -#if USE_NATIVE_DETECTION - static class CPitchTracker - { - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void DeInit(); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int GetTone(double[] samples, int sampleCt, float[] weights); - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - public delegate void LogCallback(string message); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void SetLogCallback(LogCallback c); - } -#endif - class CBuffer : IDisposable { private static int _InitCount; @@ -67,7 +46,7 @@ namespace Vocaluxe.Lib.Sound.Record private const int _AnalysisBufLen = 4096; private const int _AnalysisByteBufLen = _AnalysisBufLen * 2; - private readonly double[] _AnalysisBuffer = new double[_AnalysisBufLen]; + private readonly short[] _AnalysisBuffer = new short[_AnalysisBufLen]; private readonly byte[] _AnalysisByteBuffer = new byte[_AnalysisByteBufLen]; //tmp buffer (stream->tmpBuffer->(Int16)AnalysisBuffer) private readonly float[] _TmpWeights = new float[NumHalfTones]; //tmp buffer for weights (gets copied to ToneWeight when checked) @@ -211,8 +190,7 @@ namespace Vocaluxe.Lib.Sound.Record _NewSamples = false; } - for (int i = 0; i < _AnalysisBufLen; i++) - _AnalysisBuffer[i] = BitConverter.ToInt16(_AnalysisByteBuffer, i * 2); + Buffer.BlockCopy(_AnalysisByteBuffer, 0, _AnalysisBuffer, 0, _AnalysisByteBufLen); try { @@ -229,22 +207,22 @@ namespace Vocaluxe.Lib.Sound.Record private void _FindMaxVolume() { - double maxVolume = 0; + int maxVolume = 0; for (int i = 0; i < _AnalysisBufLen / 4; i++) { - double volume = _AnalysisBuffer[i]; + int volume = _AnalysisBuffer[i]; if (volume < 0) volume = -volume; if (volume > maxVolume) maxVolume = volume; } - _MaxVolume = maxVolume / Int16.MaxValue; + _MaxVolume = (double)maxVolume / Int16.MaxValue; } private void _AnalyzeTones() { #if USE_NATIVE_DETECTION - int maxTone = CPitchTracker.GetTone(_AnalysisBuffer, _AnalysisBufLen, _TmpWeights); + int maxTone = CPitchTracker.GetTone(_AnalysisBuffer, _TmpWeights); if (maxTone >= 0) #else // prepare to analyze @@ -305,7 +283,6 @@ namespace Vocaluxe.Lib.Sound.Record // calc distance to corresponding sample in next period (lower means more distant) double dist = _AnalysisBuffer[sampleIndex] * (_AnalysisBuffer[correlatingSampleIndex] * fLow + _AnalysisBuffer[correlatingSampleIndex + 1] * fHigh); - //double dist = _AnalysisBuffer[sampleIndex] * _AnalysisBuffer[correlatingSampleIndex]; accumDist += dist; } diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index fcf7e6f6..fd3f9ab0 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -199,6 +199,10 @@ ..\Output\OpenTK.GLControl.dll + + ..\Output\x64\PitchTracker.dll + False + False ..\Output\PortAudioSharp.dll From e54892391fbc6b7c496031b3a6f5d8fc3af9110f Mon Sep 17 00:00:00 2001 From: Flamefire Date: Tue, 25 Mar 2014 18:41:25 +0100 Subject: [PATCH 12/34] Fix Testcase Add commented implementation of new detector (need to decide) --- PitchTracker/PitchWrapper.cpp | 9 +++++++ PitchTracker/PitchWrapper.h | 1 + Vocaluxe/Lib/Sound/Record/CBuffer.cs | 37 +++++++++++++++++++++------- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 6c18714e..5677550e 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -27,6 +27,15 @@ namespace Native{ freeFloatArray(dataFloat); } + void CAnalyzer::Input(array^ data){ + if(data->Length == 0) + return; + pin_ptr dataPtr = &data[0]; + float* dataFloat = short2FloatArray(static_cast(static_cast(dataPtr)), data->Length); + m_analyzer->input(dataFloat, dataFloat + data->Length); + freeFloatArray(dataFloat); + } + void CAnalyzer::Process(){ m_analyzer->process(); } diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 617c24f3..603ec470 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -38,6 +38,7 @@ namespace Native{ void Input(array^ data); void Input(array^ data); + void Input(array^ data); void Process(); double GetPeak(); array^ GetTones(); diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 46c3c59a..ef905ced 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -24,6 +24,7 @@ using System.IO; using System.Diagnostics; #if USE_NATIVE_DETECTION using Native.PitchTracking; + #endif #if TEST_PITCH using System.Windows.Forms; @@ -72,6 +73,8 @@ namespace Vocaluxe.Lib.Sound.Record private DAnalyzeTone _AnalyzeToneFunc; private double _MinWeightDiff; // ReSharper restore FieldCanBeMadeReadOnly.Local +#else + private readonly CAnalyzer _Analyzer = new CAnalyzer(44100.0, ""); #endif private double _MaxVolume; private bool _NewSamples; @@ -173,6 +176,7 @@ namespace Vocaluxe.Lib.Sound.Record _Add(buffer); _NewSamples = true; } + //_Analyzer.Input(buffer); } public void AnalyzeBuffer() @@ -180,6 +184,19 @@ namespace Vocaluxe.Lib.Sound.Record if (!_NewSamples) return; + /*_NewSamples = false; + _Analyzer.Process(); + _MaxVolume = _Analyzer.GetPeak() / 43 + 1; + CTone tone = _Analyzer.FindTone(); + if (tone != null) + { + ToneAbs = tone.Note; + Tone = ToneAbs % 12; + ToneValid = true; + } + else + ToneValid = false;*/ + lock (_Stream) { if (_Stream.Length >= _AnalysisByteBufLen) @@ -360,11 +377,12 @@ namespace Vocaluxe.Lib.Sound.Record Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); byte[] data; int ok = 0; + double angle = 0; for (int distort = 0; distort < 10; distort++) { for (int tone = toneFrom; tone <= toneTo; tone++) { - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, out data); + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, ref angle, out data); _Distort(data, tone, distort); ProcessNewBuffer(data); @@ -377,7 +395,7 @@ namespace Vocaluxe.Lib.Sound.Record ok++; } } - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, out data); + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); ProcessNewBuffer(data); AnalyzeBuffer(); Stopwatch sw = new Stopwatch(); @@ -385,10 +403,8 @@ namespace Vocaluxe.Lib.Sound.Record const int repeats = 2000; for (int i = 0; i < repeats; i++) { - //ProcessNewBuffer(data); - //AnalyzeBuffer(); - _FindMaxVolume(); - _AnalyzeTones(); + ProcessNewBuffer(data); + AnalyzeBuffer(); } sw.Stop(); string msg = "Analyser: Errors: " + ((toneTo - toneFrom + 1) * 10 - ok) + "; Speed: " + @@ -435,7 +451,8 @@ namespace Vocaluxe.Lib.Sound.Record break; } byte[] data2; - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone + newTone), 44100, out data2); + double angle = 0; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone + newTone), 44100, ref angle, out data2); Buffer.BlockCopy(data2, 0, sdata, 0, len * 2); } else @@ -469,13 +486,15 @@ namespace Vocaluxe.Lib.Sound.Record Buffer.BlockCopy(sdata, 0, data, 0, data.Length); } - private static void _GetSineWave(double freq, int sampleRate, out byte[] data) + private static void _GetSineWave(double freq, int sampleRate, ref double angle, out byte[] data) { const short max = short.MaxValue; const int len = _AnalysisBufLen; //sampleRate * durationMs / 1000; short[] data16Bit = new short[len]; for (int i = 0; i < len; i++) - data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq) * max); + data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq + angle) * max); + angle = 2 * Math.PI * len / sampleRate * freq + angle; + angle = angle % (2 * Math.PI); data = new byte[data16Bit.Length * 2]; Buffer.BlockCopy(data16Bit, 0, data, 0, data.Length); } From ae9f8bb30a6df37bba0694d61643b6c7756c84ee Mon Sep 17 00:00:00 2001 From: Flamefire Date: Wed, 26 Mar 2014 19:52:35 +0100 Subject: [PATCH 13/34] Remove C++/Cli version and replace with P/Invoke wrapper to support all platforms --- PitchTracker/Helper.h | 23 ++--- PitchTracker/PitchTracker.vcxproj | 15 +--- PitchTracker/PitchWrapper.cpp | 85 ++++++++++++++++-- PitchTracker/PitchWrapper.h | 117 +++++++++++++------------ PitchTracker/pitch.cc | 8 +- PitchTracker/pitch.hh | 2 +- Vocaluxe/Lib/Sound/Record/CAnalyzer.cs | 117 +++++++++++++++++++++++++ Vocaluxe/Lib/Sound/Record/CBuffer.cs | 11 +-- Vocaluxe/Vocaluxe.csproj | 5 +- 9 files changed, 283 insertions(+), 100 deletions(-) create mode 100644 Vocaluxe/Lib/Sound/Record/CAnalyzer.cs diff --git a/PitchTracker/Helper.h b/PitchTracker/Helper.h index f0416375..f9700a6f 100644 --- a/PitchTracker/Helper.h +++ b/PitchTracker/Helper.h @@ -1,9 +1,6 @@ #pragma once #include "pitch.hh" #include "PitchWrapper.h" - -#pragma managed(push, off) - #include #include @@ -43,19 +40,23 @@ void freeDoubleArray(double* floats){ free(floats); } -#pragma managed(pop) +double ToneToNote(const Tone* tone){ + return 12.0 * std::log(tone->freq / 127.09) / std::log(2.0) + 27.5 - 16; // 16 = C2 +} +/* namespace Native{ namespace PitchTracking{ - CTone^ ConvertToneToManaged(Tone tone){ + CTone^ ConvertToneToManaged(Tone* tone){ CTone^ result = gcnew CTone(); - result->Freq = tone.freq; - result->DB = tone.db; - result->Stabledb = tone.stabledb; - result->Age = static_cast(tone.age); - result->NoteExact = 12.0 * std::log(tone.freq / 127.09) / std::log(2.0) + 27.5 - 16; // 16 = C2 + result->Freq = tone->freq; + result->DB = tone->db; + result->Stabledb = tone->stabledb; + result->Age = static_cast(tone->age); + result->NoteExact = 12.0 * std::log(tone->freq / 127.09) / std::log(2.0) + 27.5 - 16; // 16 = C2 result->Note = static_cast(std::round(result->NoteExact)); return result; } } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj index e17ebdcd..80dcbccb 100644 --- a/PitchTracker/PitchTracker.vcxproj +++ b/PitchTracker/PitchTracker.vcxproj @@ -170,20 +170,7 @@ - - true - true - true - true - false - false - false - false - false - false - Default - Default - + diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 5677550e..44ffeff1 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -1,10 +1,82 @@ #include "PitchWrapper.h" -#pragma managed(push, off) #include "pitchTracker.h" -#pragma managed(pop) - #include "Helper.h" +void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ + PitchTracker::Init(baseToneFrequency, minHalfTone, maxHalfTone); +} + +void PtFast_DeInit(){ + PitchTracker::DeInit(); +} + +int PtFast_GetTone(short* samples, int sampleCt, float* weights){ + if(sampleCt <= 0) + return -1; + double* dataDouble = short2DoubleArray(samples, sampleCt, false); + int result = PitchTracker::GetTone(dataDouble, sampleCt, weights, true); + freeDoubleArray(dataDouble); + return result; +} + +Analyzer* Analyzer_Create(double rate, unsigned step){ + return new Analyzer(rate, "", step); +} + +void Analyzer_Free(Analyzer* analyzer){ + if(analyzer) + delete analyzer; +} + +void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt){ + if(sampleCt == 0 || !analyzer) + return; + analyzer->input(data, data + sampleCt); +} + +void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt){ + if(sampleCt == 0 || !analyzer) + return; + float* dataFloat = short2FloatArray(data, sampleCt); + analyzer->input(dataFloat, dataFloat + sampleCt); + freeFloatArray(dataFloat); +} + +void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt){ + if(sampleCt == 0 || !analyzer) + return; + float* dataFloat = short2FloatArray(static_cast(static_cast(data)), sampleCt); + analyzer->input(dataFloat, dataFloat + sampleCt); + freeFloatArray(dataFloat); +} + +void Analyzer_Process(Analyzer* analyzer){ + if(!analyzer) + return; + analyzer->process(); +} + +double Analyzer_GetPeak(Analyzer* analyzer){ + if(!analyzer) + return -999; + return analyzer->getPeak(); +} + +double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq){ + if(!analyzer) + return -1; + const Tone* tone = analyzer->findTone(minFreq, maxFreq); + return (tone == NULL) ? -1 : ToneToNote(tone); +} + +bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate){ + if(!analyzer) + return false; + return analyzer->output(data, data + sampleCt, rate); +} + + +/* namespace Native{ namespace PitchTracking{ @@ -31,7 +103,7 @@ namespace Native{ if(data->Length == 0) return; pin_ptr dataPtr = &data[0]; - float* dataFloat = short2FloatArray(static_cast(static_cast(dataPtr)), data->Length); + float* dataFloat = short2FloatArray(static_cast(static_cast(dataPtr)), data->Length / 2); m_analyzer->input(dataFloat, dataFloat + data->Length); freeFloatArray(dataFloat); } @@ -64,7 +136,7 @@ namespace Native{ CTone^ CAnalyzer::FindTone(double minFreq, double maxFreq){ const Tone* tone = m_analyzer->findTone(minFreq, maxFreq); - return (tone == NULL) ? nullptr : ConvertToneToManaged(*tone); + return (tone == NULL) ? nullptr : ConvertToneToManaged(tone); } void CAnalyzer::Output(array^ data, float rate){ @@ -98,4 +170,5 @@ namespace Native{ return result; } } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 603ec470..2b9783d5 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -1,63 +1,72 @@ #pragma once -#pragma managed(push, off) #include "pitch.hh" -#pragma managed(pop) -using namespace System; -using namespace System::Collections::Generic; +#define DllExport extern "C" __declspec(dllexport) -namespace Native{ - namespace PitchTracking{ - public ref class CTone { - public: - static const int MAXHARM = 48; ///< The maximum number of harmonics tracked - static const int MINAGE = 2; ///< The minimum age required for a tone to be output - double Freq; ///< Frequency (Hz) - double DB; ///< Level (dB) - double Stabledb; ///< Stable level, useful for graphics rendering - int Age; ///< How many times the tone has been detected in row - double NoteExact; - int Note; - /// Less-than compare by levels (instead of frequencies like operator< does) - static bool dbCompare(CTone l, CTone r) { return l.DB < r.DB; } - }; +DllExport void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); +DllExport void PtFast_DeInit(); +DllExport int PtFast_GetTone(short* samples, int sampleCt, float* weights); - public ref class CAnalyzer { - public: - CAnalyzer(double rate, String^ id) { - m_analyzer = new Analyzer(rate,""); - m_id = id; - } - CAnalyzer(double rate, String^ id, unsigned step) { - m_analyzer = new Analyzer(rate,"",step); - m_id = id; - } - ~CAnalyzer() { this->!CAnalyzer(); } - !CAnalyzer() { delete m_analyzer; } +DllExport Analyzer* Analyzer_Create(double rate, unsigned step); +DllExport void Analyzer_Free(Analyzer* analyzer); +DllExport void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt); +DllExport void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt); +DllExport void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt); +DllExport void Analyzer_Process(Analyzer* analyzer); +DllExport double Analyzer_GetPeak(Analyzer* analyzer); +DllExport double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq); +DllExport bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate); - void Input(array^ data); - void Input(array^ data); - void Input(array^ data); - void Process(); - double GetPeak(); - array^ GetTones(); - CTone^ FindTone(); - CTone^ FindTone(double minFreq); - CTone^ FindTone(double minFreq, double maxFreq); - void Output(array^ data, float rate); - String^ GetId(); +/* +public ref class CTone { +public: + static const int MAXHARM = 48; ///< The maximum number of harmonics tracked + static const int MINAGE = 2; ///< The minimum age required for a tone to be output + double Freq; ///< Frequency (Hz) + double DB; ///< Level (dB) + double Stabledb; ///< Stable level, useful for graphics rendering + int Age; ///< How many times the tone has been detected in row + double NoteExact; + int Note; + /// Less-than compare by levels (instead of frequencies like operator< does) + static bool dbCompare(CTone l, CTone r) { return l.DB < r.DB; } +}; - private: - Analyzer* m_analyzer; - String^ m_id; - }; - - public ref class CPitchTracker abstract sealed{ - public: - static void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); - static void DeInit(); - static int GetTone(array^ samples, array^ weights); - }; +public ref class CAnalyzer { +public: + CAnalyzer(double rate, String^ id) { + m_analyzer = new Analyzer(rate,""); + m_id = id; } -} \ No newline at end of file + CAnalyzer(double rate, String^ id, unsigned step) { + m_analyzer = new Analyzer(rate,"",step); + m_id = id; + } + ~CAnalyzer() { this->!CAnalyzer(); } + !CAnalyzer() { delete m_analyzer; } + + void Input(array^ data); + void Input(array^ data); + void Input(array^ data); + void Process(); + double GetPeak(); + array^ GetTones(); + CTone^ FindTone(); + CTone^ FindTone(double minFreq); + CTone^ FindTone(double minFreq, double maxFreq); + void Output(array^ data, float rate); + String^ GetId(); + +private: + Analyzer* m_analyzer; + String^ m_id; +}; + +public ref class CPitchTracker abstract sealed{ +public: + static void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); + static void DeInit(); + static int GetTone(array^ samples, array^ weights); +}; +*/ \ No newline at end of file diff --git a/PitchTracker/pitch.cc b/PitchTracker/pitch.cc index d4b9d9a0..85169769 100644 --- a/PitchTracker/pitch.cc +++ b/PitchTracker/pitch.cc @@ -48,14 +48,15 @@ Analyzer::Analyzer(double rate, std::string id, std::size_t step): } } -void Analyzer::output(float* begin, float* end, double rate) { +bool Analyzer::output(float* begin, float* end, double rate) { constexpr unsigned a = 2; const unsigned size = m_passthrough.size(); const unsigned out = static_cast((end - begin) / 2 /* stereo */); - if (out == 0) return; + if (out == 0) return false; const unsigned in = static_cast(m_resampleFactor * (m_rate / rate) * out + 2 * a /* lanczos kernel */ + 5 /* safety margin for rounding errors */); float pcm[m_passthrough.capacity]; - m_passthrough.read(pcm, pcm + in + 4); + if(!m_passthrough.read(pcm, pcm + in + 4)) + return false; for (unsigned i = 0; i < out; ++i) { double s = 0.0; unsigned k = static_cast(m_resamplePos); @@ -77,6 +78,7 @@ void Analyzer::output(float* begin, float* end, double rate) { m_passthrough.pop(num); m_resampleFactor = 0.99 * m_resampleFactor + 0.01 * (size > 700 ? 1.02 : 0.98); } + return true; } diff --git a/PitchTracker/pitch.hh b/PitchTracker/pitch.hh index bb543be6..ec759d1f 100644 --- a/PitchTracker/pitch.hh +++ b/PitchTracker/pitch.hh @@ -108,7 +108,7 @@ public: return best; } /** Give data away for mic pass-through */ - void output(float* begin, float* end, double rate); + bool output(float* begin, float* end, double rate); /** Returns the id (color name) of the mic */ std::string const& getId() const { return m_id; } diff --git a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs new file mode 100644 index 00000000..14ec16e8 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs @@ -0,0 +1,117 @@ +using System; +using System.Runtime.InteropServices; + +namespace Vocaluxe.Lib.Sound.Record +{ + class CAnalyzer : IDisposable + { + #region Imports + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr Analyzer_Create(double rate, uint step); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void Analyzer_Free(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void Analyzer_InputFloat(IntPtr analyzer, float[] data, int sampleCt); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void Analyzer_InputShort(IntPtr analyzer, short[] data, int sampleCt); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void Analyzer_InputByte(IntPtr analyzer, byte[] data, int sampleCt); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void Analyzer_Process(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern double Analyzer_GetPeak(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern double Analyzer_FindNote(IntPtr analyzer, double minFreq, double maxFreq); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern bool Analyzer_OutputFloat(IntPtr analyzer, [Out] float[] data, int sampleCt, float rate); + #endregion + + private IntPtr _Instance; + + public CAnalyzer(double rate = 44100.0, uint step = 200) + { + _Instance = Analyzer_Create(rate, step); + } + + ~CAnalyzer() + { + _Dispose(false); + } + + public void Input(float[] data) + { + Analyzer_InputFloat(_Instance, data, data.Length); + } + + public void Input(short[] data) + { + Analyzer_InputShort(_Instance, data, data.Length); + } + + public void Input(byte[] data) + { + Analyzer_InputByte(_Instance, data, data.Length / 2); + } + + public void Process() + { + Analyzer_Process(_Instance); + } + + public double GetPeak() + { + return Analyzer_GetPeak(_Instance); + } + + public double FindNote(double minFreq = 35.0, double maxFreq = 1000.0) + { + return Analyzer_FindNote(_Instance, minFreq, maxFreq); + } + + public bool Output(float[] data, float rate) + { + return Analyzer_OutputFloat(_Instance, data, data.Length, rate); + } + + private void _Dispose(bool disposing) + { + if (_Instance == IntPtr.Zero) + throw new ObjectDisposedException(GetType().Name); + Analyzer_Free(_Instance); + _Instance = IntPtr.Zero; + } + + public void Dispose() + { + _Dispose(true); + GC.SuppressFinalize(this); + } + } + + static class CFastAnalyzer + { + #region Imports + [DllImport("PitchTracker.dll", EntryPoint = "PtFast_Init", CallingConvention = CallingConvention.Cdecl)] + public static extern void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); + + [DllImport("PitchTracker.dll", EntryPoint = "PtFast_DeInit", CallingConvention = CallingConvention.Cdecl)] + public static extern void DeInit(); + + [DllImport("PitchTracker.dll", EntryPoint = "PtFast_GetTone", CallingConvention = CallingConvention.Cdecl)] + private static extern int PtFast_GetTone(short[] samples, int sampleCt, float[] weights); + #endregion + + public static int GetTone(short[] samples, float[] weights) + { + return PtFast_GetTone(samples, samples.Length, weights); + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index ef905ced..408ff5d8 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -22,10 +22,7 @@ using System; using System.IO; using System.Diagnostics; -#if USE_NATIVE_DETECTION -using Native.PitchTracking; -#endif #if TEST_PITCH using System.Windows.Forms; using VocaluxeLib; @@ -74,7 +71,7 @@ namespace Vocaluxe.Lib.Sound.Record private double _MinWeightDiff; // ReSharper restore FieldCanBeMadeReadOnly.Local #else - private readonly CAnalyzer _Analyzer = new CAnalyzer(44100.0, ""); + private readonly CAnalyzer _Analyzer = new CAnalyzer(); #endif private double _MaxVolume; private bool _NewSamples; @@ -115,7 +112,7 @@ namespace Vocaluxe.Lib.Sound.Record if (_InitCount > 1) return; //Do init only once #if USE_NATIVE_DETECTION - CPitchTracker.Init(_BaseToneFreq, _HalfToneMin, _HalfToneMax); + CFastAnalyzer.Init(_BaseToneFreq, _HalfToneMin, _HalfToneMax); #else //Init Array to avoid costly calculations for (int toneIndex = 0; toneIndex <= _HalfToneMax; toneIndex++) @@ -239,7 +236,7 @@ namespace Vocaluxe.Lib.Sound.Record private void _AnalyzeTones() { #if USE_NATIVE_DETECTION - int maxTone = CPitchTracker.GetTone(_AnalysisBuffer, _TmpWeights); + int maxTone = CFastAnalyzer.GetTone(_AnalysisBuffer, _TmpWeights); if (maxTone >= 0) #else // prepare to analyze @@ -350,7 +347,7 @@ namespace Vocaluxe.Lib.Sound.Record Debug.Assert(_InitCount > 0); _InitCount--; if (_InitCount == 0) - CPitchTracker.DeInit(); + CFastAnalyzer.DeInit(); #endif } diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index fd3f9ab0..d0c8f9ba 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -199,10 +199,6 @@ ..\Output\OpenTK.GLControl.dll - - ..\Output\x64\PitchTracker.dll - False - False ..\Output\PortAudioSharp.dll @@ -227,6 +223,7 @@ + From b1bca37bf883017ce4b802e0bf271412f47b84f5 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 28 Mar 2014 12:40:04 +0100 Subject: [PATCH 14/34] Little speedup --- PitchTracker/pitch.cc | 10 +++++----- PitchTracker/pitch.hh | 29 ++++++++++++++--------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/PitchTracker/pitch.cc b/PitchTracker/pitch.cc index 85169769..076dbc70 100644 --- a/PitchTracker/pitch.cc +++ b/PitchTracker/pitch.cc @@ -30,7 +30,7 @@ bool Tone::operator==(double f) const { return std::abs(freq / f - 1.0) < 0.05; } -Analyzer::Analyzer(double rate, std::string id, std::size_t step): +Analyzer::Analyzer(double rate, std::string id, unsigned step): m_step(step), m_resampleFactor(1.0), m_resamplePos(), @@ -110,7 +110,7 @@ bool Analyzer::calcFFT() { float pcm[FFT_N]; // Read FFT_N samples, move forward by m_step samples if (!m_buf.read(pcm, pcm + FFT_N)) return false; - m_buf.pop(static_cast(m_step)); + m_buf.pop(m_step); // Peak level calculation of the most recent m_step samples (the rest is overlap) for (float const* ptr = pcm + FFT_N - m_step; ptr != pcm + FFT_N; ++ptr) { float s = *ptr; @@ -133,11 +133,11 @@ void Analyzer::calcTones() { const size_t kMax = std::min(FFT_N / 2, size_t(FFT_MAXFREQ / freqPerBin)); std::vector peaks(kMax + 1); // One extra to simplify loops for (size_t k = 1; k <= kMax; ++k) { - double magnitude = std::abs(m_fft[k]); - double phase = std::arg(m_fft[k]); + float magnitude = std::abs(m_fft[k]); + float phase = std::arg(m_fft[k]); // process phase difference double delta = phase - m_fftLastPhase[k]; - m_fftLastPhase[k] = static_cast(phase); + m_fftLastPhase[k] = phase; delta -= k * phaseStep; // subtract expected phase difference delta = remainder(delta, 2.0 * M_PI); // map delta phase into +/- M_PI interval delta /= phaseStep; // calculate diff from bin center frequency diff --git a/PitchTracker/pitch.hh b/PitchTracker/pitch.hh index ec759d1f..fc431733 100644 --- a/PitchTracker/pitch.hh +++ b/PitchTracker/pitch.hh @@ -34,35 +34,34 @@ static const unsigned FFT_P = 10; static const std::size_t FFT_N = 1 << FFT_P; /// Lock-free ring buffer. Discards oldest data on overflow (not strictly thread-safe). -template class RingBuffer { +template class RingBuffer { public: - constexpr static size_t capacity = SIZE; + constexpr static unsigned capacity = SIZE; RingBuffer(): m_read(), m_write() {} ///< Initialize empty buffer template void insert(InIt begin, InIt end) { - unsigned r = static_cast(m_read); // The read position - unsigned w = static_cast(m_write); // The write position - bool overflow = false; + unsigned r = m_read; // The read position + unsigned w = m_write; // The write position + bool overflow = (end - begin >= SIZE - size()); while (begin != end) { m_buf[w] = *begin++; // Copy sample w = modulo(w + 1); // Update cursor - if (w == r) overflow = true; } m_write = w; if (overflow) m_read = modulo(w + 1); // Reset read pointer on overflow } /// Read data from current position if there is enough data to fill the range (otherwise return false). Does not move read pointer. template bool read(OutIt begin, OutIt end) { - unsigned r = static_cast(m_read); - if (modulo(static_cast(m_write) - r) <= end - begin) return false; // Not enough audio available + unsigned r = m_read; + if (size() <= end - begin) return false; // Not enough audio available while (begin != end) *begin++ = m_buf[r++ % SIZE]; // Copy audio to output iterator return true; } - void pop(unsigned n) { m_read = modulo(static_cast(m_read + n)); } ///< Move reading pointer forward. - unsigned size() const { return modulo(static_cast(m_write - m_read)); } + void pop(unsigned n) { m_read = modulo(m_read + n); } ///< Move reading pointer forward. + unsigned size() const { return modulo(m_write - m_read); } private: - static unsigned modulo(unsigned idx) { return (SIZE + idx) % SIZE; } ///< Modulo operation with proper rounding (handles slightly "negative" idx as well) + static unsigned modulo(int idx) { return (SIZE + idx) % SIZE; } ///< Modulo operation with proper rounding (handles slightly "negative" idx as well) float m_buf[SIZE]; - volatile size_t m_read, m_write; ///< The indices of the next read/write operations. read == write implies that buffer is empty. + volatile unsigned m_read, m_write; ///< The indices of the next read/write operations. read == write implies that buffer is empty. }; /// analyzer class @@ -75,7 +74,7 @@ public: /// list of tones typedef std::list tones_t; /// constructor - Analyzer(double rate, std::string id, std::size_t step = 200); + Analyzer(double rate, std::string id, unsigned step = 200); /** Add input data to buffer. This is thread-safe (against other functions). **/ template void input(InIt begin, InIt end) { m_buf.insert(begin, end); @@ -113,8 +112,8 @@ public: std::string const& getId() const { return m_id; } private: - const std::size_t m_step; - RingBuffer<2 * FFT_N> m_buf; // Twice the FFT size should give enough room for sliding window and for engine delays + const unsigned m_step; + RingBuffer<4 * FFT_N> m_buf; // Twice the FFT size should give enough room for sliding window and for engine delays RingBuffer<4096> m_passthrough; double m_resampleFactor; double m_resamplePos; From c781f5427fcec64ccbd97c5f434116f590291c73 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 28 Mar 2014 16:56:24 +0100 Subject: [PATCH 15/34] Merge fast detector with analyzer and use it in CBuffer --- PitchTracker/Helper.h | 4 +- PitchTracker/PitchTracker.vcxproj | 2 +- PitchTracker/PitchWrapper.cpp | 42 +++- PitchTracker/PitchWrapper.h | 36 ++- PitchTracker/pitch.cc | 8 +- PitchTracker/pitch.hh | 22 +- PitchTracker/pitchTracker.cpp | 50 +++-- PitchTracker/pitchTracker.h | 2 +- Vocaluxe/Lib/Sound/Record/CAnalyzer.cs | 22 +- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 265 ++--------------------- Vocaluxe/Lib/Sound/Record/CRecordBase.cs | 2 +- 11 files changed, 141 insertions(+), 314 deletions(-) diff --git a/PitchTracker/Helper.h b/PitchTracker/Helper.h index f9700a6f..27c18e8b 100644 --- a/PitchTracker/Helper.h +++ b/PitchTracker/Helper.h @@ -9,7 +9,7 @@ float* short2FloatArray(short* in, size_t len){ float* result = static_cast(malloc(len * sizeof(float))); float* curOut = result; - for(int i=0; i(malloc(len * sizeof(double))); double* curOut = result; - for(int i=0; iWIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Speed - true Fast + false Windows diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 44ffeff1..45a29b18 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -2,6 +2,22 @@ #include "pitchTracker.h" #include "Helper.h" +AnalyzerExt::AnalyzerExt(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step): Analyzer(44100., "", step){ + PitchTracker::Init(baseToneFrequency, minHalfTone, maxHalfTone); +} + +AnalyzerExt::~AnalyzerExt(){ + PitchTracker::DeInit(); +} + +int AnalyzerExt::GetNoteFast(float* weights){ + size_t size = m_fastAnalysisBuf.size(); + if(size > m_SampleCt) + m_fastAnalysisBuf.pop(size - m_SampleCt); + m_fastAnalysisBuf.read(m_AnalysisBuf, m_AnalysisBuf + m_SampleCt); + return PitchTracker::GetTone(m_AnalysisBuf, m_SampleCt, weights); +} + void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ PitchTracker::Init(baseToneFrequency, minHalfTone, maxHalfTone); } @@ -19,22 +35,22 @@ int PtFast_GetTone(short* samples, int sampleCt, float* weights){ return result; } -Analyzer* Analyzer_Create(double rate, unsigned step){ - return new Analyzer(rate, "", step); +AnalyzerExt* Analyzer_Create(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step){ + return new AnalyzerExt(baseToneFrequency, minHalfTone, maxHalfTone, step); } -void Analyzer_Free(Analyzer* analyzer){ +void Analyzer_Free(AnalyzerExt* analyzer){ if(analyzer) delete analyzer; } -void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt){ +void Analyzer_InputFloat(AnalyzerExt* analyzer, float* data, int sampleCt){ if(sampleCt == 0 || !analyzer) return; analyzer->input(data, data + sampleCt); } -void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt){ +void Analyzer_InputShort(AnalyzerExt* analyzer, short* data, int sampleCt){ if(sampleCt == 0 || !analyzer) return; float* dataFloat = short2FloatArray(data, sampleCt); @@ -42,7 +58,7 @@ void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt){ freeFloatArray(dataFloat); } -void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt){ +void Analyzer_InputByte(AnalyzerExt* analyzer, char* data, int sampleCt){ if(sampleCt == 0 || !analyzer) return; float* dataFloat = short2FloatArray(static_cast(static_cast(data)), sampleCt); @@ -50,26 +66,32 @@ void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt){ freeFloatArray(dataFloat); } -void Analyzer_Process(Analyzer* analyzer){ +void Analyzer_Process(AnalyzerExt* analyzer){ if(!analyzer) return; analyzer->process(); } -double Analyzer_GetPeak(Analyzer* analyzer){ +double Analyzer_GetPeak(AnalyzerExt* analyzer){ if(!analyzer) return -999; return analyzer->getPeak(); } -double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq){ +double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq){ if(!analyzer) return -1; const Tone* tone = analyzer->findTone(minFreq, maxFreq); return (tone == NULL) ? -1 : ToneToNote(tone); } -bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate){ +int Analyzer_GetNoteFast(AnalyzerExt* analyzer, float* weights){ + if(!analyzer) + return -1; + return analyzer->GetNoteFast(weights); +} + +bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate){ if(!analyzer) return false; return analyzer->output(data, data + sampleCt, rate); diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 2b9783d5..09298158 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -4,19 +4,35 @@ #define DllExport extern "C" __declspec(dllexport) +class AnalyzerExt: public Analyzer{ +public: + AnalyzerExt(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step = 200); + ~AnalyzerExt(); + template void input(InIt begin, InIt end){ + m_fastAnalysisBuf.insert(begin, end); + Analyzer::input(begin, end); + } + int GetNoteFast(float* weights); +private: + constexpr static size_t m_SampleCt = 4096; + RingBuffer m_fastAnalysisBuf; // Buffer used for fast analysis instead of FFT + float m_AnalysisBuf[4096]; +}; + DllExport void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); DllExport void PtFast_DeInit(); DllExport int PtFast_GetTone(short* samples, int sampleCt, float* weights); -DllExport Analyzer* Analyzer_Create(double rate, unsigned step); -DllExport void Analyzer_Free(Analyzer* analyzer); -DllExport void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt); -DllExport void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt); -DllExport void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt); -DllExport void Analyzer_Process(Analyzer* analyzer); -DllExport double Analyzer_GetPeak(Analyzer* analyzer); -DllExport double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq); -DllExport bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate); +DllExport AnalyzerExt* Analyzer_Create(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step); +DllExport void Analyzer_Free(AnalyzerExt* analyzer); +DllExport void Analyzer_InputFloat(AnalyzerExt* analyzer, float* data, int sampleCt); +DllExport void Analyzer_InputShort(AnalyzerExt* analyzer, short* data, int sampleCt); +DllExport void Analyzer_InputByte(AnalyzerExt* analyzer, char* data, int sampleCt); +DllExport void Analyzer_Process(AnalyzerExt* analyzer); +DllExport double Analyzer_GetPeak(AnalyzerExt* analyzer); +DllExport int Analyzer_GetNoteFast(AnalyzerExt* analyzer, float* weights); +DllExport double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq); +DllExport bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate); /* public ref class CTone { @@ -59,7 +75,7 @@ public: String^ GetId(); private: - Analyzer* m_analyzer; + AnalyzerExt* m_analyzer; String^ m_id; }; diff --git a/PitchTracker/pitch.cc b/PitchTracker/pitch.cc index 076dbc70..85af7d5f 100644 --- a/PitchTracker/pitch.cc +++ b/PitchTracker/pitch.cc @@ -50,7 +50,7 @@ Analyzer::Analyzer(double rate, std::string id, unsigned step): bool Analyzer::output(float* begin, float* end, double rate) { constexpr unsigned a = 2; - const unsigned size = m_passthrough.size(); + const size_t size = m_passthrough.size(); const unsigned out = static_cast((end - begin) / 2 /* stereo */); if (out == 0) return false; const unsigned in = static_cast(m_resampleFactor * (m_rate / rate) * out + 2 * a /* lanczos kernel */ + 5 /* safety margin for rounding errors */); @@ -72,7 +72,7 @@ bool Analyzer::output(float* begin, float* end, double rate) { m_resamplePos -= num; if (size > 3000) { // Reset - m_passthrough.pop(m_passthrough.size() - 700); + m_passthrough.pop(size - 700); m_resampleFactor = 1.0; } else { m_passthrough.pop(num); @@ -133,8 +133,8 @@ void Analyzer::calcTones() { const size_t kMax = std::min(FFT_N / 2, size_t(FFT_MAXFREQ / freqPerBin)); std::vector peaks(kMax + 1); // One extra to simplify loops for (size_t k = 1; k <= kMax; ++k) { - float magnitude = std::abs(m_fft[k]); - float phase = std::arg(m_fft[k]); + double magnitude = std::abs(m_fft[k]); + double phase = std::arg(m_fft[k]); // process phase difference double delta = phase - m_fftLastPhase[k]; m_fftLastPhase[k] = phase; diff --git a/PitchTracker/pitch.hh b/PitchTracker/pitch.hh index fc431733..f153ecd8 100644 --- a/PitchTracker/pitch.hh +++ b/PitchTracker/pitch.hh @@ -34,14 +34,14 @@ static const unsigned FFT_P = 10; static const std::size_t FFT_N = 1 << FFT_P; /// Lock-free ring buffer. Discards oldest data on overflow (not strictly thread-safe). -template class RingBuffer { +template class RingBuffer { public: - constexpr static unsigned capacity = SIZE; + constexpr static size_t capacity = SIZE; RingBuffer(): m_read(), m_write() {} ///< Initialize empty buffer template void insert(InIt begin, InIt end) { - unsigned r = m_read; // The read position - unsigned w = m_write; // The write position - bool overflow = (end - begin >= SIZE - size()); + size_t r = m_read; // The read position + size_t w = m_write; // The write position + bool overflow = (static_cast(end - begin) >= SIZE - size()); while (begin != end) { m_buf[w] = *begin++; // Copy sample w = modulo(w + 1); // Update cursor @@ -51,17 +51,17 @@ public: } /// Read data from current position if there is enough data to fill the range (otherwise return false). Does not move read pointer. template bool read(OutIt begin, OutIt end) { - unsigned r = m_read; - if (size() <= end - begin) return false; // Not enough audio available + size_t r = m_read; + if (size() <= static_cast(end - begin)) return false; // Not enough audio available while (begin != end) *begin++ = m_buf[r++ % SIZE]; // Copy audio to output iterator return true; } - void pop(unsigned n) { m_read = modulo(m_read + n); } ///< Move reading pointer forward. - unsigned size() const { return modulo(m_write - m_read); } + void pop(size_t n) { m_read = modulo(m_read + n); } ///< Move reading pointer forward. + size_t size() const { return modulo(m_write - m_read); } private: - static unsigned modulo(int idx) { return (SIZE + idx) % SIZE; } ///< Modulo operation with proper rounding (handles slightly "negative" idx as well) + static size_t modulo(size_t idx) { return idx % SIZE; } ///< Modulo operation with proper rounding (handles slightly "negative" idx as well) float m_buf[SIZE]; - volatile unsigned m_read, m_write; ///< The indices of the next read/write operations. read == write implies that buffer is empty. + volatile size_t m_read, m_write; ///< The indices of the next read/write operations. read == write implies that buffer is empty. }; /// analyzer class diff --git a/PitchTracker/pitchTracker.cpp b/PitchTracker/pitchTracker.cpp index 4d472ee2..bd075c7e 100644 --- a/PitchTracker/pitchTracker.cpp +++ b/PitchTracker/pitchTracker.cpp @@ -35,15 +35,19 @@ namespace PitchTracker{ Log=Callback; } - double *SamplesPerPeriodPerTone = NULL; - int MinHalfTone = 0, MaxHalfTone = 38; - const double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) + static double *SamplesPerPeriodPerTone = NULL; + static double BaseToneFrequency = -1; + static int MinHalfTone = -1, MaxHalfTone = -1; + static const double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ + if(SamplesPerPeriodPerTone && abs(baseToneFrequency - BaseToneFrequency) < 1. && minHalfTone == MinHalfTone && maxHalfTone == MaxHalfTone) + return; + BaseToneFrequency = baseToneFrequency; MinHalfTone = minHalfTone; MaxHalfTone = maxHalfTone; DeInit(); - if(maxHalfTone <= 0) + if(minHalfTone < 0 || maxHalfTone < minHalfTone) return; SamplesPerPeriodPerTone = (double*) malloc((MaxHalfTone + 1) * sizeof(double)); //Init Array to avoid costly calculations @@ -61,13 +65,14 @@ namespace PitchTracker{ } } - static double _AnalyzeToneFunc(double *samples, int sampleCt, int toneIndex){ + template + static T _AnalyzeToneFunc(T *samples, int sampleCt, int toneIndex){ double samplesPerPeriodD = SamplesPerPeriodPerTone[toneIndex]; // samples in one period - int samplesPerPeriod = (int)samplesPerPeriodD; - double fHigh = samplesPerPeriodD - samplesPerPeriod; - double fLow = 1.0 - fHigh; + int samplesPerPeriod = static_cast(samplesPerPeriodD); + T fHigh = static_cast(samplesPerPeriodD - samplesPerPeriod); + T fLow = static_cast(1.0 - fHigh); - double accumDist = 0; // accumulated distances + T accumDist = 0; // accumulated distances // compare correlating samples int sampleIndex = 0; // index of sample to analyze @@ -75,28 +80,30 @@ namespace PitchTracker{ for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < sampleCt; correlatingSampleIndex++, sampleIndex++) { // calc distance to corresponding sample in next period (lower means more distant) - double dist = samples[sampleIndex] * (samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh); + T dist = samples[sampleIndex] * (samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh); accumDist += dist; } - //Using _AnalysisBufLen here makes it return correct values among all analyzed frequencies - double scaleValue = sampleCt; // Divide also by Int16.MaxValue^2 - return accumDist / scaleValue; + //Using sampleCt here makes it return correct values among all analyzed frequencies + return accumDist / sampleCt; } - int GetTone(double *samples, int sampleCt, float *weights, bool scale){ - double maxVolume = 0; + template + int GetTone(T *samples, int sampleCt, float *weights, bool scale){ + if(!SamplesPerPeriodPerTone) + return -1; + T maxVolume = 0; for(int i = 0; i < sampleCt; i++){ - double vol = abs(samples[i]); + T vol = abs(samples[i]); if(vol > maxVolume) maxVolume = vol; } - double maxWeight = -1; - double minWeight = 1; + T maxWeight = -1; + T minWeight = 1; int maxTone = -1; for (int toneIndex = MinHalfTone; toneIndex <= MaxHalfTone; toneIndex++) { - double curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolume; + T curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolume; if(scale) curWeight /= 32768.0; //maximum abs value of a short, would actually need to scale by MaxValue^2 but we already scaled by maxVolume @@ -109,7 +116,7 @@ namespace PitchTracker{ if (curWeight < minWeight) minWeight = curWeight; - weights[toneIndex - MinHalfTone] = (float) curWeight; + weights[toneIndex - MinHalfTone] = static_cast(curWeight); } if(maxWeight - minWeight > 0.01){ @@ -117,4 +124,7 @@ namespace PitchTracker{ }else return -1; } + template int GetTone(float *samples, int sampleCt, float *weights, bool scale); + template int GetTone(double *samples, int sampleCt, float *weights, bool scale); + } \ No newline at end of file diff --git a/PitchTracker/pitchTracker.h b/PitchTracker/pitchTracker.h index 961c436c..a03d5926 100644 --- a/PitchTracker/pitchTracker.h +++ b/PitchTracker/pitchTracker.h @@ -3,7 +3,7 @@ namespace PitchTracker{ void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); void DeInit(); - int GetTone(double *samples, int sampleCt, float *weights, bool scale = false); + template int GetTone(T *samples, int sampleCt, float *weights, bool scale = false); typedef void (__stdcall * LogCallback)(const char* text); static LogCallback Log; diff --git a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs index 14ec16e8..676f37b3 100644 --- a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs +++ b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs @@ -7,19 +7,19 @@ namespace Vocaluxe.Lib.Sound.Record { #region Imports [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr Analyzer_Create(double rate, uint step); + private static extern IntPtr Analyzer_Create(double baseToneFrequency, int minHalfTone, int maxHalfTone, uint step = 200); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void Analyzer_Free(IntPtr analyzer); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void Analyzer_InputFloat(IntPtr analyzer, float[] data, int sampleCt); + private static extern void Analyzer_InputFloat(IntPtr analyzer, [In] float[] data, int sampleCt); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void Analyzer_InputShort(IntPtr analyzer, short[] data, int sampleCt); + private static extern void Analyzer_InputShort(IntPtr analyzer, [In] short[] data, int sampleCt); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void Analyzer_InputByte(IntPtr analyzer, byte[] data, int sampleCt); + private static extern void Analyzer_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void Analyzer_Process(IntPtr analyzer); @@ -27,6 +27,9 @@ namespace Vocaluxe.Lib.Sound.Record [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern double Analyzer_GetPeak(IntPtr analyzer); + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern double Analyzer_GetNoteFast(IntPtr analyzer, [Out] float[] weights); + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern double Analyzer_FindNote(IntPtr analyzer, double minFreq, double maxFreq); @@ -36,9 +39,9 @@ namespace Vocaluxe.Lib.Sound.Record private IntPtr _Instance; - public CAnalyzer(double rate = 44100.0, uint step = 200) + public CAnalyzer(double baseToneFrequency, int minHalfTone, int maxHalfTone, uint step = 200) { - _Instance = Analyzer_Create(rate, step); + _Instance = Analyzer_Create(baseToneFrequency, minHalfTone, maxHalfTone, step); } ~CAnalyzer() @@ -76,6 +79,11 @@ namespace Vocaluxe.Lib.Sound.Record return Analyzer_FindNote(_Instance, minFreq, maxFreq); } + public double GetNoteFast(float[] weights) + { + return Analyzer_GetNoteFast(_Instance, weights); + } + public bool Output(float[] data, float rate) { return Analyzer_OutputFloat(_Instance, data, data.Length, rate); @@ -106,7 +114,7 @@ namespace Vocaluxe.Lib.Sound.Record public static extern void DeInit(); [DllImport("PitchTracker.dll", EntryPoint = "PtFast_GetTone", CallingConvention = CallingConvention.Cdecl)] - private static extern int PtFast_GetTone(short[] samples, int sampleCt, float[] weights); + private static extern int PtFast_GetTone([In] short[] samples, int sampleCt, [Out] float[] weights); #endregion public static int GetTone(short[] samples, float[] weights) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 408ff5d8..edcbb9b3 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -15,16 +15,12 @@ // along with Vocaluxe. If not, see . #endregion -//#define TEST_PITCH -#define USE_NATIVE_DETECTION -//If defined, it uses a library with native code that speeds up detection by a factor of 10 +#define TEST_PITCH using System; -using System.IO; -using System.Diagnostics; - #if TEST_PITCH using System.Windows.Forms; +using System.Diagnostics; using VocaluxeLib; #endif @@ -33,69 +29,23 @@ namespace Vocaluxe.Lib.Sound.Record { class CBuffer : IDisposable { - private static int _InitCount; //Half tones: C C♯ D D# E F F♯ G G♯ A A# B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) +#if TEST_PITCH private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) +#endif private const int _HalfToneMin = 0; // C2 private const int _HalfToneMax = 38; //45; // inclusive, 38=D5; 45=A5 public const int NumHalfTones = _HalfToneMax - _HalfToneMin + 1; //Number of halftones to analyze + private CAnalyzer _Analyzer = new CAnalyzer(_BaseToneFreq, _HalfToneMin, _HalfToneMax); - private const int _AnalysisBufLen = 4096; - private const int _AnalysisByteBufLen = _AnalysisBufLen * 2; - - private readonly short[] _AnalysisBuffer = new short[_AnalysisBufLen]; - private readonly byte[] _AnalysisByteBuffer = new byte[_AnalysisByteBufLen]; //tmp buffer (stream->tmpBuffer->(Int16)AnalysisBuffer) - - private readonly float[] _TmpWeights = new float[NumHalfTones]; //tmp buffer for weights (gets copied to ToneWeight when checked) -#if !USE_NATIVE_DETECTION - //Precalculated table holding sample# per period for each tone (actually we may not use the lower few entries, but keep it to avoid index modification - private static readonly double[] _SamplesPerPeriodPerTone = new double[_HalfToneMax + 1]; - - public enum EAnalyzeFunction - { - AutoCorrelation, //Faster, more resistent to noise, good value for HalfToneMax=38 (higher->wrong results in test case, WHY?) with 38 no wrong values in test case - Amdf //Average magnitude difference, slower, detects everything in range -> HalfToneMax=45 - } - private delegate double DAnalyzeTone(int tone); - - // ReSharper disable MemberCanBePrivate.Global - // ReSharper disable ConvertToConstant.Global - // ReSharper disable FieldCanBeMadeReadOnly.Global - public static EAnalyzeFunction AnalyzeFunction = EAnalyzeFunction.AutoCorrelation; - // ReSharper restore FieldCanBeMadeReadOnly.Global - // ReSharper restore ConvertToConstant.Global - // ReSharper restore MemberCanBePrivate.Global - // ReSharper disable FieldCanBeMadeReadOnly.Local - private DAnalyzeTone _AnalyzeToneFunc; - private double _MinWeightDiff; - // ReSharper restore FieldCanBeMadeReadOnly.Local -#else - private readonly CAnalyzer _Analyzer = new CAnalyzer(); -#endif private double _MaxVolume; - private bool _NewSamples; - - private MemoryStream _Stream = new MemoryStream(); // full buffer public CBuffer() { - _Init(); MinVolume = 0.02f; - ToneWeigth = new float[NumHalfTones]; + ToneWeigths = new float[NumHalfTones]; Reset(); -#if !USE_NATIVE_DETECTION - if (AnalyzeFunction == EAnalyzeFunction.Amdf) - { - _AnalyzeToneFunc = _GetAmdf; - _MinWeightDiff = 0.01; - } - else if (AnalyzeFunction == EAnalyzeFunction.AutoCorrelation) - { - _AnalyzeToneFunc = _GetAutoCorrelation; - _MinWeightDiff = 0.0001; - } -#endif #if TEST_PITCH _TestPitchDetection(); #endif @@ -106,23 +56,6 @@ namespace Vocaluxe.Lib.Sound.Record _Dispose(); } - private static void _Init() - { - _InitCount++; - if (_InitCount > 1) - return; //Do init only once -#if USE_NATIVE_DETECTION - CFastAnalyzer.Init(_BaseToneFreq, _HalfToneMin, _HalfToneMax); -#else - //Init Array to avoid costly calculations - for (int toneIndex = 0; toneIndex <= _HalfToneMax; toneIndex++) - { - double freq = _BaseToneFreq * Math.Pow(_HalftoneBase, toneIndex); - _SamplesPerPeriodPerTone[toneIndex] = 44100.0 / freq; // samples in one period - } -#endif - } - public int ToneAbs { get; private set; } public int Tone { get; set; } @@ -134,7 +67,7 @@ namespace Vocaluxe.Lib.Sound.Record public bool ToneValid { get; private set; } - public float[] ToneWeigth { get; private set; } + public float[] ToneWeigths { get; private set; } ///

/// Minimum volume for a tone to be valid @@ -143,21 +76,11 @@ namespace Vocaluxe.Lib.Sound.Record public void Reset() { - lock (_Stream) - { - _Stream.SetLength(0L); - _NewSamples = false; - } ToneValid = false; ToneAbs = 0; Tone = 0; - for (int i = 0; i < ToneWeigth.Length; i++) - ToneWeigth[i] = 0f; - } - - private void _Add(byte[] bytes) - { - _Stream.Write(bytes, 0, bytes.Length); + for (int i = 0; i < ToneWeigths.Length; i++) + ToneWeigths[i] = 0f; } public void ProcessNewBuffer(byte[] buffer) @@ -168,168 +91,24 @@ namespace Vocaluxe.Lib.Sound.Record // voice passthrough (send data to playback-device) //if (assigned(fVoiceStream)) then //fVoiceStream.WriteData(Buffer, BufferSize); - lock (_Stream) - { - _Add(buffer); - _NewSamples = true; - } - //_Analyzer.Input(buffer); + _Analyzer.Input(buffer); } public void AnalyzeBuffer() { - if (!_NewSamples) - return; - - /*_NewSamples = false; _Analyzer.Process(); _MaxVolume = _Analyzer.GetPeak() / 43 + 1; - CTone tone = _Analyzer.FindTone(); - if (tone != null) + int tone = (int)Math.Round(_Analyzer.FindNote()); + if (tone >= 0) { - ToneAbs = tone.Note; + ToneAbs = tone; Tone = ToneAbs % 12; ToneValid = true; } - else - ToneValid = false;*/ - - lock (_Stream) - { - if (_Stream.Length >= _AnalysisByteBufLen) - { - _Stream.Position -= _AnalysisByteBufLen; - _Stream.Read(_AnalysisByteBuffer, 0, _AnalysisByteBufLen); - } - _NewSamples = false; - } - - Buffer.BlockCopy(_AnalysisByteBuffer, 0, _AnalysisBuffer, 0, _AnalysisByteBufLen); - - try - { - // find maximum volume - _FindMaxVolume(); - - if (MaxVolume >= MinVolume) - _AnalyzeTones(); - else - ToneValid = false; - } - catch (Exception) {} - } - - private void _FindMaxVolume() - { - int maxVolume = 0; - for (int i = 0; i < _AnalysisBufLen / 4; i++) - { - int volume = _AnalysisBuffer[i]; - if (volume < 0) - volume = -volume; - if (volume > maxVolume) - maxVolume = volume; - } - _MaxVolume = (double)maxVolume / Int16.MaxValue; - } - - private void _AnalyzeTones() - { -#if USE_NATIVE_DETECTION - int maxTone = CFastAnalyzer.GetTone(_AnalysisBuffer, _TmpWeights); - if (maxTone >= 0) -#else - // prepare to analyze - double maxWeight = -1.0; - double minWeight = 1.0; - int maxTone = -1; - - - // analyze halftones - // Note: at the lowest tone (~65Hz) and a buffer-size of 4096 - // at 44.1 (or 48kHz) only 6 (or 5) samples are compared, this might be - // too few samples -> use a bigger buffer-size - for (int toneIndex = _HalfToneMin; toneIndex <= _HalfToneMax; toneIndex++) - { - double curWeight = _AnalyzeToneFunc(toneIndex); - - if (curWeight > maxWeight) - { - maxWeight = curWeight; - maxTone = toneIndex; - } - - if (curWeight < minWeight) - minWeight = curWeight; - - _TmpWeights[toneIndex - _HalfToneMin] = (float)curWeight; - } - - if (maxWeight - minWeight > _MinWeightDiff) -#endif - { - Array.Copy(_TmpWeights, ToneWeigth, NumHalfTones); - - ToneAbs = maxTone; - //Console.WriteLine(maxTone); - Tone = maxTone % 12; - ToneValid = true; - } else ToneValid = false; } -#if !USE_NATIVE_DETECTION - private double _GetAutoCorrelation(int tone) - { - double samplesPerPeriodD = _SamplesPerPeriodPerTone[tone]; // samples in one period - int samplesPerPeriod = (int)samplesPerPeriodD; - double fHigh = samplesPerPeriodD - samplesPerPeriod; - double fLow = 1.0 - fHigh; - - double accumDist = 0; // accumulated distances - - // compare correlating samples - int sampleIndex = 0; // index of sample to analyze - // Start value= index of sample one period ahead - for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) - { - // calc distance to corresponding sample in next period (lower means more distant) - double dist = _AnalysisBuffer[sampleIndex] * - (_AnalysisBuffer[correlatingSampleIndex] * fLow + _AnalysisBuffer[correlatingSampleIndex + 1] * fHigh); - accumDist += dist; - } - - //Using _AnalysisBufLen here makes it return correct values among all analyzed frequencies - const double scaleValue = (double)Int16.MaxValue * (double)Int16.MaxValue * _AnalysisBufLen; - return accumDist / scaleValue; - } - - private double _GetAmdf(int tone) - { - double samplesPerPeriodD = _SamplesPerPeriodPerTone[tone]; // samples in one period - int samplesPerPeriod = (int)samplesPerPeriodD; - double fHigh = samplesPerPeriodD - samplesPerPeriod; - double fLow = 1.0 - fHigh; - - double accumDist = 0; // accumulated distances - - // compare correlating samples - int sampleIndex = 0; // index of sample to analyze - // Start value= index of sample one period ahead - for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _AnalysisBufLen; correlatingSampleIndex++, sampleIndex++) - { - // calc distance (correlation: 1-dist/IntMax*2) to corresponding sample in next period (0=equal .. IntMax*2=totally different) - //int dist = (int)Math.Abs(_AnalysisBuffer[sampleIndex] - _AnalysisBuffer[correlatingSampleIndex]); - double dist = Math.Abs(_AnalysisBuffer[sampleIndex] - - (_AnalysisBuffer[correlatingSampleIndex] * fLow + _AnalysisBuffer[correlatingSampleIndex + 1] * fHigh)); - accumDist += dist; - } - //Use analyzed sample count here. BufLen yields more errors - return 1.0 - accumDist / Int16.MaxValue / sampleIndex; - } -#endif - public void Dispose() { _Dispose(); @@ -338,17 +117,11 @@ namespace Vocaluxe.Lib.Sound.Record private void _Dispose() { - if (_Stream != null) + if (_Analyzer != null) { - _Stream.Dispose(); - _Stream = null; + _Analyzer.Dispose(); + _Analyzer = null; } -#if USE_NATIVE_DETECTION - Debug.Assert(_InitCount > 0); - _InitCount--; - if (_InitCount == 0) - CFastAnalyzer.DeInit(); -#endif } #if TEST_PITCH @@ -393,11 +166,9 @@ namespace Vocaluxe.Lib.Sound.Record } } _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); - ProcessNewBuffer(data); - AnalyzeBuffer(); Stopwatch sw = new Stopwatch(); sw.Start(); - const int repeats = 2000; + const int repeats = 1000; for (int i = 0; i < repeats; i++) { ProcessNewBuffer(data); @@ -486,7 +257,7 @@ namespace Vocaluxe.Lib.Sound.Record private static void _GetSineWave(double freq, int sampleRate, ref double angle, out byte[] data) { const short max = short.MaxValue; - const int len = _AnalysisBufLen; //sampleRate * durationMs / 1000; + const int len = 4096; //sampleRate * durationMs / 1000; short[] data16Bit = new short[len]; for (int i = 0; i < len; i++) data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq + angle) * max); diff --git a/Vocaluxe/Lib/Sound/Record/CRecordBase.cs b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs index 78630c90..074a7711 100644 --- a/Vocaluxe/Lib/Sound/Record/CRecordBase.cs +++ b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs @@ -137,7 +137,7 @@ namespace Vocaluxe.Lib.Sound.Record public float[] ToneWeigth(int player) { - return _Initialized ? _Buffer[player].ToneWeigth : null; + return _Initialized ? _Buffer[player].ToneWeigths : null; } public ReadOnlyCollection RecordDevices() From 980644108e3359a7b49ff628a7460d714af030b5 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 28 Mar 2014 22:13:52 +0100 Subject: [PATCH 16/34] Add FastAnalyzer to the class (split it later) Fix some bugs Use FastAnalyzer as Analyzer seems not to be reliable by now (need further tests) --- PitchTracker/PitchWrapper.cpp | 15 ++++++++------- PitchTracker/PitchWrapper.h | 4 ++-- PitchTracker/pitch.cc | 2 +- PitchTracker/pitch.hh | 2 +- PitchTracker/pitchTracker.cpp | 15 ++++++++------- PitchTracker/pitchTracker.h | 2 +- Vocaluxe/Lib/Sound/Record/CAnalyzer.cs | 12 ++++++------ Vocaluxe/Lib/Sound/Record/CBuffer.cs | 19 ++++++++++++------- 8 files changed, 39 insertions(+), 32 deletions(-) diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 45a29b18..992b6c10 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -10,12 +10,13 @@ AnalyzerExt::~AnalyzerExt(){ PitchTracker::DeInit(); } -int AnalyzerExt::GetNoteFast(float* weights){ +int AnalyzerExt::GetNoteFast(double* maxVolume, float* weights){ size_t size = m_fastAnalysisBuf.size(); if(size > m_SampleCt) m_fastAnalysisBuf.pop(size - m_SampleCt); - m_fastAnalysisBuf.read(m_AnalysisBuf, m_AnalysisBuf + m_SampleCt); - return PitchTracker::GetTone(m_AnalysisBuf, m_SampleCt, weights); + if(!m_fastAnalysisBuf.read(m_AnalysisBuf, m_AnalysisBuf + m_SampleCt)) + return -1; + return PitchTracker::GetTone(m_AnalysisBuf, m_SampleCt, maxVolume, weights); } void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ @@ -26,11 +27,11 @@ void PtFast_DeInit(){ PitchTracker::DeInit(); } -int PtFast_GetTone(short* samples, int sampleCt, float* weights){ +int PtFast_GetTone(short* samples, int sampleCt, double* maxVolume, float* weights){ if(sampleCt <= 0) return -1; double* dataDouble = short2DoubleArray(samples, sampleCt, false); - int result = PitchTracker::GetTone(dataDouble, sampleCt, weights, true); + int result = PitchTracker::GetTone(dataDouble, sampleCt, maxVolume, weights, true); freeDoubleArray(dataDouble); return result; } @@ -85,10 +86,10 @@ double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq){ return (tone == NULL) ? -1 : ToneToNote(tone); } -int Analyzer_GetNoteFast(AnalyzerExt* analyzer, float* weights){ +int Analyzer_GetNoteFast(AnalyzerExt* analyzer, double* maxVolume, float* weights){ if(!analyzer) return -1; - return analyzer->GetNoteFast(weights); + return analyzer->GetNoteFast(maxVolume, weights); } bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate){ diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 09298158..37fc9444 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -12,7 +12,7 @@ public: m_fastAnalysisBuf.insert(begin, end); Analyzer::input(begin, end); } - int GetNoteFast(float* weights); + int GetNoteFast(double* maxVolume, float* weights); private: constexpr static size_t m_SampleCt = 4096; RingBuffer m_fastAnalysisBuf; // Buffer used for fast analysis instead of FFT @@ -30,7 +30,7 @@ DllExport void Analyzer_InputShort(AnalyzerExt* analyzer, short* data, int sampl DllExport void Analyzer_InputByte(AnalyzerExt* analyzer, char* data, int sampleCt); DllExport void Analyzer_Process(AnalyzerExt* analyzer); DllExport double Analyzer_GetPeak(AnalyzerExt* analyzer); -DllExport int Analyzer_GetNoteFast(AnalyzerExt* analyzer, float* weights); +DllExport int Analyzer_GetNoteFast(AnalyzerExt* analyzer, double* maxVolume, float* weights); DllExport double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq); DllExport bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate); diff --git a/PitchTracker/pitch.cc b/PitchTracker/pitch.cc index 85af7d5f..760dc9dc 100644 --- a/PitchTracker/pitch.cc +++ b/PitchTracker/pitch.cc @@ -137,7 +137,7 @@ void Analyzer::calcTones() { double phase = std::arg(m_fft[k]); // process phase difference double delta = phase - m_fftLastPhase[k]; - m_fftLastPhase[k] = phase; + m_fftLastPhase[k] = static_cast(phase); delta -= k * phaseStep; // subtract expected phase difference delta = remainder(delta, 2.0 * M_PI); // map delta phase into +/- M_PI interval delta /= phaseStep; // calculate diff from bin center frequency diff --git a/PitchTracker/pitch.hh b/PitchTracker/pitch.hh index f153ecd8..ff3d982e 100644 --- a/PitchTracker/pitch.hh +++ b/PitchTracker/pitch.hh @@ -52,7 +52,7 @@ public: /// Read data from current position if there is enough data to fill the range (otherwise return false). Does not move read pointer. template bool read(OutIt begin, OutIt end) { size_t r = m_read; - if (size() <= static_cast(end - begin)) return false; // Not enough audio available + if (size() < static_cast(end - begin)) return false; // Not enough audio available while (begin != end) *begin++ = m_buf[r++ % SIZE]; // Copy audio to output iterator return true; } diff --git a/PitchTracker/pitchTracker.cpp b/PitchTracker/pitchTracker.cpp index bd075c7e..8850fb1b 100644 --- a/PitchTracker/pitchTracker.cpp +++ b/PitchTracker/pitchTracker.cpp @@ -89,21 +89,22 @@ namespace PitchTracker{ } template - int GetTone(T *samples, int sampleCt, float *weights, bool scale){ + int GetTone(T *samples, int sampleCt, double* maxVolume, float *weights, bool scale){ if(!SamplesPerPeriodPerTone) return -1; - T maxVolume = 0; + T maxVolumeL = 0; for(int i = 0; i < sampleCt; i++){ T vol = abs(samples[i]); - if(vol > maxVolume) - maxVolume = vol; + if(vol > maxVolumeL) + maxVolumeL = vol; } + *maxVolume = maxVolumeL; T maxWeight = -1; T minWeight = 1; int maxTone = -1; for (int toneIndex = MinHalfTone; toneIndex <= MaxHalfTone; toneIndex++) { - T curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolume; + T curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolumeL; if(scale) curWeight /= 32768.0; //maximum abs value of a short, would actually need to scale by MaxValue^2 but we already scaled by maxVolume @@ -124,7 +125,7 @@ namespace PitchTracker{ }else return -1; } - template int GetTone(float *samples, int sampleCt, float *weights, bool scale); - template int GetTone(double *samples, int sampleCt, float *weights, bool scale); + template int GetTone(float *samples, int sampleCt, double* maxVolume, float *weights, bool scale); + template int GetTone(double *samples, int sampleCt, double* maxVolume, float *weights, bool scale); } \ No newline at end of file diff --git a/PitchTracker/pitchTracker.h b/PitchTracker/pitchTracker.h index a03d5926..3d3c2de0 100644 --- a/PitchTracker/pitchTracker.h +++ b/PitchTracker/pitchTracker.h @@ -3,7 +3,7 @@ namespace PitchTracker{ void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); void DeInit(); - template int GetTone(T *samples, int sampleCt, float *weights, bool scale = false); + template int GetTone(T *samples, int sampleCt, double* maxVolume, float *weights, bool scale = false); typedef void (__stdcall * LogCallback)(const char* text); static LogCallback Log; diff --git a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs index 676f37b3..426572d0 100644 --- a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs +++ b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs @@ -28,7 +28,7 @@ namespace Vocaluxe.Lib.Sound.Record private static extern double Analyzer_GetPeak(IntPtr analyzer); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern double Analyzer_GetNoteFast(IntPtr analyzer, [Out] float[] weights); + private static extern int Analyzer_GetNoteFast(IntPtr analyzer, [Out] out double maxVolume, [Out] float[] weights); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern double Analyzer_FindNote(IntPtr analyzer, double minFreq, double maxFreq); @@ -79,9 +79,9 @@ namespace Vocaluxe.Lib.Sound.Record return Analyzer_FindNote(_Instance, minFreq, maxFreq); } - public double GetNoteFast(float[] weights) + public int GetNoteFast(out double maxVolume, float[] weights) { - return Analyzer_GetNoteFast(_Instance, weights); + return Analyzer_GetNoteFast(_Instance, out maxVolume, weights); } public bool Output(float[] data, float rate) @@ -114,12 +114,12 @@ namespace Vocaluxe.Lib.Sound.Record public static extern void DeInit(); [DllImport("PitchTracker.dll", EntryPoint = "PtFast_GetTone", CallingConvention = CallingConvention.Cdecl)] - private static extern int PtFast_GetTone([In] short[] samples, int sampleCt, [Out] float[] weights); + private static extern int PtFast_GetTone([In] short[] samples, int sampleCt, [Out] out double maxVolume, [Out] float[] weights); #endregion - public static int GetTone(short[] samples, float[] weights) + public static int GetTone(short[] samples, out double maxVolume, float[] weights) { - return PtFast_GetTone(samples, samples.Length, weights); + return PtFast_GetTone(samples, samples.Length, out maxVolume, weights); } } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index edcbb9b3..6b4db2f8 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -96,10 +96,10 @@ namespace Vocaluxe.Lib.Sound.Record public void AnalyzeBuffer() { - _Analyzer.Process(); - _MaxVolume = _Analyzer.GetPeak() / 43 + 1; - int tone = (int)Math.Round(_Analyzer.FindNote()); - if (tone >= 0) + //_Analyzer.Process(); + //_MaxVolume = _Analyzer.GetPeak() / 43 + 1; + int tone = _Analyzer.GetNoteFast(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // + if (tone >= 0 && _MaxVolume >= MinVolume) { ToneAbs = tone; Tone = ToneAbs % 12; @@ -146,6 +146,7 @@ namespace Vocaluxe.Lib.Sound.Record const int toneTo = 47; //B5 Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); byte[] data; + byte[] data2 = new byte[2048]; int ok = 0; double angle = 0; for (int distort = 0; distort < 10; distort++) @@ -155,8 +156,12 @@ namespace Vocaluxe.Lib.Sound.Record _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, ref angle, out data); _Distort(data, tone, distort); - ProcessNewBuffer(data); - AnalyzeBuffer(); + for (int i = 0; i < 4; i++) + { + Buffer.BlockCopy(data, i * 2048, data2, 0, 2048); + ProcessNewBuffer(data2); + AnalyzeBuffer(); + } if (!ToneValid) CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " not detected (Distortion: " + distort + ")"); else if (Tone != tone % 12) @@ -168,7 +173,7 @@ namespace Vocaluxe.Lib.Sound.Record _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); Stopwatch sw = new Stopwatch(); sw.Start(); - const int repeats = 1000; + const int repeats = 100; for (int i = 0; i < repeats; i++) { ProcessNewBuffer(data); From 6ad9f6a1ef93fb8ae9881035e67a8d55d64e965e Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 29 Mar 2014 17:47:52 +0100 Subject: [PATCH 17/34] Improve robustness by combining AKF and AMDF --- PitchTracker/PitchWrapper.cpp | 5 +++-- PitchTracker/PitchWrapper.h | 1 - PitchTracker/pitchTracker.cpp | 30 ++++++++++++++++++++---------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 992b6c10..ffe6bfac 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -11,12 +11,13 @@ AnalyzerExt::~AnalyzerExt(){ } int AnalyzerExt::GetNoteFast(double* maxVolume, float* weights){ + float AnaylsisBuf[m_SampleCt]; size_t size = m_fastAnalysisBuf.size(); if(size > m_SampleCt) m_fastAnalysisBuf.pop(size - m_SampleCt); - if(!m_fastAnalysisBuf.read(m_AnalysisBuf, m_AnalysisBuf + m_SampleCt)) + if(!m_fastAnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + m_SampleCt)) return -1; - return PitchTracker::GetTone(m_AnalysisBuf, m_SampleCt, maxVolume, weights); + return PitchTracker::GetTone(AnaylsisBuf, m_SampleCt, maxVolume, weights); } void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 37fc9444..bd9374fc 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -16,7 +16,6 @@ public: private: constexpr static size_t m_SampleCt = 4096; RingBuffer m_fastAnalysisBuf; // Buffer used for fast analysis instead of FFT - float m_AnalysisBuf[4096]; }; DllExport void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); diff --git a/PitchTracker/pitchTracker.cpp b/PitchTracker/pitchTracker.cpp index 8850fb1b..85e8bebd 100644 --- a/PitchTracker/pitchTracker.cpp +++ b/PitchTracker/pitchTracker.cpp @@ -66,26 +66,35 @@ namespace PitchTracker{ } template - static T _AnalyzeToneFunc(T *samples, int sampleCt, int toneIndex){ + static T _AnalyzeToneFunc(T *samples, int sampleCt, int toneIndex, bool scale){ + // Use method by Kobayashi and Shimamura (1995): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 double samplesPerPeriodD = SamplesPerPeriodPerTone[toneIndex]; // samples in one period int samplesPerPeriod = static_cast(samplesPerPeriodD); T fHigh = static_cast(samplesPerPeriodD - samplesPerPeriod); T fLow = static_cast(1.0 - fHigh); - T accumDist = 0; // accumulated distances + T accumDistAKF = 0; // accumulated distances + T accumDistAMDF = 0; // accumulated distances // compare correlating samples int sampleIndex = 0; // index of sample to analyze // Start value= index of sample one period ahead for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < sampleCt; correlatingSampleIndex++, sampleIndex++) { - // calc distance to corresponding sample in next period (lower means more distant) - T dist = samples[sampleIndex] * (samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh); - accumDist += dist; + // calc distance to corresponding sample in next period + T xn = samples[sampleIndex]; + T xnt = samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh; + accumDistAKF += xn * xnt; + accumDistAMDF += abs(xn - xnt); } - //Using sampleCt here makes it return correct values among all analyzed frequencies - return accumDist / sampleCt; + accumDistAKF /= sampleCt; + accumDistAMDF /= sampleIndex; + + if(scale) + return accumDistAKF / (accumDistAMDF * 32767.f + 32767.f); // Need to scale AKF by MAX^2 and AMDF by MAX, so do some maths to divide only once + else + return accumDistAKF / (accumDistAMDF + 1.f); } template @@ -98,15 +107,16 @@ namespace PitchTracker{ if(vol > maxVolumeL) maxVolumeL = vol; } + if(scale) + maxVolumeL /= 32767.; *maxVolume = maxVolumeL; + T maxWeight = -1; T minWeight = 1; int maxTone = -1; for (int toneIndex = MinHalfTone; toneIndex <= MaxHalfTone; toneIndex++) { - T curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex) / maxVolumeL; - if(scale) - curWeight /= 32768.0; //maximum abs value of a short, would actually need to scale by MaxValue^2 but we already scaled by maxVolume + T curWeight = _AnalyzeToneFunc(samples, sampleCt, toneIndex, scale); if (curWeight > maxWeight) { From 4c597cb4f895e35d171a7b8a75d6dd3e6ecc8cac Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 29 Mar 2014 22:54:37 +0100 Subject: [PATCH 18/34] Better structure --- PitchTracker/Helper.h | 5 +- PitchTracker/License.txt | 2 - PitchTracker/PitchTracker.vcxproj | 14 +++--- PitchTracker/PitchTracker.vcxproj.filters | 47 +++++++++++-------- PitchTracker/PitchWrapper.cpp | 16 +++---- PitchTracker/PitchWrapper.h | 2 +- PitchTracker/{pitchTracker.cpp => pdaAKF.cpp} | 4 +- PitchTracker/{pitchTracker.h => pdaAKF.h} | 3 +- PitchTracker/performous/License.txt | 3 ++ PitchTracker/{ => performous}/Performous.txt | 0 PitchTracker/{ => performous}/libda/fft.hpp | 0 .../{ => performous}/libda/sample.hpp | 0 PitchTracker/{ => performous}/pitch.cc | 0 PitchTracker/{ => performous}/pitch.hh | 2 +- PitchTracker/{ => performous}/util.hh | 0 15 files changed, 54 insertions(+), 44 deletions(-) delete mode 100644 PitchTracker/License.txt rename PitchTracker/{pitchTracker.cpp => pdaAKF.cpp} (98%) rename PitchTracker/{pitchTracker.h => pdaAKF.h} (74%) create mode 100644 PitchTracker/performous/License.txt rename PitchTracker/{ => performous}/Performous.txt (100%) rename PitchTracker/{ => performous}/libda/fft.hpp (100%) rename PitchTracker/{ => performous}/libda/sample.hpp (100%) rename PitchTracker/{ => performous}/pitch.cc (100%) rename PitchTracker/{ => performous}/pitch.hh (99%) rename PitchTracker/{ => performous}/util.hh (100%) diff --git a/PitchTracker/Helper.h b/PitchTracker/Helper.h index 27c18e8b..ae13e309 100644 --- a/PitchTracker/Helper.h +++ b/PitchTracker/Helper.h @@ -1,5 +1,4 @@ #pragma once -#include "pitch.hh" #include "PitchWrapper.h" #include #include @@ -40,8 +39,8 @@ void freeDoubleArray(double* floats){ free(floats); } -double ToneToNote(const Tone* tone){ - return 12.0 * std::log(tone->freq / 127.09) / std::log(2.0) + 27.5 - 16; // 16 = C2 +double FreqToNote(double freq){ + return 12.0 * std::log(freq / 127.09) / std::log(2.0) + 27.5 - 16; // 16 = C2 } /* diff --git a/PitchTracker/License.txt b/PitchTracker/License.txt deleted file mode 100644 index 0db6541a..00000000 --- a/PitchTracker/License.txt +++ /dev/null @@ -1,2 +0,0 @@ -Some code is taken from Performous: https://github.com/performous/performous/tree/master/game -From 25.03.2014 \ No newline at end of file diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj index c77885a1..a2053137 100644 --- a/PitchTracker/PitchTracker.vcxproj +++ b/PitchTracker/PitchTracker.vcxproj @@ -168,21 +168,21 @@ - - + + - - - + + + - - + + diff --git a/PitchTracker/PitchTracker.vcxproj.filters b/PitchTracker/PitchTracker.vcxproj.filters index f122cd3f..821a397b 100644 --- a/PitchTracker/PitchTracker.vcxproj.filters +++ b/PitchTracker/PitchTracker.vcxproj.filters @@ -13,47 +13,56 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {a47c9d33-78d2-453d-bb59-e5724cd85f67} + + + {4c72400a-ff2c-4842-8c20-54deb5df606d} + + + {d71782a0-47fc-4fe1-8569-0a0ce8fe9b45} + - - Quelldateien - - - Quelldateien - Quelldateien Quelldateien + + Quelldateien\performous + + + Quelldateien + - - Headerdateien - - - Headerdateien - Headerdateien - - Headerdateien - Headerdateien Headerdateien + + Headerdateien\performous\libda + + + Headerdateien\performous\libda + + + Headerdateien + - - Headerdateien + + Headerdateien\performous - - Headerdateien + + Headerdateien\performous \ No newline at end of file diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index ffe6bfac..31271e82 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -1,13 +1,13 @@ #include "PitchWrapper.h" -#include "pitchTracker.h" +#include "pdaAKF.h" #include "Helper.h" AnalyzerExt::AnalyzerExt(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step): Analyzer(44100., "", step){ - PitchTracker::Init(baseToneFrequency, minHalfTone, maxHalfTone); + PitchTrackerAKF::Init(baseToneFrequency, minHalfTone, maxHalfTone); } AnalyzerExt::~AnalyzerExt(){ - PitchTracker::DeInit(); + PitchTrackerAKF::DeInit(); } int AnalyzerExt::GetNoteFast(double* maxVolume, float* weights){ @@ -17,22 +17,22 @@ int AnalyzerExt::GetNoteFast(double* maxVolume, float* weights){ m_fastAnalysisBuf.pop(size - m_SampleCt); if(!m_fastAnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + m_SampleCt)) return -1; - return PitchTracker::GetTone(AnaylsisBuf, m_SampleCt, maxVolume, weights); + return PitchTrackerAKF::GetTone(AnaylsisBuf, m_SampleCt, maxVolume, weights); } void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ - PitchTracker::Init(baseToneFrequency, minHalfTone, maxHalfTone); + PitchTrackerAKF::Init(baseToneFrequency, minHalfTone, maxHalfTone); } void PtFast_DeInit(){ - PitchTracker::DeInit(); + PitchTrackerAKF::DeInit(); } int PtFast_GetTone(short* samples, int sampleCt, double* maxVolume, float* weights){ if(sampleCt <= 0) return -1; double* dataDouble = short2DoubleArray(samples, sampleCt, false); - int result = PitchTracker::GetTone(dataDouble, sampleCt, maxVolume, weights, true); + int result = PitchTrackerAKF::GetTone(dataDouble, sampleCt, maxVolume, weights, true); freeDoubleArray(dataDouble); return result; } @@ -84,7 +84,7 @@ double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq){ if(!analyzer) return -1; const Tone* tone = analyzer->findTone(minFreq, maxFreq); - return (tone == NULL) ? -1 : ToneToNote(tone); + return (tone == NULL) ? -1 : FreqToNote(tone->freq); } int Analyzer_GetNoteFast(AnalyzerExt* analyzer, double* maxVolume, float* weights){ diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index bd9374fc..f22771ba 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -1,6 +1,6 @@ #pragma once -#include "pitch.hh" +#include "performous/pitch.hh" #define DllExport extern "C" __declspec(dllexport) diff --git a/PitchTracker/pitchTracker.cpp b/PitchTracker/pdaAKF.cpp similarity index 98% rename from PitchTracker/pitchTracker.cpp rename to PitchTracker/pdaAKF.cpp index 85e8bebd..460a74b9 100644 --- a/PitchTracker/pitchTracker.cpp +++ b/PitchTracker/pdaAKF.cpp @@ -13,13 +13,13 @@ // You should have received a copy of the GNU General Public License // along with Vocaluxe. If not, see . -#include "pitchTracker.h" +#include "pdaAKF.h" #include #include #include #include -namespace PitchTracker{ +namespace PitchTrackerAKF{ static void doLog(const char* msg,...){ va_list argptr = NULL; diff --git a/PitchTracker/pitchTracker.h b/PitchTracker/pdaAKF.h similarity index 74% rename from PitchTracker/pitchTracker.h rename to PitchTracker/pdaAKF.h index 3d3c2de0..6341e973 100644 --- a/PitchTracker/pitchTracker.h +++ b/PitchTracker/pdaAKF.h @@ -1,6 +1,7 @@ #pragma once -namespace PitchTracker{ +// A pitch detection that is based on the AKF and AMDF (initially from original Vocaluxe/USDx) +namespace PitchTrackerAKF{ void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); void DeInit(); template int GetTone(T *samples, int sampleCt, double* maxVolume, float *weights, bool scale = false); diff --git a/PitchTracker/performous/License.txt b/PitchTracker/performous/License.txt new file mode 100644 index 00000000..9a031336 --- /dev/null +++ b/PitchTracker/performous/License.txt @@ -0,0 +1,3 @@ +code is based on Performous: https://github.com/performous/performous/tree/master/game +Some modifications were made to make it compile with VS2012, fix warnings and make it suitable for our needs +From 25.03.2014 \ No newline at end of file diff --git a/PitchTracker/Performous.txt b/PitchTracker/performous/Performous.txt similarity index 100% rename from PitchTracker/Performous.txt rename to PitchTracker/performous/Performous.txt diff --git a/PitchTracker/libda/fft.hpp b/PitchTracker/performous/libda/fft.hpp similarity index 100% rename from PitchTracker/libda/fft.hpp rename to PitchTracker/performous/libda/fft.hpp diff --git a/PitchTracker/libda/sample.hpp b/PitchTracker/performous/libda/sample.hpp similarity index 100% rename from PitchTracker/libda/sample.hpp rename to PitchTracker/performous/libda/sample.hpp diff --git a/PitchTracker/pitch.cc b/PitchTracker/performous/pitch.cc similarity index 100% rename from PitchTracker/pitch.cc rename to PitchTracker/performous/pitch.cc diff --git a/PitchTracker/pitch.hh b/PitchTracker/performous/pitch.hh similarity index 99% rename from PitchTracker/pitch.hh rename to PitchTracker/performous/pitch.hh index ff3d982e..1108e0b9 100644 --- a/PitchTracker/pitch.hh +++ b/PitchTracker/performous/pitch.hh @@ -5,7 +5,7 @@ #include #include #include -#include "compatibility.h" +#include "../compatibility.h" /// struct to represent tones struct Tone { diff --git a/PitchTracker/util.hh b/PitchTracker/performous/util.hh similarity index 100% rename from PitchTracker/util.hh rename to PitchTracker/performous/util.hh From f1a885b95e0b91dc3b2a32551286a44510231044 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 30 Mar 2014 01:32:25 +0100 Subject: [PATCH 19/34] Make an own class for AKF detector (tested for C2-B5) --- PitchTracker/PitchTracker.vcxproj | 6 +- PitchTracker/PitchTracker.vcxproj.filters | 4 +- PitchTracker/PitchWrapper.cpp | 90 +++++++--------- PitchTracker/PitchWrapper.h | 44 +++----- PitchTracker/pdaAKF.h | 12 --- PitchTracker/{pdaAKF.cpp => ptAKF.cpp} | 125 ++++++++++++++++++---- PitchTracker/ptAKF.h | 27 +++++ Vocaluxe/Lib/Sound/Record/CAnalyzer.cs | 77 +++++++++---- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 18 ++-- Vocaluxe/Lib/Sound/Record/CRecordBase.cs | 2 +- 10 files changed, 259 insertions(+), 146 deletions(-) delete mode 100644 PitchTracker/pdaAKF.h rename PitchTracker/{pdaAKF.cpp => ptAKF.cpp} (57%) create mode 100644 PitchTracker/ptAKF.h diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj index a2053137..47be7dd7 100644 --- a/PitchTracker/PitchTracker.vcxproj +++ b/PitchTracker/PitchTracker.vcxproj @@ -95,6 +95,7 @@ WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Fast + false Windows @@ -112,6 +113,7 @@ WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Fast + false Windows @@ -169,7 +171,7 @@ - + @@ -177,7 +179,7 @@ - + diff --git a/PitchTracker/PitchTracker.vcxproj.filters b/PitchTracker/PitchTracker.vcxproj.filters index 821a397b..efd0974f 100644 --- a/PitchTracker/PitchTracker.vcxproj.filters +++ b/PitchTracker/PitchTracker.vcxproj.filters @@ -33,7 +33,7 @@ Quelldateien\performous - + Quelldateien @@ -53,7 +53,7 @@ Headerdateien\performous\libda - + Headerdateien diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 31271e82..4fc47b4c 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -1,58 +1,23 @@ #include "PitchWrapper.h" -#include "pdaAKF.h" #include "Helper.h" -AnalyzerExt::AnalyzerExt(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step): Analyzer(44100., "", step){ - PitchTrackerAKF::Init(baseToneFrequency, minHalfTone, maxHalfTone); + +Analyzer* Analyzer_Create(unsigned step){ + return new Analyzer(44100, "", step); } -AnalyzerExt::~AnalyzerExt(){ - PitchTrackerAKF::DeInit(); -} - -int AnalyzerExt::GetNoteFast(double* maxVolume, float* weights){ - float AnaylsisBuf[m_SampleCt]; - size_t size = m_fastAnalysisBuf.size(); - if(size > m_SampleCt) - m_fastAnalysisBuf.pop(size - m_SampleCt); - if(!m_fastAnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + m_SampleCt)) - return -1; - return PitchTrackerAKF::GetTone(AnaylsisBuf, m_SampleCt, maxVolume, weights); -} - -void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone){ - PitchTrackerAKF::Init(baseToneFrequency, minHalfTone, maxHalfTone); -} - -void PtFast_DeInit(){ - PitchTrackerAKF::DeInit(); -} - -int PtFast_GetTone(short* samples, int sampleCt, double* maxVolume, float* weights){ - if(sampleCt <= 0) - return -1; - double* dataDouble = short2DoubleArray(samples, sampleCt, false); - int result = PitchTrackerAKF::GetTone(dataDouble, sampleCt, maxVolume, weights, true); - freeDoubleArray(dataDouble); - return result; -} - -AnalyzerExt* Analyzer_Create(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step){ - return new AnalyzerExt(baseToneFrequency, minHalfTone, maxHalfTone, step); -} - -void Analyzer_Free(AnalyzerExt* analyzer){ +void Analyzer_Free(Analyzer* analyzer){ if(analyzer) delete analyzer; } -void Analyzer_InputFloat(AnalyzerExt* analyzer, float* data, int sampleCt){ +void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt){ if(sampleCt == 0 || !analyzer) return; analyzer->input(data, data + sampleCt); } -void Analyzer_InputShort(AnalyzerExt* analyzer, short* data, int sampleCt){ +void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt){ if(sampleCt == 0 || !analyzer) return; float* dataFloat = short2FloatArray(data, sampleCt); @@ -60,45 +25,64 @@ void Analyzer_InputShort(AnalyzerExt* analyzer, short* data, int sampleCt){ freeFloatArray(dataFloat); } -void Analyzer_InputByte(AnalyzerExt* analyzer, char* data, int sampleCt){ - if(sampleCt == 0 || !analyzer) +void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt){ + if(sampleCt <= 0 || !analyzer) return; float* dataFloat = short2FloatArray(static_cast(static_cast(data)), sampleCt); analyzer->input(dataFloat, dataFloat + sampleCt); freeFloatArray(dataFloat); } -void Analyzer_Process(AnalyzerExt* analyzer){ +void Analyzer_Process(Analyzer* analyzer){ if(!analyzer) return; analyzer->process(); } -double Analyzer_GetPeak(AnalyzerExt* analyzer){ +double Analyzer_GetPeak(Analyzer* analyzer){ if(!analyzer) return -999; return analyzer->getPeak(); } -double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq){ +double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq){ if(!analyzer) return -1; const Tone* tone = analyzer->findTone(minFreq, maxFreq); return (tone == NULL) ? -1 : FreqToNote(tone->freq); } -int Analyzer_GetNoteFast(AnalyzerExt* analyzer, double* maxVolume, float* weights){ - if(!analyzer) - return -1; - return analyzer->GetNoteFast(maxVolume, weights); -} - -bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate){ +bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate){ if(!analyzer) return false; return analyzer->output(data, data + sampleCt, rate); } +DllExport PtAKF* PtAKF_Create(){ + return new PtAKF(); +} + +DllExport void PtAKF_Free(PtAKF* analyzer){ + if(analyzer) + delete analyzer; +} + +DllExport int PtAKF_GetNumHalfTones(){ + return PtAKF::GetNumHalfTones(); +} + +DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){ + if(sampleCt <= 0 || !analyzer) + return; + short* dataShort = static_cast(static_cast(data)); + analyzer->input(dataShort, dataShort + sampleCt); +} + +DllExport int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights){ + if(!analyzer) + return -1; + return analyzer->GetNote(maxVolume, weights); +} /* namespace Native{ diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index f22771ba..d3039bc9 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -1,37 +1,25 @@ #pragma once #include "performous/pitch.hh" +#include "ptAKF.h" #define DllExport extern "C" __declspec(dllexport) -class AnalyzerExt: public Analyzer{ -public: - AnalyzerExt(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step = 200); - ~AnalyzerExt(); - template void input(InIt begin, InIt end){ - m_fastAnalysisBuf.insert(begin, end); - Analyzer::input(begin, end); - } - int GetNoteFast(double* maxVolume, float* weights); -private: - constexpr static size_t m_SampleCt = 4096; - RingBuffer m_fastAnalysisBuf; // Buffer used for fast analysis instead of FFT -}; +DllExport Analyzer* Analyzer_Create(unsigned step); +DllExport void Analyzer_Free(Analyzer* analyzer); +DllExport void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt); +DllExport void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt); +DllExport void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt); +DllExport void Analyzer_Process(Analyzer* analyzer); +DllExport double Analyzer_GetPeak(Analyzer* analyzer); +DllExport double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq); +DllExport bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate); -DllExport void PtFast_Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); -DllExport void PtFast_DeInit(); -DllExport int PtFast_GetTone(short* samples, int sampleCt, float* weights); - -DllExport AnalyzerExt* Analyzer_Create(double baseToneFrequency, int minHalfTone, int maxHalfTone, unsigned step); -DllExport void Analyzer_Free(AnalyzerExt* analyzer); -DllExport void Analyzer_InputFloat(AnalyzerExt* analyzer, float* data, int sampleCt); -DllExport void Analyzer_InputShort(AnalyzerExt* analyzer, short* data, int sampleCt); -DllExport void Analyzer_InputByte(AnalyzerExt* analyzer, char* data, int sampleCt); -DllExport void Analyzer_Process(AnalyzerExt* analyzer); -DllExport double Analyzer_GetPeak(AnalyzerExt* analyzer); -DllExport int Analyzer_GetNoteFast(AnalyzerExt* analyzer, double* maxVolume, float* weights); -DllExport double Analyzer_FindNote(AnalyzerExt* analyzer, double minFreq, double maxFreq); -DllExport bool Analyzer_OutputFloat(AnalyzerExt* analyzer, float* data, int sampleCt, float rate); +DllExport PtAKF* PtAKF_Create(); +DllExport void PtAKF_Free(PtAKF* analyzer); +DllExport int PtAKF_GetNumHalfTones(); +DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt); +DllExport int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights); /* public ref class CTone { @@ -74,7 +62,7 @@ public: String^ GetId(); private: - AnalyzerExt* m_analyzer; + Analyzer* m_analyzer; String^ m_id; }; diff --git a/PitchTracker/pdaAKF.h b/PitchTracker/pdaAKF.h deleted file mode 100644 index 6341e973..00000000 --- a/PitchTracker/pdaAKF.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -// A pitch detection that is based on the AKF and AMDF (initially from original Vocaluxe/USDx) -namespace PitchTrackerAKF{ - void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); - void DeInit(); - template int GetTone(T *samples, int sampleCt, double* maxVolume, float *weights, bool scale = false); - - typedef void (__stdcall * LogCallback)(const char* text); - static LogCallback Log; - void SetLogCallback(LogCallback Callback); -} diff --git a/PitchTracker/pdaAKF.cpp b/PitchTracker/ptAKF.cpp similarity index 57% rename from PitchTracker/pdaAKF.cpp rename to PitchTracker/ptAKF.cpp index 460a74b9..fd272a6f 100644 --- a/PitchTracker/pdaAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -13,28 +13,112 @@ // You should have received a copy of the GNU General Public License // along with Vocaluxe. If not, see . -#include "pdaAKF.h" +#include "ptAKF.h" #include -#include -#include -#include + +static constexpr double BaseToneFrequency = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) +static constexpr double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) +int PtAKF::_InitCount = 0; +float* PtAKF::_SamplesPerPeriodPerTone = NULL; + +PtAKF::PtAKF(){ + _InitCount++; + if(_InitCount == 1){ + _SamplesPerPeriodPerTone = new float[_MaxHalfTone + 1]; + //Init Array to avoid costly calculations + for (int toneIndex = 0; toneIndex <= _MaxHalfTone; toneIndex++) + { + double freq = BaseToneFrequency * pow(HalftoneBase, toneIndex); + _SamplesPerPeriodPerTone[toneIndex] = static_cast(44100.0 / freq); // samples in one period + } + } +} + +PtAKF::~PtAKF(){ + _InitCount--; + if(!_InitCount){ + delete[] _SamplesPerPeriodPerTone; + _SamplesPerPeriodPerTone = NULL; + } +} + +int PtAKF::GetNote(double* maxVolume, float* weights){ + float AnaylsisBuf[_SampleCt]; + size_t size = _AnalysisBuf.size(); + if(size > _SampleCt) + _AnalysisBuf.pop(size - _SampleCt); + if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)) + return -1; + return _GetNote(AnaylsisBuf, maxVolume, weights); +} + +int PtAKF::_GetNote(float* samples, double* maxVolume, float* weights){ + float maxVolumeL = 0; + for(int i = 0; i < _SampleCt; i++){ + float vol = abs(samples[i]); + if(vol > maxVolumeL) + maxVolumeL = vol; + } + maxVolumeL /= 32767.; + *maxVolume = maxVolumeL; + + float maxWeight = -1; + float minWeight = 1; + int maxTone = -1; + for (int toneIndex = _MinHalfTone; toneIndex <= _MaxHalfTone; toneIndex++) + { + float curWeight = _AnalyzeToneFunc(samples, toneIndex); + + if (curWeight > maxWeight) + { + maxWeight = curWeight; + maxTone = toneIndex; + } + + if (curWeight < minWeight) + minWeight = curWeight; + + weights[toneIndex - _MinHalfTone] = curWeight; + } + + if(maxWeight - minWeight > 0.01){ + return maxTone; + }else return -1; +} + +float PtAKF::_AnalyzeToneFunc(float* samples, int toneIndex){ + // Use method by Kobayashi and Shimamura (1995): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 + + float samplesPerPeriodD = _SamplesPerPeriodPerTone[toneIndex]; // samples in one period + int samplesPerPeriod = static_cast(samplesPerPeriodD); + float fHigh = samplesPerPeriodD - samplesPerPeriod; + float fLow = 1.0f - fHigh; + + float accumDistAKF = 0; // accumulated distances + float accumDistAMDF = 0; // accumulated distances + + // compare correlating samples + int sampleIndex = 0; // index of sample to analyze + // Start value= index of sample one period ahead + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _SampleCt; correlatingSampleIndex++, sampleIndex++) + { + // calc distance to corresponding sample in next period + float xn = samples[sampleIndex]; + float xnt = samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh; + accumDistAKF += xn * xnt; + accumDistAMDF += abs(xn - xnt); + } + + accumDistAKF /= _SampleCt; + accumDistAMDF /= sampleIndex; + + return accumDistAKF / (accumDistAMDF * 32767.f + 32767.f); // Need to scale AKF by MAX^2 and AMDF by MAX, so do some maths to divide only once +} +/* + + namespace PitchTrackerAKF{ - - static void doLog(const char* msg,...){ - va_list argptr = NULL; - va_start(argptr, msg); - - char buffer[200]; - vsprintf_s(buffer,msg, argptr); - if(Log) Log(buffer); - va_end(argptr); - } - - void SetLogCallback(LogCallback Callback){ - Log=Callback; - } - static double *SamplesPerPeriodPerTone = NULL; static double BaseToneFrequency = -1; static int MinHalfTone = -1, MaxHalfTone = -1; @@ -138,4 +222,5 @@ namespace PitchTrackerAKF{ template int GetTone(float *samples, int sampleCt, double* maxVolume, float *weights, bool scale); template int GetTone(double *samples, int sampleCt, double* maxVolume, float *weights, bool scale); -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h new file mode 100644 index 00000000..240e7aa7 --- /dev/null +++ b/PitchTracker/ptAKF.h @@ -0,0 +1,27 @@ +#pragma once +#include "performous/pitch.hh" + +// A pitch detection that is based on the AKF and AMDF (initially from original Vocaluxe/USDx) +class PtAKF{ +public: + PtAKF(); + ~PtAKF(); + + void input(short* begin, short* end){ + _AnalysisBuf.insert(begin, end); + } + + int GetNote(double* maxVolume, float* weights); + static int GetNumHalfTones(){ return _MaxHalfTone - _MinHalfTone + 1;} +private: + static int _InitCount; + static float* _SamplesPerPeriodPerTone; + static constexpr int _MinHalfTone = 0; //C2 + static constexpr int _MaxHalfTone = 47; //B5 + + constexpr static size_t _SampleCt = 4096; + RingBuffer<_SampleCt * 2> _AnalysisBuf; + + static int _GetNote(float* samples, double* maxVolume, float* weights); + static float _AnalyzeToneFunc(float* samples, int toneIndex); +}; \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs index 426572d0..39d79f00 100644 --- a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs +++ b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs @@ -3,11 +3,15 @@ using System.Runtime.InteropServices; namespace Vocaluxe.Lib.Sound.Record { + /// + /// Analyzer from Performous + /// Should be very reliable but needs some proof (artificial tests show some errors) + /// class CAnalyzer : IDisposable { #region Imports [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr Analyzer_Create(double baseToneFrequency, int minHalfTone, int maxHalfTone, uint step = 200); + private static extern IntPtr Analyzer_Create(uint step = 200); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void Analyzer_Free(IntPtr analyzer); @@ -27,9 +31,6 @@ namespace Vocaluxe.Lib.Sound.Record [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern double Analyzer_GetPeak(IntPtr analyzer); - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int Analyzer_GetNoteFast(IntPtr analyzer, [Out] out double maxVolume, [Out] float[] weights); - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern double Analyzer_FindNote(IntPtr analyzer, double minFreq, double maxFreq); @@ -39,9 +40,9 @@ namespace Vocaluxe.Lib.Sound.Record private IntPtr _Instance; - public CAnalyzer(double baseToneFrequency, int minHalfTone, int maxHalfTone, uint step = 200) + public CAnalyzer(uint step = 200) { - _Instance = Analyzer_Create(baseToneFrequency, minHalfTone, maxHalfTone, step); + _Instance = Analyzer_Create(step); } ~CAnalyzer() @@ -79,11 +80,6 @@ namespace Vocaluxe.Lib.Sound.Record return Analyzer_FindNote(_Instance, minFreq, maxFreq); } - public int GetNoteFast(out double maxVolume, float[] weights) - { - return Analyzer_GetNoteFast(_Instance, out maxVolume, weights); - } - public bool Output(float[] data, float rate) { return Analyzer_OutputFloat(_Instance, data, data.Length, rate); @@ -104,22 +100,63 @@ namespace Vocaluxe.Lib.Sound.Record } } - static class CFastAnalyzer + /// + /// Pitchtracker (Pt) that uses autocorrelation (AKF) and AMDF + /// Quite fast and perfect in artificial tests, but may fail in real world scenarios (e.g. missing fundamental) + /// + class CPtAKF : IDisposable { #region Imports - [DllImport("PitchTracker.dll", EntryPoint = "PtFast_Init", CallingConvention = CallingConvention.Cdecl)] - public static extern void Init(double baseToneFrequency, int minHalfTone, int maxHalfTone); + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr PtAKF_Create(); - [DllImport("PitchTracker.dll", EntryPoint = "PtFast_DeInit", CallingConvention = CallingConvention.Cdecl)] - public static extern void DeInit(); + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtAKF_Free(IntPtr analyzer); - [DllImport("PitchTracker.dll", EntryPoint = "PtFast_GetTone", CallingConvention = CallingConvention.Cdecl)] - private static extern int PtFast_GetTone([In] short[] samples, int sampleCt, [Out] out double maxVolume, [Out] float[] weights); + [DllImport("PitchTracker.dll", EntryPoint = "PtAKF_GetNumHalfTones", CallingConvention = CallingConvention.Cdecl)] + public static extern int GetNumHalfTones(); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtAKF_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int PtAKF_GetNote(IntPtr analyzer, [Out] out double maxVolume, [Out] float[] weights); #endregion - public static int GetTone(short[] samples, out double maxVolume, float[] weights) + private IntPtr _Instance; + + public CPtAKF() { - return PtFast_GetTone(samples, samples.Length, out maxVolume, weights); + _Instance = PtAKF_Create(); + } + + ~CPtAKF() + { + _Dispose(false); + } + + public void Input(byte[] data) + { + PtAKF_InputByte(_Instance, data, data.Length / 2); + } + + public int GetNote(out double maxVolume, float[] weights) + { + return PtAKF_GetNote(_Instance, out maxVolume, weights); + } + + private void _Dispose(bool disposing) + { + if (_Instance == IntPtr.Zero) + throw new ObjectDisposedException(GetType().Name); + PtAKF_Free(_Instance); + _Instance = IntPtr.Zero; + } + + public void Dispose() + { + _Dispose(true); + GC.SuppressFinalize(this); } } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 6b4db2f8..f2114109 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -29,22 +29,19 @@ namespace Vocaluxe.Lib.Sound.Record { class CBuffer : IDisposable { +#if TEST_PITCH //Half tones: C C♯ D D# E F F♯ G G♯ A A# B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) -#if TEST_PITCH private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) #endif - private const int _HalfToneMin = 0; // C2 - private const int _HalfToneMax = 38; //45; // inclusive, 38=D5; 45=A5 - public const int NumHalfTones = _HalfToneMax - _HalfToneMin + 1; //Number of halftones to analyze - private CAnalyzer _Analyzer = new CAnalyzer(_BaseToneFreq, _HalfToneMin, _HalfToneMax); + private CPtAKF _Analyzer = new CPtAKF(); private double _MaxVolume; public CBuffer() { MinVolume = 0.02f; - ToneWeigths = new float[NumHalfTones]; + ToneWeigths = new float[GetNumHalfTones()]; Reset(); #if TEST_PITCH _TestPitchDetection(); @@ -56,6 +53,11 @@ namespace Vocaluxe.Lib.Sound.Record _Dispose(); } + public static int GetNumHalfTones() + { + return CPtAKF.GetNumHalfTones(); + } + public int ToneAbs { get; private set; } public int Tone { get; set; } @@ -98,7 +100,7 @@ namespace Vocaluxe.Lib.Sound.Record { //_Analyzer.Process(); //_MaxVolume = _Analyzer.GetPeak() / 43 + 1; - int tone = _Analyzer.GetNoteFast(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // + int tone = _Analyzer.GetNote(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // if (tone >= 0 && _MaxVolume >= MinVolume) { ToneAbs = tone; @@ -142,7 +144,7 @@ namespace Vocaluxe.Lib.Sound.Record if (_PitchTestRun) return; _PitchTestRun = true; - int toneFrom = Math.Max(0, _HalfToneMin); + int toneFrom = 0; const int toneTo = 47; //B5 Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); byte[] data; diff --git a/Vocaluxe/Lib/Sound/Record/CRecordBase.cs b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs index 074a7711..f68fc268 100644 --- a/Vocaluxe/Lib/Sound/Record/CRecordBase.cs +++ b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs @@ -132,7 +132,7 @@ namespace Vocaluxe.Lib.Sound.Record public int NumHalfTones() { - return CBuffer.NumHalfTones; + return CBuffer.GetNumHalfTones(); } public float[] ToneWeigth(int player) From 614a7e0ed2b97877e7c384e77d4b95a2ee172572 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Mon, 31 Mar 2014 17:55:31 +0200 Subject: [PATCH 20/34] Add step size --- PitchTracker/PitchWrapper.cpp | 4 ++-- PitchTracker/PitchWrapper.h | 2 +- PitchTracker/ptAKF.cpp | 4 +++- PitchTracker/ptAKF.h | 3 ++- Vocaluxe/Lib/Sound/Record/CAnalyzer.cs | 6 +++--- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 4fc47b4c..3d725b15 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -58,8 +58,8 @@ bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float r return analyzer->output(data, data + sampleCt, rate); } -DllExport PtAKF* PtAKF_Create(){ - return new PtAKF(); +DllExport PtAKF* PtAKF_Create(unsigned step){ + return new PtAKF(step); } DllExport void PtAKF_Free(PtAKF* analyzer){ diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index d3039bc9..08f32eed 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -15,7 +15,7 @@ DllExport double Analyzer_GetPeak(Analyzer* analyzer); DllExport double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq); DllExport bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate); -DllExport PtAKF* PtAKF_Create(); +DllExport PtAKF* PtAKF_Create(unsigned step); DllExport void PtAKF_Free(PtAKF* analyzer); DllExport int PtAKF_GetNumHalfTones(); DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt); diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index fd272a6f..b5e8bccb 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -21,7 +21,7 @@ static constexpr double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBas int PtAKF::_InitCount = 0; float* PtAKF::_SamplesPerPeriodPerTone = NULL; -PtAKF::PtAKF(){ +PtAKF::PtAKF(unsigned step){ _InitCount++; if(_InitCount == 1){ _SamplesPerPeriodPerTone = new float[_MaxHalfTone + 1]; @@ -32,6 +32,7 @@ PtAKF::PtAKF(){ _SamplesPerPeriodPerTone[toneIndex] = static_cast(44100.0 / freq); // samples in one period } } + _Step = step; } PtAKF::~PtAKF(){ @@ -49,6 +50,7 @@ int PtAKF::GetNote(double* maxVolume, float* weights){ _AnalysisBuf.pop(size - _SampleCt); if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)) return -1; + _AnalysisBuf.pop(_Step); return _GetNote(AnaylsisBuf, maxVolume, weights); } diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h index 240e7aa7..8ddc7c97 100644 --- a/PitchTracker/ptAKF.h +++ b/PitchTracker/ptAKF.h @@ -4,7 +4,7 @@ // A pitch detection that is based on the AKF and AMDF (initially from original Vocaluxe/USDx) class PtAKF{ public: - PtAKF(); + PtAKF(unsigned step); ~PtAKF(); void input(short* begin, short* end){ @@ -21,6 +21,7 @@ private: constexpr static size_t _SampleCt = 4096; RingBuffer<_SampleCt * 2> _AnalysisBuf; + unsigned _Step; static int _GetNote(float* samples, double* maxVolume, float* weights); static float _AnalyzeToneFunc(float* samples, int toneIndex); diff --git a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs index 39d79f00..e4e5807c 100644 --- a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs +++ b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs @@ -108,7 +108,7 @@ namespace Vocaluxe.Lib.Sound.Record { #region Imports [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr PtAKF_Create(); + private static extern IntPtr PtAKF_Create(uint step); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void PtAKF_Free(IntPtr analyzer); @@ -125,9 +125,9 @@ namespace Vocaluxe.Lib.Sound.Record private IntPtr _Instance; - public CPtAKF() + public CPtAKF(uint step = 200) { - _Instance = PtAKF_Create(); + _Instance = PtAKF_Create(step); } ~CPtAKF() From d584206a7fe6c10caa6ff58f78ce4076688f4437 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Wed, 9 Apr 2014 18:28:35 +0200 Subject: [PATCH 21/34] Fix bugs in AKF detection Add CWavFile.cs for reading wav files Add more test cases --- PitchTracker/Helper.h | 4 +- PitchTracker/PitchWrapper.cpp | 6 +- PitchTracker/TestSounds.rar | Bin 0 -> 840777 bytes PitchTracker/ptAKF.cpp | 93 ++++++++- PitchTracker/ptAKF.h | 9 +- Vocaluxe/Base/CLog.cs | 3 + Vocaluxe/Lib/Sound/Record/CBuffer.cs | 130 +++++++++++- VocaluxeLib/Utils/CWavFile.cs | 295 +++++++++++++++++++++++++++ VocaluxeLib/VocaluxeLib.csproj | 1 + 9 files changed, 524 insertions(+), 17 deletions(-) create mode 100644 PitchTracker/TestSounds.rar create mode 100644 VocaluxeLib/Utils/CWavFile.cs diff --git a/PitchTracker/Helper.h b/PitchTracker/Helper.h index ae13e309..1c27221c 100644 --- a/PitchTracker/Helper.h +++ b/PitchTracker/Helper.h @@ -4,7 +4,7 @@ #include float* short2FloatArray(short* in, size_t len){ - const float maxShort = 32768.0; //maximum abs value of a short + const float maxShort = 32767.0; float* result = static_cast(malloc(len * sizeof(float))); float* curOut = result; @@ -17,7 +17,7 @@ float* short2FloatArray(short* in, size_t len){ } double* short2DoubleArray(short* in, size_t len, bool scale = true){ - const double maxShort = 32768.0; //maximum abs value of a short + const double maxShort = 32767.0; double* result = static_cast(malloc(len * sizeof(double))); double* curOut = result; diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 3d725b15..d0f6d1f4 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -75,7 +75,11 @@ DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){ if(sampleCt <= 0 || !analyzer) return; short* dataShort = static_cast(static_cast(data)); - analyzer->input(dataShort, dataShort + sampleCt); + float* dataFloat = short2FloatArray(static_cast(static_cast(data)), sampleCt); + analyzer->input(dataFloat, dataFloat + sampleCt); + freeFloatArray(dataFloat); + + //analyzer->input(dataShort, dataShort + sampleCt); } DllExport int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights){ diff --git a/PitchTracker/TestSounds.rar b/PitchTracker/TestSounds.rar new file mode 100644 index 0000000000000000000000000000000000000000..463321f4f86fef1b6f471e439bcc5a0f16fe9d5d GIT binary patch literal 840777 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

1GPmGygE`U%PCJUfi5@lzGCDU`Qkx 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

LmfnjM_fuCtASp{ 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 F2LP7xK#BkW literal 0 HcmV?d00001 diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index b5e8bccb..d8a73088 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -24,9 +24,9 @@ float* PtAKF::_SamplesPerPeriodPerTone = NULL; PtAKF::PtAKF(unsigned step){ _InitCount++; if(_InitCount == 1){ - _SamplesPerPeriodPerTone = new float[_MaxHalfTone + 1]; + _SamplesPerPeriodPerTone = new float[_MaxHalfTone + 1 + _HalfTonesAdd]; //Init Array to avoid costly calculations - for (int toneIndex = 0; toneIndex <= _MaxHalfTone; toneIndex++) + for (int toneIndex = 0; toneIndex <= _MaxHalfTone + _HalfTonesAdd; toneIndex++) { double freq = BaseToneFrequency * pow(HalftoneBase, toneIndex); _SamplesPerPeriodPerTone[toneIndex] = static_cast(44100.0 / freq); // samples in one period @@ -61,12 +61,23 @@ int PtAKF::_GetNote(float* samples, double* maxVolume, float* weights){ if(vol > maxVolumeL) maxVolumeL = vol; } - maxVolumeL /= 32767.; + //maxVolumeL /= 32767.; *maxVolume = maxVolumeL; + //Scale the samples to have a peak of 1 to better decide between voiced/unvoiced + //float scaleVal = 1 / maxVolumeL; + //for(int i = 0; i < _SampleCt; i++){ + // samples[i] *= scaleVal; + //} + float maxWeight = -1; float minWeight = 1; int maxTone = -1; + + //Attention: We have a peak at lag 0 that might stretch that far, that we detect a wrong "peak" at _MaxHalfTone + //Because of that we filter out all tones that are past the last zero crossing from below but keep tones with decreasing weights (going towards zero crossing from above) + int lastValidTone = 0; + float lastWeight = 1.f; for (int toneIndex = _MinHalfTone; toneIndex <= _MaxHalfTone; toneIndex++) { float curWeight = _AnalyzeToneFunc(samples, toneIndex); @@ -81,18 +92,61 @@ int PtAKF::_GetNote(float* samples, double* maxVolume, float* weights){ minWeight = curWeight; weights[toneIndex - _MinHalfTone] = curWeight; + + //Filter: + if(lastWeight > curWeight || (lastWeight > 0.f && curWeight <= 0.f)) + lastValidTone = toneIndex - 1; + lastWeight = curWeight; } - if(maxWeight - minWeight > 0.01){ + if(maxTone==_MaxHalfTone){ + //We might have caught the lag 0 peak so go a bit further to check for other zero crossings (or we won't be able to detect _MaxHalfTone) + float lastWeight = _FastAKF(samples, _SamplesPerPeriodPerTone[_MaxHalfTone]); + for(int toneIndex = _MaxHalfTone+1; toneIndex <= _MaxHalfTone + _HalfTonesAdd; toneIndex++){ + float curWeight = _FastAKF(samples, _SamplesPerPeriodPerTone[toneIndex]); + if(lastWeight > curWeight || (lastWeight > 0.f && curWeight <= 0.f)){ + lastValidTone = toneIndex - 1; + break; + } + lastWeight = curWeight; + } + if(lastValidTone < maxTone){ + maxWeight = -1.f; + minWeight = 1.f; + for(int toneIndex = _MinHalfTone; toneIndex <= lastValidTone; toneIndex++){ + float curWeight = weights[toneIndex-_MinHalfTone]; + if (curWeight > maxWeight) + { + maxWeight = curWeight; + maxTone = toneIndex; + } + + if (curWeight < minWeight) + minWeight = curWeight; + } + //Set all invalid weights to 0 + for(int toneIndex = lastValidTone + 1;toneIndex < _MaxHalfTone; toneIndex++){ + weights[toneIndex - _MinHalfTone]=0.f; + } + } + } + + float energy = _FastAKF(samples, 0); + float maxAKF = _FastAKF(samples, _SamplesPerPeriodPerTone[maxTone]); + //printf("%g %g\n",energy, maxAKF); + + //if(maxWeight - minWeight > 0.025){ + if(maxAKF >= 0.3 * energy){ return maxTone; }else return -1; } float PtAKF::_AnalyzeToneFunc(float* samples, int toneIndex){ - // Use method by Kobayashi and Shimamura (1995): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 + // Use method by Kobayashi and Shimamura (2001): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 float samplesPerPeriodD = _SamplesPerPeriodPerTone[toneIndex]; // samples in one period int samplesPerPeriod = static_cast(samplesPerPeriodD); + int maxSampleCt = static_cast(_SamplesPerPeriodPerTone[0]); float fHigh = samplesPerPeriodD - samplesPerPeriod; float fLow = 1.0f - fHigh; @@ -114,7 +168,34 @@ float PtAKF::_AnalyzeToneFunc(float* samples, int toneIndex){ accumDistAKF /= _SampleCt; accumDistAMDF /= sampleIndex; - return accumDistAKF / (accumDistAMDF * 32767.f + 32767.f); // Need to scale AKF by MAX^2 and AMDF by MAX, so do some maths to divide only once + //return accumDistAKF / (accumDistAMDF * 32767.f + 32767.f * 32767.f); // Need to scale AKF by MAX^2 and AMDF by MAX, so do some maths to divide only once + float result = accumDistAKF / (accumDistAMDF + 1.f); + return result; // Need to scale AKF by MAX^2 and AMDF by MAX, so do some maths to divide only once + //{toneIndex}: {accumDistAKF} ; {accumDistAMDF}; {result} +} + +float PtAKF::_FastAKF(float* samples, float samplesPerPeriodD){ + // Do a fast, non-scaled AKF (used for Lag 0 peak removal) + + int samplesPerPeriod = static_cast(samplesPerPeriodD); + int maxSampleCt = static_cast(_SamplesPerPeriodPerTone[0]); + float fHigh = samplesPerPeriodD - samplesPerPeriod; + float fLow = 1.0f - fHigh; + + float accumDistAKF = 0; // accumulated distances + + // compare correlating samples + int sampleIndex = 0; // index of sample to analyze + // Start value= index of sample one period ahead + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _SampleCt; correlatingSampleIndex++, sampleIndex++) + { + // calc distance to corresponding sample in next period + float xn = samples[sampleIndex]; + float xnt = samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh; + accumDistAKF += xn * xnt; + } + + return accumDistAKF; } /* diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h index 8ddc7c97..6d5fd609 100644 --- a/PitchTracker/ptAKF.h +++ b/PitchTracker/ptAKF.h @@ -7,7 +7,8 @@ public: PtAKF(unsigned step); ~PtAKF(); - void input(short* begin, short* end){ + /** Add input data to buffer. This is thread-safe (against other functions). **/ + template void input(InIt begin, InIt end) { _AnalysisBuf.insert(begin, end); } @@ -17,12 +18,14 @@ private: static int _InitCount; static float* _SamplesPerPeriodPerTone; static constexpr int _MinHalfTone = 0; //C2 - static constexpr int _MaxHalfTone = 47; //B5 + static constexpr int _MaxHalfTone = 55;//47; //B5 + static constexpr int _HalfTonesAdd = 4; //Additonal half tones to analyze to remove the peak at lag 0 - constexpr static size_t _SampleCt = 4096; + constexpr static size_t _SampleCt = 2048; RingBuffer<_SampleCt * 2> _AnalysisBuf; unsigned _Step; static int _GetNote(float* samples, double* maxVolume, float* weights); static float _AnalyzeToneFunc(float* samples, int toneIndex); + static float _FastAKF(float* samples, float samplesPerPeriodD); }; \ No newline at end of file diff --git a/Vocaluxe/Base/CLog.cs b/Vocaluxe/Base/CLog.cs index a0484670..f90b7043 100644 --- a/Vocaluxe/Base/CLog.cs +++ b/Vocaluxe/Base/CLog.cs @@ -164,6 +164,9 @@ namespace Vocaluxe.Base public static void LogDebug(string text) { _DebugLog.Add(String.Format("{0:HH:mm:ss.ffff}", DateTime.Now) + ":" + text); +#if DEBUG + Console.WriteLine(text); +#endif } public static void LogSongInfo(string text) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index f2114109..394af07b 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -19,9 +19,12 @@ using System; #if TEST_PITCH +using System.Collections.Generic; +using System.IO; using System.Windows.Forms; using System.Diagnostics; using VocaluxeLib; +using VocaluxeLib.Utils; #endif @@ -30,11 +33,12 @@ namespace Vocaluxe.Lib.Sound.Record class CBuffer : IDisposable { #if TEST_PITCH - //Half tones: C C♯ D D# E F F♯ G G♯ A A# B + //Half tones: C C# D D# E F F# G G# A A# B private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) #endif private CPtAKF _Analyzer = new CPtAKF(); + private CAnalyzer _Analyzer2 = new CAnalyzer(); private double _MaxVolume; @@ -94,11 +98,12 @@ namespace Vocaluxe.Lib.Sound.Record //if (assigned(fVoiceStream)) then //fVoiceStream.WriteData(Buffer, BufferSize); _Analyzer.Input(buffer); + _Analyzer2.Input(buffer); } public void AnalyzeBuffer() { - //_Analyzer.Process(); + _Analyzer2.Process(); //_MaxVolume = _Analyzer.GetPeak() / 43 + 1; int tone = _Analyzer.GetNote(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // if (tone >= 0 && _MaxVolume >= MinVolume) @@ -132,7 +137,7 @@ namespace Vocaluxe.Lib.Sound.Record private static string _ToneToNote(int tone, bool withOctave = true) { tone += 24; - string[] notes = {"C", "C♯", "D", "D#", "E", "F", "F♯", "G", "G♯", "A", "A#", "B"}; + string[] notes = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; string result = notes[tone % 12]; if (withOctave) result += (tone / 12); @@ -145,11 +150,12 @@ namespace Vocaluxe.Lib.Sound.Record return; _PitchTestRun = true; int toneFrom = 0; - const int toneTo = 47; //B5 + const int toneTo = -1; // 47; //B5 Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); byte[] data; byte[] data2 = new byte[2048]; int ok = 0; + int tests = 0; double angle = 0; for (int distort = 0; distort < 10; distort++) { @@ -167,11 +173,30 @@ namespace Vocaluxe.Lib.Sound.Record if (!ToneValid) CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " not detected (Distortion: " + distort + ")"); else if (Tone != tone % 12) + { CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " wrongly detected as " + _ToneToNote(Tone, false) + " (Distortion: " + distort + ")"); + CWavFile file = new CWavFile(); + file.Create(tone + "-" + distort + ".wav", 1, 44100, 16); + file.Write16BitSamples(data, 1); + file.Close(); + } else ok++; + tests++; } } + if (_TestFile("toneG3.wav", 19)) + ok++; + tests++; + if (_TestFile("toneG3Miss.wav", 19)) + ok++; + tests++; + if (_TestFile("toneG4.wav", 31)) + ok++; + tests++; + _TestFile("whistling3.wav", "whistling3.txt", ref tests, ref ok); + _TestFile("sClausVoc.wav", "sClausVoc.txt", ref tests, ref ok); + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); Stopwatch sw = new Stopwatch(); sw.Start(); @@ -182,13 +207,108 @@ namespace Vocaluxe.Lib.Sound.Record AnalyzeBuffer(); } sw.Stop(); - string msg = "Analyser: Errors: " + ((toneTo - toneFrom + 1) * 10 - ok) + "; Speed: " + + string msg = "Analyser: Errors: " + (tests - ok) + "/" + tests + "; Speed: " + (int)(repeats / (sw.ElapsedMilliseconds / 1000.0)) + " buffers/s"; Console.WriteLine(msg); MessageBox.Show(msg); Reset(); } + private struct STimedNote + { + public int Time, Note; + } + + private void _TestFile(string fileName, string testFileName, ref int ct, ref int ok) + { + if (!File.Exists(testFileName)) + { + ok = ct = 0; + return; + } + List tones = new List(); + using (StreamReader reader = new StreamReader(testFileName)) + { + String line; + while ((line = reader.ReadLine()) != null) + { + int p = line.IndexOf(' '); + if (p < 0) + continue; + STimedNote note; + note.Time = int.Parse(line.Substring(0, p)); + note.Note = int.Parse(line.Substring(p + 1)); + tones.Add(note); + } + } + _TestFile(fileName, tones, ref ct, ref ok); + } + + private bool _TestFile(string fileName, int tone) + { + STimedNote note; + note.Note = tone; + note.Time = 46; + List tones = new List {note}; + int ct = 0; + int ok = 0; + _TestFile(fileName, tones, ref ct, ref ok); + return ok >= ct - 4; + } + + private void _TestFile(string fileName, IList tones, ref int ct, ref int ok) + { + CWavFile wavFile = new CWavFile(); + try + { + if (!wavFile.Open(fileName)) + return; + if (wavFile.BitsPerSample != 16) + { + wavFile.Close(); + return; + } + int samplesRead = 0; + int curTimeIndex = -1; + int curNote = -1; + const int maxSamplesPerBatch = 512; + while (wavFile.NumSamplesLeft / wavFile.NumChannels > maxSamplesPerBatch) + { + byte[] samples = wavFile.GetNextSamples16BitAsBytes(maxSamplesPerBatch, 1); + samplesRead += samples.Length / 2; + int time = samplesRead * 1000 / wavFile.SampleRate; + ProcessNewBuffer(samples); + AnalyzeBuffer(); + while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) + { + curTimeIndex++; + curNote = tones[curTimeIndex].Note; + } + if (curNote < 0) + continue; + ct++; + if (!ToneValid) + CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms not detected"); + else if (ToneAbs % 12 != curNote % 12) + CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(ToneAbs)); + else + ok++; + int note2 = (int)Math.Round(_Analyzer2.FindNote()); + if (note2 < 0) + CBase.Log.LogDebug("Note2 " + _ToneToNote(curNote) + " at " + time + "ms not detected"); + else if (note2 % 12 != curNote % 12) + CBase.Log.LogDebug("Note2 " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(note2)); + else + ok++; + } + } + catch (Exception e) + { + Console.WriteLine("Error on file " + fileName + ": " + e); + } + wavFile.Close(); + } + private static short[] _GetDistort(int len, int tone, int type) { short[] sdata = new short[len]; diff --git a/VocaluxeLib/Utils/CWavFile.cs b/VocaluxeLib/Utils/CWavFile.cs new file mode 100644 index 00000000..7dea4478 --- /dev/null +++ b/VocaluxeLib/Utils/CWavFile.cs @@ -0,0 +1,295 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace VocaluxeLib.Utils +{ + //Simple class to read and write WAV files + public class CWavFile + { + public short NumChannels { get; private set; } + public int SampleRate { get; private set; } + public short BitsPerSample { get; private set; } + public string FileName { get; private set; } + //Unless this is true, all fields are to be considered as invalid + public int DataSize { get; private set; } + //Number of samples (=SampesPerChannel*NumChannels) + public int NumSamples + { + get { return (DataSize / (BitsPerSample / 8)); } + } + public int NumSamplesLeft { get; private set; } + public bool IsOpen { get; private set; } + private int _DataPos; + private FileStream _File; + private bool _IsWritable; + + public CWavFile() + { + IsOpen = false; + } + + ~CWavFile() + { + Debug.Assert(!IsOpen); + Close(); + } + + public void Create(string fileName, short numChannels, int sampleRate, short bitsPerSample) + { + if (IsOpen) + Close(); + _File = new FileStream(fileName, FileMode.Create); + FileName = fileName; + NumChannels = numChannels; + SampleRate = sampleRate; + BitsPerSample = bitsPerSample; + DataSize = 0; + NumSamplesLeft = 0; + IsOpen = true; + _IsWritable = true; + _WriteHeader(); + } + + public void Close() + { + if (!IsOpen) + return; + if (_IsWritable) + { + BinaryWriter writer = new BinaryWriter(_File); + writer.Seek(4, SeekOrigin.Begin); + writer.Write((int)_File.Length - 8); + writer.Seek(_DataPos - 4, SeekOrigin.Begin); + writer.Write(DataSize); + } + _File.Dispose(); + _File = null; + IsOpen = false; + } + + public bool Open(string fileName) + { + if (IsOpen) + Close(); + if (!File.Exists(fileName)) + return false; + FileName = fileName; + _File = new FileStream(FileName, FileMode.Open); + try + { + BinaryReader reader = new BinaryReader(_File); + if (Encoding.ASCII.GetString(reader.ReadBytes(4)) != "RIFF") + return false; + reader.ReadInt32(); //Chunksize (file) + if (Encoding.ASCII.GetString(reader.ReadBytes(4)) != "WAVE") + return false; + long curPos = _File.Position; + if (_SeekTo(reader, "fmt ") < 0) + return false; + short audioFormat = reader.ReadInt16(); + if (audioFormat != 1) //PCM + return false; + NumChannels = reader.ReadInt16(); + SampleRate = reader.ReadInt32(); + int bytesPerSec = reader.ReadInt32(); + short blockAlign = reader.ReadInt16(); + BitsPerSample = reader.ReadInt16(); + if (BitsPerSample != 8 && BitsPerSample != 16) + return false; + if (blockAlign != NumChannels * (BitsPerSample / 8)) + return false; + if (bytesPerSec != blockAlign * SampleRate) + return false; + _File.Position = curPos; + DataSize = _SeekTo(reader, "data"); + if (DataSize <= 0) + return false; + _DataPos = (int)_File.Position; + DataSize = Math.Min(DataSize, (int)_File.Length - _DataPos); + NumSamplesLeft = NumSamples; + } + catch (Exception) + { + _File.Dispose(); + throw; + } + IsOpen = true; + return true; + } + + ///

+ /// Gets an array of numSamples samples per channel for the selected channel(s) + /// + /// Samples per channel + /// Channel for which to get the samples (0=all) + /// + public byte[] GetNextSamples8Bit(int numSamples, int channel = 0) + { + if (channel < 0 || channel > NumChannels || BitsPerSample != 8) + return null; + int samplesPerBlock = (channel == 0 ? NumChannels : 1); + if (NumSamplesLeft < numSamples * samplesPerBlock) + return null; + byte[] result; + BinaryReader reader = new BinaryReader(_File); + if (channel == 0 || NumChannels == 1) + result = reader.ReadBytes(numSamples * samplesPerBlock); + else + { + result = new byte[numSamples]; + for (int i = 0; i < numSamples; i++) + { + _File.Seek(channel - 1, SeekOrigin.Current); + result[i] = reader.ReadByte(); + _File.Seek(NumChannels - channel, SeekOrigin.Current); + } + } + NumSamplesLeft -= numSamples * samplesPerBlock; + return result; + } + + /// + /// Gets an array of numSamples samples per channel for the selected channel(s) + /// + /// Samples per channel + /// Channel for which to get the samples (0=all) + /// + public short[] GetNextSamples16Bit(int numSamples, int channel = 0) + { + if (channel < 0 || channel > NumChannels || BitsPerSample != 16) + return null; + int samplesPerBlock = (channel == 0 ? NumChannels : 1); + if (NumSamplesLeft < numSamples * samplesPerBlock) + return null; + short[] result; + BinaryReader reader = new BinaryReader(_File); + try + { + if (channel == 0 || NumChannels == 1) + { + result = new short[numSamples * NumChannels]; + for (int i = 0; i < numSamples * NumChannels; i++) + result[i] = reader.ReadInt16(); + } + else + { + result = new short[numSamples]; + for (int i = 0; i < numSamples; i++) + { + _File.Seek((channel - 1) * 2, SeekOrigin.Current); + result[i] = reader.ReadInt16(); + _File.Seek((NumChannels - channel) * 2, SeekOrigin.Current); + } + } + NumSamplesLeft -= numSamples * samplesPerBlock; + } + catch (EndOfStreamException e) + { + Console.WriteLine("Error: " + e); + return null; + } + return result; + } + + public byte[] GetNextSamples16BitAsBytes(int numSamples, int channel = 0) + { + short[] samples = GetNextSamples16Bit(numSamples, channel); + if (samples == null) + return null; + byte[] samplesByte = new byte[samples.Length * 2]; + Buffer.BlockCopy(samples, 0, samplesByte, 0, samplesByte.Length); + return samplesByte; + } + + public bool WriteSamples(byte[] samples, int channel = 0) + { + if (!_IsWritable || channel < 0 || channel > NumChannels || BitsPerSample != 8) + return false; + BinaryWriter writer = new BinaryWriter(_File); + if (channel == 0 || NumChannels == 1) + writer.Write(samples); + else + { + foreach (byte sample in samples) + { + _File.Seek(channel - 1, SeekOrigin.Current); + writer.Write(sample); + _File.Seek(NumChannels - channel, SeekOrigin.Current); + } + } + DataSize += samples.Length; + return true; + } + + public bool Write16BitSamples(short[] samples, int channel = 0) + { + if (!_IsWritable || channel < 0 || channel > NumChannels || BitsPerSample != 16) + return false; + BinaryWriter writer = new BinaryWriter(_File); + if (channel == 0 || NumChannels == 1) + { + foreach (short sample in samples) + writer.Write(sample); + } + else + { + foreach (short sample in samples) + { + _File.Seek((channel - 1) * 2, SeekOrigin.Current); + writer.Write(sample); + _File.Seek((NumChannels - channel) * 2, SeekOrigin.Current); + } + } + DataSize += samples.Length * 2; + return true; + } + + public bool Write16BitSamples(byte[] samples, int channel = 0) + { + if (samples.Length == 0) + return true; + short[] samplesShort = new short[samples.Length / 2]; + Buffer.BlockCopy(samples, 0, samplesShort, 0, samples.Length); + return Write16BitSamples(samplesShort, channel); + } + + private void _WriteHeader() + { + if (!IsOpen || !_IsWritable) + return; + BinaryWriter writer = new BinaryWriter(_File); + writer.Write(Encoding.ASCII.GetBytes("RIFF")); + writer.Write(0); + writer.Write(Encoding.ASCII.GetBytes("WAVE")); + writer.Write(Encoding.ASCII.GetBytes("fmt ")); + writer.Write(16); + writer.Write((short)1); // PCM + writer.Write(NumChannels); // Channels + writer.Write(SampleRate); // Sample rate + writer.Write(SampleRate * NumChannels * (BitsPerSample / 8)); // Average bytes per second + writer.Write((short)((BitsPerSample / 8) * NumChannels)); // block align + writer.Write(BitsPerSample); // bits per sample + writer.Write(Encoding.ASCII.GetBytes("data")); + writer.Write(DataSize); + _DataPos = (int)_File.Position; + writer.Seek(4, SeekOrigin.Begin); + writer.Write((int)writer.BaseStream.Length); + writer.Seek(_DataPos, SeekOrigin.Begin); + } + + private static int _SeekTo(BinaryReader reader, string chunkId) + { + do + { + string curChunkId = Encoding.ASCII.GetString(reader.ReadBytes(4)); + int chunkSize = reader.ReadInt32(); + if (curChunkId == chunkId) + return chunkSize; + reader.BaseStream.Seek(chunkSize, SeekOrigin.Current); + } while (reader.BaseStream.Position < reader.BaseStream.Length); + return -1; + } + } +} \ No newline at end of file diff --git a/VocaluxeLib/VocaluxeLib.csproj b/VocaluxeLib/VocaluxeLib.csproj index 22d6a2b1..5a6f5a21 100644 --- a/VocaluxeLib/VocaluxeLib.csproj +++ b/VocaluxeLib/VocaluxeLib.csproj @@ -188,6 +188,7 @@ + From 7c380f62f1f2d12369bb025f16271d402865729a Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 11 Apr 2014 22:59:01 +0200 Subject: [PATCH 22/34] Add dywapitchtracker Improvements for PtAKF (finer resolution at end) Bugfix for WavFile --- PitchTracker/Helper.cpp | 43 ++ PitchTracker/Helper.h | 47 +- PitchTracker/PitchTracker.vcxproj | 5 + PitchTracker/PitchTracker.vcxproj.filters | 21 + PitchTracker/PitchWrapper.cpp | 41 +- PitchTracker/PitchWrapper.h | 7 + PitchTracker/dywapitchtrack/DOCUMENTATION.txt | 29 ++ PitchTracker/dywapitchtrack/README.txt | 43 ++ .../dywapitchtrack/dywapitchtrack.cpp | 448 ++++++++++++++++++ PitchTracker/dywapitchtrack/dywapitchtrack.h | 110 +++++ PitchTracker/dywapitchtrack/ptDyWa.cpp | 27 ++ PitchTracker/dywapitchtrack/ptDyWa.h | 22 + PitchTracker/performous/pitch.cc | 20 +- PitchTracker/ptAKF.cpp | 182 +++++-- PitchTracker/ptAKF.h | 38 +- Vocaluxe/Lib/Sound/Record/CAnalyzer.cs | 65 +++ Vocaluxe/Lib/Sound/Record/CBuffer.cs | 50 +- VocaluxeLib/Utils/CWavFile.cs | 17 +- 18 files changed, 1075 insertions(+), 140 deletions(-) create mode 100644 PitchTracker/Helper.cpp create mode 100644 PitchTracker/dywapitchtrack/DOCUMENTATION.txt create mode 100644 PitchTracker/dywapitchtrack/README.txt create mode 100644 PitchTracker/dywapitchtrack/dywapitchtrack.cpp create mode 100644 PitchTracker/dywapitchtrack/dywapitchtrack.h create mode 100644 PitchTracker/dywapitchtrack/ptDyWa.cpp create mode 100644 PitchTracker/dywapitchtrack/ptDyWa.h diff --git a/PitchTracker/Helper.cpp b/PitchTracker/Helper.cpp new file mode 100644 index 00000000..41e00776 --- /dev/null +++ b/PitchTracker/Helper.cpp @@ -0,0 +1,43 @@ +#include "Helper.h" +#include +#include + +float* short2FloatArray(short* in, size_t len){ + const float maxShort = 32767.0; + + float* result = static_cast(malloc(len * sizeof(float))); + float* curOut = result; + for(size_t i=0; i(malloc(len * sizeof(double))); + double* curOut = result; + for(size_t i=0; i -#include -float* short2FloatArray(short* in, size_t len){ - const float maxShort = 32767.0; - - float* result = static_cast(malloc(len * sizeof(float))); - float* curOut = result; - for(size_t i=0; i(malloc(len * sizeof(double))); - double* curOut = result; - for(size_t i=0; i + + + + + diff --git a/PitchTracker/PitchTracker.vcxproj.filters b/PitchTracker/PitchTracker.vcxproj.filters index efd0974f..6e3d94f4 100644 --- a/PitchTracker/PitchTracker.vcxproj.filters +++ b/PitchTracker/PitchTracker.vcxproj.filters @@ -22,6 +22,12 @@ {d71782a0-47fc-4fe1-8569-0a0ce8fe9b45} + + {e8eab624-6cc3-42db-93d9-575aaeff06f7} + + + {2a09cee1-51b7-4c24-aa9f-32bec53c3a36} + @@ -36,6 +42,15 @@ Quelldateien + + Quelldateien\dywapitchtrack + + + Quelldateien\dywapitchtrack + + + Quelldateien + @@ -56,6 +71,12 @@ Headerdateien + + Headerdateien\dywapitchtrack + + + Headerdateien\dywapitchtrack + diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index d0f6d1f4..ff6e4252 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -58,23 +58,23 @@ bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float r return analyzer->output(data, data + sampleCt, rate); } -DllExport PtAKF* PtAKF_Create(unsigned step){ +PtAKF* PtAKF_Create(unsigned step){ return new PtAKF(step); } -DllExport void PtAKF_Free(PtAKF* analyzer){ +void PtAKF_Free(PtAKF* analyzer){ if(analyzer) delete analyzer; } -DllExport int PtAKF_GetNumHalfTones(){ +int PtAKF_GetNumHalfTones(){ return PtAKF::GetNumHalfTones(); } -DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){ +void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){ if(sampleCt <= 0 || !analyzer) return; - short* dataShort = static_cast(static_cast(data)); + //short* dataShort = static_cast(static_cast(data)); float* dataFloat = short2FloatArray(static_cast(static_cast(data)), sampleCt); analyzer->input(dataFloat, dataFloat + sampleCt); freeFloatArray(dataFloat); @@ -82,12 +82,41 @@ DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){ //analyzer->input(dataShort, dataShort + sampleCt); } -DllExport int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights){ +int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights){ if(!analyzer) return -1; return analyzer->GetNote(maxVolume, weights); } +PtDyWa* PtDyWa_Create(unsigned step){ + return new PtDyWa(step); +} + +void PtDyWa_Free(PtDyWa* analyzer){ + if(analyzer) + delete analyzer; +} + +void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt){ + if(sampleCt <= 0 || !analyzer) + return; + float* dataFloat = short2FloatArray(static_cast(static_cast(data)), sampleCt); + analyzer->input(dataFloat, dataFloat + sampleCt); + freeFloatArray(dataFloat); +} + +void PtDyWa_Process(PtDyWa* analyzer){ + if(!analyzer) + return; + analyzer->Process(); +} + +double PtDyWa_GetNote(PtDyWa* analyzer){ + if(!analyzer) + return -1; + return analyzer->GetNote(); +} + /* namespace Native{ namespace PitchTracking{ diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 08f32eed..80c5cfa7 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -2,6 +2,7 @@ #include "performous/pitch.hh" #include "ptAKF.h" +#include "dywapitchtrack/ptDyWa.h" #define DllExport extern "C" __declspec(dllexport) @@ -21,6 +22,12 @@ DllExport int PtAKF_GetNumHalfTones(); DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt); DllExport int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights); +DllExport PtDyWa* PtDyWa_Create(unsigned step); +DllExport void PtDyWa_Free(PtDyWa* analyzer); +DllExport void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt); +DllExport void PtDyWa_Process(PtDyWa* analyzer); +DllExport double PtDyWa_GetNote(PtDyWa* analyzer); + /* public ref class CTone { public: diff --git a/PitchTracker/dywapitchtrack/DOCUMENTATION.txt b/PitchTracker/dywapitchtrack/DOCUMENTATION.txt new file mode 100644 index 00000000..7c064fe7 --- /dev/null +++ b/PitchTracker/dywapitchtrack/DOCUMENTATION.txt @@ -0,0 +1,29 @@ + +dywapitchtrack pitch tracking library +Documentation + +The dywapitchtrack library computes the pitch of an audio stream in real time. The pitch is the main frequency of the waveform (the 'note' being played or sung). It is expressed as a float in Hz. + +Unlike the human ear, pitch detection is difficult to achieve for computers. Many algorithms have been designed and experimented, but there is no 'best' algorithm. They all depend on the context and the tradeoffs acceptable in terms of speed and latency. The context includes the quality and 'cleanness' of the audio : obviously polyphonic sounds (multiple instruments playing different notes at the same time) are extremely difficult to track, percussive or noisy audio has no pitch, most real-life audio have some noisy moments, some instruments have a lot of harmonics, etc... + +The dywapitchtrack is based on a custom-tailored algorithm which is of very high quality: both very accurate (precision < 0.05 semitones), very low latency (< 23 ms) and very low error rate. It has been thoroughly tested on human voice. + +It can best be described as a dynamic wavelet algorithm (dywa): + +The heart of the algorithm is a very powerful wavelet algorithm, described in a paper by Eric Larson and Ross Maddox : +"Real-Time Time-Domain Pitch Tracking Using Wavelets" http://online.physics.uiuc.edu/courses/phys406/NSF_REU_Reports/2005_reu/Real-Time_Time-Domain_Pitch_Tracking_Using_Wavelets.pdf + +This central algorithm has been improved by adding dynamic tracking, to reduce the common problems of frequency-halving and voiced/unvoiced errors. This dynamic tracking explains the need for a tracking structure (dywapitchtracker). The dynamic tracking assumes that the main function dywapitch_computepitch is called repeatedly, as it follows the pitch over time and makes assumptions about human voice capabilities and reallife conditions (as documented inside the code). + +Note : The algorithm currently assumes a 44100Hz audio sampling rate. If you use a different samplerate, you can just multiply the resulting pitch by the ratio between your samplerate and 44100. + +See the dywapitchtrack.h file for the library API documentation. + +History : +This algorithm has been designed during a mission for a customer. As I had kept the author's rights on the source code, I eventually decided to make this code public and open source, because it is of really high quality. This algorithms has been extensibely tested, especially it has been included in an Adobe Director Xtra (plugin), asPitchDetect Xtra, that has been distributed widely for a few years. + +I hope that it can be used with pleasure and efficiency in your project. + +Thank you +Antoine Schmitt April 2010 + diff --git a/PitchTracker/dywapitchtrack/README.txt b/PitchTracker/dywapitchtrack/README.txt new file mode 100644 index 00000000..db8bfbcc --- /dev/null +++ b/PitchTracker/dywapitchtrack/README.txt @@ -0,0 +1,43 @@ +dywapitchtrack +Dynamic Wavelet Algorithm Pitch Tracking library + +Copyright (c) 2010 Antoine Schmitt as@schmittmachine.com + +-- Documentation + +See the dywapitchtrack.h file for the library API documentation. + + +-- Version history + +Inital release : Antoine Schmitt April 2010 +jan 2012 : Minor update : changed the link to the Eric Larson and Ross Maddox paper +apr 2012 : Included the SpeakHere iPhone app example + +-- Building, Installing + +- the algorithm can be included directly in your project by including the .h and .c files. +- the iPhone/dywapitchtrack.xcodeproj builds an iPhone static library, against which one can statically link an iPhone application. + + +-- MIT open source licence + + Copyright (c) 2010 Antoine Schmitt + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/PitchTracker/dywapitchtrack/dywapitchtrack.cpp b/PitchTracker/dywapitchtrack/dywapitchtrack.cpp new file mode 100644 index 00000000..f4c6e653 --- /dev/null +++ b/PitchTracker/dywapitchtrack/dywapitchtrack.cpp @@ -0,0 +1,448 @@ +/* dywapitchtrack.c + + Dynamic Wavelet Algorithm Pitch Tracking library + Released under the MIT open source licence + + Copyright (c) 2010 Antoine Schmitt + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "dywapitchtrack.h" +#include +#include +#include // for memset + + +//********************** +// Utils +//********************** + +#ifndef max +#define max(x, y) ((x) > (y)) ? (x) : (y) +#endif +#ifndef min +#define min(x, y) ((x) < (y)) ? (x) : (y) +#endif + +// returns 1 if power of 2 +int _power2p(int value) { + if (value == 0) return 1; + if (value == 2) return 1; + if (value & 0x1) return 0; + return (_power2p(value >> 1)); +} + +// count number of bits +int _bitcount(int value) { + if (value == 0) return 0; + if (value == 1) return 1; + if (value == 2) return 2; + return _bitcount(value >> 1) + 1; +} + +// closest power of 2 above or equal +int _ceil_power2(int value) { + if (_power2p(value)) return value; + + if (value == 1) return 2; + int j, i = _bitcount(value); + int res = 1; + for (j = 0; j < i; j++) res <<= 1; + return res; +} + +// closest power of 2 below or equal +int _floor_power2(int value) { + if (_power2p(value)) return value; + return _ceil_power2(value)/2; +} + +// abs value +int _iabs(int x) { + if (x >= 0) return x; + return -x; +} + +// 2 power +int _2power(int i) { + int res = 1, j; + for (j = 0; j < i; j++) res <<= 1; + return res; +} + +//****************************** +// the Wavelet algorithm itself +//****************************** + +int dywapitch_neededsamplecount(int minFreq) { + int nbSam = 3*44100/minFreq; // 1017. for 130 Hz + nbSam = _ceil_power2(nbSam); // 1024 + return nbSam; +} + +typedef struct _minmax { + int index; + struct _minmax *next; +} minmax; + +double _dywapitch_computeWaveletPitch(double * samples, int startsample, int samplecount) { + double pitchF = 0.0; + + int i, j; + double si, si1; + + // must be a power of 2 + samplecount = _floor_power2(samplecount); + + double *sam = (double *)malloc(sizeof(double)*samplecount); + memcpy(sam, samples + startsample, sizeof(double)*samplecount); + int curSamNb = samplecount; + + int *distances = (int *)malloc(sizeof(int)*samplecount); + int *mins = (int *)malloc(sizeof(int)*samplecount); + int *maxs = (int *)malloc(sizeof(int)*samplecount); + int nbMins, nbMaxs; + + // algorithm parameters + int maxFLWTlevels = 6; + double maxF = 3000.; + int differenceLevelsN = 3; + double maximaThresholdRatio = 0.75; + + double ampltitudeThreshold; + double theDC = 0.0; + + { // compute ampltitudeThreshold and theDC + //first compute the DC and maxAMplitude + double maxValue = 0.0; + double minValue = 0.0; + for (i = 0; i < samplecount;i++) { + si = sam[i]; + theDC = theDC + si; + if (si > maxValue) maxValue = si; + if (si < minValue) minValue = si; + } + theDC = theDC/samplecount; + maxValue = maxValue - theDC; + minValue = minValue - theDC; + double amplitudeMax = (maxValue > -minValue ? maxValue : -minValue); + + ampltitudeThreshold = amplitudeMax*maximaThresholdRatio; + //asLog("dywapitch theDC=%f ampltitudeThreshold=%f\n", theDC, ampltitudeThreshold); + + } + + // levels, start without downsampling.. + int curLevel = 0; + double curModeDistance = -1.; + int delta; + + while(1) { + + // delta + delta = static_cast(44100./(_2power(curLevel)*maxF)); + //("dywapitch doing level=%ld delta=%ld\n", curLevel, delta); + + if (curSamNb < 2) goto cleanup; + + // compute the first maximums and minumums after zero-crossing + // store if greater than the min threshold + // and if at a greater distance than delta + double dv, previousDV = -1000; + nbMins = nbMaxs = 0; + int lastMinIndex = -1000000; + int lastmaxIndex = -1000000; + int findMax = 0; + int findMin = 0; + for (i = 2; i < curSamNb; i++) { + si = sam[i] - theDC; + si1 = sam[i-1] - theDC; + + if (si1 <= 0 && si > 0) findMax = 1; + if (si1 >= 0 && si < 0) findMin = 1; + + // min or max ? + dv = si - si1; + + if (previousDV > -1000) { + + if (findMin && previousDV < 0 && dv >= 0) { + // minimum + if (fabs(si) >= ampltitudeThreshold) { + if (i > lastMinIndex + delta) { + mins[nbMins++] = i; + lastMinIndex = i; + findMin = 0; + //if DEBUGG then put "min ok"&&si + // + } else { + //if DEBUGG then put "min too close to previous"&&(i - lastMinIndex) + // + } + } else { + // if DEBUGG then put "min "&abs(si)&" < thresh = "&ltitudeThreshold + //-- + } + } + + if (findMax && previousDV > 0 && dv <= 0) { + // maximum + if (fabs(si) >= ampltitudeThreshold) { + if (i > lastmaxIndex + delta) { + maxs[nbMaxs++] = i; + lastmaxIndex = i; + findMax = 0; + } else { + //if DEBUGG then put "max too close to previous"&&(i - lastmaxIndex) + //-- + } + } else { + //if DEBUGG then put "max "&abs(si)&" < thresh = "&ltitudeThreshold + //-- + } + } + } + + previousDV = dv; + } + + if (nbMins == 0 && nbMaxs == 0) { + // no best distance ! + //asLog("dywapitch no mins nor maxs, exiting\n"); + + // if DEBUGG then put "no mins nor maxs, exiting" + goto cleanup; + } + //if DEBUGG then put count(maxs)&&"maxs &"&&count(mins)&&"mins" + + // maxs = [5, 20, 100,...] + // compute distances + int d; + memset(distances, 0, samplecount*sizeof(int)); + for (i = 0 ; i < nbMins ; i++) { + for (j = 1; j < differenceLevelsN; j++) { + if (i+j < nbMins) { + d = _iabs(mins[i] - mins[i+j]); + //asLog("dywapitch i=%ld j=%ld d=%ld\n", i, j, d); + distances[d] = distances[d] + 1; + } + } + } + for (i = 0 ; i < nbMaxs ; i++) { + for (j = 1; j < differenceLevelsN; j++) { + if (i+j < nbMaxs) { + d = _iabs(maxs[i] - maxs[i+j]); + //asLog("dywapitch i=%ld j=%ld d=%ld\n", i, j, d); + distances[d] = distances[d] + 1; + } + } + } + + // find best summed distance + int bestDistance = -1; + int bestValue = -1; + for (i = 0; i< curSamNb; i++) { + int summed = 0; + for (j = -delta ; j <= delta ; j++) { + if (i+j >=0 && i+j < curSamNb) + summed += distances[i+j]; + } + //asLog("dywapitch i=%ld summed=%ld bestDistance=%ld\n", i, summed, bestDistance); + if (summed == bestValue) { + if (i == 2*bestDistance) + bestDistance = i; + + } else if (summed > bestValue) { + bestValue = summed; + bestDistance = i; + } + } + //asLog("dywapitch bestDistance=%ld\n", bestDistance); + + // averaging + double distAvg = 0.0; + double nbDists = 0; + for (j = -delta ; j <= delta ; j++) { + if (bestDistance+j >=0 && bestDistance+j < samplecount) { + int nbDist = distances[bestDistance+j]; + if (nbDist > 0) { + nbDists += nbDist; + distAvg += (bestDistance+j)*nbDist; + } + } + } + // this is our mode distance ! + distAvg /= nbDists; + //asLog("dywapitch distAvg=%f\n", distAvg); + + // continue the levels ? + if (curModeDistance > -1.) { + double similarity = fabs(distAvg*2 - curModeDistance); + if (similarity <= 2*delta) { + //if DEBUGG then put "similarity="&similarity&&"delta="&delta&&"ok" + //asLog("dywapitch similarity=%f OK !\n", similarity); + // two consecutive similar mode distances : ok ! + pitchF = 44100./(_2power(curLevel-1)*curModeDistance); + goto cleanup; + } + //if DEBUGG then put "similarity="&similarity&&"delta="&delta&&"not" + } + + // not similar, continue next level + curModeDistance = distAvg; + + curLevel = curLevel + 1; + if (curLevel >= maxFLWTlevels) { + // put "max levels reached, exiting" + //asLog("dywapitch max levels reached, exiting\n"); + goto cleanup; + } + + // downsample + if (curSamNb < 2) { + //asLog("dywapitch not enough samples, exiting\n"); + goto cleanup; + } + for (i = 0; i < curSamNb/2; i++) { + sam[i] = (sam[2*i] + sam[2*i + 1])/2.; + } + curSamNb /= 2; + } + + /// +cleanup: + free(distances); + free(mins); + free(maxs); + free(sam); + + return pitchF; +} + +// *********************************** +// the dynamic postprocess +// *********************************** + +/*** +It states: + - a pitch cannot change much all of a sudden (20%) (impossible humanly, + so if such a situation happens, consider that it is a mistake and drop it. + - a pitch cannot double or be divided by 2 all of a sudden : it is an + algorithm side-effect : divide it or double it by 2. + - a lonely voiced pitch cannot happen, nor can a sudden drop in the middle + of a voiced segment. Smooth the plot. +***/ + +double _dywapitch_dynamicprocess(dywapitchtracker *pitchtracker, double pitch) { + + // equivalence + if (pitch == 0.0) pitch = -1.0; + + // + double estimatedPitch = -1; + double acceptedError = 0.2f; + int maxConfidence = 5; + + if (pitch != -1) { + // I have a pitch here + + if (pitchtracker->_prevPitch == -1) { + // no previous + estimatedPitch = pitch; + pitchtracker->_prevPitch = pitch; + pitchtracker->_pitchConfidence = 1; + + } else if (abs(pitchtracker->_prevPitch - pitch)/pitch < acceptedError) { + // similar : remember and increment pitch + pitchtracker->_prevPitch = pitch; + estimatedPitch = pitch; + pitchtracker->_pitchConfidence = min(maxConfidence, pitchtracker->_pitchConfidence + 1); // maximum 3 + + } else if ((pitchtracker->_pitchConfidence >= maxConfidence-2) && abs(pitchtracker->_prevPitch - 2.*pitch)/(2.*pitch) < acceptedError) { + // close to half the last pitch, which is trusted + estimatedPitch = 2.*pitch; + pitchtracker->_prevPitch = estimatedPitch; + + } else if ((pitchtracker->_pitchConfidence >= maxConfidence-2) && abs(pitchtracker->_prevPitch - 0.5*pitch)/(0.5*pitch) < acceptedError) { + // close to twice the last pitch, which is trusted + estimatedPitch = 0.5*pitch; + pitchtracker->_prevPitch = estimatedPitch; + + } else { + // nothing like this : very different value + if (pitchtracker->_pitchConfidence >= 1) { + // previous trusted : keep previous + estimatedPitch = pitchtracker->_prevPitch; + pitchtracker->_pitchConfidence = max(0, pitchtracker->_pitchConfidence - 1); + } else { + // previous not trusted : take current + estimatedPitch = pitch; + pitchtracker->_prevPitch = pitch; + pitchtracker->_pitchConfidence = 1; + } + } + + } else { + // no pitch now + if (pitchtracker->_prevPitch != -1) { + // was pitch before + if (pitchtracker->_pitchConfidence >= 1) { + // continue previous + estimatedPitch = pitchtracker->_prevPitch; + pitchtracker->_pitchConfidence = max(0, pitchtracker->_pitchConfidence - 1); + } else { + pitchtracker->_prevPitch = -1; + estimatedPitch = -1.; + pitchtracker->_pitchConfidence = 0; + } + } + } + + // put "_pitchConfidence="&pitchtracker->_pitchConfidence + if (pitchtracker->_pitchConfidence >= 1) { + // ok + pitch = estimatedPitch; + } else { + pitch = -1; + } + + // equivalence + if (pitch == -1) pitch = 0.0; + + return pitch; +} + + +// ************************************ +// the API main entry points +// ************************************ + +void dywapitch_inittracking(dywapitchtracker *pitchtracker) { + pitchtracker->_prevPitch = -1.; + pitchtracker->_pitchConfidence = -1; +} + +double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount) { + double raw_pitch = _dywapitch_computeWaveletPitch(samples, startsample, samplecount); + return _dywapitch_dynamicprocess(pitchtracker, raw_pitch); +} + + + diff --git a/PitchTracker/dywapitchtrack/dywapitchtrack.h b/PitchTracker/dywapitchtrack/dywapitchtrack.h new file mode 100644 index 00000000..39aeb38d --- /dev/null +++ b/PitchTracker/dywapitchtrack/dywapitchtrack.h @@ -0,0 +1,110 @@ +/* dywapitchtrack.h + + Dynamic Wavelet Algorithm Pitch Tracking library + Released under the MIT open source licence + + Copyright (c) 2010 Antoine Schmitt + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* Documentation + + The dywapitchtrack library computes the pitch of an audio stream in real time. + + The pitch is the main frequency of the waveform (the 'note' being played or sung). + It is expressed as a float in Hz. + + Unlike the human ear, pitch detection is difficult to achieve for computers. Many + algorithms have been designed and experimented, but there is no 'best' algorithm. + They all depend on the context and the tradeoffs acceptable in terms of speed and + latency. The context includes the quality and 'cleanness' of the audio : obviously + polyphonic sounds (multiple instruments playing different notes at the same time) + are extremely difficult to track, percussive or noisy audio has no pitch, most + real-life audio have some noisy moments, some instruments have a lot of harmonics, + etc... + + The dywapitchtrack is based on a custom-tailored algorithm which is of very high quality: + both very accurate (precision < 0.05 semitones), very low latency (< 23 ms) and + very low error rate. It has been thoroughly tested on human voice. + + It can best be described as a dynamic wavelet algorithm (dywa): + + The heart of the algorithm is a very powerful wavelet algorithm, described in a paper + by Eric Larson and Ross Maddox : "Real-Time Time-Domain Pitch Tracking Using Wavelets" + http://online.physics.uiuc.edu/courses/phys498pom/NSF_REU_Reports/2005_reu/Real-Time_Time-Domain_Pitch_Tracking_Using_Wavelets.pdf + + This central algorithm has been improved by adding dynamic tracking, to reduce the + common problems of frequency-halving and voiced/unvoiced errors. This dynamic tracking + explains the need for a tracking structure (dywapitchtracker). The dynamic tracking assumes + that the main function dywapitch_computepitch is called repeatedly, as it follows the pitch + over time and makes assumptions about human voice capabilities and reallife conditions + (as documented inside the code). + + Note : The algorithm currently assumes a 44100Hz audio sampling rate. If you use a different + samplerate, you can just multiply the resulting pitch by the ratio between your samplerate and 44100. +*/ + +/* Usage + + // Allocate your audio buffers and start the audio stream. + // Allocate a 'dywapitchtracker' structure. + // Start the pitch tracking by calling 'dywapitch_inittracking'. + dywapitchtracker pitchtracker; + dywapitch_inittracking(&pitchtracker); + + // For each available audio buffer, call 'dywapitch_computepitch' + double thepitch = dywapitch_computepitch(&pitchtracker, samples, start, count); + +*/ + +#ifndef dywapitchtrack__H +#define dywapitchtrack__H + +#ifdef __cplusplus +extern "C" { +#endif + +// structure to hold tracking data +typedef struct _dywapitchtracker { + double _prevPitch; + int _pitchConfidence; +} dywapitchtracker; + +// returns the number of samples needed to compute pitch for fequencies equal and above the given minFreq (in Hz) +// useful to allocate large enough audio buffer +// ex : for frequencies above 130Hz, you need 1024 samples (assuming a 44100 Hz samplerate) +int dywapitch_neededsamplecount(int minFreq); + +// call before computing any pitch, passing an allocated dywapitchtracker structure +void dywapitch_inittracking(dywapitchtracker *pitchtracker); + +// computes the pitch. Pass the inited dywapitchtracker structure +// samples : a pointer to the sample buffer +// startsample : the index of the first sample to use in the sample buffer +// samplecount : the number of samples to use to compte the pitch +// return 0.0 if no pitch was found (sound too low, noise, etc..) +double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif + diff --git a/PitchTracker/dywapitchtrack/ptDyWa.cpp b/PitchTracker/dywapitchtrack/ptDyWa.cpp new file mode 100644 index 00000000..fa3ab4f0 --- /dev/null +++ b/PitchTracker/dywapitchtrack/ptDyWa.cpp @@ -0,0 +1,27 @@ +#include "ptDyWa.h" +#include "../Helper.h" + + +PtDyWa::PtDyWa(unsigned step){ + _Step = step; + dywapitch_inittracking(&_State); +} + +void PtDyWa::Process(){ + double AnaylsisBuf[_SampleCt]; + size_t size = _AnalysisBuf.size(); + if(size > _SampleCt) + _AnalysisBuf.pop(size - _SampleCt); + if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)) + return; + _AnalysisBuf.pop(_Step); + double pitch = dywapitch_computepitch(&_State, AnaylsisBuf,0,_SampleCt); + if(pitch == 0.0) + _LastNote = -1; + else + _LastNote = FreqToNote(pitch); +} + +double PtDyWa::GetNote(){ + return _LastNote; +} \ No newline at end of file diff --git a/PitchTracker/dywapitchtrack/ptDyWa.h b/PitchTracker/dywapitchtrack/ptDyWa.h new file mode 100644 index 00000000..c66e1ac7 --- /dev/null +++ b/PitchTracker/dywapitchtrack/ptDyWa.h @@ -0,0 +1,22 @@ +#pragma once +#include "../performous/pitch.hh" +#include "dywapitchtrack.h" + +class PtDyWa{ +public: + PtDyWa(unsigned step); + + /** Add input data to buffer. This is thread-safe (against other functions). **/ + template void input(InIt begin, InIt end) { + _AnalysisBuf.insert(begin, end); + } + + void Process(); + double GetNote(); +private: + dywapitchtracker _State; + constexpr static size_t _SampleCt = 2048; + RingBuffer<_SampleCt * 2> _AnalysisBuf; + unsigned _Step; + double _LastNote; +}; \ No newline at end of file diff --git a/PitchTracker/performous/pitch.cc b/PitchTracker/performous/pitch.cc index 760dc9dc..a8453764 100644 --- a/PitchTracker/performous/pitch.cc +++ b/PitchTracker/performous/pitch.cc @@ -139,7 +139,7 @@ void Analyzer::calcTones() { double delta = phase - m_fftLastPhase[k]; m_fftLastPhase[k] = static_cast(phase); delta -= k * phaseStep; // subtract expected phase difference - delta = remainder(delta, 2.0 * M_PI); // map delta phase into +/- M_PI interval + delta = remainder(delta, M_PI); // map delta phase into +/- M_PI interval delta /= phaseStep; // calculate diff from bin center frequency double freq = (k + delta) * freqPerBin; // calculate the true frequency if (freq > 1.0 && magnitude > minMagnitude) { @@ -164,15 +164,16 @@ void Analyzer::calcTones() { int bestScore = 0; for (std::size_t div = 2; div <= Tone::MAXHARM && k / div > 1; ++div) { double freq = peaks[k].freq / div; // Fundamental + double db = peaks[k].db; int score = 0; for (std::size_t n = 1; n < div && n < 8; ++n) { Peak& p = match(peaks, k * n / div); --score; - if (p.db < -90.0 || std::abs(p.freq / n / freq - 1.0) > .03) continue; - if (n == 1) score += 4; // Extra for fundamental + if (std::abs(p.db/db - 1.0) > 0.4 || std::abs(p.freq / n / freq - 1.0) > .04) continue; + if (n == 1) score += 1; // Extra for fundamental score += 2; } - if (score > bestScore) { + if (score >= bestScore) { bestScore = score; bestDiv = div; } @@ -185,12 +186,11 @@ void Analyzer::calcTones() { for (std::size_t n = 1; n <= bestDiv; ++n) { // Find the peak for n'th harmonic Peak& p = match(peaks, k * n / bestDiv); - if (std::abs(p.freq / n / freq - 1.0) > .03) continue; // Does it match the fundamental freq? - if (p.db > t.db - 10.0) { - t.db = std::max(t.db, p.db); - ++count; - t.freq += p.freq / n; - } + if (std::abs(p.freq / n / freq - 1.0) > .04) continue; // Does it match the fundamental freq? + if (std::abs(p.db/t.db - 1.0) > 0.4) continue; + t.db = std::max(t.db, p.db); + ++count; + t.freq += p.freq / n; t.harmonics[n - 1] = p.db; p.clear(); } diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index d8a73088..be84893b 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -13,23 +13,37 @@ // You should have received a copy of the GNU General Public License // along with Vocaluxe. If not, see . +#define _USE_MATH_DEFINES #include "ptAKF.h" -#include +#include static constexpr double BaseToneFrequency = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) static constexpr double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) int PtAKF::_InitCount = 0; -float* PtAKF::_SamplesPerPeriodPerTone = NULL; +float* restrict PtAKF::_SamplesPerPeriodPerTone = NULL; +float* restrict PtAKF::_SamplesPerPeriodPerToneFine = NULL; +float* restrict PtAKF::_Window = NULL; + +double GetFrequencyFromTone(double toneIndex){ + return BaseToneFrequency * pow(HalftoneBase, toneIndex); +} PtAKF::PtAKF(unsigned step){ _InitCount++; if(_InitCount == 1){ _SamplesPerPeriodPerTone = new float[_MaxHalfTone + 1 + _HalfTonesAdd]; + _SamplesPerPeriodPerToneFine = new float[(_MaxHalfTone + 1 + _HalfTonesAdd) * 2]; //Init Array to avoid costly calculations for (int toneIndex = 0; toneIndex <= _MaxHalfTone + _HalfTonesAdd; toneIndex++) { - double freq = BaseToneFrequency * pow(HalftoneBase, toneIndex); - _SamplesPerPeriodPerTone[toneIndex] = static_cast(44100.0 / freq); // samples in one period + _SamplesPerPeriodPerTone[toneIndex] = static_cast(44100.0 / GetFrequencyFromTone(toneIndex)); // samples in one period + _SamplesPerPeriodPerToneFine[2 * toneIndex] = static_cast(44100.0 / GetFrequencyFromTone(toneIndex - 1./3.)); // samples for a bit below exact frequency + _SamplesPerPeriodPerToneFine[2 * toneIndex + 1] = static_cast(44100.0 / GetFrequencyFromTone(toneIndex + 1./3.)); // samples for a bit above exact frequency + } + _Window = new float[_SampleCt]; + double cosMult = 2. * M_PI / (_SampleCt - 1.); //To simplify and speed up + for (int i = 0; i < _SampleCt; i++) { + _Window[i] = static_cast(0.54 - 0.46 * cos(i * cosMult)); } } _Step = step; @@ -40,10 +54,12 @@ PtAKF::~PtAKF(){ if(!_InitCount){ delete[] _SamplesPerPeriodPerTone; _SamplesPerPeriodPerTone = NULL; + delete[] _SamplesPerPeriodPerToneFine; + _SamplesPerPeriodPerToneFine = NULL; } } -int PtAKF::GetNote(double* maxVolume, float* weights){ +int PtAKF::GetNote(double* restrict maxVolume, float* restrict weights){ float AnaylsisBuf[_SampleCt]; size_t size = _AnalysisBuf.size(); if(size > _SampleCt) @@ -54,9 +70,37 @@ int PtAKF::GetNote(double* maxVolume, float* weights){ return _GetNote(AnaylsisBuf, maxVolume, weights); } -int PtAKF::_GetNote(float* samples, double* maxVolume, float* weights){ +void PtAKF::InitPeaks(SPeak peaks[_MaxPeaks]){ + for(int i = 0; i < _MaxPeaks; i++){ + peaks[i].toneIndex = -1; + peaks[i].weight = -9.f; + } +} + +void PtAKF::AddPeak(SPeak peaks[], float curWeight, int toneIndex){ + if(curWeight > peaks[0].weight){ + int i; + for(i = 1; i < _MaxPeaks; i++){ + if(curWeight < peaks[i].weight){ + peaks[i-1].toneIndex = toneIndex; + peaks[i-1].weight = curWeight; + break; + }else{ + peaks[i-1] = peaks[i]; + } + } + if(i == _MaxPeaks){ + peaks[i-1].toneIndex = toneIndex; + peaks[i-1].weight = curWeight; + } + } +} + +int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* restrict weights){ + // Calculate maximum volume + float maxVolumeL = 0; - for(int i = 0; i < _SampleCt; i++){ + for(int i = _SampleCt / 2; i < _SampleCt; i++){ float vol = abs(samples[i]); if(vol > maxVolumeL) maxVolumeL = vol; @@ -64,15 +108,14 @@ int PtAKF::_GetNote(float* samples, double* maxVolume, float* weights){ //maxVolumeL /= 32767.; *maxVolume = maxVolumeL; - //Scale the samples to have a peak of 1 to better decide between voiced/unvoiced - //float scaleVal = 1 / maxVolumeL; - //for(int i = 0; i < _SampleCt; i++){ - // samples[i] *= scaleVal; - //} + for(int i = 0; i < _SampleCt; i++){ + samples[i] *= _Window[i]; + } - float maxWeight = -1; - float minWeight = 1; - int maxTone = -1; + // Now analyze the samples and get peaks at the most appropriate tones + + SPeak peaks[_MaxPeaks]; + InitPeaks(peaks); //Attention: We have a peak at lag 0 that might stretch that far, that we detect a wrong "peak" at _MaxHalfTone //Because of that we filter out all tones that are past the last zero crossing from below but keep tones with decreasing weights (going towards zero crossing from above) @@ -80,16 +123,9 @@ int PtAKF::_GetNote(float* samples, double* maxVolume, float* weights){ float lastWeight = 1.f; for (int toneIndex = _MinHalfTone; toneIndex <= _MaxHalfTone; toneIndex++) { - float curWeight = _AnalyzeToneFunc(samples, toneIndex); + float curWeight = _AnalyzeByTone(samples, toneIndex); - if (curWeight > maxWeight) - { - maxWeight = curWeight; - maxTone = toneIndex; - } - - if (curWeight < minWeight) - minWeight = curWeight; + AddPeak(peaks, curWeight, toneIndex); weights[toneIndex - _MinHalfTone] = curWeight; @@ -99,54 +135,96 @@ int PtAKF::_GetNote(float* samples, double* maxVolume, float* weights){ lastWeight = curWeight; } - if(maxTone==_MaxHalfTone){ + // Now clear off the lag 0 peak if required + + if(peaks[_MaxPeaks - 1].toneIndex ==_MaxHalfTone){ //We might have caught the lag 0 peak so go a bit further to check for other zero crossings (or we won't be able to detect _MaxHalfTone) - float lastWeight = _FastAKF(samples, _SamplesPerPeriodPerTone[_MaxHalfTone]); + float lastWeight = _AKFByTone(samples, _MaxHalfTone); for(int toneIndex = _MaxHalfTone+1; toneIndex <= _MaxHalfTone + _HalfTonesAdd; toneIndex++){ - float curWeight = _FastAKF(samples, _SamplesPerPeriodPerTone[toneIndex]); + float curWeight = _AKFByTone(samples, toneIndex); if(lastWeight > curWeight || (lastWeight > 0.f && curWeight <= 0.f)){ lastValidTone = toneIndex - 1; break; } lastWeight = curWeight; } - if(lastValidTone < maxTone){ - maxWeight = -1.f; - minWeight = 1.f; + if(lastValidTone < peaks[_MaxPeaks - 1].toneIndex){ + InitPeaks(peaks); for(int toneIndex = _MinHalfTone; toneIndex <= lastValidTone; toneIndex++){ - float curWeight = weights[toneIndex-_MinHalfTone]; - if (curWeight > maxWeight) - { - maxWeight = curWeight; - maxTone = toneIndex; - } - - if (curWeight < minWeight) - minWeight = curWeight; + AddPeak(peaks, weights[toneIndex - _MinHalfTone], toneIndex); } //Set all invalid weights to 0 for(int toneIndex = lastValidTone + 1;toneIndex < _MaxHalfTone; toneIndex++){ - weights[toneIndex - _MinHalfTone]=0.f; + weights[toneIndex - _MinHalfTone] = 0.f; } } } - float energy = _FastAKF(samples, 0); - float maxAKF = _FastAKF(samples, _SamplesPerPeriodPerTone[maxTone]); - //printf("%g %g\n",energy, maxAKF); + // Further analyze the found peaks and find the real maximum + // This is necessary because we may have our real peak a bit off the exact tone frequency + // and a 'wrong' peak that is exactly at another tone which might become higher than the one at the 'right' tone + + int maxTone = peaks[_MaxPeaks - 1].toneIndex; + int maxToneFine = -1; + float maxWeight = peaks[_MaxPeaks - 1].weight; + for(int i = 0; i < _MaxPeaks; i++){ + int toneIndex = peaks[i].toneIndex; + float curWeightCenter = peaks[i].weight; + float curWeightDown = _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerToneFine[toneIndex * 2]); + float curWeight; + int otherToneIndex; + int otherToneFineIndex; + if(curWeightDown > curWeightCenter){ + otherToneIndex = toneIndex - 1; + otherToneFineIndex = 1; + curWeight = curWeightDown; + }else{ + float curWeightUp = _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerToneFine[toneIndex * 2 + 1]); + if(curWeightUp > curWeightCenter){ + otherToneIndex = (toneIndex < _MaxHalfTone)? toneIndex + 1: -1; // If the other tone is invalid just set it to -1 which will be skipped below + otherToneFineIndex = 0; + curWeight = curWeightUp; + }else + continue; + } + weights[toneIndex - _MinHalfTone] = curWeight; + if(curWeight > maxWeight){ + maxTone = toneIndex; + maxToneFine = 1 - otherToneFineIndex; + maxWeight = curWeight; + } + + // Now check also neighbouring tone + if(otherToneIndex > 0){ + float curWeightOther = _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerToneFine[otherToneIndex * 2 + otherToneFineIndex]); + if(curWeightOther > weights[otherToneIndex - _MinHalfTone]){ + weights[otherToneIndex - _MinHalfTone] = curWeightOther; + if(curWeightOther > maxWeight){ + maxTone = otherToneIndex; + maxToneFine = otherToneFineIndex; + maxWeight = curWeightOther; + } + } + } + } + + float energy = _AKFBySampleCt(samples, 0); + float maxAKF = (maxToneFine < 0) ? _AKFByTone(samples, maxTone):_AKFBySampleCt(samples, _SamplesPerPeriodPerToneFine[maxTone * 2 + maxToneFine]); + float aa = _AKFByTone(samples, maxTone); //if(maxWeight - minWeight > 0.025){ - if(maxAKF >= 0.3 * energy){ + if(maxAKF >= 0.4 * energy){ return maxTone; }else return -1; } -float PtAKF::_AnalyzeToneFunc(float* samples, int toneIndex){ - // Use method by Kobayashi and Shimamura (2001): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 +float PtAKF::_AnalyzeByTone(float* restrict samples, int toneIndex){ + return _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); +} - float samplesPerPeriodD = _SamplesPerPeriodPerTone[toneIndex]; // samples in one period +float PtAKF::_AnalyzeBySampleCt(float* restrict samples, float samplesPerPeriodD){ + // Use method by Kobayashi and Shimamura (2001): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 int samplesPerPeriod = static_cast(samplesPerPeriodD); - int maxSampleCt = static_cast(_SamplesPerPeriodPerTone[0]); float fHigh = samplesPerPeriodD - samplesPerPeriod; float fLow = 1.0f - fHigh; @@ -174,11 +252,13 @@ float PtAKF::_AnalyzeToneFunc(float* samples, int toneIndex){ //{toneIndex}: {accumDistAKF} ; {accumDistAMDF}; {result} } -float PtAKF::_FastAKF(float* samples, float samplesPerPeriodD){ - // Do a fast, non-scaled AKF (used for Lag 0 peak removal) +float PtAKF::_AKFByTone(float* restrict samples, int toneIndex){ + return _AKFBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); +} +float PtAKF::_AKFBySampleCt(float* restrict samples, float samplesPerPeriodD){ + // Do a fast, non-scaled AKF (used e.g. for Lag 0 peak removal) int samplesPerPeriod = static_cast(samplesPerPeriodD); - int maxSampleCt = static_cast(_SamplesPerPeriodPerTone[0]); float fHigh = samplesPerPeriodD - samplesPerPeriod; float fLow = 1.0f - fHigh; diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h index 6d5fd609..688e04d0 100644 --- a/PitchTracker/ptAKF.h +++ b/PitchTracker/ptAKF.h @@ -1,6 +1,23 @@ #pragma once #include "performous/pitch.hh" +#if __STDC__ != 1 +# define restrict __restrict +#else +# ifndef __STDC_VERSION__ +# define restrict __restrict +# else +# if __STDC_VERSION__ < 199901L +# define restrict __restrict +# endif +# endif +#endif + +struct SPeak{ + int toneIndex; + float weight; +}; + // A pitch detection that is based on the AKF and AMDF (initially from original Vocaluxe/USDx) class PtAKF{ public: @@ -12,20 +29,31 @@ public: _AnalysisBuf.insert(begin, end); } - int GetNote(double* maxVolume, float* weights); + int GetNote(double* restrict maxVolume, float* restrict weights); static int GetNumHalfTones(){ return _MaxHalfTone - _MinHalfTone + 1;} + private: static int _InitCount; - static float* _SamplesPerPeriodPerTone; + static float* restrict _SamplesPerPeriodPerTone; + // Use a 3 times finer resolution for exact peak detection + // So this array will store for each note the number of samples 1/3 below and up + // (cannot use halves as it would be ambiguous) + static float* restrict _SamplesPerPeriodPerToneFine; + static float* restrict _Window; static constexpr int _MinHalfTone = 0; //C2 static constexpr int _MaxHalfTone = 55;//47; //B5 static constexpr int _HalfTonesAdd = 4; //Additonal half tones to analyze to remove the peak at lag 0 + static constexpr int _MaxPeaks = 3; constexpr static size_t _SampleCt = 2048; RingBuffer<_SampleCt * 2> _AnalysisBuf; unsigned _Step; - static int _GetNote(float* samples, double* maxVolume, float* weights); - static float _AnalyzeToneFunc(float* samples, int toneIndex); - static float _FastAKF(float* samples, float samplesPerPeriodD); + static int _GetNote(float* restrict samples, double* restrict maxVolume, float* restrict weights); + static float _AnalyzeBySampleCt(float* restrict samples, float samplesPerPeriodD); + static inline float _AnalyzeByTone(float* restrict samples, int toneIndex); + static float _AKFBySampleCt(float* restrict samples, float samplesPerPeriodD); + static inline float _AKFByTone(float* restrict samples, int toneIndex); + static inline void InitPeaks(SPeak peaks[_MaxPeaks]); + static inline void AddPeak(SPeak peaks[_MaxPeaks], float curWeight, int toneIndex); }; \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs index e4e5807c..9f9529e3 100644 --- a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs +++ b/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs @@ -159,4 +159,69 @@ namespace Vocaluxe.Lib.Sound.Record GC.SuppressFinalize(this); } } + + /// + /// Pitchtracker (Pt) that uses a dynamic wavelet (DyWa) algorithm + /// Quite fast and perfect in artificial tests, but may fail in real world scenarios (e.g. missing fundamental) + /// + class CPtDyWa : IDisposable + { + #region Imports + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr PtDyWa_Create(uint step); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtDyWa_Free(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtDyWa_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int PtDyWa_Process(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern double PtDyWa_GetNote(IntPtr analyzer); + #endregion + + private IntPtr _Instance; + + public CPtDyWa(uint step = 200) + { + _Instance = PtDyWa_Create(step); + } + + ~CPtDyWa() + { + _Dispose(false); + } + + public void Input(byte[] data) + { + PtDyWa_InputByte(_Instance, data, data.Length / 2); + } + + public void Process() + { + PtDyWa_Process(_Instance); + } + + public double GetNote() + { + return PtDyWa_GetNote(_Instance); + } + + private void _Dispose(bool disposing) + { + if (_Instance == IntPtr.Zero) + throw new ObjectDisposedException(GetType().Name); + PtDyWa_Free(_Instance); + _Instance = IntPtr.Zero; + } + + public void Dispose() + { + _Dispose(true); + GC.SuppressFinalize(this); + } + } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 394af07b..2479c76a 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -38,7 +38,6 @@ namespace Vocaluxe.Lib.Sound.Record private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) #endif private CPtAKF _Analyzer = new CPtAKF(); - private CAnalyzer _Analyzer2 = new CAnalyzer(); private double _MaxVolume; @@ -98,12 +97,10 @@ namespace Vocaluxe.Lib.Sound.Record //if (assigned(fVoiceStream)) then //fVoiceStream.WriteData(Buffer, BufferSize); _Analyzer.Input(buffer); - _Analyzer2.Input(buffer); } public void AnalyzeBuffer() { - _Analyzer2.Process(); //_MaxVolume = _Analyzer.GetPeak() / 43 + 1; int tone = _Analyzer.GetNote(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // if (tone >= 0 && _MaxVolume >= MinVolume) @@ -136,6 +133,8 @@ namespace Vocaluxe.Lib.Sound.Record private static string _ToneToNote(int tone, bool withOctave = true) { + if (tone < 0) + return "inv."; tone += 24; string[] notes = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; string result = notes[tone % 12]; @@ -149,7 +148,7 @@ namespace Vocaluxe.Lib.Sound.Record if (_PitchTestRun) return; _PitchTestRun = true; - int toneFrom = 0; + const int toneFrom = 0; const int toneTo = -1; // 47; //B5 Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); byte[] data; @@ -185,7 +184,7 @@ namespace Vocaluxe.Lib.Sound.Record tests++; } } - if (_TestFile("toneG3.wav", 19)) + /*if (_TestFile("toneG3.wav", 19)) ok++; tests++; if (_TestFile("toneG3Miss.wav", 19)) @@ -193,9 +192,9 @@ namespace Vocaluxe.Lib.Sound.Record tests++; if (_TestFile("toneG4.wav", 31)) ok++; - tests++; - _TestFile("whistling3.wav", "whistling3.txt", ref tests, ref ok); + tests++;*/ _TestFile("sClausVoc.wav", "sClausVoc.txt", ref tests, ref ok); + _TestFile("whistling3.wav", "whistling3.txt", ref tests, ref ok); _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); Stopwatch sw = new Stopwatch(); @@ -271,35 +270,52 @@ namespace Vocaluxe.Lib.Sound.Record int samplesRead = 0; int curTimeIndex = -1; int curNote = -1; + int lastNote = -1; //It is ok not to detect a note change immediately so the old note is kept for a bit as ok + int lastNoteEndTime = 0; + const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples const int maxSamplesPerBatch = 512; - while (wavFile.NumSamplesLeft / wavFile.NumChannels > maxSamplesPerBatch) + CAnalyzer analyzer2 = new CAnalyzer(); + CPtDyWa analyzer3 = new CPtDyWa(); + while (wavFile.NumSamplesLeft > maxSamplesPerBatch) { byte[] samples = wavFile.GetNextSamples16BitAsBytes(maxSamplesPerBatch, 1); samplesRead += samples.Length / 2; int time = samplesRead * 1000 / wavFile.SampleRate; ProcessNewBuffer(samples); AnalyzeBuffer(); + analyzer2.Input(samples); + analyzer3.Input(samples); + analyzer2.Process(); + analyzer3.Process(); while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) { curTimeIndex++; + lastNote = curNote; + lastNoteEndTime = tones[curTimeIndex].Time; curNote = tones[curTimeIndex].Note; } if (curNote < 0) continue; - ct++; + if (lastNoteEndTime + lastNoteMaxTimeDiff < time) + lastNote = curNote; + int tone1 = ToneValid ? ToneAbs : -1; + int tone2 = (int)Math.Round(analyzer2.FindNote(64, 1770)); + int tone3 = (int)Math.Round(analyzer3.GetNote()); + /*ct++; if (!ToneValid) CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms not detected"); else if (ToneAbs % 12 != curNote % 12) CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(ToneAbs)); else - ok++; - int note2 = (int)Math.Round(_Analyzer2.FindNote()); - if (note2 < 0) - CBase.Log.LogDebug("Note2 " + _ToneToNote(curNote) + " at " + time + "ms not detected"); - else if (note2 % 12 != curNote % 12) - CBase.Log.LogDebug("Note2 " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(note2)); - else - ok++; + ok++;*/ + bool ok1 = tone1 == curNote || tone1 == lastNote; + bool ok2 = tone2 == curNote || tone2 == lastNote; + bool ok3 = tone3 == curNote || tone3 == lastNote; + if (!ok1 || !ok2 || !ok3) + { + CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms detected as " + _ToneToNote(tone1) + (ok1 ? "" : "(!)") + "; " + _ToneToNote(tone2) + + (ok2 ? "" : "(!)") + "; " + _ToneToNote(tone3) + (ok3 ? "" : "(!)") + "; "); + } } } catch (Exception e) diff --git a/VocaluxeLib/Utils/CWavFile.cs b/VocaluxeLib/Utils/CWavFile.cs index 7dea4478..9993ed24 100644 --- a/VocaluxeLib/Utils/CWavFile.cs +++ b/VocaluxeLib/Utils/CWavFile.cs @@ -14,11 +14,12 @@ namespace VocaluxeLib.Utils public string FileName { get; private set; } //Unless this is true, all fields are to be considered as invalid public int DataSize { get; private set; } - //Number of samples (=SampesPerChannel*NumChannels) + //Number of samples (per channel) public int NumSamples { - get { return (DataSize / (BitsPerSample / 8)); } + get { return (DataSize / (BitsPerSample / 8 * NumChannels)); } } + //Number of samples left to be read (per channel) public int NumSamplesLeft { get; private set; } public bool IsOpen { get; private set; } private int _DataPos; @@ -129,13 +130,12 @@ namespace VocaluxeLib.Utils { if (channel < 0 || channel > NumChannels || BitsPerSample != 8) return null; - int samplesPerBlock = (channel == 0 ? NumChannels : 1); - if (NumSamplesLeft < numSamples * samplesPerBlock) + if (numSamples > NumSamplesLeft) return null; byte[] result; BinaryReader reader = new BinaryReader(_File); if (channel == 0 || NumChannels == 1) - result = reader.ReadBytes(numSamples * samplesPerBlock); + result = reader.ReadBytes(numSamples * NumChannels); else { result = new byte[numSamples]; @@ -146,7 +146,7 @@ namespace VocaluxeLib.Utils _File.Seek(NumChannels - channel, SeekOrigin.Current); } } - NumSamplesLeft -= numSamples * samplesPerBlock; + NumSamplesLeft -= numSamples; return result; } @@ -160,8 +160,7 @@ namespace VocaluxeLib.Utils { if (channel < 0 || channel > NumChannels || BitsPerSample != 16) return null; - int samplesPerBlock = (channel == 0 ? NumChannels : 1); - if (NumSamplesLeft < numSamples * samplesPerBlock) + if (numSamples > NumSamplesLeft) return null; short[] result; BinaryReader reader = new BinaryReader(_File); @@ -183,7 +182,7 @@ namespace VocaluxeLib.Utils _File.Seek((NumChannels - channel) * 2, SeekOrigin.Current); } } - NumSamplesLeft -= numSamples * samplesPerBlock; + NumSamplesLeft -= numSamples; } catch (EndOfStreamException e) { From be6a40aa1d2eec1f65ef8ef50e9a0790d722978a Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 12 Apr 2014 14:03:10 +0200 Subject: [PATCH 23/34] Use window function Update reference notes Improve comparison --- PitchTracker/TestSounds.rar | Bin 840777 -> 840954 bytes PitchTracker/ptAKF.cpp | 140 ++++++++++++++++----------- PitchTracker/ptAKF.h | 10 +- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 31 +++--- 4 files changed, 108 insertions(+), 73 deletions(-) diff --git a/PitchTracker/TestSounds.rar b/PitchTracker/TestSounds.rar index 463321f4f86fef1b6f471e439bcc5a0f16fe9d5d..7dd70d57103cc09683f6ca47483abd7539590d5e 100644 GIT binary patch delta 94828 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 Wf&MI*&w~9dxX*%bMw3A}{P{mNJO#x7 diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index be84893b..f5f95bf7 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -108,24 +108,26 @@ int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* //maxVolumeL /= 32767.; *maxVolume = maxVolumeL; + float samplesWindowed[_SampleCt]; + for(int i = 0; i < _SampleCt; i++){ - samples[i] *= _Window[i]; + samplesWindowed[i] = samples[i] * _Window[i]; } // Now analyze the samples and get peaks at the most appropriate tones - SPeak peaks[_MaxPeaks]; - InitPeaks(peaks); - //Attention: We have a peak at lag 0 that might stretch that far, that we detect a wrong "peak" at _MaxHalfTone //Because of that we filter out all tones that are past the last zero crossing from below but keep tones with decreasing weights (going towards zero crossing from above) int lastValidTone = 0; float lastWeight = 1.f; + float maxWeight = 0.f; for (int toneIndex = _MinHalfTone; toneIndex <= _MaxHalfTone; toneIndex++) { - float curWeight = _AnalyzeByTone(samples, toneIndex); + float curWeight = _AnalyzeByTone(samples, samplesWindowed, toneIndex); - AddPeak(peaks, curWeight, toneIndex); + if(curWeight > maxWeight){ + maxWeight = curWeight; + } weights[toneIndex - _MinHalfTone] = curWeight; @@ -137,7 +139,7 @@ int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* // Now clear off the lag 0 peak if required - if(peaks[_MaxPeaks - 1].toneIndex ==_MaxHalfTone){ + if(maxWeight >= weights[_MaxHalfTone]){ //We might have caught the lag 0 peak so go a bit further to check for other zero crossings (or we won't be able to detect _MaxHalfTone) float lastWeight = _AKFByTone(samples, _MaxHalfTone); for(int toneIndex = _MaxHalfTone+1; toneIndex <= _MaxHalfTone + _HalfTonesAdd; toneIndex++){ @@ -148,40 +150,57 @@ int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* } lastWeight = curWeight; } - if(lastValidTone < peaks[_MaxPeaks - 1].toneIndex){ - InitPeaks(peaks); - for(int toneIndex = _MinHalfTone; toneIndex <= lastValidTone; toneIndex++){ - AddPeak(peaks, weights[toneIndex - _MinHalfTone], toneIndex); - } - //Set all invalid weights to 0 - for(int toneIndex = lastValidTone + 1;toneIndex < _MaxHalfTone; toneIndex++){ - weights[toneIndex - _MinHalfTone] = 0.f; - } + //Set all invalid weights to 0 + for(int toneIndex = lastValidTone + 1;toneIndex < _MaxHalfTone; toneIndex++){ + weights[toneIndex - _MinHalfTone] = 0.f; } } + SPeak peaks[_MaxPeaks]; + InitPeaks(peaks); + int numPeaks = 0; + bool up = true; + for(int i = _MinHalfTone + 1; i <= _MaxHalfTone; i++){ + if(weights[i-1] > weights[i]){ + if(up){ + AddPeak(peaks, weights[i - 1 - _MinHalfTone], i - 1); + numPeaks++; + up = false; + } + }else if(!up){ + up = true; + } + } + if(up){ + AddPeak(peaks, weights[_MaxHalfTone - _MinHalfTone], _MaxHalfTone); + numPeaks++; + } + if(numPeaks > _MaxPeaks) + numPeaks = _MaxPeaks; + // Further analyze the found peaks and find the real maximum // This is necessary because we may have our real peak a bit off the exact tone frequency // and a 'wrong' peak that is exactly at another tone which might become higher than the one at the 'right' tone - int maxTone = peaks[_MaxPeaks - 1].toneIndex; + int maxTone = peaks[_MaxPeaks-1].toneIndex; int maxToneFine = -1; - float maxWeight = peaks[_MaxPeaks - 1].weight; - for(int i = 0; i < _MaxPeaks; i++){ + maxWeight = peaks[_MaxPeaks-1].weight; + for(int i = _MaxPeaks - numPeaks; i < _MaxPeaks; i++){ + float curWeight = peaks[i].weight; + if(curWeight * 3.f < maxWeight) + continue; int toneIndex = peaks[i].toneIndex; - float curWeightCenter = peaks[i].weight; - float curWeightDown = _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerToneFine[toneIndex * 2]); - float curWeight; + float curWeightDown = _AnalyzeBySampleCt(samples, samplesWindowed, _SamplesPerPeriodPerToneFine[toneIndex * 2]); int otherToneIndex; int otherToneFineIndex; - if(curWeightDown > curWeightCenter){ + if(curWeightDown > curWeight){ otherToneIndex = toneIndex - 1; otherToneFineIndex = 1; curWeight = curWeightDown; }else{ - float curWeightUp = _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerToneFine[toneIndex * 2 + 1]); - if(curWeightUp > curWeightCenter){ - otherToneIndex = (toneIndex < _MaxHalfTone)? toneIndex + 1: -1; // If the other tone is invalid just set it to -1 which will be skipped below + float curWeightUp = _AnalyzeBySampleCt(samples, samplesWindowed, _SamplesPerPeriodPerToneFine[toneIndex * 2 + 1]); + if(curWeightUp > curWeight){ + otherToneIndex = (toneIndex < _MaxHalfTone) ? toneIndex + 1: -1; // If the other tone is invalid just set it to -1 which will be skipped below otherToneFineIndex = 0; curWeight = curWeightUp; }else @@ -196,7 +215,7 @@ int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* // Now check also neighbouring tone if(otherToneIndex > 0){ - float curWeightOther = _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerToneFine[otherToneIndex * 2 + otherToneFineIndex]); + float curWeightOther = _AnalyzeBySampleCt(samples, samplesWindowed, _SamplesPerPeriodPerToneFine[otherToneIndex * 2 + otherToneFineIndex]); if(curWeightOther > weights[otherToneIndex - _MinHalfTone]){ weights[otherToneIndex - _MinHalfTone] = curWeightOther; if(curWeightOther > maxWeight){ @@ -209,45 +228,26 @@ int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* } float energy = _AKFBySampleCt(samples, 0); - float maxAKF = (maxToneFine < 0) ? _AKFByTone(samples, maxTone):_AKFBySampleCt(samples, _SamplesPerPeriodPerToneFine[maxTone * 2 + maxToneFine]); - float aa = _AKFByTone(samples, maxTone); + float maxAKF = (maxToneFine < 0) ? _AKFByTone(samples, maxTone) : _AKFBySampleCt(samples, _SamplesPerPeriodPerToneFine[maxTone * 2 + maxToneFine]); //if(maxWeight - minWeight > 0.025){ - if(maxAKF >= 0.4 * energy){ + if(maxAKF >= 0.35f * energy){ return maxTone; }else return -1; } -float PtAKF::_AnalyzeByTone(float* restrict samples, int toneIndex){ - return _AnalyzeBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); +float PtAKF::_AnalyzeByTone(float* restrict samples, float* restrict samplesWindowed, int toneIndex){ + return _AnalyzeBySampleCt(samples, samplesWindowed, _SamplesPerPeriodPerTone[toneIndex]); } -float PtAKF::_AnalyzeBySampleCt(float* restrict samples, float samplesPerPeriodD){ +float PtAKF::_AnalyzeBySampleCt(float* restrict samples, float* restrict samplesWindowed, float samplesPerPeriodD){ // Use method by Kobayashi and Shimamura (2001): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 - int samplesPerPeriod = static_cast(samplesPerPeriodD); - float fHigh = samplesPerPeriodD - samplesPerPeriod; - float fLow = 1.0f - fHigh; - float accumDistAKF = 0; // accumulated distances - float accumDistAMDF = 0; // accumulated distances - - // compare correlating samples - int sampleIndex = 0; // index of sample to analyze - // Start value= index of sample one period ahead - for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _SampleCt; correlatingSampleIndex++, sampleIndex++) - { - // calc distance to corresponding sample in next period - float xn = samples[sampleIndex]; - float xnt = samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh; - accumDistAKF += xn * xnt; - accumDistAMDF += abs(xn - xnt); - } - - accumDistAKF /= _SampleCt; - accumDistAMDF /= sampleIndex; + float akf = _AKFBySampleCt(samplesWindowed, samplesPerPeriodD); + float amdf = _AMDFBySampleCt(samples, samplesPerPeriodD); //return accumDistAKF / (accumDistAMDF * 32767.f + 32767.f * 32767.f); // Need to scale AKF by MAX^2 and AMDF by MAX, so do some maths to divide only once - float result = accumDistAKF / (accumDistAMDF + 1.f); + float result = akf / (amdf + 1.f); return result; // Need to scale AKF by MAX^2 and AMDF by MAX, so do some maths to divide only once //{toneIndex}: {accumDistAKF} ; {accumDistAMDF}; {result} } @@ -257,12 +257,11 @@ float PtAKF::_AKFByTone(float* restrict samples, int toneIndex){ } float PtAKF::_AKFBySampleCt(float* restrict samples, float samplesPerPeriodD){ - // Do a fast, non-scaled AKF (used e.g. for Lag 0 peak removal) int samplesPerPeriod = static_cast(samplesPerPeriodD); float fHigh = samplesPerPeriodD - samplesPerPeriod; float fLow = 1.0f - fHigh; - float accumDistAKF = 0; // accumulated distances + float accumDist = 0; // accumulated distances // compare correlating samples int sampleIndex = 0; // index of sample to analyze @@ -272,10 +271,35 @@ float PtAKF::_AKFBySampleCt(float* restrict samples, float samplesPerPeriodD){ // calc distance to corresponding sample in next period float xn = samples[sampleIndex]; float xnt = samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh; - accumDistAKF += xn * xnt; + accumDist += xn * xnt; } - return accumDistAKF; + return accumDist / _SampleCt; +} + +float PtAKF::_AMDFByTone(float* restrict samples, int toneIndex){ + return _AKFBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); +} + +float PtAKF::_AMDFBySampleCt(float* restrict samples, float samplesPerPeriodD){ + int samplesPerPeriod = static_cast(samplesPerPeriodD); + float fHigh = samplesPerPeriodD - samplesPerPeriod; + float fLow = 1.0f - fHigh; + + float accumDist = 0; // accumulated distances + + // compare correlating samples + int sampleIndex = 0; // index of sample to analyze + // Start value= index of sample one period ahead + for (int correlatingSampleIndex = sampleIndex + samplesPerPeriod; correlatingSampleIndex + 1 < _SampleCt; correlatingSampleIndex++, sampleIndex++) + { + // calc distance to corresponding sample in next period + float xn = samples[sampleIndex]; + float xnt = samples[correlatingSampleIndex] * fLow + samples[correlatingSampleIndex + 1] * fHigh; + accumDist += abs(xn - xnt); + } + + return accumDist / sampleIndex; } /* diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h index 688e04d0..02a2baf2 100644 --- a/PitchTracker/ptAKF.h +++ b/PitchTracker/ptAKF.h @@ -41,19 +41,21 @@ private: static float* restrict _SamplesPerPeriodPerToneFine; static float* restrict _Window; static constexpr int _MinHalfTone = 0; //C2 - static constexpr int _MaxHalfTone = 55;//47; //B5 + static constexpr int _MaxHalfTone = 56;//47; //B5 static constexpr int _HalfTonesAdd = 4; //Additonal half tones to analyze to remove the peak at lag 0 - static constexpr int _MaxPeaks = 3; + static constexpr int _MaxPeaks = 10; constexpr static size_t _SampleCt = 2048; RingBuffer<_SampleCt * 2> _AnalysisBuf; unsigned _Step; static int _GetNote(float* restrict samples, double* restrict maxVolume, float* restrict weights); - static float _AnalyzeBySampleCt(float* restrict samples, float samplesPerPeriodD); - static inline float _AnalyzeByTone(float* restrict samples, int toneIndex); + static float _AnalyzeBySampleCt(float* restrict samples, float* restrict samplesWindowed, float samplesPerPeriodD); + static inline float _AnalyzeByTone(float* restrict samples, float* restrict samplesWindowed, int toneIndex); static float _AKFBySampleCt(float* restrict samples, float samplesPerPeriodD); static inline float _AKFByTone(float* restrict samples, int toneIndex); + static float _AMDFBySampleCt(float* restrict samples, float samplesPerPeriodD); + static inline float _AMDFByTone(float* restrict samples, int toneIndex); static inline void InitPeaks(SPeak peaks[_MaxPeaks]); static inline void AddPeak(SPeak peaks[_MaxPeaks], float curWeight, int toneIndex); }; \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 2479c76a..df6284a3 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -193,8 +193,8 @@ namespace Vocaluxe.Lib.Sound.Record if (_TestFile("toneG4.wav", 31)) ok++; tests++;*/ - _TestFile("sClausVoc.wav", "sClausVoc.txt", ref tests, ref ok); _TestFile("whistling3.wav", "whistling3.txt", ref tests, ref ok); + _TestFile("sClausVoc.wav", "sClausVoc.txt", ref tests, ref ok); _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); Stopwatch sw = new Stopwatch(); @@ -255,6 +255,22 @@ namespace Vocaluxe.Lib.Sound.Record return ok >= ct - 4; } + private bool _IsNoteValid(int note, int time, IList tones) + { + const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples + for (int i = 0; i < tones.Count; i++) + { + if (tones[i].Time > time) + break; + if (i + 1 == tones.Count || time <= tones[i + 1].Time + lastNoteMaxTimeDiff) + { + if (tones[i].Note == note) + return true; + } + } + return false; + } + private void _TestFile(string fileName, IList tones, ref int ct, ref int ok) { CWavFile wavFile = new CWavFile(); @@ -270,9 +286,6 @@ namespace Vocaluxe.Lib.Sound.Record int samplesRead = 0; int curTimeIndex = -1; int curNote = -1; - int lastNote = -1; //It is ok not to detect a note change immediately so the old note is kept for a bit as ok - int lastNoteEndTime = 0; - const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples const int maxSamplesPerBatch = 512; CAnalyzer analyzer2 = new CAnalyzer(); CPtDyWa analyzer3 = new CPtDyWa(); @@ -290,14 +303,10 @@ namespace Vocaluxe.Lib.Sound.Record while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) { curTimeIndex++; - lastNote = curNote; - lastNoteEndTime = tones[curTimeIndex].Time; curNote = tones[curTimeIndex].Note; } if (curNote < 0) continue; - if (lastNoteEndTime + lastNoteMaxTimeDiff < time) - lastNote = curNote; int tone1 = ToneValid ? ToneAbs : -1; int tone2 = (int)Math.Round(analyzer2.FindNote(64, 1770)); int tone3 = (int)Math.Round(analyzer3.GetNote()); @@ -308,9 +317,9 @@ namespace Vocaluxe.Lib.Sound.Record CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(ToneAbs)); else ok++;*/ - bool ok1 = tone1 == curNote || tone1 == lastNote; - bool ok2 = tone2 == curNote || tone2 == lastNote; - bool ok3 = tone3 == curNote || tone3 == lastNote; + bool ok1 = _IsNoteValid(tone1, time, tones); + bool ok2 = _IsNoteValid(tone2, time, tones); + bool ok3 = _IsNoteValid(tone3, time, tones); if (!ok1 || !ok2 || !ok3) { CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms detected as " + _ToneToNote(tone1) + (ok1 ? "" : "(!)") + "; " + _ToneToNote(tone2) + From 5f79406cf2c611aab714f90ca9f26dab1a95ba1c Mon Sep 17 00:00:00 2001 From: Flamefire Date: Tue, 15 Apr 2014 14:23:32 +0200 Subject: [PATCH 24/34] Add another pitch tracker and compare all 4 --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 47 +- .../Lib/Sound/Record/Pitch/CircularBuffer.cs | 176 +++++ Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs | 108 +++ Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs | 616 ++++++++++++++++++ Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs | 577 ++++++++++++++++ .../Lib/Sound/Record/Pitch/PitchTracker.cs | 414 ++++++++++++ Vocaluxe/Vocaluxe.csproj | 5 + 7 files changed, 1932 insertions(+), 11 deletions(-) create mode 100644 Vocaluxe/Lib/Sound/Record/Pitch/CircularBuffer.cs create mode 100644 Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs create mode 100644 Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs create mode 100644 Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs create mode 100644 Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index df6284a3..755aa118 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -23,6 +23,7 @@ using System.Collections.Generic; using System.IO; using System.Windows.Forms; using System.Diagnostics; +using Pitch; using VocaluxeLib; using VocaluxeLib.Utils; @@ -289,6 +290,10 @@ namespace Vocaluxe.Lib.Sound.Record const int maxSamplesPerBatch = 512; CAnalyzer analyzer2 = new CAnalyzer(); CPtDyWa analyzer3 = new CPtDyWa(); + PitchTracker analyzer4 = new PitchTracker {SampleRate = 44100, DetectLevelThreshold = 0.001f}; + int[] detectedTones = new int[4]; + int[] oks = new int[4]; + int lCt = 0; while (wavFile.NumSamplesLeft > maxSamplesPerBatch) { byte[] samples = wavFile.GetNextSamples16BitAsBytes(maxSamplesPerBatch, 1); @@ -300,6 +305,12 @@ namespace Vocaluxe.Lib.Sound.Record analyzer3.Input(samples); analyzer2.Process(); analyzer3.Process(); + short[] samplesShort = new short[samples.Length / 2]; + Buffer.BlockCopy(samples, 0, samplesShort, 0, samples.Length); + float[] samplesFloat = new float[samplesShort.Length]; + for (int i = 0; i < samplesShort.Length; i++) + samplesFloat[i] = (float)samplesShort[i] / short.MaxValue; + analyzer4.ProcessBuffer(samplesFloat); while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) { curTimeIndex++; @@ -307,25 +318,39 @@ namespace Vocaluxe.Lib.Sound.Record } if (curNote < 0) continue; - int tone1 = ToneValid ? ToneAbs : -1; - int tone2 = (int)Math.Round(analyzer2.FindNote(64, 1770)); - int tone3 = (int)Math.Round(analyzer3.GetNote()); - /*ct++; - if (!ToneValid) + detectedTones[0] = ToneValid ? ToneAbs : -1; + detectedTones[1] = (int)Math.Round(analyzer2.FindNote(64, 1770)); + detectedTones[2] = (int)Math.Round(analyzer3.GetNote()); + detectedTones[3] = analyzer4.CurrentPitchRecord.MidiNote - 15 - 21; + lCt++; + /*if (!ToneValid) CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms not detected"); else if (ToneAbs % 12 != curNote % 12) CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(ToneAbs)); else ok++;*/ - bool ok1 = _IsNoteValid(tone1, time, tones); - bool ok2 = _IsNoteValid(tone2, time, tones); - bool ok3 = _IsNoteValid(tone3, time, tones); - if (!ok1 || !ok2 || !ok3) + bool[] valids = new bool[4]; + bool error = false; + for (int i = 0; i < 4; i++) { - CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms detected as " + _ToneToNote(tone1) + (ok1 ? "" : "(!)") + "; " + _ToneToNote(tone2) + - (ok2 ? "" : "(!)") + "; " + _ToneToNote(tone3) + (ok3 ? "" : "(!)") + "; "); + valids[i] = _IsNoteValid(detectedTones[i], time, tones); + if (valids[i]) + oks[i]++; + else + error = true; + } + if (error) + { + string msg = "Note " + _ToneToNote(curNote) + " at " + time + "ms detected as "; + for (int i = 0; i < 4; i++) + msg += _ToneToNote(detectedTones[i]) + (valids[i] ? "" : "(!)") + "; "; + CBase.Log.LogDebug(msg); } } + string msg2 = "Detected "; + for (int i = 0; i < 4; i++) + msg2 += oks[i] + "|" + (lCt - oks[i]) + " "; + CBase.Log.LogDebug(msg2); } catch (Exception e) { diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/CircularBuffer.cs b/Vocaluxe/Lib/Sound/Record/Pitch/CircularBuffer.cs new file mode 100644 index 00000000..d784e2df --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/Pitch/CircularBuffer.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; + +namespace Pitch +{ + public class CircularBuffer : IDisposable + { + int m_bufSize; + int m_begBufOffset; + int m_availBuf; + long m_startPos; // total circular buffer position + T[] m_buffer; + + ///

+ /// Constructor + /// + public CircularBuffer() + { + } + + /// + /// Constructor + /// + /// + public CircularBuffer(int bufCount) + { + SetSize(bufCount); + } + + /// + /// Dispose + /// + public void Dispose() + { + SetSize(0); + } + + /// + /// Reset to the beginning of the buffer + /// + public void Reset() + { + m_begBufOffset = 0; + m_availBuf = 0; + m_startPos = 0; + } + + /// + /// Set the buffer to the specified size + /// + /// + public void SetSize(int newSize) + { + Reset(); + + if (m_bufSize == newSize) + return; + + if (m_buffer != null) + m_buffer = null; + + m_bufSize = newSize; + + if (m_bufSize > 0) + m_buffer = new T[m_bufSize]; + } + + /// + /// Clear the buffer + /// + public void Clear() + { + Array.Clear(m_buffer, 0, m_buffer.Length); + } + + /// + /// Get or set the start position + /// + public long StartPosition + { + get { return m_startPos; } + set { m_startPos = value; } + } + + /// + /// Get the end position + /// + public long EndPosition + { + get { return m_startPos + m_availBuf; } + } + + /// + /// Get or set the amount of avaliable space + /// + public int Available + { + get { return m_availBuf; } + set { m_availBuf = Math.Min(value, m_bufSize); } + } + + /// + /// Write data into the buffer + /// + /// + /// + /// + public int WriteBuffer(T[] m_pInBuffer, int count) + { + count = Math.Min(count, m_bufSize); + + var startPos = m_availBuf != m_bufSize ? m_availBuf : m_begBufOffset; + var pass1Count = Math.Min(count, m_bufSize - startPos); + var pass2Count = count - pass1Count; + + PitchDsp.CopyBuffer(m_pInBuffer, 0, m_buffer, startPos, pass1Count); + + if (pass2Count > 0) + PitchDsp.CopyBuffer(m_pInBuffer, pass1Count, m_buffer, 0, pass2Count); + + if (pass2Count == 0) + { + // did not wrap around + if (m_availBuf != m_bufSize) + m_availBuf += count; // have never wrapped around + else + { + m_begBufOffset += count; + m_startPos += count; + } + } + else + { + // wrapped around + if (m_availBuf != m_bufSize) + m_startPos += pass2Count; // first time wrap-around + else + m_startPos += count; + + m_begBufOffset = pass2Count; + m_availBuf = m_bufSize; + } + + return count; + } + + /// + /// Read from the buffer + /// + /// + /// + /// + /// + public bool ReadBuffer(T[] outBuffer, long startRead, int readCount) + { + var endRead = (int)(startRead + readCount); + var endAvail = (int)(m_startPos + m_availBuf); + + if (startRead < m_startPos || endRead > endAvail) + return false; + + var startReadPos = (int)(((startRead - m_startPos) + m_begBufOffset) % m_bufSize); + var block1Samples = Math.Min(readCount, m_bufSize - startReadPos); + var block2Samples = readCount - block1Samples; + + PitchDsp.CopyBuffer(m_buffer, startReadPos, outBuffer, 0, block1Samples); + + if (block2Samples > 0) + PitchDsp.CopyBuffer(m_buffer, 0, outBuffer, block1Samples, block2Samples); + + return true; + } + } +} diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs b/Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs new file mode 100644 index 00000000..2487ea18 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Pitch +{ + public static class Extensions + { + /// + /// Clear the buffer + /// + /// + /// + static public void Clear(this float[] buffer) + { + Array.Clear(buffer, 0, buffer.Length); + } + + /// + /// Clear the buffer + /// + /// + /// + static public void Clear(this double[] buffer) + { + Array.Clear(buffer, 0, buffer.Length); + } + + /// + /// Copy the values from one buffer to a different or the same buffer. + /// It is safe to copy to the same buffer, even if the areas overlap + /// + /// + /// + /// + /// + static public void Copy(this float[] fromBuffer, float[] toBuffer, int fromStart, int toStart, int length) + { + if (toBuffer == null || fromBuffer.Length == 0 || toBuffer.Length == 0) + return; + + var fromBegIdx = fromStart; + var fromEndIdx = fromStart + length; + var toBegIdx = toStart; + var toEndIdx = toStart + length; + + if (fromBegIdx < 0) + { + toBegIdx -= fromBegIdx; + fromBegIdx = 0; + } + + if (toBegIdx < 0) + { + fromBegIdx -= toBegIdx; + toBegIdx = 0; + } + + if (fromEndIdx >= fromBuffer.Length) + { + toEndIdx -= fromEndIdx - fromBuffer.Length + 1; + fromEndIdx = fromBuffer.Length - 1; + } + + if (toEndIdx >= toBuffer.Length) + { + fromEndIdx -= toEndIdx - toBuffer.Length + 1; + toEndIdx = fromBuffer.Length - 1; + } + + if (fromBegIdx < toBegIdx) + { + // Shift right, so start at the right + for (int fromIdx = fromEndIdx, toIdx = toEndIdx; fromIdx >= fromBegIdx; fromIdx--, toIdx--) + toBuffer[toIdx] = fromBuffer[fromIdx]; + } + else + { + // Shift left, so start at the left + for (int fromIdx = fromBegIdx, toIdx = toBegIdx; fromIdx <= fromEndIdx; fromIdx++, toIdx++) + toBuffer[toIdx] = fromBuffer[fromIdx]; + } + } + + /// + /// + /// + /// + /// + static public void Clear(this float[] buffer, int startIdx, int endIdx) + { + Array.Clear(buffer, startIdx, endIdx - startIdx + 1); + } + + /// + /// Fill the buffer with the specified value + /// + /// + /// + /// + static public void Fill(this double[] buffer, double value) + { + for (int idx = 0; idx < buffer.Length; idx++) + buffer[idx] = value; + } + } +} diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs b/Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs new file mode 100644 index 00000000..8759c77e --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs @@ -0,0 +1,616 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Pitch +{ + /// + /// Infinite impulse response filter (old style analog filters) + /// + class IIRFilter + { + /// + /// The type of filter + /// + public enum FilterType + { + None = 0, + LP, + HP, + BP + } + + /// + /// The filter prototype + /// + public enum ProtoType + { + None = 0, + Butterworth, + Chebyshev, + } + + const int kHistMask = 31; + const int kHistSize = 32; + + private int m_order; + private ProtoType m_protoType; + private FilterType m_filterType; + + private float m_fp1; + private float m_fp2; + private float m_fN; + private float m_ripple; + private float m_sampleRate; + private double[] m_real; + private double[] m_imag; + private double[] m_z; + private double[] m_aCoeff; + private double[] m_bCoeff; + private double[] m_inHistory; + private double[] m_outHistory; + private int m_histIdx; + private bool m_invertDenormal; + + public IIRFilter() + { + } + + /// + /// Returns true if all the filter parameters are valid + /// + public bool FilterValid + { + get + { + if (m_order < 1 || m_order > 16 || + m_protoType == ProtoType.None || + m_filterType == FilterType.None || + m_sampleRate <= 0.0f || + m_fN <= 0.0f) + return false; + + switch (m_filterType) + { + case FilterType.LP: + if (m_fp2 <= 0.0f) + return false; + break; + + case FilterType.BP: + if (m_fp1 <= 0.0f || m_fp2 <= 0.0f || m_fp1 >= m_fp2) + return false; + break; + + case FilterType.HP: + if (m_fp1 <= 0.0f) + return false; + break; + } + + // For bandpass, the order must be even + if (m_filterType == FilterType.BP && (m_order & 1) != 0) + return false; + + return true; + } + } + + /// + /// Set the filter prototype + /// + public ProtoType Proto + { + get { return m_protoType; } + + set + { + m_protoType = value; + Design(); + } + } + + /// + /// Set the filter type + /// + public FilterType Type + { + get { return m_filterType; } + + set + { + m_filterType = value; + Design(); + } + } + + public int Order + { + get { return m_order; } + + set + { + m_order = Math.Min(16, Math.Max(1, Math.Abs(value))); + + if (m_filterType == FilterType.BP && Odd(m_order)) + m_order++; + + Design(); + } + } + + public float SampleRate + { + get { return m_sampleRate; } + + set + { + m_sampleRate = value; + m_fN = 0.5f * m_sampleRate; + Design(); + } + } + + public float FreqLow + { + get { return m_fp1; } + + set + { + m_fp1 = value; + Design(); + } + } + + public float FreqHigh + { + get { return m_fp2; } + + set + { + m_fp2 = value; + Design(); + } + } + + public float Ripple + { + get { return m_ripple; } + + set + { + m_ripple = value; + Design(); + } + } + + /// + /// Returns true if n is odd + /// + /// + /// + private bool Odd(int n) + { + return (n & 1) == 1; + } + + /// + /// Square + /// + /// + /// + private float Sqr(float value) + { + return value * value; + } + + /// + /// Square + /// + /// + /// + private double Sqr(double value) + { + return value * value; + } + + /// + /// Determines poles and zeros of IIR filter + /// based on bilinear transform method + /// + private void LocatePolesAndZeros() + { + m_real = new double[m_order + 1]; + m_imag = new double[m_order + 1]; + m_z = new double[m_order + 1]; + double ln10 = Math.Log(10.0); + + // Butterworth, Chebyshev parameters + int n = m_order; + + if (m_filterType == FilterType.BP) + n = n / 2; + + int ir = n % 2; + int n1 = n + ir; + int n2 = (3 * n + ir) / 2 - 1; + double f1; + + switch (m_filterType) + { + case FilterType.LP: + f1 = m_fp2; + break; + + case FilterType.HP: + f1 = m_fN - m_fp1; + break; + + case FilterType.BP: + f1 = m_fp2 - m_fp1; + break; + + default: + f1 = 0.0; + break; + } + + double tanw1 = Math.Tan(0.5 * Math.PI * f1 / m_fN); + double tansqw1 = Sqr(tanw1); + + // Real and Imaginary parts of low-pass poles + double t, a = 1.0, r = 1.0, i = 1.0; + + for (int k = n1; k <= n2; k++) + { + t = 0.5 * (2 * k + 1 - ir) * Math.PI / (double)n; + + switch (m_protoType) + { + case ProtoType.Butterworth: + double b3 = 1.0 - 2.0 * tanw1 * Math.Cos(t) + tansqw1; + r = (1.0 - tansqw1) / b3; + i = 2.0 * tanw1 * Math.Sin(t) / b3; + break; + + case ProtoType.Chebyshev: + double d = 1.0 - Math.Exp(-0.05 * m_ripple * ln10); + double e = 1.0 / Math.Sqrt(1.0 / Sqr(1.0 - d) - 1.0); + double x = Math.Pow(Math.Sqrt(e * e + 1.0) + e, 1.0 / (double)n); + a = 0.5 * (x - 1.0 / x); + double b = 0.5 * (x + 1.0 / x); + double c3 = a * tanw1 * Math.Cos(t); + double c4 = b * tanw1 * Math.Sin(t); + double c5 = Sqr(1.0 - c3) + Sqr(c4); + r = 2.0 * (1.0 - c3) / c5 - 1.0; + i = 2.0 * c4 / c5; + break; + } + + int m = 2 * (n2 - k) + 1; + m_real[m + ir] = r; + m_imag[m + ir] = Math.Abs(i); + m_real[m + ir + 1] = r; + m_imag[m + ir + 1] = -Math.Abs(i); + } + + if (Odd(n)) + { + if (m_protoType == ProtoType.Butterworth) + r = (1.0 - tansqw1) / (1.0 + 2.0 * tanw1 + tansqw1); + + if (m_protoType == ProtoType.Chebyshev) + r = 2.0 / (1.0 + a * tanw1) - 1.0; + + m_real[1] = r; + m_imag[1] = 0.0; + } + + switch (m_filterType) + { + case FilterType.LP: + for (int m = 1; m <= n; m++) + m_z[m] = -1.0; + break; + + case FilterType.HP: + // Low-pass to high-pass transformation + for (int m = 1; m <= n; m++) + { + m_real[m] = -m_real[m]; + m_z[m] = 1.0; + } + break; + + case FilterType.BP: + // Low-pass to bandpass transformation + for (int m = 1; m <= n; m++) + { + m_z[m] = 1.0; + m_z[m + n] = -1.0; + } + + double f4 = 0.5 * Math.PI * m_fp1 / m_fN; + double f5 = 0.5 * Math.PI * m_fp2 / m_fN; + double aa = Math.Cos(f4 + f5) / Math.Cos(f5 - f4); + double aR, aI, h1, h2, p1R, p2R, p1I, p2I; + + for (int m1 = 0; m1 <= (m_order - 1) / 2; m1++) + { + int m = 1 + 2 * m1; + aR = m_real[m]; + aI = m_imag[m]; + + if (Math.Abs(aI) < 0.0001) + { + h1 = 0.5 * aa * (1.0 + aR); + h2 = Sqr(h1) - aR; + if (h2 > 0.0) + { + p1R = h1 + Math.Sqrt(h2); + p2R = h1 - Math.Sqrt(h2); + p1I = 0.0; + p2I = 0.0; + } + else + { + p1R = h1; + p2R = h1; + p1I = Math.Sqrt(Math.Abs(h2)); + p2I = -p1I; + } + } + else + { + double fR = aa * 0.5 * (1.0 + aR); + double fI = aa * 0.5 * aI; + double gR = Sqr(fR) - Sqr(fI) - aR; + double gI = 2 * fR * fI - aI; + double sR = Math.Sqrt(0.5 * Math.Abs(gR + Math.Sqrt(Sqr(gR) + Sqr(gI)))); + double sI = gI / (2.0 * sR); + p1R = fR + sR; + p1I = fI + sI; + p2R = fR - sR; + p2I = fI - sI; + } + + m_real[m] = p1R; + m_real[m + 1] = p2R; + m_imag[m] = p1I; + m_imag[m + 1] = p2I; + } + + if (Odd(n)) + { + m_real[2] = m_real[n + 1]; + m_imag[2] = m_imag[n + 1]; + } + + for (int k = n; k >= 1; k--) + { + int m = 2 * k - 1; + m_real[m] = m_real[k]; + m_real[m + 1] = m_real[k]; + m_imag[m] = Math.Abs(m_imag[k]); + m_imag[m + 1] = -Math.Abs(m_imag[k]); + } + + break; + } + } + + /// + /// Calculate all the values + /// + public void Design() + { + if (!this.FilterValid) + return; + + m_aCoeff = new double[m_order + 1]; + m_bCoeff = new double[m_order + 1]; + m_inHistory = new double[kHistSize]; + m_outHistory = new double[kHistSize]; + + double[] newA = new double[m_order + 1]; + double[] newB = new double[m_order + 1]; + + // Find filter poles and zeros + LocatePolesAndZeros(); + + // Compute filter coefficients from pole/zero values + m_aCoeff[0] = 1.0; + m_bCoeff[0] = 1.0; + + for (int i = 1; i <= m_order; i++) + { + m_aCoeff[i] = 0.0; + m_bCoeff[i] = 0.0; + } + + int k = 0; + int n = m_order; + int pairs = n / 2; + + if (Odd(m_order)) + { + // First subfilter is first order + m_aCoeff[1] = -m_z[1]; + m_bCoeff[1] = -m_real[1]; + k = 1; + } + + for (int p = 1; p <= pairs; p++) + { + int m = 2 * p - 1 + k; + double alpha1 = -(m_z[m] + m_z[m + 1]); + double alpha2 = m_z[m] * m_z[m + 1]; + double beta1 = -2.0 * m_real[m]; + double beta2 = Sqr(m_real[m]) + Sqr(m_imag[m]); + + newA[1] = m_aCoeff[1] + alpha1 * m_aCoeff[0]; + newB[1] = m_bCoeff[1] + beta1 * m_bCoeff[0]; + + for (int i = 2; i <= n; i++) + { + newA[i] = m_aCoeff[i] + alpha1 * m_aCoeff[i - 1] + alpha2 * m_aCoeff[i - 2]; + newB[i] = m_bCoeff[i] + beta1 * m_bCoeff[i - 1] + beta2 * m_bCoeff[i - 2]; + } + + for (int i = 1; i <= n; i++) + { + m_aCoeff[i] = newA[i]; + m_bCoeff[i] = newB[i]; + } + } + + // Ensure the filter is normalized + FilterGain(1000); + } + + /// + /// Reset the history buffers + /// + public void Reset() + { + if (m_inHistory != null) + m_inHistory.Clear(); + + if (m_outHistory != null) + m_outHistory.Clear(); + + m_histIdx = 0; + } + + /// + /// Reset the filter, and fill the appropriate history buffers with the specified value + /// + /// + public void Reset(double startValue) + { + m_histIdx = 0; + + if (m_inHistory == null || m_outHistory == null) + return; + + m_inHistory.Fill(startValue); + + if (m_inHistory != null) + { + switch (m_filterType) + { + case FilterType.LP: + m_outHistory.Fill(startValue); + break; + + default: + m_outHistory.Clear(); + break; + } + } + } + + /// + /// Apply the filter to the buffer + /// + /// + public void FilterBuffer(float[] srcBuf, long srcPos, float[] dstBuf, long dstPos, long nLen) + { + const double kDenormal = 0.000000000000001; + double denormal = m_invertDenormal ? -kDenormal : kDenormal; + m_invertDenormal = !m_invertDenormal; + + for (int sampleIdx = 0; sampleIdx < nLen; sampleIdx++) + { + double sum = 0.0f; + + m_inHistory[m_histIdx] = srcBuf[srcPos + sampleIdx] + denormal; + + for (int idx = 0; idx < m_aCoeff.Length; idx++) + sum += m_aCoeff[idx] * m_inHistory[(m_histIdx - idx) & kHistMask]; + + for (int idx = 1; idx < m_bCoeff.Length; idx++) + sum -= m_bCoeff[idx] * m_outHistory[(m_histIdx - idx) & kHistMask]; + + m_outHistory[m_histIdx] = sum; + m_histIdx = (m_histIdx + 1) & kHistMask; + dstBuf[dstPos + sampleIdx] = (float)sum; + } + } + + public float FilterSample(float inVal) + { + double sum = 0.0f; + + m_inHistory[m_histIdx] = inVal; + + for (int idx = 0; idx < m_aCoeff.Length; idx++) + sum += m_aCoeff[idx] * m_inHistory[(m_histIdx - idx) & kHistMask]; + + for (int idx = 1; idx < m_bCoeff.Length; idx++) + sum -= m_bCoeff[idx] * m_outHistory[(m_histIdx - idx) & kHistMask]; + + m_outHistory[m_histIdx] = sum; + m_histIdx = (m_histIdx + 1) & kHistMask; + + return (float)sum; + } + + /// + /// Get the gain at the specified number of frequency points + /// + /// + /// + public float[] FilterGain(int freqPoints) + { + // Filter gain at uniform frequency intervals + float[] g = new float[freqPoints]; + double theta, s, c, sac, sas, sbc, sbs; + float gMax = -100.0f; + float sc = 10.0f / (float)Math.Log(10.0f); + double t = Math.PI / (freqPoints - 1); + + for (int i = 0; i < freqPoints; i++) + { + theta = i * t; + + if (i == 0) + theta = Math.PI * 0.0001; + + if (i == freqPoints - 1) + theta = Math.PI * 0.9999; + + sac = 0.0f; + sas = 0.0f; + sbc = 0.0f; + sbs = 0.0f; + + for (int k = 0; k <= m_order; k++) + { + c = Math.Cos(k * theta); + s = Math.Sin(k * theta); + sac += c * m_aCoeff[k]; + sas += s * m_aCoeff[k]; + sbc += c * m_bCoeff[k]; + sbs += s * m_bCoeff[k]; + } + + g[i] = sc * (float)Math.Log((Sqr(sac) + Sqr(sas)) / (Sqr(sbc) + Sqr(sbs))); + gMax = Math.Max(gMax, g[i]); + } + + // Normalize to 0 dB maximum gain + for (int i = 0; i < freqPoints; i++) + g[i] -= gMax; + + // Normalize numerator (a) coefficients + float normFactor = (float)Math.Pow(10.0, -0.05 * gMax); + + for (int i = 0; i <= m_order; i++) + m_aCoeff[i] *= normFactor; + + return g; + } + } +} diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs b/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs new file mode 100644 index 00000000..b04f5bbf --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs @@ -0,0 +1,577 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.Collections; + +namespace Pitch +{ + /// + /// Pitch related DSP + /// + public class PitchDsp + { + public static readonly double InverseLog2 = 1.0 / Math.Log10(2.0); + + private const int kCourseOctaveSteps = 96; + private const int kScanHiSize = 31; + private const float kScanHiFreqStep = 1.005f; + private const int kMinMidiNote = 21; // A0 + private const int kMaxMidiNote = 108; // C8 + + private float m_minPitch; + private float m_maxPitch; + private int m_minNote; + private int m_maxNote; + private int m_blockLen14; // 1/4 block len + private int m_blockLen24; // 2/4 block len + private int m_blockLen34; // 3/4 block len + private int m_blockLen44; // 4/4 block len + private double m_sampleRate; + private float m_detectLevelThreshold; + + private int m_numCourseSteps; + private float[] m_pCourseFreqOffset; + private float[] m_pCourseFreq; + private float[] m_scanHiOffset = new float[kScanHiSize]; + private float[] m_peakBuf = new float[kScanHiSize]; + private int m_prevPitchIdx; + private float[] m_detectCurve; + + /// + /// Constructor + /// + /// + /// + /// + /// + public PitchDsp(double sampleRate, float minPitch, float maxPitch, float detectLevelThreshold) + { + m_sampleRate = sampleRate; + m_minPitch = minPitch; + m_maxPitch = maxPitch; + m_detectLevelThreshold = detectLevelThreshold; + + m_minNote = (int)(PitchToMidiNote(m_minPitch) + 0.5f) + 2; + m_maxNote = (int)(PitchToMidiNote(m_maxPitch) + 0.5f) - 2; + + m_blockLen44 = (int)(m_sampleRate / m_minPitch + 0.5f); + m_blockLen34 = (m_blockLen44 * 3) / 4; + m_blockLen24 = m_blockLen44 / 2; + m_blockLen14 = m_blockLen44 / 4; + + m_numCourseSteps = (int)((Math.Log((double)m_maxPitch / (double)m_minPitch) / Math.Log(2.0)) * kCourseOctaveSteps + 0.5) + 3; + + m_pCourseFreqOffset = new float[m_numCourseSteps + 10000]; + m_pCourseFreq = new float[m_numCourseSteps + 10000]; + + m_detectCurve = new float[m_numCourseSteps]; + + double freqStep = 1.0 / Math.Pow(2.0, 1.0 / kCourseOctaveSteps); + double curFreq = m_maxPitch / freqStep; + + // frequency is stored from high to low + for (int idx = 0; idx < m_numCourseSteps; idx++) + { + m_pCourseFreq[idx] = (float)curFreq; + m_pCourseFreqOffset[idx] = (float)(m_sampleRate / curFreq); + curFreq *= freqStep; + } + + for (int idx = 0; idx < kScanHiSize; idx++) + m_scanHiOffset[idx] = (float)Math.Pow(kScanHiFreqStep, (kScanHiSize / 2) - idx); + } + + /// + /// Get the max detected pitch + /// + public float MaxPitch + { + get { return m_maxPitch; } + } + + /// + /// Get the min detected pitch + /// + public float MinPitch + { + get { return m_minPitch; } + } + + /// + /// Get the max note + /// + public int MaxNote + { + get { return m_maxNote; } + } + + /// + /// Get the min note + /// + public int MinNote + { + get { return m_minNote; } + } + + /// + /// Detect the pitch + /// + public float DetectPitch(float[] samplesLo, float[] samplesHi, int numSamples) + { + float pitch = 0.0f; + + if (!LevelIsAbove(samplesLo, numSamples, m_detectLevelThreshold) && + !LevelIsAbove(samplesHi, numSamples, m_detectLevelThreshold)) + { + // Level is too low + return 0.0f; + } + + pitch = DetectPitchLo(samplesLo, samplesHi); + return pitch; + } + + /// + /// Low resolution pitch detection + /// + /// + /// + /// + /// + /// + /// + private float DetectPitchLo(float[] samplesLo, float[] samplesHi) + { + m_detectCurve.Clear(); + + const int skipSize = 8; + const int peakScanSize = 23; + const int peakScanSizeHalf = peakScanSize / 2; + + float peakThresh1 = 200.0f; + float peakThresh2 = 600.0f; + bool bufferSwitched = false; + + for (int idx = 0; idx < m_numCourseSteps; idx += skipSize) + { + int blockLen = Math.Min(m_blockLen44, (int)m_pCourseFreqOffset[idx] * 2); + float[] curSamples = null; + + // 258 is at 250 Hz, which is the switchover frequency for the two filters + bool loBuffer = idx >= 258; + + if (loBuffer) + { + if (!bufferSwitched) + { + m_detectCurve.Clear(258 - peakScanSizeHalf, 258 + peakScanSizeHalf); + bufferSwitched = true; + } + + curSamples = samplesLo; + } + else + curSamples = samplesHi; + + int stepSizeLoRes = blockLen / 10; + int stepSizeHiRes = Math.Max(1, Math.Min(5, idx * 5 / m_numCourseSteps)); + + float fValue = RatioAbsDiffLinear(curSamples, idx, blockLen, stepSizeLoRes, false); + + if (fValue > peakThresh1) + { + // Do a closer search for the peak + int peakIdx = -1; + float peakVal = 0.0f; + float prevVal = 0.0f; + int dir = 4; // start going forward + int curPos = idx; // start at center of the scan range + int begSearch = Math.Max(idx - peakScanSizeHalf, 0); + int endSearch = Math.Min(idx + peakScanSizeHalf, m_numCourseSteps - 1); + + while (curPos >= begSearch && curPos < endSearch) + { + float curVal = RatioAbsDiffLinear(curSamples, curPos, blockLen, stepSizeHiRes, true); + + if (peakVal < curVal) + { + peakVal = curVal; + peakIdx = curPos; + } + + if (prevVal > curVal) + { + dir = -dir >> 1; + + if (dir == 0) + { + if (peakVal > peakThresh2 && peakIdx >= 6 && peakIdx <= m_numCourseSteps - 7) + { + float fValL = RatioAbsDiffLinear(curSamples, peakIdx - 5, blockLen, stepSizeHiRes, true); + float fValR = RatioAbsDiffLinear(curSamples, peakIdx + 5, blockLen, stepSizeHiRes, true); + float fPointy = peakVal / (fValL + fValR) * 2.0f; + + float minPointy = (m_prevPitchIdx > 0 && Math.Abs(m_prevPitchIdx - peakIdx) < 10) ? 1.2f : 1.5f; + + if (fPointy > minPointy) + { + float pitchHi = DetectPitchHi(curSamples, peakIdx); + + if (pitchHi > 1.0f) + { + m_prevPitchIdx = peakIdx; + return pitchHi; + } + } + } + + break; + } + } + + prevVal = curVal; + curPos += dir; + } + } + } + + m_prevPitchIdx = 0; + return 0.0f; + } + + /// + /// High resolution pitch detection + /// + /// + /// + /// + private float DetectPitchHi(float[] samples, int lowFreqIdx) + { + int peakIdx = -1; + float prevVal = 0.0f; + int dir = 4; // start going forward + int curPos = kScanHiSize >> 1; // start at center of the scan range + + m_peakBuf.Clear(); + + float offset = m_pCourseFreqOffset[lowFreqIdx]; + + while (curPos >= 0 && curPos < kScanHiSize) + { + if (m_peakBuf[curPos] == 0.0f) + m_peakBuf[curPos] = SumAbsDiffHermite(samples, offset * m_scanHiOffset[curPos], m_blockLen44, 1); + + if (peakIdx < 0 || m_peakBuf[peakIdx] < m_peakBuf[curPos]) + peakIdx = curPos; + + if (prevVal > m_peakBuf[curPos]) + { + dir = -dir >> 1; + + if (dir == 0) + { + // found the peak + float minVal = Math.Min(m_peakBuf[peakIdx - 1], m_peakBuf[peakIdx + 1]); + + minVal -= minVal * (1.0f / 32.0f); + + var y1 = (float)Math.Log10(m_peakBuf[peakIdx - 1] - minVal); + var y2 = (float)Math.Log10(m_peakBuf[peakIdx] - minVal); + var y3 = (float)Math.Log10(m_peakBuf[peakIdx + 1] - minVal); + + float fIdx = (float)peakIdx + (y3 - y1) / (2.0f * (2.0f * y2 - y1 - y3)); + + return (float)Math.Pow(kScanHiFreqStep, fIdx - (kScanHiSize / 2)) * m_pCourseFreq[lowFreqIdx]; + } + } + + prevVal = m_peakBuf[curPos]; + curPos += dir; + } + + return 0.0f; + } + + /// + /// Create a sine wave with the specified frequency, amplitude and starting angle. + /// Returns the updated angle. + /// + /// + /// + /// + /// + /// + /// + public static double CreateSineWave(float[] buffer, int numSamples, float sampleRate, + float freq, float amplitude, double startAngle) + { + double angleStep = freq / sampleRate * Math.PI * 2.0; + double curAngle = startAngle; + + for (int idx = 0; idx < numSamples; idx++) + { + buffer[idx] = (float)Math.Sin(curAngle) * amplitude; + + curAngle += angleStep; + + while (curAngle > Math.PI) + curAngle -= Math.PI * 2.0; + } + + return curAngle; + } + + /// + /// Returns true if the level is above the specified value + /// + /// + /// + /// + /// + /// + public bool LevelIsAbove(float[] buffer, int len, float level) + { + if (buffer == null || buffer.Length == 0) + return false; + + int endIdx = Math.Min(buffer.Length, len); + + for (int idx = 0; idx < endIdx; idx++) + { + if (Math.Abs(buffer[idx]) >= level) + return true; + } + + return false; + } + + /// + /// Copy the data from the source to the destination buffer + /// + /// + /// + /// + /// + public static void CopyBuffer(T[] source, int srcStart, T[] destination, int dstStart, int length) + { + if (length < 0) + throw new ArgumentOutOfRangeException("length"); + + if (source == null || source.Length < srcStart + length) + throw new Exception("Source buffer is null or not large enough"); + + if (destination == null || destination.Length < dstStart + length) + throw new Exception("Destination buffer is null or not large enough"); + + int srcIdx = srcStart; + int dstIdx = dstStart; + + for (int idx = 0; idx < length; idx++) + destination[dstIdx++] = source[srcIdx++]; + } + + /// + /// // 4-point, 3rd-order Hermite (x-form) + /// + private float InterpolateHermite(float fY0, float fY1, float fY2, float fY3, float frac) + { + float c1 = 0.5f * (fY2 - fY0); + float c3 = 1.5f * (fY1 - fY2) + 0.5f * (fY3 - fY0); + float c2 = fY0 - fY1 + c1 - c3; + + return ((c3 * frac + c2) * frac + c1) * frac + fY1; + } + + /// + /// Linear interpolation + /// nFrac is based on 1.0 = 256 + /// + private float InterpolateLinear(float y0, float y1, float frac) + { + return y0 * (1.0f - frac) + y1 * frac; + } + + /// + /// Medium Low res SumAbsDiff + /// + private float RatioAbsDiffLinear(float[] samples, int freqIdx, int blockLen, int stepSize, bool hiRes) + { + if (hiRes && m_detectCurve[freqIdx] > 0.0f) + return m_detectCurve[freqIdx]; + + var offsetInt = (int)m_pCourseFreqOffset[freqIdx]; + float offsetFrac = m_pCourseFreqOffset[freqIdx] - offsetInt; + float rect = 0.0f; + float absDiff = 0.01f; // prevent divide by zero + int count = 0; + float interp; + float sample; + + // Do a scan using linear interpolation and the specified step size + for (int idx = 0; idx < blockLen; idx += stepSize, count++) + { + sample = samples[idx]; + interp = InterpolateLinear(samples[offsetInt + idx], samples[offsetInt + idx + 1], offsetFrac); + absDiff += Math.Abs(sample - interp); + rect += Math.Abs(sample) + Math.Abs(interp); + } + + float finalVal = rect / absDiff * 100.0f; + + if (hiRes) + m_detectCurve[freqIdx] = finalVal; + + return finalVal; + } + + /// + /// Medium High res SumAbsDiff + /// + private float SumAbsDiffHermite(float[] samples, float fOffset, int blockLen, int stepSize) + { + var offsetInt = (int)fOffset; + float offsetFrac = fOffset - offsetInt; + float value = 0.001f; // prevent divide by zero + int count = 0; + + // do a scan using linear interpolation and the specified step size + for (int idx = 0; idx < blockLen; idx += stepSize, count++) + { + int offsetIdx = offsetInt + idx; + + value += Math.Abs(samples[idx] - InterpolateHermite(samples[offsetIdx - 1], + samples[offsetIdx], + samples[offsetIdx + 1], + samples[offsetIdx + 2], + offsetFrac)); + } + + return count / value; + } + + /// + /// Get the MIDI note and cents of the pitch + /// + /// + /// + /// + /// + public static bool PitchToMidiNote(float pitch, out int note, out int cents) + { + if (pitch < 20.0f) + { + note = 0; + cents = 0; + return false; + } + + float fNote = (float)((12.0 * Math.Log10(pitch / 55.0) * InverseLog2)) + 33.0f; + note = (int)(fNote + 0.5f); + cents = (int)((note - fNote) * 100); + return true; + } + + /// + /// Get the pitch from the MIDI note + /// + /// + /// + public static float PitchToMidiNote(float pitch) + { + if (pitch < 20.0f) + return 0.0f; + + return (float)(12.0 * Math.Log10(pitch / 55.0) * InverseLog2) + 33.0f; + } + + /// + /// Get the pitch from the MIDI note + /// + /// + /// + public float MidiNoteToPitch(float note) + { + if (note < 33.0f) + return 0.0f; + + float pitch = (float)Math.Pow(10.0, (note - 33.0f) / InverseLog2 / 12.0f) * 55.0f; + return pitch <= m_maxPitch ? pitch : 0.0f; + } + + /// + /// Format a midi note to text + /// + /// + /// + /// + /// + public static string GetNoteName(int note, bool sharps, bool showOctave) + { + if (note < kMinMidiNote || note > kMaxMidiNote) + return null; + + note -= kMinMidiNote; + + int octave = (note + 9) / 12; + note = note % 12; + string noteText = null; + + switch (note) + { + case 0: + noteText = "A"; + break; + + case 1: + noteText = sharps ? "A#" : "Bb"; + break; + + case 2: + noteText = "B"; + break; + + case 3: + noteText = "C"; + break; + + case 4: + noteText = sharps ? "C#" : "Db"; + break; + + case 5: + noteText = "D"; + break; + + case 6: + noteText = sharps ? "D#" : "Eb"; + break; + + case 7: + noteText = "E"; + break; + + case 8: + noteText = "F"; + break; + + case 9: + noteText = sharps ? "F#" : "Gb"; + break; + + case 10: + noteText = "G"; + break; + + case 11: + noteText = sharps ? "G#" : "Ab"; + break; + } + + if (showOctave) + noteText += " " + octave.ToString(); + + return noteText; + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs b/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs new file mode 100644 index 00000000..d496ea16 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs @@ -0,0 +1,414 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; +using System.Threading; + +namespace Pitch +{ + /// + /// Tracks pitch + /// + public class PitchTracker + { + private const int kOctaveSteps = 96; + private const int kStepOverlap = 4; + private const float kMinFreq = 50.0f; // A1, Midi note 33, 55.0Hz + private const float kMaxFreq = 1800.0f; // A#6. Midi note 92 + private const int kStartCircular = 40; // how far into the sample buffer do we start checking (allow for filter settling) + private const float kDetectOverlapSec = 0.005f; + private const float kMaxOctaveSecRate = 10.0f; + + private const float kAvgOffset = 0.005f; // time offset between pitch averaging values + private const int kAvgCount = 1; // number of average pitch samples to take + private const float kCircularBufSaveTime = 1.0f; // Amount of samples to store in the history buffer + + private PitchDsp m_dsp; + private CircularBuffer m_circularBufferLo; + private CircularBuffer m_circularBufferHi; + private double m_sampleRate; + private float m_detectLevelThreshold = 0.01f; // -40dB + private int m_pitchRecordsPerSecond = 50; // default is 50, or one record every 20ms + + private float[] m_pitchBufLo; + private float[] m_pitchBufHi; + private int m_pitchBufSize; + private int m_samplesPerPitchBlock; + private int m_curPitchIndex; + private long m_curPitchSamplePos; + + private int m_detectOverlapSamples; + private float m_maxOverlapDiff; + + private bool m_recordPitchRecords; + private int m_pitchRecordHistorySize; + private List m_pitchRecords = new List(); + private PitchRecord m_curPitchRecord = new PitchRecord(); + + private IIRFilter m_iirFilterLoLo; + private IIRFilter m_iirFilterLoHi; + private IIRFilter m_iirFilterHiLo; + private IIRFilter m_iirFilterHiHi; + + public delegate void PitchDetectedHandler(PitchTracker sender, PitchRecord pitchRecord); + + public event PitchDetectedHandler PitchDetected; + + /// + /// Constructor + /// + public PitchTracker() {} + + /// + /// Set the sample rate + /// + public double SampleRate + { + set + { + if (m_sampleRate == value) + return; + + m_sampleRate = value; + Setup(); + } + } + + /// + /// Set the detect level threshold, The value must be between 0.0001f and 1.0f (-80 dB to 0 dB) + /// + public float DetectLevelThreshold + { + set + { + float newValue = Math.Max(0.0001f, Math.Min(1.0f, value)); + + if (m_detectLevelThreshold == newValue) + return; + + m_detectLevelThreshold = newValue; + Setup(); + } + } + + /// + /// Return the samples per pitch block + /// + public int SamplesPerPitchBlock + { + get { return m_samplesPerPitchBlock; } + } + + /// + /// Get or set the number of pitch records per second (default is 50, or one record every 20ms) + /// + public int PitchRecordsPerSecond + { + get { return m_pitchRecordsPerSecond; } + set + { + m_pitchRecordsPerSecond = Math.Max(1, Math.Min(100, value)); + Setup(); + } + } + + /// + /// Get or set whether pitch records should be recorded into a history buffer + /// + public bool RecordPitchRecords + { + get { return m_recordPitchRecords; } + set + { + if (m_recordPitchRecords == value) + return; + + m_recordPitchRecords = value; + + if (!m_recordPitchRecords) + m_pitchRecords = new List(); + } + } + + /// + /// Get or set the max number of pitch records to keep. A value of 0 means no limit. + /// Don't leave this at 0 when RecordPitchRecords is true and this is used in a realtime + /// application since the buffer will grow indefinately! + /// + public int PitchRecordHistorySize + { + get { return m_pitchRecordHistorySize; } + set + { + m_pitchRecordHistorySize = value; + + m_pitchRecords.Capacity = m_pitchRecordHistorySize; + } + } + + /// + /// Get the current pitch records + /// + public IList PitchRecords + { + get { return m_pitchRecords.AsReadOnly(); } + } + + /// + /// Get the latest pitch record + /// + public PitchRecord CurrentPitchRecord + { + get { return m_curPitchRecord; } + } + + /// + /// Get the current pitch position + /// + public long CurrentPitchSamplePosition + { + get { return m_curPitchSamplePos; } + } + + /// + /// Get the minimum frequency that can be detected + /// + public static float MinDetectFrequency + { + get { return kMinFreq; } + } + + /// + /// Get the maximum frequency that can be detected + /// + public static float MaxDetectFrequency + { + get { return kMaxFreq; } + } + + /// + /// Get the frequency step + /// + public static double FrequencyStep + { + get { return Math.Pow(2.0, 1.0 / kOctaveSteps); } + } + + /// + /// Get the number of samples that the detected pitch is offset from the input buffer. + /// This is just an estimate to sync up the samples and detected pitch + /// + public int DetectSampleOffset + { + get { return (m_pitchBufSize + m_detectOverlapSamples) / 2; } + } + + /// + /// Reset the pitch tracker. Call this when the sample position is + /// not consecutive from the previous position + /// + public void Reset() + { + m_curPitchIndex = 0; + m_curPitchSamplePos = 0; + m_pitchRecords.Clear(); + m_iirFilterLoLo.Reset(); + m_iirFilterLoHi.Reset(); + m_iirFilterHiLo.Reset(); + m_iirFilterHiHi.Reset(); + m_circularBufferLo.Reset(); + m_circularBufferLo.Clear(); + m_circularBufferHi.Reset(); + m_circularBufferHi.Clear(); + m_pitchBufLo.Clear(); + m_pitchBufHi.Clear(); + + m_circularBufferLo.StartPosition = -m_detectOverlapSamples; + m_circularBufferLo.Available = m_detectOverlapSamples; + m_circularBufferHi.StartPosition = -m_detectOverlapSamples; + m_circularBufferHi.Available = m_detectOverlapSamples; + } + + /// + /// Process the passed in buffer of data. During this call, the PitchDetected event will + /// be fired zero or more times, depending how many pitch records will fit in the new + /// and previously cached buffer. + /// + /// This means that there is no size restriction on the buffer that is passed into ProcessBuffer. + /// For instance, ProcessBuffer can be called with one very large buffer that contains all of the + /// audio to be processed (many PitchDetected events will be fired), or just a small buffer at + /// a time which is more typical for realtime applications. In the latter case, the PitchDetected + /// event might not be fired at all since additional calls must first be made to accumulate enough + /// data do another pitch detect operation. + /// + /// Input buffer. Samples must be in the range -1.0 to 1.0 + /// Number of samples to process. Zero means all samples in the buffer + public void ProcessBuffer(float[] inBuffer, int sampleCount = 0) + { + if (inBuffer == null) + throw new ArgumentNullException("inBuffer", "Input buffer cannot be null"); + + int samplesProcessed = 0; + int srcLength = sampleCount == 0 ? inBuffer.Length : Math.Min(sampleCount, inBuffer.Length); + + while (samplesProcessed < srcLength) + { + int frameCount = Math.Min(srcLength - samplesProcessed, m_pitchBufSize + m_detectOverlapSamples); + + m_iirFilterLoLo.FilterBuffer(inBuffer, samplesProcessed, m_pitchBufLo, 0, frameCount); + m_iirFilterLoHi.FilterBuffer(m_pitchBufLo, 0, m_pitchBufLo, 0, frameCount); + + m_iirFilterHiLo.FilterBuffer(inBuffer, samplesProcessed, m_pitchBufHi, 0, frameCount); + m_iirFilterHiHi.FilterBuffer(m_pitchBufHi, 0, m_pitchBufHi, 0, frameCount); + + m_circularBufferLo.WriteBuffer(m_pitchBufLo, frameCount); + m_circularBufferHi.WriteBuffer(m_pitchBufHi, frameCount); + + // Loop while there is enough samples in the circular buffer + while (m_circularBufferLo.ReadBuffer(m_pitchBufLo, m_curPitchSamplePos, m_pitchBufSize + m_detectOverlapSamples)) + { + float pitch1; + float pitch2 = 0.0f; + float detectedPitch = 0.0f; + + m_circularBufferHi.ReadBuffer(m_pitchBufHi, m_curPitchSamplePos, m_pitchBufSize + m_detectOverlapSamples); + + pitch1 = m_dsp.DetectPitch(m_pitchBufLo, m_pitchBufHi, m_pitchBufSize); + + if (pitch1 > 0.0f) + { + // Shift the buffers left by the overlapping amount + m_pitchBufLo.Copy(m_pitchBufLo, m_detectOverlapSamples - 1, 0, m_pitchBufSize); + m_pitchBufHi.Copy(m_pitchBufHi, m_detectOverlapSamples - 1, 0, m_pitchBufSize); + + pitch2 = m_dsp.DetectPitch(m_pitchBufLo, m_pitchBufHi, m_pitchBufSize); + + if (pitch2 > 0.0f) + { + float fDiff = Math.Max(pitch1, pitch2) / Math.Min(pitch1, pitch2) - 1.0f; + + if (fDiff < m_maxOverlapDiff) + detectedPitch = (pitch1 + pitch2) * 0.5f; + } + } + + // Log the pitch record + AddPitchRecord(detectedPitch); + + m_curPitchSamplePos += m_samplesPerPitchBlock; + m_curPitchIndex++; + } + + samplesProcessed += frameCount; + } + } + + /// + /// Setup + /// + private void Setup() + { + if (m_sampleRate < 1.0f) + return; + + m_dsp = new PitchDsp(m_sampleRate, kMinFreq, kMaxFreq, m_detectLevelThreshold); + + m_iirFilterLoLo = new IIRFilter(); + m_iirFilterLoLo.Proto = IIRFilter.ProtoType.Butterworth; + m_iirFilterLoLo.Type = IIRFilter.FilterType.HP; + m_iirFilterLoLo.Order = 5; + m_iirFilterLoLo.FreqLow = 45.0f; + m_iirFilterLoLo.SampleRate = (float)m_sampleRate; + + m_iirFilterLoHi = new IIRFilter(); + m_iirFilterLoHi.Proto = IIRFilter.ProtoType.Butterworth; + m_iirFilterLoHi.Type = IIRFilter.FilterType.LP; + m_iirFilterLoHi.Order = 5; + m_iirFilterLoHi.FreqHigh = 280.0f; + m_iirFilterLoHi.SampleRate = (float)m_sampleRate; + + m_iirFilterHiLo = new IIRFilter(); + m_iirFilterHiLo.Proto = IIRFilter.ProtoType.Butterworth; + m_iirFilterHiLo.Type = IIRFilter.FilterType.HP; + m_iirFilterHiLo.Order = 5; + m_iirFilterHiLo.FreqLow = 45.0f; + m_iirFilterHiLo.SampleRate = (float)m_sampleRate; + + m_iirFilterHiHi = new IIRFilter(); + m_iirFilterHiHi.Proto = IIRFilter.ProtoType.Butterworth; + m_iirFilterHiHi.Type = IIRFilter.FilterType.LP; + m_iirFilterHiHi.Order = 5; + m_iirFilterHiHi.FreqHigh = 2000.0f; + m_iirFilterHiHi.SampleRate = (float)m_sampleRate; + + m_detectOverlapSamples = (int)(kDetectOverlapSec * m_sampleRate); + m_maxOverlapDiff = kMaxOctaveSecRate * kDetectOverlapSec; + + m_pitchBufSize = (int)(((1.0f / (float)kMinFreq) * 2.0f + ((kAvgCount - 1) * kAvgOffset)) * m_sampleRate) + 16; + m_pitchBufLo = new float[m_pitchBufSize + m_detectOverlapSamples]; + m_pitchBufHi = new float[m_pitchBufSize + m_detectOverlapSamples]; + m_samplesPerPitchBlock = (int)Math.Round(m_sampleRate / m_pitchRecordsPerSecond); + + m_circularBufferLo = new CircularBuffer((int)(kCircularBufSaveTime * m_sampleRate + 0.5f) + 10000); + m_circularBufferHi = new CircularBuffer((int)(kCircularBufSaveTime * m_sampleRate + 0.5f) + 10000); + } + + /// + /// The pitch was detected - add the record + /// + /// + private void AddPitchRecord(float pitch) + { + int midiNote = 0; + int midiCents = 0; + + PitchDsp.PitchToMidiNote(pitch, out midiNote, out midiCents); + + var record = new PitchRecord(); + + record.RecordIndex = m_curPitchIndex; + record.Pitch = pitch; + record.MidiNote = midiNote; + record.MidiCents = midiCents; + + m_curPitchRecord = record; + + if (m_recordPitchRecords) + { + if (m_pitchRecordHistorySize > 0 && m_pitchRecords.Count >= m_pitchRecordHistorySize) + m_pitchRecords.RemoveAt(0); + + m_pitchRecords.Add(record); + } + + if (this.PitchDetected != null) + this.PitchDetected(this, record); + } + + /// + /// Stores one record + /// + public struct PitchRecord + { + /// + /// The index of the pitch record since the last Reset call + /// + public int RecordIndex { get; set; } + + /// + /// The detected pitch + /// + public float Pitch { get; set; } + + /// + /// The detected MIDI note, or 0 for no pitch + /// + public int MidiNote { get; set; } + + /// + /// The offset from the detected MIDI note in cents, from -50 to +50. + /// + public int MidiCents { get; set; } + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index d0c8f9ba..bc2260e4 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -268,6 +268,11 @@ + + + + + From d04cbe7ceb1764a8f428098a6f6ab791bcec7a54 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Wed, 16 Apr 2014 21:05:57 +0200 Subject: [PATCH 25/34] Add an Interface for Pitchtrackers and set VolTresholds --- PitchTracker/PitchWrapper.cpp | 42 ++-- PitchTracker/PitchWrapper.h | 11 +- .../dywapitchtrack/dywapitchtrack.cpp | 9 +- PitchTracker/dywapitchtrack/dywapitchtrack.h | 2 +- PitchTracker/dywapitchtrack/ptDyWa.cpp | 24 ++- PitchTracker/dywapitchtrack/ptDyWa.h | 8 +- PitchTracker/performous/pitch.hh | 1 + PitchTracker/ptAKF.cpp | 19 +- PitchTracker/ptAKF.h | 9 +- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 56 +++--- Vocaluxe/Lib/Sound/Record/CRecordBase.cs | 2 +- Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs | 18 +- .../Lib/Sound/Record/Pitch/PitchTracker.cs | 60 ++++-- .../Record/{ => PitchTracker}/CAnalyzer.cs | 180 +++++++++++------- .../Record/PitchTracker/IPitchTracker.cs | 73 +++++++ Vocaluxe/Vocaluxe.csproj | 3 +- 16 files changed, 344 insertions(+), 173 deletions(-) rename Vocaluxe/Lib/Sound/Record/{ => PitchTracker}/CAnalyzer.cs (55%) create mode 100644 Vocaluxe/Lib/Sound/Record/PitchTracker/IPitchTracker.cs diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index ff6e4252..6314b64c 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -39,17 +39,17 @@ void Analyzer_Process(Analyzer* analyzer){ analyzer->process(); } -double Analyzer_GetPeak(Analyzer* analyzer){ +float Analyzer_GetPeak(Analyzer* analyzer){ if(!analyzer) return -999; - return analyzer->getPeak(); + return static_cast(analyzer->getPeakRaw()); } double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq){ if(!analyzer) return -1; const Tone* tone = analyzer->findTone(minFreq, maxFreq); - return (tone == NULL) ? -1 : FreqToNote(tone->freq); + return (tone == NULL) ? -1 : FreqToNote(tone->freq); } bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate){ @@ -71,6 +71,18 @@ int PtAKF_GetNumHalfTones(){ return PtAKF::GetNumHalfTones(); } +void PtAKF_SetVolumeTreshold(PtAKF* analyzer, float threshold){ + if(!analyzer) + return; + analyzer->SetVolumeThreshold(threshold); +} + +float PtAKF_GetVolumeThreshold(PtAKF* analyzer){ + if(!analyzer) + return 0.f; + return analyzer->GetVolumeThreshold(); +} + void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){ if(sampleCt <= 0 || !analyzer) return; @@ -82,7 +94,7 @@ void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt){ //analyzer->input(dataShort, dataShort + sampleCt); } -int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights){ +int PtAKF_GetNote(PtAKF* analyzer, float* maxVolume, float* weights){ if(!analyzer) return -1; return analyzer->GetNote(maxVolume, weights); @@ -97,6 +109,18 @@ void PtDyWa_Free(PtDyWa* analyzer){ delete analyzer; } +void PtDyWa_SetVolumeTreshold(PtDyWa* analyzer, float threshold){ + if(!analyzer) + return; + analyzer->SetVolumeThreshold(threshold); +} + +float PtDyWa_GetVolumeThreshold(PtDyWa* analyzer){ + if(!analyzer) + return 0.f; + return analyzer->GetVolumeThreshold(); +} + void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt){ if(sampleCt <= 0 || !analyzer) return; @@ -105,16 +129,10 @@ void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt){ freeFloatArray(dataFloat); } -void PtDyWa_Process(PtDyWa* analyzer){ - if(!analyzer) - return; - analyzer->Process(); -} - -double PtDyWa_GetNote(PtDyWa* analyzer){ +double PtDyWa_FindNote(PtDyWa* analyzer, float* maxVolume){ if(!analyzer) return -1; - return analyzer->GetNote(); + return analyzer->FindNote(maxVolume); } /* diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 80c5cfa7..6425f862 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -12,21 +12,24 @@ DllExport void Analyzer_InputFloat(Analyzer* analyzer, float* data, int sampleCt DllExport void Analyzer_InputShort(Analyzer* analyzer, short* data, int sampleCt); DllExport void Analyzer_InputByte(Analyzer* analyzer, char* data, int sampleCt); DllExport void Analyzer_Process(Analyzer* analyzer); -DllExport double Analyzer_GetPeak(Analyzer* analyzer); +DllExport float Analyzer_GetPeak(Analyzer* analyzer); DllExport double Analyzer_FindNote(Analyzer* analyzer, double minFreq, double maxFreq); DllExport bool Analyzer_OutputFloat(Analyzer* analyzer, float* data, int sampleCt, float rate); DllExport PtAKF* PtAKF_Create(unsigned step); DllExport void PtAKF_Free(PtAKF* analyzer); DllExport int PtAKF_GetNumHalfTones(); +DllExport void PtAKF_SetVolumeThreshold(PtAKF* analyzer, float threshold); +DllExport float PtAKF_GetVolumeThreshold(PtAKF* analyzer); DllExport void PtAKF_InputByte(PtAKF* analyzer, char* data, int sampleCt); -DllExport int PtAKF_GetNote(PtAKF* analyzer, double* maxVolume, float* weights); +DllExport int PtAKF_GetNote(PtAKF* analyzer, float* maxVolume, float* weights); DllExport PtDyWa* PtDyWa_Create(unsigned step); DllExport void PtDyWa_Free(PtDyWa* analyzer); +DllExport void PtDyWa_SetVolumeTreshold(PtDyWa* analyzer,float threshold); +DllExport float PtDyWa_GetVolumeThreshold(PtDyWa* analyzer); DllExport void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt); -DllExport void PtDyWa_Process(PtDyWa* analyzer); -DllExport double PtDyWa_GetNote(PtDyWa* analyzer); +DllExport double PtDyWa_FindNote(PtDyWa* analyzer); /* public ref class CTone { diff --git a/PitchTracker/dywapitchtrack/dywapitchtrack.cpp b/PitchTracker/dywapitchtrack/dywapitchtrack.cpp index f4c6e653..ec17f052 100644 --- a/PitchTracker/dywapitchtrack/dywapitchtrack.cpp +++ b/PitchTracker/dywapitchtrack/dywapitchtrack.cpp @@ -102,7 +102,7 @@ typedef struct _minmax { struct _minmax *next; } minmax; -double _dywapitch_computeWaveletPitch(double * samples, int startsample, int samplecount) { +double _dywapitch_computeWaveletPitch(double * samples, int startsample, int samplecount, float* maxVolume, double volThreshold) { double pitchF = 0.0; int i, j; @@ -143,6 +143,9 @@ double _dywapitch_computeWaveletPitch(double * samples, int startsample, int sam maxValue = maxValue - theDC; minValue = minValue - theDC; double amplitudeMax = (maxValue > -minValue ? maxValue : -minValue); + *maxVolume = static_cast(amplitudeMax + theDC); + if(*maxVolume < volThreshold) + return 0.0; ampltitudeThreshold = amplitudeMax*maximaThresholdRatio; //asLog("dywapitch theDC=%f ampltitudeThreshold=%f\n", theDC, ampltitudeThreshold); @@ -439,8 +442,8 @@ void dywapitch_inittracking(dywapitchtracker *pitchtracker) { pitchtracker->_pitchConfidence = -1; } -double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount) { - double raw_pitch = _dywapitch_computeWaveletPitch(samples, startsample, samplecount); +double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount, float* maxVolume, double volThreshold) { + double raw_pitch = _dywapitch_computeWaveletPitch(samples, startsample, samplecount, maxVolume, volThreshold); return _dywapitch_dynamicprocess(pitchtracker, raw_pitch); } diff --git a/PitchTracker/dywapitchtrack/dywapitchtrack.h b/PitchTracker/dywapitchtrack/dywapitchtrack.h index 39aeb38d..95767c29 100644 --- a/PitchTracker/dywapitchtrack/dywapitchtrack.h +++ b/PitchTracker/dywapitchtrack/dywapitchtrack.h @@ -100,7 +100,7 @@ void dywapitch_inittracking(dywapitchtracker *pitchtracker); // startsample : the index of the first sample to use in the sample buffer // samplecount : the number of samples to use to compte the pitch // return 0.0 if no pitch was found (sound too low, noise, etc..) -double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount); +double dywapitch_computepitch(dywapitchtracker *pitchtracker, double * samples, int startsample, int samplecount, float* maxVolume, double volThreshold); #ifdef __cplusplus } // extern "C" diff --git a/PitchTracker/dywapitchtrack/ptDyWa.cpp b/PitchTracker/dywapitchtrack/ptDyWa.cpp index fa3ab4f0..96572e27 100644 --- a/PitchTracker/dywapitchtrack/ptDyWa.cpp +++ b/PitchTracker/dywapitchtrack/ptDyWa.cpp @@ -5,23 +5,27 @@ PtDyWa::PtDyWa(unsigned step){ _Step = step; dywapitch_inittracking(&_State); + _VolTreshold = 0.01f; + _LastMaxVol = 0.f; } -void PtDyWa::Process(){ +void PtDyWa::SetVolumeThreshold(float threshold){ + _VolTreshold = threshold; +} + +double PtDyWa::FindNote(float* maxVolume){ double AnaylsisBuf[_SampleCt]; size_t size = _AnalysisBuf.size(); if(size > _SampleCt) _AnalysisBuf.pop(size - _SampleCt); - if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)) - return; + if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)){ + *maxVolume = _LastMaxVol * 0.85f; + return -1; + } _AnalysisBuf.pop(_Step); - double pitch = dywapitch_computepitch(&_State, AnaylsisBuf,0,_SampleCt); + double pitch = dywapitch_computepitch(&_State, AnaylsisBuf, 0, _SampleCt, maxVolume, _VolTreshold); if(pitch == 0.0) - _LastNote = -1; + return -1; else - _LastNote = FreqToNote(pitch); -} - -double PtDyWa::GetNote(){ - return _LastNote; + return FreqToNote(pitch); } \ No newline at end of file diff --git a/PitchTracker/dywapitchtrack/ptDyWa.h b/PitchTracker/dywapitchtrack/ptDyWa.h index c66e1ac7..dd0eb615 100644 --- a/PitchTracker/dywapitchtrack/ptDyWa.h +++ b/PitchTracker/dywapitchtrack/ptDyWa.h @@ -11,12 +11,14 @@ public: _AnalysisBuf.insert(begin, end); } - void Process(); - double GetNote(); + double FindNote(float* maxVolume); + void SetVolumeThreshold(float threshold); + float GetVolumeThreshold(){return _VolTreshold;} private: dywapitchtracker _State; constexpr static size_t _SampleCt = 2048; RingBuffer<_SampleCt * 2> _AnalysisBuf; unsigned _Step; - double _LastNote; + float _VolTreshold; + float _LastMaxVol; }; \ No newline at end of file diff --git a/PitchTracker/performous/pitch.hh b/PitchTracker/performous/pitch.hh index 1108e0b9..f87a7638 100644 --- a/PitchTracker/performous/pitch.hh +++ b/PitchTracker/performous/pitch.hh @@ -86,6 +86,7 @@ public: fft_t const& getFFT() const { return m_fft; } /** Get the peak level in dB (negative value, 0.0 = clipping). **/ double getPeak() const { return 10.0 * log10(m_peak); } + double getPeakRaw() const { return m_peak; } /** Get a list of all tones detected. **/ tones_t const& getTones() const { return m_tones; } /** Find a tone within the singing range; prefers strong tones around 200-400 Hz. **/ diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index f5f95bf7..7a418f22 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -47,6 +47,8 @@ PtAKF::PtAKF(unsigned step){ } } _Step = step; + _VolTreshold = 0.01f; + _LastMaxVol = 0.f; } PtAKF::~PtAKF(){ @@ -59,13 +61,19 @@ PtAKF::~PtAKF(){ } } -int PtAKF::GetNote(double* restrict maxVolume, float* restrict weights){ +void PtAKF::SetVolumeThreshold(float threshold){ + _VolTreshold = threshold; +} + +int PtAKF::GetNote(float* restrict maxVolume, float* restrict weights){ float AnaylsisBuf[_SampleCt]; size_t size = _AnalysisBuf.size(); if(size > _SampleCt) _AnalysisBuf.pop(size - _SampleCt); - if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)) + if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)){ + *maxVolume = _LastMaxVol * 0.85f; return -1; + } _AnalysisBuf.pop(_Step); return _GetNote(AnaylsisBuf, maxVolume, weights); } @@ -96,7 +104,7 @@ void PtAKF::AddPeak(SPeak peaks[], float curWeight, int toneIndex){ } } -int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* restrict weights){ +int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* restrict weights){ // Calculate maximum volume float maxVolumeL = 0; @@ -105,9 +113,12 @@ int PtAKF::_GetNote(float* restrict samples, double* restrict maxVolume, float* if(vol > maxVolumeL) maxVolumeL = vol; } - //maxVolumeL /= 32767.; + //maxVolumeL /= 32767.f; *maxVolume = maxVolumeL; + if(maxVolumeL < _VolTreshold) + return -1; + float samplesWindowed[_SampleCt]; for(int i = 0; i < _SampleCt; i++){ diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h index 02a2baf2..58c04433 100644 --- a/PitchTracker/ptAKF.h +++ b/PitchTracker/ptAKF.h @@ -29,7 +29,9 @@ public: _AnalysisBuf.insert(begin, end); } - int GetNote(double* restrict maxVolume, float* restrict weights); + int GetNote(float* restrict maxVolume, float* restrict weights); + void SetVolumeThreshold(float threshold); + float GetVolumeThreshold(){return _VolTreshold;} static int GetNumHalfTones(){ return _MaxHalfTone - _MinHalfTone + 1;} private: @@ -48,8 +50,11 @@ private: constexpr static size_t _SampleCt = 2048; RingBuffer<_SampleCt * 2> _AnalysisBuf; unsigned _Step; + float _VolTreshold; + float _LastMaxVol; + + int _GetNote(float* restrict samples, float* restrict maxVolume, float* restrict weights); - static int _GetNote(float* restrict samples, double* restrict maxVolume, float* restrict weights); static float _AnalyzeBySampleCt(float* restrict samples, float* restrict samplesWindowed, float samplesPerPeriodD); static inline float _AnalyzeByTone(float* restrict samples, float* restrict samplesWindowed, int toneIndex); static float _AKFBySampleCt(float* restrict samples, float samplesPerPeriodD); diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 755aa118..9a4a7b4d 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -24,6 +24,8 @@ using System.IO; using System.Windows.Forms; using System.Diagnostics; using Pitch; +using Vocaluxe.Lib.Sound.Record.Pitch; +using Vocaluxe.Lib.Sound.Record.PitchTracker; using VocaluxeLib; using VocaluxeLib.Utils; @@ -38,17 +40,18 @@ namespace Vocaluxe.Lib.Sound.Record private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) #endif - private CPtAKF _Analyzer = new CPtAKF(); + private CPitchTracker _PitchTracker = new CPtAKF(); - private double _MaxVolume; + private float _MaxVolume; public CBuffer() { - MinVolume = 0.02f; + VolTreshold = 0.02f; ToneWeigths = new float[GetNumHalfTones()]; Reset(); #if TEST_PITCH _TestPitchDetection(); + Reset(); #endif } @@ -57,9 +60,9 @@ namespace Vocaluxe.Lib.Sound.Record _Dispose(); } - public static int GetNumHalfTones() + public int GetNumHalfTones() { - return CPtAKF.GetNumHalfTones(); + return _PitchTracker.GetNumHalfTones(); } public int ToneAbs { get; private set; } @@ -68,7 +71,7 @@ namespace Vocaluxe.Lib.Sound.Record public float MaxVolume { - get { return (float)_MaxVolume; } + get { return _MaxVolume; } } public bool ToneValid { get; private set; } @@ -78,7 +81,11 @@ namespace Vocaluxe.Lib.Sound.Record /// /// Minimum volume for a tone to be valid /// - public float MinVolume { get; set; } + public float VolTreshold + { + get { return _PitchTracker.VolumeTreshold; } + set { _PitchTracker.VolumeTreshold = value; } + } public void Reset() { @@ -97,14 +104,14 @@ namespace Vocaluxe.Lib.Sound.Record // voice passthrough (send data to playback-device) //if (assigned(fVoiceStream)) then //fVoiceStream.WriteData(Buffer, BufferSize); - _Analyzer.Input(buffer); + _PitchTracker.Input(buffer); } public void AnalyzeBuffer() { //_MaxVolume = _Analyzer.GetPeak() / 43 + 1; - int tone = _Analyzer.GetNote(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // - if (tone >= 0 && _MaxVolume >= MinVolume) + int tone = _PitchTracker.GetNote(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // + if (tone >= 0) { ToneAbs = tone; Tone = ToneAbs % 12; @@ -122,10 +129,10 @@ namespace Vocaluxe.Lib.Sound.Record private void _Dispose() { - if (_Analyzer != null) + if (_PitchTracker != null) { - _Analyzer.Dispose(); - _Analyzer = null; + _PitchTracker.Dispose(); + _PitchTracker = null; } } @@ -288,11 +295,13 @@ namespace Vocaluxe.Lib.Sound.Record int curTimeIndex = -1; int curNote = -1; const int maxSamplesPerBatch = 512; - CAnalyzer analyzer2 = new CAnalyzer(); - CPtDyWa analyzer3 = new CPtDyWa(); - PitchTracker analyzer4 = new PitchTracker {SampleRate = 44100, DetectLevelThreshold = 0.001f}; + CPitchTracker analyzer2 = new CAnalyzer(); + CPitchTracker analyzer3 = new CPtDyWa(); + CPitchTracker analyzer4 = new CPtSharp(); int[] detectedTones = new int[4]; int[] oks = new int[4]; + float dummyMaxVol; + float[] dummyWeights = new float[ToneWeigths.Length]; int lCt = 0; while (wavFile.NumSamplesLeft > maxSamplesPerBatch) { @@ -303,14 +312,7 @@ namespace Vocaluxe.Lib.Sound.Record AnalyzeBuffer(); analyzer2.Input(samples); analyzer3.Input(samples); - analyzer2.Process(); - analyzer3.Process(); - short[] samplesShort = new short[samples.Length / 2]; - Buffer.BlockCopy(samples, 0, samplesShort, 0, samples.Length); - float[] samplesFloat = new float[samplesShort.Length]; - for (int i = 0; i < samplesShort.Length; i++) - samplesFloat[i] = (float)samplesShort[i] / short.MaxValue; - analyzer4.ProcessBuffer(samplesFloat); + analyzer4.Input(samples); while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) { curTimeIndex++; @@ -319,9 +321,9 @@ namespace Vocaluxe.Lib.Sound.Record if (curNote < 0) continue; detectedTones[0] = ToneValid ? ToneAbs : -1; - detectedTones[1] = (int)Math.Round(analyzer2.FindNote(64, 1770)); - detectedTones[2] = (int)Math.Round(analyzer3.GetNote()); - detectedTones[3] = analyzer4.CurrentPitchRecord.MidiNote - 15 - 21; + detectedTones[1] = analyzer2.GetNote(out dummyMaxVol, dummyWeights); + detectedTones[2] = analyzer3.GetNote(out dummyMaxVol, dummyWeights); + detectedTones[3] = analyzer4.GetNote(out dummyMaxVol, dummyWeights); lCt++; /*if (!ToneValid) CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms not detected"); diff --git a/Vocaluxe/Lib/Sound/Record/CRecordBase.cs b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs index f68fc268..5dd64987 100644 --- a/Vocaluxe/Lib/Sound/Record/CRecordBase.cs +++ b/Vocaluxe/Lib/Sound/Record/CRecordBase.cs @@ -132,7 +132,7 @@ namespace Vocaluxe.Lib.Sound.Record public int NumHalfTones() { - return CBuffer.GetNumHalfTones(); + return _Buffer[0].GetNumHalfTones(); } public float[] ToneWeigth(int player) diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs b/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs index b04f5bbf..0eb79432 100644 --- a/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs +++ b/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs @@ -28,7 +28,6 @@ namespace Pitch private int m_blockLen34; // 3/4 block len private int m_blockLen44; // 4/4 block len private double m_sampleRate; - private float m_detectLevelThreshold; private int m_numCourseSteps; private float[] m_pCourseFreqOffset; @@ -45,12 +44,11 @@ namespace Pitch /// /// /// - public PitchDsp(double sampleRate, float minPitch, float maxPitch, float detectLevelThreshold) + public PitchDsp(double sampleRate, float minPitch, float maxPitch) { m_sampleRate = sampleRate; m_minPitch = minPitch; m_maxPitch = maxPitch; - m_detectLevelThreshold = detectLevelThreshold; m_minNote = (int)(PitchToMidiNote(m_minPitch) + 0.5f) + 2; m_maxNote = (int)(PitchToMidiNote(m_maxPitch) + 0.5f) - 2; @@ -117,19 +115,9 @@ namespace Pitch /// /// Detect the pitch /// - public float DetectPitch(float[] samplesLo, float[] samplesHi, int numSamples) + public float DetectPitch(float[] samplesLo, float[] samplesHi) { - float pitch = 0.0f; - - if (!LevelIsAbove(samplesLo, numSamples, m_detectLevelThreshold) && - !LevelIsAbove(samplesHi, numSamples, m_detectLevelThreshold)) - { - // Level is too low - return 0.0f; - } - - pitch = DetectPitchLo(samplesLo, samplesHi); - return pitch; + return DetectPitchLo(samplesLo, samplesHi); } /// diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs b/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs index d496ea16..8e7e6776 100644 --- a/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs +++ b/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; -using System.Text; using System.Collections; -using System.Threading; +using Pitch; -namespace Pitch +namespace Vocaluxe.Lib.Sound.Record.Pitch { /// /// Tracks pitch /// + // ReSharper disable InconsistentNaming public class PitchTracker { private const int kOctaveSteps = 96; @@ -50,6 +50,8 @@ namespace Pitch private IIRFilter m_iirFilterHiLo; private IIRFilter m_iirFilterHiHi; + public float LastMaxVol = 0; + public delegate void PitchDetectedHandler(PitchTracker sender, PitchRecord pitchRecord); public event PitchDetectedHandler PitchDetected; @@ -87,8 +89,9 @@ namespace Pitch return; m_detectLevelThreshold = newValue; - Setup(); + //Setup(); } + get { return m_detectLevelThreshold; } } /// @@ -229,19 +232,20 @@ namespace Pitch m_circularBufferHi.Available = m_detectOverlapSamples; } - /// - /// Process the passed in buffer of data. During this call, the PitchDetected event will - /// be fired zero or more times, depending how many pitch records will fit in the new - /// and previously cached buffer. - /// - /// This means that there is no size restriction on the buffer that is passed into ProcessBuffer. - /// For instance, ProcessBuffer can be called with one very large buffer that contains all of the - /// audio to be processed (many PitchDetected events will be fired), or just a small buffer at - /// a time which is more typical for realtime applications. In the latter case, the PitchDetected - /// event might not be fired at all since additional calls must first be made to accumulate enough - /// data do another pitch detect operation. - /// - /// Input buffer. Samples must be in the range -1.0 to 1.0 + /// + /// Process the passed in buffer of data. During this call, the PitchDetected event will + /// be fired zero or more times, depending how many pitch records will fit in the new + /// and previously cached buffer. + /// + /// This means that there is no size restriction on the buffer that is passed into ProcessBuffer. + /// For instance, ProcessBuffer can be called with one very large buffer that contains all of the + /// audio to be processed (many PitchDetected events will be fired), or just a small buffer at + /// a time which is more typical for realtime applications. In the latter case, the PitchDetected + /// event might not be fired at all since additional calls must first be made to accumulate enough + /// data do another pitch detect operation. + /// + /// Input buffer. Samples must be in the range -1.0 to 1.0 + /// /// Number of samples to process. Zero means all samples in the buffer public void ProcessBuffer(float[] inBuffer, int sampleCount = 0) { @@ -251,6 +255,8 @@ namespace Pitch int samplesProcessed = 0; int srcLength = sampleCount == 0 ? inBuffer.Length : Math.Min(sampleCount, inBuffer.Length); + float maxVolume = LastMaxVol * 0.85f; + while (samplesProcessed < srcLength) { int frameCount = Math.Min(srcLength - samplesProcessed, m_pitchBufSize + m_detectOverlapSamples); @@ -268,12 +274,21 @@ namespace Pitch while (m_circularBufferLo.ReadBuffer(m_pitchBufLo, m_curPitchSamplePos, m_pitchBufSize + m_detectOverlapSamples)) { float pitch1; - float pitch2 = 0.0f; + float pitch2; float detectedPitch = 0.0f; m_circularBufferHi.ReadBuffer(m_pitchBufHi, m_curPitchSamplePos, m_pitchBufSize + m_detectOverlapSamples); - pitch1 = m_dsp.DetectPitch(m_pitchBufLo, m_pitchBufHi, m_pitchBufSize); + maxVolume = 0f; + for (int i = 0; i < (m_pitchBufSize + m_detectOverlapSamples) / 2; i++) + { + if (maxVolume < m_pitchBufHi[i]) + maxVolume = m_pitchBufHi[i]; + if (maxVolume < m_pitchBufLo[i]) + maxVolume = m_pitchBufLo[i]; + } + + pitch1 = (maxVolume >= m_detectLevelThreshold) ? m_dsp.DetectPitch(m_pitchBufLo, m_pitchBufHi) : 0f; if (pitch1 > 0.0f) { @@ -281,7 +296,7 @@ namespace Pitch m_pitchBufLo.Copy(m_pitchBufLo, m_detectOverlapSamples - 1, 0, m_pitchBufSize); m_pitchBufHi.Copy(m_pitchBufHi, m_detectOverlapSamples - 1, 0, m_pitchBufSize); - pitch2 = m_dsp.DetectPitch(m_pitchBufLo, m_pitchBufHi, m_pitchBufSize); + pitch2 = m_dsp.DetectPitch(m_pitchBufLo, m_pitchBufHi); if (pitch2 > 0.0f) { @@ -301,6 +316,7 @@ namespace Pitch samplesProcessed += frameCount; } + LastMaxVol = maxVolume; } /// @@ -311,7 +327,7 @@ namespace Pitch if (m_sampleRate < 1.0f) return; - m_dsp = new PitchDsp(m_sampleRate, kMinFreq, kMaxFreq, m_detectLevelThreshold); + m_dsp = new PitchDsp(m_sampleRate, kMinFreq, kMaxFreq); m_iirFilterLoLo = new IIRFilter(); m_iirFilterLoLo.Proto = IIRFilter.ProtoType.Butterworth; @@ -411,4 +427,6 @@ namespace Pitch public int MidiCents { get; set; } } } + + // ReSharper restore InconsistentNaming } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CAnalyzer.cs similarity index 55% rename from Vocaluxe/Lib/Sound/Record/CAnalyzer.cs rename to Vocaluxe/Lib/Sound/Record/PitchTracker/CAnalyzer.cs index 9f9529e3..fcb45fa8 100644 --- a/Vocaluxe/Lib/Sound/Record/CAnalyzer.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CAnalyzer.cs @@ -1,13 +1,13 @@ using System; using System.Runtime.InteropServices; -namespace Vocaluxe.Lib.Sound.Record +namespace Vocaluxe.Lib.Sound.Record.PitchTracker { /// /// Analyzer from Performous /// Should be very reliable but needs some proof (artificial tests show some errors) /// - class CAnalyzer : IDisposable + class CAnalyzer : CPitchTracker { #region Imports [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] @@ -29,7 +29,7 @@ namespace Vocaluxe.Lib.Sound.Record private static extern void Analyzer_Process(IntPtr analyzer); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern double Analyzer_GetPeak(IntPtr analyzer); + private static extern float Analyzer_GetPeak(IntPtr analyzer); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern double Analyzer_FindNote(IntPtr analyzer, double minFreq, double maxFreq); @@ -39,45 +39,28 @@ namespace Vocaluxe.Lib.Sound.Record #endregion private IntPtr _Instance; + private float _VolumeTreshold; public CAnalyzer(uint step = 200) { _Instance = Analyzer_Create(step); + _VolumeTreshold = 0.01f; } - ~CAnalyzer() - { - _Dispose(false); - } - - public void Input(float[] data) - { - Analyzer_InputFloat(_Instance, data, data.Length); - } - - public void Input(short[] data) - { - Analyzer_InputShort(_Instance, data, data.Length); - } - - public void Input(byte[] data) + public override void Input(byte[] data) { Analyzer_InputByte(_Instance, data, data.Length / 2); } - public void Process() + public override int GetNote(out float maxVolume, float[] weights) { Analyzer_Process(_Instance); - } - - public double GetPeak() - { - return Analyzer_GetPeak(_Instance); - } - - public double FindNote(double minFreq = 35.0, double maxFreq = 1000.0) - { - return Analyzer_FindNote(_Instance, minFreq, maxFreq); + maxVolume = Analyzer_GetPeak(_Instance); + if (maxVolume < _VolumeTreshold) + return -1; + int note = (int)Math.Round(Analyzer_FindNote(_Instance, 60, 1800)); + _SetWeights(note, weights); + return note; } public bool Output(float[] data, float rate) @@ -85,7 +68,7 @@ namespace Vocaluxe.Lib.Sound.Record return Analyzer_OutputFloat(_Instance, data, data.Length, rate); } - private void _Dispose(bool disposing) + protected override void _Dispose(bool disposing) { if (_Instance == IntPtr.Zero) throw new ObjectDisposedException(GetType().Name); @@ -93,10 +76,15 @@ namespace Vocaluxe.Lib.Sound.Record _Instance = IntPtr.Zero; } - public void Dispose() + public override int GetNumHalfTones() { - _Dispose(true); - GC.SuppressFinalize(this); + return NumHalfTonesDef; + } + + public override float VolumeTreshold + { + get { return _VolumeTreshold; } + set { _VolumeTreshold = value; } } } @@ -104,7 +92,7 @@ namespace Vocaluxe.Lib.Sound.Record /// Pitchtracker (Pt) that uses autocorrelation (AKF) and AMDF /// Quite fast and perfect in artificial tests, but may fail in real world scenarios (e.g. missing fundamental) /// - class CPtAKF : IDisposable + class CPtAKF : CPitchTracker { #region Imports [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] @@ -113,14 +101,20 @@ namespace Vocaluxe.Lib.Sound.Record [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void PtAKF_Free(IntPtr analyzer); - [DllImport("PitchTracker.dll", EntryPoint = "PtAKF_GetNumHalfTones", CallingConvention = CallingConvention.Cdecl)] - public static extern int GetNumHalfTones(); + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int PtAKF_GetNumHalfTones(); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void PtAKF_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int PtAKF_GetNote(IntPtr analyzer, [Out] out double maxVolume, [Out] float[] weights); + private static extern void PtAKF_SetVolumeThreshold(IntPtr analyzer, float threshold); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern float PtAKF_GetVolumeThreshold(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int PtAKF_GetNote(IntPtr analyzer, [Out] out float maxVolume, [Out] float[] weights); #endregion private IntPtr _Instance; @@ -130,41 +124,40 @@ namespace Vocaluxe.Lib.Sound.Record _Instance = PtAKF_Create(step); } - ~CPtAKF() + public override int GetNumHalfTones() { - _Dispose(false); + return PtAKF_GetNumHalfTones(); } - public void Input(byte[] data) + public override float VolumeTreshold + { + get { return PtAKF_GetVolumeThreshold(_Instance); } + set { PtAKF_SetVolumeThreshold(_Instance, value); } + } + + public override void Input(byte[] data) { PtAKF_InputByte(_Instance, data, data.Length / 2); } - public int GetNote(out double maxVolume, float[] weights) + public override int GetNote(out float maxVolume, float[] weights) { return PtAKF_GetNote(_Instance, out maxVolume, weights); } - private void _Dispose(bool disposing) + protected override void _Dispose(bool disposing) { if (_Instance == IntPtr.Zero) throw new ObjectDisposedException(GetType().Name); PtAKF_Free(_Instance); _Instance = IntPtr.Zero; } - - public void Dispose() - { - _Dispose(true); - GC.SuppressFinalize(this); - } } /// /// Pitchtracker (Pt) that uses a dynamic wavelet (DyWa) algorithm - /// Quite fast and perfect in artificial tests, but may fail in real world scenarios (e.g. missing fundamental) /// - class CPtDyWa : IDisposable + class CPtDyWa : CPitchTracker { #region Imports [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] @@ -173,14 +166,17 @@ namespace Vocaluxe.Lib.Sound.Record [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void PtDyWa_Free(IntPtr analyzer); + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtDyWa_SetVolumeThreshold(IntPtr analyzer, float threshold); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern float PtDyWa_GetVolumeThreshold(IntPtr analyzer); + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void PtDyWa_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int PtDyWa_Process(IntPtr analyzer); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern double PtDyWa_GetNote(IntPtr analyzer); + private static extern double PtDyWa_FindNote(IntPtr analyzer, [Out] out float maxVolume); #endregion private IntPtr _Instance; @@ -190,38 +186,84 @@ namespace Vocaluxe.Lib.Sound.Record _Instance = PtDyWa_Create(step); } - ~CPtDyWa() - { - _Dispose(false); - } - - public void Input(byte[] data) + public override void Input(byte[] data) { PtDyWa_InputByte(_Instance, data, data.Length / 2); } - public void Process() + public override int GetNote(out float maxVolume, float[] weights) { - PtDyWa_Process(_Instance); + int note = (int)Math.Round(PtDyWa_FindNote(_Instance, out maxVolume)); + _SetWeights(note, weights); + return note; } - public double GetNote() + public override int GetNumHalfTones() { - return PtDyWa_GetNote(_Instance); + return NumHalfTonesDef; } - private void _Dispose(bool disposing) + public override float VolumeTreshold + { + get { return PtDyWa_GetVolumeThreshold(_Instance); } + set { PtDyWa_SetVolumeThreshold(_Instance, value); } + } + + protected override void _Dispose(bool disposing) { if (_Instance == IntPtr.Zero) throw new ObjectDisposedException(GetType().Name); PtDyWa_Free(_Instance); _Instance = IntPtr.Zero; } + } - public void Dispose() + /// + /// Pitchtracker (Pt) in C# that uses IIR filters for smoothing and an intelligent detection algorithm to reduce calculations + /// + class CPtSharp : CPitchTracker + { + private Pitch.PitchTracker _Instance; + + public CPtSharp() { - _Dispose(true); - GC.SuppressFinalize(this); + _Instance = new Pitch.PitchTracker {SampleRate = 44100, DetectLevelThreshold = 0.01f, PitchRecordHistorySize = 1}; + } + + public override void Input(byte[] data) + { + short[] samplesShort = new short[data.Length / 2]; + Buffer.BlockCopy(data, 0, samplesShort, 0, data.Length); + float[] samplesFloat = new float[samplesShort.Length]; + for (int i = 0; i < samplesShort.Length; i++) + samplesFloat[i] = (float)samplesShort[i] / short.MaxValue; + _Instance.ProcessBuffer(samplesFloat); + } + + public override int GetNote(out float maxVolume, float[] weights) + { + int note = _Instance.CurrentPitchRecord.MidiNote - 15 - 21; + maxVolume = _Instance.LastMaxVol; + _SetWeights(note, weights); + return note; + } + + public override int GetNumHalfTones() + { + return NumHalfTonesDef; + } + + public override float VolumeTreshold + { + get { return _Instance.DetectLevelThreshold; } + set { _Instance.DetectLevelThreshold = value; } + } + + protected override void _Dispose(bool disposing) + { + if (_Instance == null) + throw new ObjectDisposedException(GetType().Name); + _Instance = null; } } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/IPitchTracker.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/IPitchTracker.cs new file mode 100644 index 00000000..94c4876f --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/IPitchTracker.cs @@ -0,0 +1,73 @@ +using System; +using System.Diagnostics; + +namespace Vocaluxe.Lib.Sound.Record.PitchTracker +{ + /// + /// Base class/Interface for pitch detectors + /// Most likely some structures or system resources are used, hence it should be disposed if no longer needed + /// + abstract class CPitchTracker : IDisposable + { + //Default number of half tones (1 octave) + protected const int NumHalfTonesDef = 12; + + ~CPitchTracker() + { + _Dispose(false); + } + + protected abstract void _Dispose(bool disposing); + + public void Dispose() + { + _Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Method to set weights if the algorithm does not provide anything that could simulate a visualizer. + /// Should be called with each valid detection + /// + /// Current note + /// Array of weights (Length = NumHalfTonesDef) + protected static void _SetWeights(int note, float[] weights) + { + Debug.Assert(weights.Length == NumHalfTonesDef); + for (int i = 0; i < NumHalfTonesDef; i++) + weights[i] *= 0.9f; + if (note < 0) + return; + int w = note % NumHalfTonesDef; + weights[w] = Math.Min(1f, weights[w] + 0.15f); + } + + /// + /// Gets the number of half tones the algorithm provides weights for. + /// This may not be the number of half tones the algorithm detects! + /// + /// + public abstract int GetNumHalfTones(); + + /// + /// The treshold for detecting silence + /// Value (0-1) for which everything below is considered silence + /// + public abstract float VolumeTreshold { get; set; } + + /// + /// Recorded data. Has to be 16 bit short values. + /// + /// 16bit short values of data + public abstract void Input(byte[] data); + + /// + /// Returns the current note detected + /// + /// Current maximum volume (0-1) + /// Array of NumHalfTones floats that gets filled with the current weights (0-1) where each value indicates how strong that tone is. + /// Only for basic visualization as it may not be accurate. + /// Current note index (0 = C2, 12 = C3, ...) + public abstract int GetNote(out float maxVolume, float[] weights); + } +} \ No newline at end of file diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index bc2260e4..852cd4f4 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -223,7 +223,7 @@ - + @@ -268,6 +268,7 @@ + From 9bf12315b7e63f2913271b84b2f05a62cdba38a7 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Wed, 16 Apr 2014 21:11:05 +0200 Subject: [PATCH 26/34] Move Pitchtrackers to separate files --- .../Sound/Record/PitchTracker/CAnalyzer.cs | 179 ------------------ .../Lib/Sound/Record/PitchTracker/CPtAKF.cs | 71 +++++++ .../Lib/Sound/Record/PitchTracker/CPtDyWa.cs | 69 +++++++ .../Lib/Sound/Record/PitchTracker/CPtSharp.cs | 53 ++++++ Vocaluxe/Vocaluxe.csproj | 3 + 5 files changed, 196 insertions(+), 179 deletions(-) create mode 100644 Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs create mode 100644 Vocaluxe/Lib/Sound/Record/PitchTracker/CPtDyWa.cs create mode 100644 Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CAnalyzer.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CAnalyzer.cs index fcb45fa8..2a50540f 100644 --- a/Vocaluxe/Lib/Sound/Record/PitchTracker/CAnalyzer.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CAnalyzer.cs @@ -87,183 +87,4 @@ namespace Vocaluxe.Lib.Sound.Record.PitchTracker set { _VolumeTreshold = value; } } } - - /// - /// Pitchtracker (Pt) that uses autocorrelation (AKF) and AMDF - /// Quite fast and perfect in artificial tests, but may fail in real world scenarios (e.g. missing fundamental) - /// - class CPtAKF : CPitchTracker - { - #region Imports - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr PtAKF_Create(uint step); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void PtAKF_Free(IntPtr analyzer); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int PtAKF_GetNumHalfTones(); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void PtAKF_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void PtAKF_SetVolumeThreshold(IntPtr analyzer, float threshold); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern float PtAKF_GetVolumeThreshold(IntPtr analyzer); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int PtAKF_GetNote(IntPtr analyzer, [Out] out float maxVolume, [Out] float[] weights); - #endregion - - private IntPtr _Instance; - - public CPtAKF(uint step = 200) - { - _Instance = PtAKF_Create(step); - } - - public override int GetNumHalfTones() - { - return PtAKF_GetNumHalfTones(); - } - - public override float VolumeTreshold - { - get { return PtAKF_GetVolumeThreshold(_Instance); } - set { PtAKF_SetVolumeThreshold(_Instance, value); } - } - - public override void Input(byte[] data) - { - PtAKF_InputByte(_Instance, data, data.Length / 2); - } - - public override int GetNote(out float maxVolume, float[] weights) - { - return PtAKF_GetNote(_Instance, out maxVolume, weights); - } - - protected override void _Dispose(bool disposing) - { - if (_Instance == IntPtr.Zero) - throw new ObjectDisposedException(GetType().Name); - PtAKF_Free(_Instance); - _Instance = IntPtr.Zero; - } - } - - /// - /// Pitchtracker (Pt) that uses a dynamic wavelet (DyWa) algorithm - /// - class CPtDyWa : CPitchTracker - { - #region Imports - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr PtDyWa_Create(uint step); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void PtDyWa_Free(IntPtr analyzer); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void PtDyWa_SetVolumeThreshold(IntPtr analyzer, float threshold); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern float PtDyWa_GetVolumeThreshold(IntPtr analyzer); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern void PtDyWa_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); - - [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern double PtDyWa_FindNote(IntPtr analyzer, [Out] out float maxVolume); - #endregion - - private IntPtr _Instance; - - public CPtDyWa(uint step = 200) - { - _Instance = PtDyWa_Create(step); - } - - public override void Input(byte[] data) - { - PtDyWa_InputByte(_Instance, data, data.Length / 2); - } - - public override int GetNote(out float maxVolume, float[] weights) - { - int note = (int)Math.Round(PtDyWa_FindNote(_Instance, out maxVolume)); - _SetWeights(note, weights); - return note; - } - - public override int GetNumHalfTones() - { - return NumHalfTonesDef; - } - - public override float VolumeTreshold - { - get { return PtDyWa_GetVolumeThreshold(_Instance); } - set { PtDyWa_SetVolumeThreshold(_Instance, value); } - } - - protected override void _Dispose(bool disposing) - { - if (_Instance == IntPtr.Zero) - throw new ObjectDisposedException(GetType().Name); - PtDyWa_Free(_Instance); - _Instance = IntPtr.Zero; - } - } - - /// - /// Pitchtracker (Pt) in C# that uses IIR filters for smoothing and an intelligent detection algorithm to reduce calculations - /// - class CPtSharp : CPitchTracker - { - private Pitch.PitchTracker _Instance; - - public CPtSharp() - { - _Instance = new Pitch.PitchTracker {SampleRate = 44100, DetectLevelThreshold = 0.01f, PitchRecordHistorySize = 1}; - } - - public override void Input(byte[] data) - { - short[] samplesShort = new short[data.Length / 2]; - Buffer.BlockCopy(data, 0, samplesShort, 0, data.Length); - float[] samplesFloat = new float[samplesShort.Length]; - for (int i = 0; i < samplesShort.Length; i++) - samplesFloat[i] = (float)samplesShort[i] / short.MaxValue; - _Instance.ProcessBuffer(samplesFloat); - } - - public override int GetNote(out float maxVolume, float[] weights) - { - int note = _Instance.CurrentPitchRecord.MidiNote - 15 - 21; - maxVolume = _Instance.LastMaxVol; - _SetWeights(note, weights); - return note; - } - - public override int GetNumHalfTones() - { - return NumHalfTonesDef; - } - - public override float VolumeTreshold - { - get { return _Instance.DetectLevelThreshold; } - set { _Instance.DetectLevelThreshold = value; } - } - - protected override void _Dispose(bool disposing) - { - if (_Instance == null) - throw new ObjectDisposedException(GetType().Name); - _Instance = null; - } - } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs new file mode 100644 index 00000000..0dbbc501 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs @@ -0,0 +1,71 @@ +using System; +using System.Runtime.InteropServices; + +namespace Vocaluxe.Lib.Sound.Record.PitchTracker +{ + /// + /// Pitchtracker (Pt) that uses autocorrelation (AKF) and AMDF + /// Quite fast and perfect in artificial tests, but may fail in real world scenarios (e.g. missing fundamental) + /// + class CPtAKF : CPitchTracker + { + #region Imports + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr PtAKF_Create(uint step); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtAKF_Free(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int PtAKF_GetNumHalfTones(); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtAKF_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtAKF_SetVolumeThreshold(IntPtr analyzer, float threshold); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern float PtAKF_GetVolumeThreshold(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int PtAKF_GetNote(IntPtr analyzer, [Out] out float maxVolume, [Out] float[] weights); + #endregion + + private IntPtr _Instance; + + public CPtAKF(uint step = 200) + { + _Instance = PtAKF_Create(step); + } + + public override int GetNumHalfTones() + { + return PtAKF_GetNumHalfTones(); + } + + public override float VolumeTreshold + { + get { return PtAKF_GetVolumeThreshold(_Instance); } + set { PtAKF_SetVolumeThreshold(_Instance, value); } + } + + public override void Input(byte[] data) + { + PtAKF_InputByte(_Instance, data, data.Length / 2); + } + + public override int GetNote(out float maxVolume, float[] weights) + { + return PtAKF_GetNote(_Instance, out maxVolume, weights); + } + + protected override void _Dispose(bool disposing) + { + if (_Instance == IntPtr.Zero) + throw new ObjectDisposedException(GetType().Name); + PtAKF_Free(_Instance); + _Instance = IntPtr.Zero; + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtDyWa.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtDyWa.cs new file mode 100644 index 00000000..2907f1c8 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtDyWa.cs @@ -0,0 +1,69 @@ +using System; +using System.Runtime.InteropServices; + +namespace Vocaluxe.Lib.Sound.Record.PitchTracker +{ + /// + /// Pitchtracker (Pt) that uses a dynamic wavelet (DyWa) algorithm + /// + class CPtDyWa : CPitchTracker + { + #region Imports + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr PtDyWa_Create(uint step); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtDyWa_Free(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtDyWa_SetVolumeThreshold(IntPtr analyzer, float threshold); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern float PtDyWa_GetVolumeThreshold(IntPtr analyzer); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void PtDyWa_InputByte(IntPtr analyzer, [In] byte[] data, int sampleCt); + + [DllImport("PitchTracker.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern double PtDyWa_FindNote(IntPtr analyzer, [Out] out float maxVolume); + #endregion + + private IntPtr _Instance; + + public CPtDyWa(uint step = 200) + { + _Instance = PtDyWa_Create(step); + } + + public override void Input(byte[] data) + { + PtDyWa_InputByte(_Instance, data, data.Length / 2); + } + + public override int GetNote(out float maxVolume, float[] weights) + { + int note = (int)Math.Round(PtDyWa_FindNote(_Instance, out maxVolume)); + _SetWeights(note, weights); + return note; + } + + public override int GetNumHalfTones() + { + return NumHalfTonesDef; + } + + public override float VolumeTreshold + { + get { return PtDyWa_GetVolumeThreshold(_Instance); } + set { PtDyWa_SetVolumeThreshold(_Instance, value); } + } + + protected override void _Dispose(bool disposing) + { + if (_Instance == IntPtr.Zero) + throw new ObjectDisposedException(GetType().Name); + PtDyWa_Free(_Instance); + _Instance = IntPtr.Zero; + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs new file mode 100644 index 00000000..af38e362 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs @@ -0,0 +1,53 @@ +using System; + +namespace Vocaluxe.Lib.Sound.Record.PitchTracker +{ + /// + /// Pitchtracker (Pt) in C# that uses IIR filters for smoothing and an intelligent detection algorithm to reduce calculations + /// + class CPtSharp : CPitchTracker + { + private Pitch.PitchTracker _Instance; + + public CPtSharp() + { + _Instance = new Pitch.PitchTracker {SampleRate = 44100, DetectLevelThreshold = 0.01f, PitchRecordHistorySize = 1}; + } + + public override void Input(byte[] data) + { + short[] samplesShort = new short[data.Length / 2]; + Buffer.BlockCopy(data, 0, samplesShort, 0, data.Length); + float[] samplesFloat = new float[samplesShort.Length]; + for (int i = 0; i < samplesShort.Length; i++) + samplesFloat[i] = (float)samplesShort[i] / short.MaxValue; + _Instance.ProcessBuffer(samplesFloat); + } + + public override int GetNote(out float maxVolume, float[] weights) + { + int note = _Instance.CurrentPitchRecord.MidiNote - 15 - 21; + maxVolume = _Instance.LastMaxVol; + _SetWeights(note, weights); + return note; + } + + public override int GetNumHalfTones() + { + return NumHalfTonesDef; + } + + public override float VolumeTreshold + { + get { return _Instance.DetectLevelThreshold; } + set { _Instance.DetectLevelThreshold = value; } + } + + protected override void _Dispose(bool disposing) + { + if (_Instance == null) + throw new ObjectDisposedException(GetType().Name); + _Instance = null; + } + } +} \ No newline at end of file diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 852cd4f4..1f6afd01 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -268,6 +268,9 @@ + + + From 001884ed9d8af6bb2aa5ff90d7db5b392db295c1 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Wed, 16 Apr 2014 23:58:49 +0200 Subject: [PATCH 27/34] Extract class for testing pitchtrackers Fix some typos --- PitchTracker/PitchWrapper.cpp | 2 +- PitchTracker/PitchWrapper.h | 2 +- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 338 +-------------- .../Record/PitchTracker/CPitchTrackerTest.cs | 388 ++++++++++++++++++ Vocaluxe/Vocaluxe.csproj | 1 + 5 files changed, 398 insertions(+), 333 deletions(-) create mode 100644 Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs diff --git a/PitchTracker/PitchWrapper.cpp b/PitchTracker/PitchWrapper.cpp index 6314b64c..612882c0 100644 --- a/PitchTracker/PitchWrapper.cpp +++ b/PitchTracker/PitchWrapper.cpp @@ -71,7 +71,7 @@ int PtAKF_GetNumHalfTones(){ return PtAKF::GetNumHalfTones(); } -void PtAKF_SetVolumeTreshold(PtAKF* analyzer, float threshold){ +void PtAKF_SetVolumeThreshold(PtAKF* analyzer, float threshold){ if(!analyzer) return; analyzer->SetVolumeThreshold(threshold); diff --git a/PitchTracker/PitchWrapper.h b/PitchTracker/PitchWrapper.h index 6425f862..11b32b84 100644 --- a/PitchTracker/PitchWrapper.h +++ b/PitchTracker/PitchWrapper.h @@ -29,7 +29,7 @@ DllExport void PtDyWa_Free(PtDyWa* analyzer); DllExport void PtDyWa_SetVolumeTreshold(PtDyWa* analyzer,float threshold); DllExport float PtDyWa_GetVolumeThreshold(PtDyWa* analyzer); DllExport void PtDyWa_InputByte(PtDyWa* analyzer, char* data, int sampleCt); -DllExport double PtDyWa_FindNote(PtDyWa* analyzer); +DllExport double PtDyWa_FindNote(PtDyWa* analyzer, float* maxVolume); /* public ref class CTone { diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 9a4a7b4d..43950e7d 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -18,28 +18,12 @@ #define TEST_PITCH using System; -#if TEST_PITCH -using System.Collections.Generic; -using System.IO; -using System.Windows.Forms; -using System.Diagnostics; -using Pitch; -using Vocaluxe.Lib.Sound.Record.Pitch; using Vocaluxe.Lib.Sound.Record.PitchTracker; -using VocaluxeLib; -using VocaluxeLib.Utils; - -#endif namespace Vocaluxe.Lib.Sound.Record { class CBuffer : IDisposable { -#if TEST_PITCH - //Half tones: C C# D D# E F F# G G# A A# B - private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) - private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) -#endif private CPitchTracker _PitchTracker = new CPtAKF(); private float _MaxVolume; @@ -50,8 +34,12 @@ namespace Vocaluxe.Lib.Sound.Record ToneWeigths = new float[GetNumHalfTones()]; Reset(); #if TEST_PITCH - _TestPitchDetection(); - Reset(); + CPitchTrackerTest tester = new CPitchTrackerTest(); + tester.AddAnalyzer(new CAnalyzer()); + tester.AddAnalyzer(new CPtAKF()); + tester.AddAnalyzer(new CPtDyWa()); + tester.AddAnalyzer(new CPtSharp()); + tester.RunTest(); #endif } @@ -109,8 +97,7 @@ namespace Vocaluxe.Lib.Sound.Record public void AnalyzeBuffer() { - //_MaxVolume = _Analyzer.GetPeak() / 43 + 1; - int tone = _PitchTracker.GetNote(out _MaxVolume, ToneWeigths); //(int)Math.Round(_Analyzer.FindNote()); // + int tone = _PitchTracker.GetNote(out _MaxVolume, ToneWeigths); if (tone >= 0) { ToneAbs = tone; @@ -135,316 +122,5 @@ namespace Vocaluxe.Lib.Sound.Record _PitchTracker = null; } } - -#if TEST_PITCH - private static bool _PitchTestRun; - - private static string _ToneToNote(int tone, bool withOctave = true) - { - if (tone < 0) - return "inv."; - tone += 24; - string[] notes = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; - string result = notes[tone % 12]; - if (withOctave) - result += (tone / 12); - return result; - } - - private void _TestPitchDetection() - { - if (_PitchTestRun) - return; - _PitchTestRun = true; - const int toneFrom = 0; - const int toneTo = -1; // 47; //B5 - Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); - byte[] data; - byte[] data2 = new byte[2048]; - int ok = 0; - int tests = 0; - double angle = 0; - for (int distort = 0; distort < 10; distort++) - { - for (int tone = toneFrom; tone <= toneTo; tone++) - { - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, ref angle, out data); - _Distort(data, tone, distort); - - for (int i = 0; i < 4; i++) - { - Buffer.BlockCopy(data, i * 2048, data2, 0, 2048); - ProcessNewBuffer(data2); - AnalyzeBuffer(); - } - if (!ToneValid) - CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " not detected (Distortion: " + distort + ")"); - else if (Tone != tone % 12) - { - CBase.Log.LogDebug("Note " + _ToneToNote(tone) + " wrongly detected as " + _ToneToNote(Tone, false) + " (Distortion: " + distort + ")"); - CWavFile file = new CWavFile(); - file.Create(tone + "-" + distort + ".wav", 1, 44100, 16); - file.Write16BitSamples(data, 1); - file.Close(); - } - else - ok++; - tests++; - } - } - /*if (_TestFile("toneG3.wav", 19)) - ok++; - tests++; - if (_TestFile("toneG3Miss.wav", 19)) - ok++; - tests++; - if (_TestFile("toneG4.wav", 31)) - ok++; - tests++;*/ - _TestFile("whistling3.wav", "whistling3.txt", ref tests, ref ok); - _TestFile("sClausVoc.wav", "sClausVoc.txt", ref tests, ref ok); - - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, ref angle, out data); - Stopwatch sw = new Stopwatch(); - sw.Start(); - const int repeats = 100; - for (int i = 0; i < repeats; i++) - { - ProcessNewBuffer(data); - AnalyzeBuffer(); - } - sw.Stop(); - string msg = "Analyser: Errors: " + (tests - ok) + "/" + tests + "; Speed: " + - (int)(repeats / (sw.ElapsedMilliseconds / 1000.0)) + " buffers/s"; - Console.WriteLine(msg); - MessageBox.Show(msg); - Reset(); - } - - private struct STimedNote - { - public int Time, Note; - } - - private void _TestFile(string fileName, string testFileName, ref int ct, ref int ok) - { - if (!File.Exists(testFileName)) - { - ok = ct = 0; - return; - } - List tones = new List(); - using (StreamReader reader = new StreamReader(testFileName)) - { - String line; - while ((line = reader.ReadLine()) != null) - { - int p = line.IndexOf(' '); - if (p < 0) - continue; - STimedNote note; - note.Time = int.Parse(line.Substring(0, p)); - note.Note = int.Parse(line.Substring(p + 1)); - tones.Add(note); - } - } - _TestFile(fileName, tones, ref ct, ref ok); - } - - private bool _TestFile(string fileName, int tone) - { - STimedNote note; - note.Note = tone; - note.Time = 46; - List tones = new List {note}; - int ct = 0; - int ok = 0; - _TestFile(fileName, tones, ref ct, ref ok); - return ok >= ct - 4; - } - - private bool _IsNoteValid(int note, int time, IList tones) - { - const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples - for (int i = 0; i < tones.Count; i++) - { - if (tones[i].Time > time) - break; - if (i + 1 == tones.Count || time <= tones[i + 1].Time + lastNoteMaxTimeDiff) - { - if (tones[i].Note == note) - return true; - } - } - return false; - } - - private void _TestFile(string fileName, IList tones, ref int ct, ref int ok) - { - CWavFile wavFile = new CWavFile(); - try - { - if (!wavFile.Open(fileName)) - return; - if (wavFile.BitsPerSample != 16) - { - wavFile.Close(); - return; - } - int samplesRead = 0; - int curTimeIndex = -1; - int curNote = -1; - const int maxSamplesPerBatch = 512; - CPitchTracker analyzer2 = new CAnalyzer(); - CPitchTracker analyzer3 = new CPtDyWa(); - CPitchTracker analyzer4 = new CPtSharp(); - int[] detectedTones = new int[4]; - int[] oks = new int[4]; - float dummyMaxVol; - float[] dummyWeights = new float[ToneWeigths.Length]; - int lCt = 0; - while (wavFile.NumSamplesLeft > maxSamplesPerBatch) - { - byte[] samples = wavFile.GetNextSamples16BitAsBytes(maxSamplesPerBatch, 1); - samplesRead += samples.Length / 2; - int time = samplesRead * 1000 / wavFile.SampleRate; - ProcessNewBuffer(samples); - AnalyzeBuffer(); - analyzer2.Input(samples); - analyzer3.Input(samples); - analyzer4.Input(samples); - while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) - { - curTimeIndex++; - curNote = tones[curTimeIndex].Note; - } - if (curNote < 0) - continue; - detectedTones[0] = ToneValid ? ToneAbs : -1; - detectedTones[1] = analyzer2.GetNote(out dummyMaxVol, dummyWeights); - detectedTones[2] = analyzer3.GetNote(out dummyMaxVol, dummyWeights); - detectedTones[3] = analyzer4.GetNote(out dummyMaxVol, dummyWeights); - lCt++; - /*if (!ToneValid) - CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms not detected"); - else if (ToneAbs % 12 != curNote % 12) - CBase.Log.LogDebug("Note " + _ToneToNote(curNote) + " at " + time + "ms wrongly detected as " + _ToneToNote(ToneAbs)); - else - ok++;*/ - bool[] valids = new bool[4]; - bool error = false; - for (int i = 0; i < 4; i++) - { - valids[i] = _IsNoteValid(detectedTones[i], time, tones); - if (valids[i]) - oks[i]++; - else - error = true; - } - if (error) - { - string msg = "Note " + _ToneToNote(curNote) + " at " + time + "ms detected as "; - for (int i = 0; i < 4; i++) - msg += _ToneToNote(detectedTones[i]) + (valids[i] ? "" : "(!)") + "; "; - CBase.Log.LogDebug(msg); - } - } - string msg2 = "Detected "; - for (int i = 0; i < 4; i++) - msg2 += oks[i] + "|" + (lCt - oks[i]) + " "; - CBase.Log.LogDebug(msg2); - } - catch (Exception e) - { - Console.WriteLine("Error on file " + fileName + ": " + e); - } - wavFile.Close(); - } - - private static short[] _GetDistort(int len, int tone, int type) - { - short[] sdata = new short[len]; - if (type < 9) - { - int newTone = 1; - switch (type) - { - case 0: - newTone = 2; - break; - case 1: - newTone = 3; - break; - case 2: - newTone = 6; - break; - case 3: - newTone = 8; - break; - case 4: - newTone = 10; - break; - case 5: - newTone = 15; - break; - case 6: - newTone = 25; - break; - case 7: - newTone = 26; - break; - case 8: - newTone = 29; - break; - } - byte[] data2; - double angle = 0; - _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone + newTone), 44100, ref angle, out data2); - Buffer.BlockCopy(data2, 0, sdata, 0, len * 2); - } - else - { - Random r = new Random(0xBEEF); - for (int i = 0; i < sdata.Length; i++) - sdata[i] = (short)(r.Next() - Int16.MinValue); - } - return sdata; - } - - private static void _Distort(byte[] data, int tone, int distortCt) - { - if (distortCt < 1) - return; - short[] sdata = new short[data.Length / 2]; - Buffer.BlockCopy(data, 0, sdata, 0, data.Length); - - short[][] distortions = new short[distortCt][]; - for (int i = 0; i < distortCt; i++) - distortions[i] = _GetDistort(data.Length / 2, tone, i); - - for (int i = 0; i < sdata.Length; i++) - { - double distortion = 0; - for (int j = 0; j < distortCt; j++) - distortion += distortions[j][i]; - distortion /= distortCt; - sdata[i] = (short)(sdata[i] * 4.0 / 5.0 + distortion / 5.0); - } - Buffer.BlockCopy(sdata, 0, data, 0, data.Length); - } - - private static void _GetSineWave(double freq, int sampleRate, ref double angle, out byte[] data) - { - const short max = short.MaxValue; - const int len = 4096; //sampleRate * durationMs / 1000; - short[] data16Bit = new short[len]; - for (int i = 0; i < len; i++) - data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq + angle) * max); - angle = 2 * Math.PI * len / sampleRate * freq + angle; - angle = angle % (2 * Math.PI); - data = new byte[data16Bit.Length * 2]; - Buffer.BlockCopy(data16Bit, 0, data, 0, data.Length); - } -#endif } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs new file mode 100644 index 00000000..00670ad1 --- /dev/null +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs @@ -0,0 +1,388 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using VocaluxeLib; +using VocaluxeLib.Utils; + +namespace Vocaluxe.Lib.Sound.Record.PitchTracker +{ + class CPitchTrackerTest + { + //Half tones: C C# D D# E F F# G G# A A# B + private const double _BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) + private const double _HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) + + private readonly List _Analyzers = new List(); + private int[] _Tones; + private float[][] _Weights; + private float _MaxVolume; + private int _CurTestCount; + private int[] _CurPassedCount; + private int _TestCount; + private int[] _PassedCount; + private int[] _SamplesPerSec; + + private static bool _IsRun; + + public void AddAnalyzer(CPitchTracker analyzer) + { + _Analyzers.Add(analyzer); + } + + #region Init + private void _InitTests() + { + _Tones = new int[_Analyzers.Count]; + _TestCount = 0; + _PassedCount = new int[_Analyzers.Count]; + _CurTestCount = 0; + _CurPassedCount = new int[_Analyzers.Count]; + _Weights = new float[_Analyzers.Count][]; + for (int i = 0; i < _Analyzers.Count; i++) + _Weights[i] = new float[_Analyzers[i].GetNumHalfTones()]; + _SamplesPerSec = new int[_Analyzers.Count]; + } + + private void _InitNext(string lastTest) + { + string msg = "Errors " + lastTest + ": "; + for (int i = 0; i < _CurPassedCount.Length; i++) + { + msg += _CurTestCount - _CurPassedCount[i] + " "; + _PassedCount[i] += _CurPassedCount[i]; + _CurPassedCount[i] = 0; + } + msg += "of " + _CurTestCount; + CBase.Log.LogDebug(msg); + _TestCount += _CurTestCount; + _CurTestCount = 0; + } + #endregion + + public void RunTest(bool reRun = false) + { + if (_IsRun && !reRun) + return; + _IsRun = true; + + _InitTests(); + + _TestSines(); + _InitNext("Sines"); + + _TestFile("toneG3.wav", 19); + _InitNext("Real G3"); + + _TestFile("toneG3Miss.wav", 19); + _InitNext("Real G3 with miss. fundamental"); + + _TestFile("toneG4.wav", 31); + _InitNext("Real G4"); + + _TestFile("whistling3.wav", "whistling3.txt"); + _InitNext("High whistling"); + + _TestFile("sClausVoc.wav", "sClausVoc.txt"); + _InitNext("Real song"); + + _TestSpeed(); + CBase.Log.LogDebug("Finished: "); + for (int i = 0; i < _Analyzers.Count; i++) + { + string msg = _Analyzers[i].GetType().Name + ":"; + msg += " Errors=" + (_TestCount - _PassedCount[i]); + msg += " Passed=" + _PassedCount[i]; + msg += " Total=" + _TestCount; + msg += " Speed=" + _SamplesPerSec[i] + "samples/s (=" + (_SamplesPerSec[i] / 44100) + "rec.s/s)"; + CBase.Log.LogDebug(msg); + } + } + + private void _TestSpeed() + { + const int samplesPerBuffer = 512; + byte[] data; + byte[] data2 = new byte[samplesPerBuffer * 2]; + double angle = 0; + const int repeats = 100; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, 5), 44100, samplesPerBuffer * repeats, ref angle, out data); + for (int i = 0; i < _Analyzers.Count; i++) + { + CPitchTracker analyzer = _Analyzers[i]; + Stopwatch sw = new Stopwatch(); + sw.Start(); + for (int j = 0; j < repeats; j++) + { + Buffer.BlockCopy(data, 0, data2, 0, samplesPerBuffer * 2); + analyzer.Input(data2); + analyzer.GetNote(out _MaxVolume, _Weights[j]); + } + sw.Stop(); + _SamplesPerSec[i] = (int)Math.Round(samplesPerBuffer * repeats / (sw.ElapsedMilliseconds / 1000.0)); + } + } + + private void _Process(byte[] data) + { + for (int j = 0; j < _Analyzers.Count; j++) + { + _Analyzers[j].Input(data); + _Tones[j] = _Analyzers[j].GetNote(out _MaxVolume, _Weights[j]); + } + } + + private static string _ToneToNote(int tone, bool withOctave = true) + { + if (tone < 0) + return "inv."; + tone += 24; + string[] notes = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; + string result = notes[tone % 12]; + if (withOctave) + result += (tone / 12); + return result; + } + + #region Sines + private void _TestSines() + { + const int toneFrom = 0; + const int toneTo = 47; //B5 + const int sampleCt = 4096; + const int batchCt = 512; + byte[] data2 = new byte[batchCt * 2]; + Console.WriteLine("Testing notes " + _ToneToNote(toneFrom) + " - " + _ToneToNote(toneTo)); + double angle = 0; + bool[] valids = new bool[_Analyzers.Count]; + for (int distort = 0; distort < 10; distort++) + { + for (int tone = toneFrom; tone <= toneTo; tone++) + { + byte[] data; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone), 44100, sampleCt, ref angle, out data); + _Distort(data, tone, distort); + + for (int i = 0; i < sampleCt / batchCt; i++) + { + Buffer.BlockCopy(data, i * batchCt * 2, data2, 0, batchCt * 2); + _Process(data2); + if (i * batchCt < 2048) + continue; + _CurTestCount++; + bool ok = true; + for (int j = 0; j < valids.Length; j++) + { + valids[j] = _Tones[j] == tone; + if (!valids[j]) + ok = false; + else + _CurPassedCount[j]++; + } + if (ok) + continue; + string msg = "Note " + _ToneToNote(tone) + " detected as "; + for (int j = 0; j < valids.Length; j++) + msg += _ToneToNote(_Tones[j]) + (valids[j] ? "" : "(!)") + "; "; + CBase.Log.LogDebug(msg); + } + } + } + } + + private static short[] _GetDistort(int sampleCt, int tone, int type) + { + short[] sdata = new short[sampleCt]; + if (type < 9) + { + int newTone = 1; + switch (type) + { + case 0: + newTone = 2; + break; + case 1: + newTone = 3; + break; + case 2: + newTone = 6; + break; + case 3: + newTone = 8; + break; + case 4: + newTone = 10; + break; + case 5: + newTone = 15; + break; + case 6: + newTone = 25; + break; + case 7: + newTone = 26; + break; + case 8: + newTone = 29; + break; + } + byte[] data2; + double angle = 0; + _GetSineWave(_BaseToneFreq * Math.Pow(_HalftoneBase, tone + newTone), 44100, sampleCt, ref angle, out data2); + Buffer.BlockCopy(data2, 0, sdata, 0, sampleCt * 2); + } + else + { + Random r = new Random(0xBEEF); + for (int i = 0; i < sdata.Length; i++) + sdata[i] = (short)(r.Next() - Int16.MinValue); + } + return sdata; + } + + private static void _Distort(byte[] data, int tone, int distortCt) + { + if (distortCt < 1) + return; + short[] sdata = new short[data.Length / 2]; + Buffer.BlockCopy(data, 0, sdata, 0, data.Length); + + short[][] distortions = new short[distortCt][]; + for (int i = 0; i < distortCt; i++) + distortions[i] = _GetDistort(data.Length / 2, tone, i); + + for (int i = 0; i < sdata.Length; i++) + { + double distortion = 0; + for (int j = 0; j < distortCt; j++) + distortion += distortions[j][i]; + distortion /= distortCt; + sdata[i] = (short)(sdata[i] * 4.0 / 5.0 + distortion / 5.0); + } + Buffer.BlockCopy(sdata, 0, data, 0, data.Length); + } + + private static void _GetSineWave(double freq, int sampleRate, int sampleCt, ref double angle, out byte[] data) + { + const short max = short.MaxValue; + short[] data16Bit = new short[sampleCt]; + for (int i = 0; i < sampleCt; i++) + data16Bit[i] = (short)(Math.Sin(2 * Math.PI * i / sampleRate * freq + angle) * max); + angle = 2 * Math.PI * sampleCt / sampleRate * freq + angle; + angle = angle % (2 * Math.PI); + data = new byte[data16Bit.Length * 2]; + Buffer.BlockCopy(data16Bit, 0, data, 0, data.Length); + } + #endregion + + #region File + private struct STimedNote + { + public int Time, Note; + } + + private void _TestFile(string fileName, string testFileName) + { + if (!File.Exists(testFileName)) + return; + List tones = new List(); + using (StreamReader reader = new StreamReader(testFileName)) + { + String line; + while ((line = reader.ReadLine()) != null) + { + int p = line.IndexOf(' '); + if (p < 0) + continue; + STimedNote note; + note.Time = int.Parse(line.Substring(0, p)); + note.Note = int.Parse(line.Substring(p + 1)); + tones.Add(note); + } + } + _TestFile(fileName, tones); + } + + private void _TestFile(string fileName, int tone) + { + STimedNote note; + note.Note = tone; + note.Time = 46; + List tones = new List {note}; + _TestFile(fileName, tones); + } + + private static bool _IsNoteValid(int note, int time, IList tones) + { + const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples + for (int i = 0; i < tones.Count; i++) + { + if (tones[i].Time > time) + break; + if (i + 1 == tones.Count || time <= tones[i + 1].Time + lastNoteMaxTimeDiff) + { + if (tones[i].Note == note) + return true; + } + } + return false; + } + + private void _TestFile(string fileName, IList tones) + { + CWavFile wavFile = new CWavFile(); + try + { + if (!wavFile.Open(fileName)) + return; + if (wavFile.BitsPerSample != 16) + { + wavFile.Close(); + return; + } + int samplesRead = 0; + int curTimeIndex = -1; + int curNote = -1; + const int maxSamplesPerBatch = 512; + bool[] valids = new bool[_Tones.Length]; + while (wavFile.NumSamplesLeft > maxSamplesPerBatch) + { + byte[] samples = wavFile.GetNextSamples16BitAsBytes(maxSamplesPerBatch, 1); + samplesRead += samples.Length / 2; + int time = samplesRead * 1000 / wavFile.SampleRate; + _Process(samples); + while (curTimeIndex + 1 < tones.Count && time >= tones[curTimeIndex + 1].Time) + { + curTimeIndex++; + curNote = tones[curTimeIndex].Note; + } + if (curNote < 0) + continue; + _CurTestCount++; + bool error = false; + for (int i = 0; i < _Tones.Length; i++) + { + valids[i] = _IsNoteValid(_Tones[i], time, tones); + if (valids[i]) + _CurPassedCount[i]++; + else + error = true; + } + if (error) + { + string msg = "Note " + _ToneToNote(curNote) + " at " + time + "ms detected as "; + for (int i = 0; i < 4; i++) + msg += _ToneToNote(_Tones[i]) + (valids[i] ? "" : "(!)") + "; "; + CBase.Log.LogDebug(msg); + } + } + } + catch (Exception e) + { + Console.WriteLine("Error on file " + fileName + ": " + e); + } + wavFile.Close(); + } + #endregion + } +} \ No newline at end of file diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 1f6afd01..df259176 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -268,6 +268,7 @@ + From 874c66d6d1aade1c8a4cdde300055b24500ae74b Mon Sep 17 00:00:00 2001 From: Flamefire Date: Thu, 17 Apr 2014 00:13:24 +0200 Subject: [PATCH 28/34] Fix bug (last value left out) --- PitchTracker/ptAKF.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index 7a418f22..99418d33 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -162,7 +162,7 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r lastWeight = curWeight; } //Set all invalid weights to 0 - for(int toneIndex = lastValidTone + 1;toneIndex < _MaxHalfTone; toneIndex++){ + for(int toneIndex = lastValidTone + 1;toneIndex <= _MaxHalfTone; toneIndex++){ weights[toneIndex - _MinHalfTone] = 0.f; } } From 29d2dce3fc924c439011db549ea72db36f2c201f Mon Sep 17 00:00:00 2001 From: Flamefire Date: Thu, 17 Apr 2014 13:45:08 +0200 Subject: [PATCH 29/34] Move files to correct dir --- .../Record/PitchTracker/CPitchTrackerTest.cs | 2 +- .../Lib/Sound/Record/PitchTracker/CPtSharp.cs | 1 + .../Pitch/CircularBuffer.cs | 5 +--- .../{ => PitchTracker}/Pitch/Extensions.cs | 25 ++++++++----------- .../{ => PitchTracker}/Pitch/IIRFilter.cs | 5 +--- .../{ => PitchTracker}/Pitch/PitchDsp.cs | 6 +---- .../{ => PitchTracker}/Pitch/PitchTracker.cs | 3 +-- Vocaluxe/Vocaluxe.csproj | 10 ++++---- 8 files changed, 22 insertions(+), 35 deletions(-) rename Vocaluxe/Lib/Sound/Record/{ => PitchTracker}/Pitch/CircularBuffer.cs (98%) rename Vocaluxe/Lib/Sound/Record/{ => PitchTracker}/Pitch/Extensions.cs (83%) rename Vocaluxe/Lib/Sound/Record/{ => PitchTracker}/Pitch/IIRFilter.cs (99%) rename Vocaluxe/Lib/Sound/Record/{ => PitchTracker}/Pitch/PitchDsp.cs (99%) rename Vocaluxe/Lib/Sound/Record/{ => PitchTracker}/Pitch/PitchTracker.cs (99%) diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs index 00670ad1..dc08cec7 100644 --- a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPitchTrackerTest.cs @@ -116,7 +116,7 @@ namespace Vocaluxe.Lib.Sound.Record.PitchTracker { Buffer.BlockCopy(data, 0, data2, 0, samplesPerBuffer * 2); analyzer.Input(data2); - analyzer.GetNote(out _MaxVolume, _Weights[j]); + analyzer.GetNote(out _MaxVolume, _Weights[i]); } sw.Stop(); _SamplesPerSec[i] = (int)Math.Round(samplesPerBuffer * repeats / (sw.ElapsedMilliseconds / 1000.0)); diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs index af38e362..9f73b0f2 100644 --- a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtSharp.cs @@ -4,6 +4,7 @@ namespace Vocaluxe.Lib.Sound.Record.PitchTracker { /// /// Pitchtracker (Pt) in C# that uses IIR filters for smoothing and an intelligent detection algorithm to reduce calculations + /// DO NOT USE in 32 Bit! Due to floating point errors the filter will raise all values to NAN (TODO: FIX it!) /// class CPtSharp : CPitchTracker { diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/CircularBuffer.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/CircularBuffer.cs similarity index 98% rename from Vocaluxe/Lib/Sound/Record/Pitch/CircularBuffer.cs rename to Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/CircularBuffer.cs index d784e2df..07b6836b 100644 --- a/Vocaluxe/Lib/Sound/Record/Pitch/CircularBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/CircularBuffer.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; -using System.Text; -using System.Collections; -namespace Pitch +namespace Vocaluxe.Lib.Sound.Record.PitchTracker.Pitch { public class CircularBuffer : IDisposable { diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/Extensions.cs similarity index 83% rename from Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs rename to Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/Extensions.cs index 2487ea18..4cbd7c81 100644 --- a/Vocaluxe/Lib/Sound/Record/Pitch/Extensions.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/Extensions.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace Pitch +namespace Vocaluxe.Lib.Sound.Record.PitchTracker.Pitch { public static class Extensions { @@ -12,7 +9,7 @@ namespace Pitch /// /// /// - static public void Clear(this float[] buffer) + public static void Clear(this float[] buffer) { Array.Clear(buffer, 0, buffer.Length); } @@ -22,7 +19,7 @@ namespace Pitch /// /// /// - static public void Clear(this double[] buffer) + public static void Clear(this double[] buffer) { Array.Clear(buffer, 0, buffer.Length); } @@ -35,15 +32,15 @@ namespace Pitch /// /// /// - static public void Copy(this float[] fromBuffer, float[] toBuffer, int fromStart, int toStart, int length) + public static void Copy(this float[] fromBuffer, float[] toBuffer, int fromStart, int toStart, int length) { if (toBuffer == null || fromBuffer.Length == 0 || toBuffer.Length == 0) return; - var fromBegIdx = fromStart; - var fromEndIdx = fromStart + length; - var toBegIdx = toStart; - var toEndIdx = toStart + length; + int fromBegIdx = fromStart; + int fromEndIdx = fromStart + length; + int toBegIdx = toStart; + int toEndIdx = toStart + length; if (fromBegIdx < 0) { @@ -88,7 +85,7 @@ namespace Pitch ///

hms7))l2%D$VAVDfq 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 sO4h0OT7Cr$bw+ delta 94529 zcmYJ4b9CJ6!^AhXZJP}n+l`aPXd1h1tZ&T5ww(rzZCj0P+j`r3Z{Od)d(O_z^O>1v z&sjVcvkw-rM_~fNh7MU#Y@h-V2!sy?0)bOx^rkMA2Z|FhMne};pB!}`m&lHR^|xV+X~43uoaU$b0FP>{xYwIX|#{( z!67ROmJ(mZ^L58 zjWk{yj}l7>isLQ#h10o4og=hf#P3iU#SQ{~pMmYq!A8dmU+H5*ejg0^pMyD@TYPh{ z1}tpN*#9|NW&C%<>tXBpbGY&k$zSg@nWPUR`IMcAKhH&}w4pZXdJ~OhRVU;2~7Eu9=Zdz#m_?AsZC0UDc zg4Az>&2Z|2z8z&(PS;8H*v(ao@+k>xi9*JCFF`Xm*VG%xy3_vcnGNI>TLDfF;H^ZX z!A7rmqluJMxHe+J*dGyf_u+1Jyg%;u22<|$2_lB*T+c=W6Q6cJ8qPTuy?)335z71Z z>MhHr>$FB8B_%odlrK1WT&5q~@#3y!BiyuyU>s`n<*5N=cnk&xya^kE#6g|&;LxwW-k>Njze-4|7f5d~QV1ABSm#H0 z5V$ZjatE5wH6jR77?H@Ed~Kf+1P8+914)rgRD#e!tWKcV_AFKqImob(=?x6^x0L>? z&mXCvx(QX9Yitmt)F(n{3uuk_0dBY$xTy~@y&wX^4OH+f$O$RnYv4Y#F*_<^k7*QM zQiuMNjgqw^N+m-?|*Jn{d)R1vmlFker42}#rpQI6S(uYKumg`L3G=`u7 zlM0kdIT5|+-B|?q6~TI=`#_1h3cscL=P2Vs-!egTW{EFR2THF?K!43q6KfPnDg*hd ziKD`WR;9cvrA-DOOtWE3eHTL)(igf8fno?UecR^%!TrXBv3CvqFD9C|eZoJOETJTR zGhw|2K_|TWc7UROGgp2S0fD6dAa8i}0fc{p@=XVxA^l(s5x5_j{^hL+f+e{|2SIux z3V8p1nwU^l6o?$x9Sp)7^!=a2Se?K-KvF=KA&ByKj!@p9=)XZCfWVkv{eQpI?BK;&Hs!Uguz{>c=~5X8AQfeS+Wo$7CWYaq-1ul@=k z{*P-75ZLl7xJXbXsU`^J?iK_N0zrzw7&3wo5gt)M;H1#R9m4A%BcW+w5c==BRD!tM z4;cT7y8;tM|5WC;_=8Y(6o?Y|$355^Ao)kVdmfe%gxdTF3j!w#sziMcBJ01l2mL|A z2tpfw#QE!<()nLFfAnQC_l^JRC$vw{{?S+O0AmsI{tX+-8{8cDui*$F$m!SMKgIk5 z2JY>Jz#EJd_+4{G5a!Y&fL2n0Zs6eRs8Q?QV?Ea5*}{cRlr>rEKw_=8;�bLezlZht2l~75YyIEQ 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

d3~y7}0l&gD4b@ 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≦WYv90Oh7)Rgqk=}*i;b_uD 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%0Di|N8V-zt7+6`{u^F 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

/// /// - static public void Clear(this float[] buffer, int startIdx, int endIdx) + public static void Clear(this float[] buffer, int startIdx, int endIdx) { Array.Clear(buffer, startIdx, endIdx - startIdx + 1); } @@ -99,10 +96,10 @@ namespace Pitch /// /// /// - static public void Fill(this double[] buffer, double value) + public static void Fill(this double[] buffer, double value) { for (int idx = 0; idx < buffer.Length; idx++) buffer[idx] = value; } } -} +} \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/IIRFilter.cs similarity index 99% rename from Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs rename to Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/IIRFilter.cs index 8759c77e..e180ff72 100644 --- a/Vocaluxe/Lib/Sound/Record/Pitch/IIRFilter.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/IIRFilter.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -namespace Pitch +namespace Vocaluxe.Lib.Sound.Record.PitchTracker.Pitch { /// /// Infinite impulse response filter (old style analog filters) diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/PitchDsp.cs similarity index 99% rename from Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs rename to Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/PitchDsp.cs index 0eb79432..3fc22ee6 100644 --- a/Vocaluxe/Lib/Sound/Record/Pitch/PitchDsp.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/PitchDsp.cs @@ -1,10 +1,6 @@ using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; -using System.Collections; -namespace Pitch +namespace Vocaluxe.Lib.Sound.Record.PitchTracker.Pitch { /// /// Pitch related DSP diff --git a/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/PitchTracker.cs similarity index 99% rename from Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs rename to Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/PitchTracker.cs index 8e7e6776..59522197 100644 --- a/Vocaluxe/Lib/Sound/Record/Pitch/PitchTracker.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/Pitch/PitchTracker.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; using System.Collections; -using Pitch; -namespace Vocaluxe.Lib.Sound.Record.Pitch +namespace Vocaluxe.Lib.Sound.Record.PitchTracker.Pitch { /// /// Tracks pitch diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index df259176..f43e6307 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -273,11 +273,11 @@ - - - - - + + + + + From a85cdaf615108e33182a95e0e18f84f319e685a5 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 25 Apr 2014 16:11:40 +0200 Subject: [PATCH 30/34] Smooth pitch result --- PitchTracker/Helper.cpp | 2 +- PitchTracker/ptAKF.cpp | 100 ++++++++++++------ PitchTracker/ptAKF.h | 22 ++-- .../Lib/Sound/Record/PitchTracker/CPtAKF.cs | 2 +- 4 files changed, 82 insertions(+), 44 deletions(-) diff --git a/PitchTracker/Helper.cpp b/PitchTracker/Helper.cpp index 41e00776..f49de316 100644 --- a/PitchTracker/Helper.cpp +++ b/PitchTracker/Helper.cpp @@ -3,7 +3,7 @@ #include float* short2FloatArray(short* in, size_t len){ - const float maxShort = 32767.0; + const float maxShort = 32767.0f; float* result = static_cast(malloc(len * sizeof(float))); float* curOut = result; diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index 99418d33..cb83edae 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -43,12 +43,15 @@ PtAKF::PtAKF(unsigned step){ _Window = new float[_SampleCt]; double cosMult = 2. * M_PI / (_SampleCt - 1.); //To simplify and speed up for (int i = 0; i < _SampleCt; i++) { - _Window[i] = static_cast(0.54 - 0.46 * cos(i * cosMult)); + _Window[i] = static_cast(0.64 - 0.36 * cos(i * cosMult)); } } _Step = step; _VolTreshold = 0.01f; _LastMaxVol = 0.f; + for(int i = 0; i < _SmoothCt; i++) + _LastTones[i] = -1; + _LastToneIndex = 0; } PtAKF::~PtAKF(){ @@ -67,15 +70,42 @@ void PtAKF::SetVolumeThreshold(float threshold){ int PtAKF::GetNote(float* restrict maxVolume, float* restrict weights){ float AnaylsisBuf[_SampleCt]; - size_t size = _AnalysisBuf.size(); - if(size > _SampleCt) - _AnalysisBuf.pop(size - _SampleCt); - if(!_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)){ - *maxVolume = _LastMaxVol * 0.85f; - return -1; + int note = _LastTones[_LastToneIndex]; + *maxVolume = _LastMaxVol * 0.85f; + if(_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)){ + do{ + _AnalysisBuf.pop(_Step); + note = _GetNote(AnaylsisBuf, maxVolume, weights); + if(++_LastToneIndex >= _SmoothCt) + _LastToneIndex = 0; + _LastTones[_LastToneIndex] = note; + }while(_AnalysisBuf.read(AnaylsisBuf, AnaylsisBuf + _SampleCt)); + note = _GetSmoothTone(); } - _AnalysisBuf.pop(_Step); - return _GetNote(AnaylsisBuf, maxVolume, weights); + return note; +} + +int PtAKF::_GetSmoothTone(){ + int tones[_SmoothCt]; + int ct = 0; + for(int i=0; i < _SmoothCt; i++){ + int j; + int tone = _LastTones[i]; + if(tone < 0) + continue; + for(j = ct; j > 0; j--){ + if(tones[j-1] > tone) + tones[j] = tones[j-1]; + else break; + } + tones[j] = tone; + ct++; + } + if(ct == 0) + return -1; //Nothing detected + if(ct % 2 == 0) + return (tones[ct/2] + tones[ct/2-1]) / 2; //For even cts get the mean of the 2 middle tones + return tones[ct/2]; //For odd cts get the median (middle tone) } void PtAKF::InitPeaks(SPeak peaks[_MaxPeaks]){ @@ -104,7 +134,7 @@ void PtAKF::AddPeak(SPeak peaks[], float curWeight, int toneIndex){ } } -int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* restrict weights){ +int PtAKF::_GetNote(float samples[_SampleCt], float* restrict maxVolume, float weights[_MaxHalfTone+1]){ // Calculate maximum volume float maxVolumeL = 0; @@ -132,15 +162,15 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r int lastValidTone = 0; float lastWeight = 1.f; float maxWeight = 0.f; - for (int toneIndex = _MinHalfTone; toneIndex <= _MaxHalfTone; toneIndex++) - { + + for (int toneIndex = 0; toneIndex <= _MaxHalfTone; toneIndex++){ float curWeight = _AnalyzeByTone(samples, samplesWindowed, toneIndex); if(curWeight > maxWeight){ maxWeight = curWeight; } - weights[toneIndex - _MinHalfTone] = curWeight; + weights[toneIndex] = curWeight; //Filter: if(lastWeight > curWeight || (lastWeight > 0.f && curWeight <= 0.f)) @@ -161,9 +191,11 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r } lastWeight = curWeight; } + if(lastValidTone < 0) + return -1; //Set all invalid weights to 0 for(int toneIndex = lastValidTone + 1;toneIndex <= _MaxHalfTone; toneIndex++){ - weights[toneIndex - _MinHalfTone] = 0.f; + weights[toneIndex] = 0.f; } } @@ -171,10 +203,10 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r InitPeaks(peaks); int numPeaks = 0; bool up = true; - for(int i = _MinHalfTone + 1; i <= _MaxHalfTone; i++){ - if(weights[i-1] > weights[i]){ + for(int i = 1; i <= _MaxHalfTone; i++){ + if(weights[i - 1] > weights[i]){ if(up){ - AddPeak(peaks, weights[i - 1 - _MinHalfTone], i - 1); + AddPeak(peaks, weights[i - 1], i - 1); numPeaks++; up = false; } @@ -182,8 +214,8 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r up = true; } } - if(up){ - AddPeak(peaks, weights[_MaxHalfTone - _MinHalfTone], _MaxHalfTone); + if(up && weights[_MaxHalfTone] > 0.001f){ + AddPeak(peaks, weights[_MaxHalfTone], _MaxHalfTone); numPeaks++; } if(numPeaks > _MaxPeaks) @@ -193,9 +225,11 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r // This is necessary because we may have our real peak a bit off the exact tone frequency // and a 'wrong' peak that is exactly at another tone which might become higher than the one at the 'right' tone + maxWeight = peaks[_MaxPeaks-1].weight; + if(maxWeight < 0.00001f) // Just a small number to check for zero values + return -1; int maxTone = peaks[_MaxPeaks-1].toneIndex; int maxToneFine = -1; - maxWeight = peaks[_MaxPeaks-1].weight; for(int i = _MaxPeaks - numPeaks; i < _MaxPeaks; i++){ float curWeight = peaks[i].weight; if(curWeight * 3.f < maxWeight) @@ -217,7 +251,7 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r }else continue; } - weights[toneIndex - _MinHalfTone] = curWeight; + weights[toneIndex] = curWeight; if(curWeight > maxWeight){ maxTone = toneIndex; maxToneFine = 1 - otherToneFineIndex; @@ -225,10 +259,10 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r } // Now check also neighbouring tone - if(otherToneIndex > 0){ + if(otherToneIndex >= 0){ float curWeightOther = _AnalyzeBySampleCt(samples, samplesWindowed, _SamplesPerPeriodPerToneFine[otherToneIndex * 2 + otherToneFineIndex]); - if(curWeightOther > weights[otherToneIndex - _MinHalfTone]){ - weights[otherToneIndex - _MinHalfTone] = curWeightOther; + if(curWeightOther > weights[otherToneIndex]){ + weights[otherToneIndex] = curWeightOther; if(curWeightOther > maxWeight){ maxTone = otherToneIndex; maxToneFine = otherToneFineIndex; @@ -238,20 +272,20 @@ int PtAKF::_GetNote(float* restrict samples, float* restrict maxVolume, float* r } } - float energy = _AKFBySampleCt(samples, 0); - float maxAKF = (maxToneFine < 0) ? _AKFByTone(samples, maxTone) : _AKFBySampleCt(samples, _SamplesPerPeriodPerToneFine[maxTone * 2 + maxToneFine]); + float energy = _AKFBySampleCt(samplesWindowed, 0); + float maxAKF = (maxToneFine < 0) ? _AKFByTone(samplesWindowed, maxTone) : _AKFBySampleCt(samplesWindowed, _SamplesPerPeriodPerToneFine[maxTone * 2 + maxToneFine]); //if(maxWeight - minWeight > 0.025){ - if(maxAKF >= 0.35f * energy){ + if(maxAKF >= 0.33f * energy){ return maxTone; }else return -1; } -float PtAKF::_AnalyzeByTone(float* restrict samples, float* restrict samplesWindowed, int toneIndex){ +float PtAKF::_AnalyzeByTone(float samples[_SampleCt], float samplesWindowed[_SampleCt], int toneIndex){ return _AnalyzeBySampleCt(samples, samplesWindowed, _SamplesPerPeriodPerTone[toneIndex]); } -float PtAKF::_AnalyzeBySampleCt(float* restrict samples, float* restrict samplesWindowed, float samplesPerPeriodD){ +float PtAKF::_AnalyzeBySampleCt(float samples[_SampleCt], float samplesWindowed[_SampleCt], float samplesPerPeriodD){ // Use method by Kobayashi and Shimamura (2001): Combine AKF and AMDF to a new f(z)=AKF(z)/(AMDF(z)+k) with k=1 float akf = _AKFBySampleCt(samplesWindowed, samplesPerPeriodD); @@ -263,11 +297,11 @@ float PtAKF::_AnalyzeBySampleCt(float* restrict samples, float* restrict samples //{toneIndex}: {accumDistAKF} ; {accumDistAMDF}; {result} } -float PtAKF::_AKFByTone(float* restrict samples, int toneIndex){ +float PtAKF::_AKFByTone(float samples[_SampleCt], int toneIndex){ return _AKFBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); } -float PtAKF::_AKFBySampleCt(float* restrict samples, float samplesPerPeriodD){ +float PtAKF::_AKFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD){ int samplesPerPeriod = static_cast(samplesPerPeriodD); float fHigh = samplesPerPeriodD - samplesPerPeriod; float fLow = 1.0f - fHigh; @@ -288,11 +322,11 @@ float PtAKF::_AKFBySampleCt(float* restrict samples, float samplesPerPeriodD){ return accumDist / _SampleCt; } -float PtAKF::_AMDFByTone(float* restrict samples, int toneIndex){ +float PtAKF::_AMDFByTone(float samples[_SampleCt], int toneIndex){ return _AKFBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); } -float PtAKF::_AMDFBySampleCt(float* restrict samples, float samplesPerPeriodD){ +float PtAKF::_AMDFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD){ int samplesPerPeriod = static_cast(samplesPerPeriodD); float fHigh = samplesPerPeriodD - samplesPerPeriod; float fLow = 1.0f - fHigh; diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h index 58c04433..b5d9a2b6 100644 --- a/PitchTracker/ptAKF.h +++ b/PitchTracker/ptAKF.h @@ -32,7 +32,7 @@ public: int GetNote(float* restrict maxVolume, float* restrict weights); void SetVolumeThreshold(float threshold); float GetVolumeThreshold(){return _VolTreshold;} - static int GetNumHalfTones(){ return _MaxHalfTone - _MinHalfTone + 1;} + static int GetNumHalfTones(){ return _MaxHalfTone + 1;} private: static int _InitCount; @@ -42,25 +42,29 @@ private: // (cannot use halves as it would be ambiguous) static float* restrict _SamplesPerPeriodPerToneFine; static float* restrict _Window; - static constexpr int _MinHalfTone = 0; //C2 + //static constexpr int _MinHalfTone = 0; //C2 static constexpr int _MaxHalfTone = 56;//47; //B5 static constexpr int _HalfTonesAdd = 4; //Additonal half tones to analyze to remove the peak at lag 0 static constexpr int _MaxPeaks = 10; + static constexpr int _SmoothCt = 3; //Number of samples used for smoothing the result constexpr static size_t _SampleCt = 2048; RingBuffer<_SampleCt * 2> _AnalysisBuf; unsigned _Step; float _VolTreshold; float _LastMaxVol; + int _LastTones[_SmoothCt]; + int _LastToneIndex; - int _GetNote(float* restrict samples, float* restrict maxVolume, float* restrict weights); + int _GetNote(float samples[_SampleCt], float* restrict maxVolume, float weights[_MaxHalfTone+1]); + int _GetSmoothTone(); - static float _AnalyzeBySampleCt(float* restrict samples, float* restrict samplesWindowed, float samplesPerPeriodD); - static inline float _AnalyzeByTone(float* restrict samples, float* restrict samplesWindowed, int toneIndex); - static float _AKFBySampleCt(float* restrict samples, float samplesPerPeriodD); - static inline float _AKFByTone(float* restrict samples, int toneIndex); - static float _AMDFBySampleCt(float* restrict samples, float samplesPerPeriodD); - static inline float _AMDFByTone(float* restrict samples, int toneIndex); + static float _AnalyzeBySampleCt(float samples[_SampleCt], float samplesWindowed[_SampleCt], float samplesPerPeriodD); + static inline float _AnalyzeByTone(float samples[_SampleCt], float samplesWindowed[_SampleCt], int toneIndex); + static float _AKFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD); + static inline float _AKFByTone(float samples[_SampleCt], int toneIndex); + static float _AMDFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD); + static inline float _AMDFByTone(float samples[_SampleCt], int toneIndex); static inline void InitPeaks(SPeak peaks[_MaxPeaks]); static inline void AddPeak(SPeak peaks[_MaxPeaks], float curWeight, int toneIndex); }; \ No newline at end of file diff --git a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs index 0dbbc501..842fdb22 100644 --- a/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs +++ b/Vocaluxe/Lib/Sound/Record/PitchTracker/CPtAKF.cs @@ -34,7 +34,7 @@ namespace Vocaluxe.Lib.Sound.Record.PitchTracker private IntPtr _Instance; - public CPtAKF(uint step = 200) + public CPtAKF(uint step = 400) { _Instance = PtAKF_Create(step); } From f481d283d6541176af68a2153b6cf28d6e4d20d9 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 25 Apr 2014 16:12:12 +0200 Subject: [PATCH 31/34] Improve test cases --- PitchTracker/TestSounds.rar | Bin 840954 -> 840957 bytes .../Record/PitchTracker/CPitchTrackerTest.cs | 23 +++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/PitchTracker/TestSounds.rar b/PitchTracker/TestSounds.rar index 7dd70d57103cc09683f6ca47483abd7539590d5e..3e956da1c6095c9fc0ef4c508bb94293a22fe292 100644 GIT binary patch delta 406 zcmeyh()jO6;|U^0Cb=aCCKxf)F)}c4F)=VOY4<-)no>E_Mb?;?L4kpRq1ZVmv9vfW zKUuG&qJ-gtAD`w#x43#{cCY$|LRVI9(=hM0HT_fn{!vYE{>CH~%c}2m(0jq@hDOdU zD!W*JSbbQNp>^Wtvt`CoTwFr2JTWpRht~WPEm0Act*>inkU5m&=r~j9!t-acCJudN zCtZ_RBO~kTTIIcRd=}3$blCjm!m+F+%FKWE967Y+^n-}d8Ehg9;ifa{#e^ds_)JU@ za9)>fu;#Ymg$<&U)e08PbM(G&{!A?|BggRssj5_eGllqPrcGiZC&jkT3_hcv;GVa^ z(QMJyy?@(HR&lob@}FIj@LH#Gt&fe^hu>mMIr}A*4jH9g>|oZ|+-|n=*1B7F8|&(4 z+~7RAkiGfM(q9ZG#pXHlAN!mnB%oAh(J&|WN1f#iM`!-yKEHXnET24D*tmFN>W8#S w6T_&a{~wwUGPWON1Yss1W(HywAZ7((HXvpPVh$kY1Y#~A=H7mgk;n2f0QHHdGynhq delta 403 zcmeyn()ia(;|U^06ZV%Jm|(xs(g8~BsL$PyCVrg+$ zezIOkMG3{!&c=4=4#{{08f78reDG1_3yuqN6!UH`{3W3u#n${|z?? zcRTU3-}L^%I7!#0O}_Wp5fz0$g^cnRyFdIXHfU;-@0 tones) { - const int lastNoteMaxTimeDiff = 1024 * 1000 / 44100; // old note is valid for 1024 more samples + const int lastNoteMaxTimeDiff = 1536 * 1000 / 44100; // old note is valid for 1536 more samples for (int i = 0; i < tones.Count; i++) { if (tones[i].Time > time) break; if (i + 1 == tones.Count || time <= tones[i + 1].Time + lastNoteMaxTimeDiff) { - if (tones[i].Note == note) + if (tones[i].Note == note || tones[i].Note < 0) return true; } } @@ -371,7 +382,7 @@ namespace Vocaluxe.Lib.Sound.Record.PitchTracker if (error) { string msg = "Note " + _ToneToNote(curNote) + " at " + time + "ms detected as "; - for (int i = 0; i < 4; i++) + for (int i = 0; i < _Tones.Length; i++) msg += _ToneToNote(_Tones[i]) + (valids[i] ? "" : "(!)") + "; "; CBase.Log.LogDebug(msg); } From 05c8bfea6c0530dae8b19440f1b10faed308d111 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 25 Apr 2014 16:12:56 +0200 Subject: [PATCH 32/34] Remove pitch test --- Vocaluxe/Lib/Sound/Record/CBuffer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Vocaluxe/Lib/Sound/Record/CBuffer.cs b/Vocaluxe/Lib/Sound/Record/CBuffer.cs index 43950e7d..65bf720f 100644 --- a/Vocaluxe/Lib/Sound/Record/CBuffer.cs +++ b/Vocaluxe/Lib/Sound/Record/CBuffer.cs @@ -15,7 +15,7 @@ // along with Vocaluxe. If not, see . #endregion -#define TEST_PITCH +//#define TEST_PITCH using System; using Vocaluxe.Lib.Sound.Record.PitchTracker; From f2711c53cc277ab9a64465cec69284e4fede42b0 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 25 Apr 2014 16:17:55 +0200 Subject: [PATCH 33/34] Use OpenMP for calculations --- PitchTracker/PitchTracker.vcxproj | 2 ++ PitchTracker/ptAKF.cpp | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj index ebb42e38..1b729255 100644 --- a/PitchTracker/PitchTracker.vcxproj +++ b/PitchTracker/PitchTracker.vcxproj @@ -135,6 +135,7 @@ Speed Fast false + true Windows @@ -157,6 +158,7 @@ true Speed Fast + true Windows diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index cb83edae..335bcde6 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -163,16 +163,18 @@ int PtAKF::_GetNote(float samples[_SampleCt], float* restrict maxVolume, float w float lastWeight = 1.f; float maxWeight = 0.f; + #pragma omp parallel for schedule(static) for (int toneIndex = 0; toneIndex <= _MaxHalfTone; toneIndex++){ float curWeight = _AnalyzeByTone(samples, samplesWindowed, toneIndex); + weights[toneIndex] = curWeight; + } + + for (int toneIndex = 0; toneIndex <= _MaxHalfTone; toneIndex++){ + float curWeight = weights[toneIndex]; if(curWeight > maxWeight){ maxWeight = curWeight; } - - weights[toneIndex] = curWeight; - - //Filter: if(lastWeight > curWeight || (lastWeight > 0.f && curWeight <= 0.f)) lastValidTone = toneIndex - 1; lastWeight = curWeight; From b3da00e081e36b74570a9a0417de471478d2d83f Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sun, 27 Apr 2014 16:41:40 +0200 Subject: [PATCH 34/34] Use FFT for calculating AKF --- PitchTracker/FFT/FFT.cpp | 180 ++++++++++ PitchTracker/FFT/FFT.h | 65 ++++ PitchTracker/FFT/License.txt | 299 +++++++++++++++++ PitchTracker/FFT/RealFFTf.cpp | 388 ++++++++++++++++++++++ PitchTracker/FFT/RealFFTf.h | 23 ++ PitchTracker/PitchTracker.vcxproj | 4 + PitchTracker/PitchTracker.vcxproj.filters | 18 + PitchTracker/performous/libda/sample.hpp | 1 - PitchTracker/ptAKF.cpp | 27 +- PitchTracker/ptAKF.h | 13 +- 10 files changed, 1009 insertions(+), 9 deletions(-) create mode 100644 PitchTracker/FFT/FFT.cpp create mode 100644 PitchTracker/FFT/FFT.h create mode 100644 PitchTracker/FFT/License.txt create mode 100644 PitchTracker/FFT/RealFFTf.cpp create mode 100644 PitchTracker/FFT/RealFFTf.h diff --git a/PitchTracker/FFT/FFT.cpp b/PitchTracker/FFT/FFT.cpp new file mode 100644 index 00000000..39fdb52f --- /dev/null +++ b/PitchTracker/FFT/FFT.cpp @@ -0,0 +1,180 @@ +/********************************************************************** + + FFT.cpp + + Dominic Mazzoni + + September 2000 + +*******************************************************************//*! + +\file FFT.cpp +\brief Fast Fourier Transform routines. + + This file contains a few FFT routines, including a real-FFT + routine that is almost twice as fast as a normal complex FFT, + and a power spectrum routine when you know you don't care + about phase information. + + Some of this code was based on a free implementation of an FFT + by Don Cross, available on the web at: + + http://www.intersrv.com/~dcross/fft.html + + The basic algorithm for his code was based on Numerican Recipes + in Fortran. I optimized his code further by reducing array + accesses, caching the bit reversal table, and eliminating + float-to-double conversions, and I added the routines to + calculate a real FFT and a real power spectrum. + +*//*******************************************************************/ + +#include +#include +#include + +#include "FFT.h" + +#include "RealFFTf.h" + +void DeinitFFT() +{ + // Deallocate any unused RealFFTf tables + CleanupFFT(); +} + +/* + * Real Fast Fourier Transform + * + */ +void RealFFT(int NumSamples, float *RealIn, float *RealOut, float *ImagOut) +{ + // Remap to RealFFTf() function + int i; + HFFT hFFT = GetFFT(NumSamples); + float *pFFT = new float[NumSamples]; + // Copy the data into the processing buffer + for(i=0; iBitReversed[i] ]; + ImagOut[i]=pFFT[hFFT->BitReversed[i]+1]; + } + // Handle the (real-only) DC and Fs/2 bins + RealOut[0] = pFFT[0]; + RealOut[i] = pFFT[1]; + ImagOut[0] = ImagOut[i] = 0; + // Fill in the upper half using symmetry properties + for(i++ ; iBitReversed[i]]; + } + // Handle the (real-only) DC + Out[0] = pFFT[0]; + delete [] pFFT; + ReleaseFFT(hFFT); +} + +/* + * PowerSpectrum + * + * This function computes the same as RealFFT, above, but + * adds the squares of the real and imaginary part of each + * coefficient, extracting the power and throwing away the + * phase. + * + * For speed, it does not call RealFFT, but duplicates some + * of its code. + */ + +void PowerSpectrum(int NumSamples, float *In, float *Out) +{ + // Remap to RealFFTf() function + int i; + HFFT hFFT = GetFFT(NumSamples); + float *pFFT = new float[NumSamples]; + // Copy the data into the processing buffer + for(i=0; iBitReversed[i] ]*pFFT[hFFT->BitReversed[i] ]) + + (pFFT[hFFT->BitReversed[i]+1]*pFFT[hFFT->BitReversed[i]+1]); + } + // Handle the (real-only) DC and Fs/2 bins + Out[0] = pFFT[0]*pFFT[0]; + Out[i] = pFFT[1]*pFFT[1]; + delete [] pFFT; + ReleaseFFT(hFFT); +} \ No newline at end of file diff --git a/PitchTracker/FFT/FFT.h b/PitchTracker/FFT/FFT.h new file mode 100644 index 00000000..b8919e61 --- /dev/null +++ b/PitchTracker/FFT/FFT.h @@ -0,0 +1,65 @@ +/********************************************************************** + + FFT.h + + Dominic Mazzoni + + September 2000 + + This file contains a few FFT routines, including a real-FFT + routine that is almost twice as fast as a normal complex FFT, + and a power spectrum routine which is more convenient when + you know you don't care about phase information. It now also + contains a few basic windowing functions. + + Some of this code was based on a free implementation of an FFT + by Don Cross, available on the web at: + + http://www.intersrv.com/~dcross/fft.html + + The basic algorithm for his code was based on Numerical Recipes + in Fortran. I optimized his code further by reducing array + accesses, caching the bit reversal table, and eliminating + float-to-double conversions, and I added the routines to + calculate a real FFT and a real power spectrum. + + Note: all of these routines use single-precision floats. + I have found that in practice, floats work well until you + get above 8192 samples. If you need to do a larger FFT, + you need to use doubles. + +**********************************************************************/ + +/* + * This is the function you will use the most often. + * Given an array of floats, this will compute the power + * spectrum by doing a Real FFT and then computing the + * sum of the squares of the real and imaginary parts. + * Note that the output array is half the length of the + * input array, and that NumSamples must be a power of two. + */ + +void PowerSpectrum(int NumSamples, float *In, float *Out); + +/* + * Computes an FFT when the input data is real but you still + * want complex data as output. The output arrays are the + * same length as the input, but will be conjugate-symmetric + * NumSamples must be a power of two. + */ + +void RealFFT(int NumSamples, + float *RealIn, float *RealOut, float *ImagOut); + +/* + * Computes an Inverse FFT when the input data is conjugate symmetric + * so the output is purely real. NumSamples must be a power of + * two. + * Requires: EXPERIMENTAL_USE_REALFFTF + */ +void InverseRealFFT(int NumSamples, + float *RealIn, float *ImagIn, float *RealOut); + +void RealInverseRealFFT(int NumSamples, float *In, float *Out); + +void DeinitFFT(); diff --git a/PitchTracker/FFT/License.txt b/PitchTracker/FFT/License.txt new file mode 100644 index 00000000..c2e7eafa --- /dev/null +++ b/PitchTracker/FFT/License.txt @@ -0,0 +1,299 @@ +Code in this folder is based on Code from Audacity. +License of that code is below: + +------------------------------------------------------------------------ + +Note: Audacity is distributed under the terms of the GNU GPL. +This includes everything in the source code distribution +except code in the lib-src directory. Code in the lib-src +directory may be released under a different license +(which is GPL-compatible). For a summary, see the +README.txt file, and for specific details, see the license +information inside each subdirectory of lib-src. + +Documentation is distributed under the Creative Commons license. +Please see here for that: +http://creativecommons.org/licenses/by/3.0/legalcode + +The full text of the GNU GPL follows: + +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +GNU GENERAL PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +a) You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. + +c) If the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary way, to print or display an +announcement including an appropriate copyright notice and a +notice that there is no warranty (or else, saying that you provide +a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/PitchTracker/FFT/RealFFTf.cpp b/PitchTracker/FFT/RealFFTf.cpp new file mode 100644 index 00000000..a18be257 --- /dev/null +++ b/PitchTracker/FFT/RealFFTf.cpp @@ -0,0 +1,388 @@ +/* +* Program: REALFFTF.C +* Author: Philip Van Baren +* Date: 2 September 1993 +* +* Description: These routines perform an FFT on real data to get a conjugate-symmetric +* output, and an inverse FFT on conjugate-symmetric input to get a real +* output sequence. +* +* This code is for floating point data. +* +* Modified 8/19/1998 by Philip Van Baren +* - made the InitializeFFT and EndFFT routines take a structure +* holding the length and pointers to the BitReversed and SinTable +* tables. +* Modified 5/23/2009 by Philip Van Baren +* - Added GetFFT and ReleaseFFT routines to retain common SinTable +* and BitReversed tables so they don't need to be reallocated +* and recomputed on every call. +* - Added Reorder* functions to undo the bit-reversal +* +* Copyright (C) 2009 Philip VanBaren +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include + +#include "RealFFTf.h" +#ifdef EXPERIMENTAL_EQ_SSE_THREADED +#include "RealFFTf48x.h" +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +/* +* Initialize the Sine table and Twiddle pointers (bit-reversed pointers) +* for the FFT routine. +*/ +HFFT InitializeFFT(int fftlen) +{ + int i; + int temp; + int mask; + HFFT h; + + if((h=(HFFT)malloc(sizeof(FFTParam)))==NULL) + { + fprintf(stderr,"Error allocating memory for FFT\n"); + exit(8); + } + /* + * FFT size is only half the number of data points + * The full FFT output can be reconstructed from this FFT's output. + * (This optimization can be made since the data is real.) + */ + h->Points = fftlen/2; + + if((h->SinTable=(fft_type *)malloc(2*h->Points*sizeof(fft_type)))==NULL) + { + fprintf(stderr,"Error allocating memory for Sine table.\n"); + exit(8); + } + + if((h->BitReversed=(int *)malloc(h->Points*sizeof(int)))==NULL) + { + fprintf(stderr,"Error allocating memory for BitReversed.\n"); + exit(8); + } + + for(i=0;iPoints;i++) + { + temp=0; + for(mask=h->Points/2;mask>0;mask >>= 1) + temp=(temp >> 1) + (i&mask ? h->Points : 0); + + h->BitReversed[i]=temp; + } + + for(i=0;iPoints;i++) + { + h->SinTable[h->BitReversed[i] ]=(fft_type)-sin(2*M_PI*i/(2*h->Points)); + h->SinTable[h->BitReversed[i]+1]=(fft_type)-cos(2*M_PI*i/(2*h->Points)); + } + + return h; +} + +/* +* Free up the memory allotted for Sin table and Twiddle Pointers +*/ +void EndFFT(HFFT h) +{ + if(h->Points>0) { + free(h->BitReversed); + free(h->SinTable); + } + h->Points=0; + free(h); +} + +#define MAX_HFFT 10 +static HFFT hFFTArray[MAX_HFFT] = { NULL }; +static int nFFTLockCount[MAX_HFFT] = { 0 }; + +/* Get a handle to the FFT tables of the desired length */ +/* This version keeps common tables rather than allocating a new table every time */ +HFFT GetFFT(int fftlen) +{ + int h,n = fftlen/2; + for(h=0; (hPoints); h++); + if(hBitReversed[i] ] +* Imag_i = buffer[ h->BitReversed[i]+1 ] ) +* Input is in normal order. +* +* Output buffer[0] is the DC bin, and output buffer[1] is the Fs/2 bin +* - this can be done because both values will always be real only +* - this allows us to not have to allocate an extra complex value for the Fs/2 bin +* +* Note: The scaling on this is done according to the standard FFT definition, +* so a unit amplitude DC signal will output an amplitude of (N) +* (Older revisions would progressively scale the input, so the output +* values would be similar in amplitude to the input values, which is +* good when using fixed point arithmetic) +*/ +void RealFFTf(fft_type *buffer,HFFT h) +{ + fft_type *A,*B; + fft_type *sptr; + fft_type *endptr1,*endptr2; + int *br1,*br2; + fft_type HRplus,HRminus,HIplus,HIminus; + fft_type v1,v2,sin,cos; + + int ButterfliesPerGroup=h->Points/2; + + /* + * Butterfly: + * Ain-----Aout + * \ / + * / \ + * Bin-----Bout + */ + + endptr1=buffer+h->Points*2; + + while(ButterfliesPerGroup>0) + { + A=buffer; + B=buffer+ButterfliesPerGroup*2; + sptr=h->SinTable; + + while(A>= 1; + } + /* Massage output to get the output for a real input sequence. */ + br1=h->BitReversed+1; + br2=h->BitReversed+h->Points-1; + + while(br1SinTable[*br1]; + cos=h->SinTable[*br1+1]; + A=buffer+*br1; + B=buffer+*br2; + HRplus = (HRminus = *A - *B ) + (*B * 2); + HIplus = (HIminus = *(A+1) - *(B+1)) + (*(B+1) * 2); + v1 = (sin*HRminus - cos*HIplus); + v2 = (cos*HRminus + sin*HIplus); + *A = (HRplus + v1) * (fft_type)0.5; + *B = *A - v1; + *(A+1) = (HIminus + v2) * (fft_type)0.5; + *(B+1) = *(A+1) - HIminus; + + br1++; + br2--; + } + /* Handle the center bin (just need a conjugate) */ + A=buffer+*br1+1; + *A=-*A; + /* Handle DC bin separately - and ignore the Fs/2 bin + buffer[0]+=buffer[1]; + buffer[1]=(fft_type)0;*/ + /* Handle DC and Fs/2 bins separately */ + /* Put the Fs/2 value into the imaginary part of the DC bin */ + v1=buffer[0]-buffer[1]; + buffer[0]+=buffer[1]; + buffer[1]=v1; +} + + +/* Description: This routine performs an inverse FFT to real data. +* This code is for floating point data. +* +* Note: Output is BIT-REVERSED! so you must use the BitReversed to +* get legible output, (i.e. wave[2*i] = buffer[ BitReversed[i] ] +* wave[2*i+1] = buffer[ BitReversed[i]+1 ] ) +* Input is in normal order, interleaved (real,imaginary) complex data +* You must call InitializeFFT(fftlen) first to initialize some buffers! +* +* Input buffer[0] is the DC bin, and input buffer[1] is the Fs/2 bin +* - this can be done because both values will always be real only +* - this allows us to not have to allocate an extra complex value for the Fs/2 bin +* +* Note: The scaling on this is done according to the standard FFT definition, +* so a unit amplitude DC signal will output an amplitude of (N) +* (Older revisions would progressively scale the input, so the output +* values would be similar in amplitude to the input values, which is +* good when using fixed point arithmetic) +*/ +void InverseRealFFTf(fft_type *buffer,HFFT h) +{ + fft_type *A,*B; + fft_type *sptr; + fft_type *endptr1,*endptr2; + int *br1; + fft_type HRplus,HRminus,HIplus,HIminus; + fft_type v1,v2,sin,cos; + + int ButterfliesPerGroup=h->Points/2; + + /* Massage input to get the input for a real output sequence. */ + A=buffer+2; + B=buffer+h->Points*2-2; + br1=h->BitReversed+1; + while(ASinTable[*br1]; + cos=h->SinTable[*br1+1]; + HRplus = (HRminus = *A - *B ) + (*B * 2); + HIplus = (HIminus = *(A+1) - *(B+1)) + (*(B+1) * 2); + v1 = (sin*HRminus + cos*HIplus); + v2 = (cos*HRminus - sin*HIplus); + *A = (HRplus + v1) * (fft_type)0.5; + *B = *A - v1; + *(A+1) = (HIminus - v2) * (fft_type)0.5; + *(B+1) = *(A+1) - HIminus; + + A+=2; + B-=2; + br1++; + } + /* Handle center bin (just need conjugate) */ + *(A+1)=-*(A+1); + /* Handle DC bin separately - this ignores any Fs/2 component + buffer[1]=buffer[0]=buffer[0]/2;*/ + /* Handle DC and Fs/2 bins specially */ + /* The DC bin is passed in as the real part of the DC complex value */ + /* The Fs/2 bin is passed in as the imaginary part of the DC complex value */ + /* (v1+v2) = buffer[0] == the DC component */ + /* (v1-v2) = buffer[1] == the Fs/2 component */ + v1=0.5f*(buffer[0]+buffer[1]); + v2=0.5f*(buffer[0]-buffer[1]); + buffer[0]=v1; + buffer[1]=v2; + + /* + * Butterfly: + * Ain-----Aout + * \ / + * / \ + * Bin-----Bout + */ + + endptr1=buffer+h->Points*2; + + while(ButterfliesPerGroup>0) + { + A=buffer; + B=buffer+ButterfliesPerGroup*2; + sptr=h->SinTable; + + while(A>= 1; + } +} + +void ReorderToFreq(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut) +{ + // Copy the data into the real and imaginary outputs + for(int i=1;iPoints;i++) { + RealOut[i]=buffer[hFFT->BitReversed[i] ]; + ImagOut[i]=buffer[hFFT->BitReversed[i]+1]; + } + RealOut[0] = buffer[0]; // DC component + ImagOut[0] = 0; + RealOut[hFFT->Points] = buffer[1]; // Fs/2 component + ImagOut[hFFT->Points] = 0; +} + +void ReorderToTime(HFFT hFFT, fft_type *buffer, fft_type *TimeOut) +{ + // Copy the data into the real outputs + for(int i=0;iPoints;i++) { + TimeOut[i*2 ]=buffer[hFFT->BitReversed[i] ]; + TimeOut[i*2+1]=buffer[hFFT->BitReversed[i]+1]; + } +} diff --git a/PitchTracker/FFT/RealFFTf.h b/PitchTracker/FFT/RealFFTf.h new file mode 100644 index 00000000..f46119ca --- /dev/null +++ b/PitchTracker/FFT/RealFFTf.h @@ -0,0 +1,23 @@ +#ifndef __realfftf_h +#define __realfftf_h + +#define fft_type float +typedef struct FFTParamType { + int *BitReversed; + fft_type *SinTable; + int Points; +} FFTParam; +#define HFFT FFTParam * + +HFFT InitializeFFT(int); +void EndFFT(HFFT); +HFFT GetFFT(int); +void ReleaseFFT(HFFT); +void CleanupFFT(); +void RealFFTf(fft_type *,HFFT); +void InverseRealFFTf(fft_type *,HFFT); +void ReorderToTime(HFFT hFFT, fft_type *buffer, fft_type *TimeOut); +void ReorderToFreq(HFFT hFFT, fft_type *buffer, fft_type *RealOut, fft_type *ImagOut); + +#endif + diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj index 1b729255..65ce0ada 100644 --- a/PitchTracker/PitchTracker.vcxproj +++ b/PitchTracker/PitchTracker.vcxproj @@ -174,6 +174,8 @@ + + @@ -183,6 +185,8 @@ + + diff --git a/PitchTracker/PitchTracker.vcxproj.filters b/PitchTracker/PitchTracker.vcxproj.filters index 6e3d94f4..81447394 100644 --- a/PitchTracker/PitchTracker.vcxproj.filters +++ b/PitchTracker/PitchTracker.vcxproj.filters @@ -28,6 +28,12 @@ {2a09cee1-51b7-4c24-aa9f-32bec53c3a36} + + {498f64e2-ff83-41fd-be25-c613750f0e34} + + + {0791b62f-ef8d-40e2-b67e-a6d9dead8720} + @@ -51,6 +57,12 @@ Quelldateien + + Quelldateien\FFT + + + Quelldateien\FFT + @@ -77,6 +89,12 @@ Headerdateien\dywapitchtrack + + Headerdateien\FFT + + + Headerdateien\FFT + diff --git a/PitchTracker/performous/libda/sample.hpp b/PitchTracker/performous/libda/sample.hpp index a09bbcb6..da55bda7 100644 --- a/PitchTracker/performous/libda/sample.hpp +++ b/PitchTracker/performous/libda/sample.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include "../compatibility.h" /** * @file sample.hpp Sample format definition and format conversions. diff --git a/PitchTracker/ptAKF.cpp b/PitchTracker/ptAKF.cpp index 335bcde6..7936cad3 100644 --- a/PitchTracker/ptAKF.cpp +++ b/PitchTracker/ptAKF.cpp @@ -17,8 +17,13 @@ #include "ptAKF.h" #include +#ifdef USE_FFT +#include "FFT/FFT.h" +#endif + static constexpr double BaseToneFrequency = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz) static constexpr double HalftoneBase = 1.05946309436; // 2^(1/12) -> HalftoneBase^12 = 2 (one octave) + int PtAKF::_InitCount = 0; float* restrict PtAKF::_SamplesPerPeriodPerTone = NULL; float* restrict PtAKF::_SamplesPerPeriodPerToneFine = NULL; @@ -41,9 +46,9 @@ PtAKF::PtAKF(unsigned step){ _SamplesPerPeriodPerToneFine[2 * toneIndex + 1] = static_cast(44100.0 / GetFrequencyFromTone(toneIndex + 1./3.)); // samples for a bit above exact frequency } _Window = new float[_SampleCt]; - double cosMult = 2. * M_PI / (_SampleCt - 1.); //To simplify and speed up + double cosMult = 2. * M_PI / (2 * _SampleCt - 1.); //To simplify and speed up; 2 * _SampleCt because we extend the data by a factor of 2 for (int i = 0; i < _SampleCt; i++) { - _Window[i] = static_cast(0.64 - 0.36 * cos(i * cosMult)); + _Window[i] = static_cast(0.54 - 0.46 * cos(i * cosMult)); } } _Step = step; @@ -149,12 +154,20 @@ int PtAKF::_GetNote(float samples[_SampleCt], float* restrict maxVolume, float w if(maxVolumeL < _VolTreshold) return -1; - float samplesWindowed[_SampleCt]; + float samplesWindowed[_SampleCt * 2]; for(int i = 0; i < _SampleCt; i++){ samplesWindowed[i] = samples[i] * _Window[i]; } +#ifdef USE_FFT + for(int i = _SampleCt; i < _SampleCt * 2; i++){ + samplesWindowed[i] = 0.f; + } + float samplesFFT[_SampleCt+1]; // +1 for middle value! + PowerSpectrum(_SampleCt*2, samplesWindowed, samplesFFT); + RealInverseRealFFT(_SampleCt*2, samplesFFT, _AKFValues); +#endif // Now analyze the samples and get peaks at the most appropriate tones //Attention: We have a peak at lag 0 that might stretch that far, that we detect a wrong "peak" at _MaxHalfTone @@ -163,6 +176,7 @@ int PtAKF::_GetNote(float samples[_SampleCt], float* restrict maxVolume, float w float lastWeight = 1.f; float maxWeight = 0.f; + //TODO: When using FFT this can be speed up a lot by only checking around the AKF peaks #pragma omp parallel for schedule(static) for (int toneIndex = 0; toneIndex <= _MaxHalfTone; toneIndex++){ float curWeight = _AnalyzeByTone(samples, samplesWindowed, toneIndex); @@ -307,6 +321,10 @@ float PtAKF::_AKFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD){ int samplesPerPeriod = static_cast(samplesPerPeriodD); float fHigh = samplesPerPeriodD - samplesPerPeriod; float fLow = 1.0f - fHigh; +#ifdef USE_FFT + float akf2 = _AKFValues[samplesPerPeriod] * fLow + _AKFValues[samplesPerPeriod+1] * fHigh; + return akf2 / (_SampleCt * _SampleCt); +#else float accumDist = 0; // accumulated distances @@ -322,10 +340,11 @@ float PtAKF::_AKFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD){ } return accumDist / _SampleCt; +#endif } float PtAKF::_AMDFByTone(float samples[_SampleCt], int toneIndex){ - return _AKFBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); + return _AMDFBySampleCt(samples, _SamplesPerPeriodPerTone[toneIndex]); } float PtAKF::_AMDFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD){ diff --git a/PitchTracker/ptAKF.h b/PitchTracker/ptAKF.h index b5d9a2b6..00f8aeb5 100644 --- a/PitchTracker/ptAKF.h +++ b/PitchTracker/ptAKF.h @@ -13,6 +13,8 @@ # endif #endif +#define USE_FFT + struct SPeak{ int toneIndex; float weight; @@ -55,14 +57,17 @@ private: float _LastMaxVol; int _LastTones[_SmoothCt]; int _LastToneIndex; +#ifdef USE_FFT + float _AKFValues[_SampleCt*2]; +#endif int _GetNote(float samples[_SampleCt], float* restrict maxVolume, float weights[_MaxHalfTone+1]); int _GetSmoothTone(); - static float _AnalyzeBySampleCt(float samples[_SampleCt], float samplesWindowed[_SampleCt], float samplesPerPeriodD); - static inline float _AnalyzeByTone(float samples[_SampleCt], float samplesWindowed[_SampleCt], int toneIndex); - static float _AKFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD); - static inline float _AKFByTone(float samples[_SampleCt], int toneIndex); + float _AnalyzeBySampleCt(float samples[_SampleCt], float samplesWindowed[_SampleCt], float samplesPerPeriodD); + inline float _AnalyzeByTone(float samples[_SampleCt], float samplesWindowed[_SampleCt], int toneIndex); + float _AKFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD); + inline float _AKFByTone(float samples[_SampleCt], int toneIndex); static float _AMDFBySampleCt(float samples[_SampleCt], float samplesPerPeriodD); static inline float _AMDFByTone(float samples[_SampleCt], int toneIndex); static inline void InitPeaks(SPeak peaks[_MaxPeaks]);