From 3b1235c937073ed83c5631c050be45b7f54625fe Mon Sep 17 00:00:00 2001 From: Jonathan Gilbert Date: Thu, 3 Jan 2019 03:05:13 -0600 Subject: [PATCH] Added project rubberband-dll to create Windows DLL files (32-bit and 64-bit) that expose the Rubber Band API as a flat API that can be imported through runtime linking. Added project rubberband-sharp to provide a .NET wrapper of the rubberband-dll files, dynamically dispatching to the 32- or 64-bit DLL based on the process platform. Configured NuGet package creation, with compatibility for both packages.config and PackageReference style consumers. --- rubberband-dll.vcxproj | 183 ++++++++++ rubberband-dll.vcxproj.filters | 36 ++ rubberband-dll/dllmain.cpp | 19 ++ rubberband-dll/rubberband-dll.cpp | 211 ++++++++++++ rubberband-dll/stdafx.cpp | 1 + rubberband-dll/stdafx.h | 16 + rubberband-dll/targetver.h | 8 + rubberband-sharp/Install.ps1 | 48 +++ rubberband-sharp/RubberBandNativeMethods.cs | 256 ++++++++++++++ .../RubberBandNativeMethodsWin32.cs | 71 ++++ .../RubberBandNativeMethodsx64.cs | 71 ++++ rubberband-sharp/RubberBandStretcher.cs | 312 ++++++++++++++++++ rubberband-sharp/rubberband-sharp.csproj | 10 + rubberband-sharp/rubberband-sharp.nuspec | 21 ++ rubberband-sharp/rubberband-sharp.targets | 12 + rubberband.sln | 38 +++ 16 files changed, 1313 insertions(+) create mode 100644 rubberband-dll.vcxproj create mode 100644 rubberband-dll.vcxproj.filters create mode 100644 rubberband-dll/dllmain.cpp create mode 100644 rubberband-dll/rubberband-dll.cpp create mode 100644 rubberband-dll/stdafx.cpp create mode 100644 rubberband-dll/stdafx.h create mode 100644 rubberband-dll/targetver.h create mode 100644 rubberband-sharp/Install.ps1 create mode 100644 rubberband-sharp/RubberBandNativeMethods.cs create mode 100644 rubberband-sharp/RubberBandNativeMethodsWin32.cs create mode 100644 rubberband-sharp/RubberBandNativeMethodsx64.cs create mode 100644 rubberband-sharp/RubberBandStretcher.cs create mode 100644 rubberband-sharp/rubberband-sharp.csproj create mode 100644 rubberband-sharp/rubberband-sharp.nuspec create mode 100644 rubberband-sharp/rubberband-sharp.targets diff --git a/rubberband-dll.vcxproj b/rubberband-dll.vcxproj new file mode 100644 index 0000000..c641bcf --- /dev/null +++ b/rubberband-dll.vcxproj @@ -0,0 +1,183 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {32C11C5C-3D27-4E57-B72C-161A48AAA95E} + rubberbanddll + Win32Proj + + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + true + _DEBUG;RUBBERBANDDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)rubberband;%(AdditionalIncludeDirectories) + + + Windows + true + $(OutDir);%(AdditionalLibraryDirectories) + rubberband-library.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)-$(Platform)$(TargetExt) + + + + + Use + Level3 + Disabled + true + WIN32;_DEBUG;RUBBERBANDDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)rubberband;%(AdditionalIncludeDirectories) + + + Windows + true + rubberband-library.lib;%(AdditionalDependencies) + $(OutDir);%(AdditionalLibraryDirectories) + $(OutDir)$(TargetName)-$(Platform)$(TargetExt) + + + + + Use + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;RUBBERBANDDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)rubberband;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + rubberband-library.lib;%(AdditionalDependencies) + $(OutDir);%(AdditionalLibraryDirectories) + $(OutDir)$(TargetName)-$(Platform)$(TargetExt) + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;RUBBERBANDDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)rubberband;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + $(OutDir);%(AdditionalLibraryDirectories) + rubberband-library.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)-$(Platform)$(TargetExt) + + + + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/rubberband-dll.vcxproj.filters b/rubberband-dll.vcxproj.filters new file mode 100644 index 0000000..016b16e --- /dev/null +++ b/rubberband-dll.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;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 + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/rubberband-dll/dllmain.cpp b/rubberband-dll/dllmain.cpp new file mode 100644 index 0000000..37bdad5 --- /dev/null +++ b/rubberband-dll/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/rubberband-dll/rubberband-dll.cpp b/rubberband-dll/rubberband-dll.cpp new file mode 100644 index 0000000..9ecc4aa --- /dev/null +++ b/rubberband-dll/rubberband-dll.cpp @@ -0,0 +1,211 @@ +// rubberband-dll.cpp : Defines the exported functions for the DLL application. +// + +#include "stdafx.h" + +using namespace RubberBand; + +#define EXPORT extern "C" __declspec(dllexport) + +#if _WIN64 +#define CONVENTION __stdcall +#else +#define CONVENTION __cdecl +#endif + +#define O(rbs) reinterpret_cast(rbs) + +EXPORT HANDLE CONVENTION RubberBandStretcher_Create( + size_t sampleRate, + size_t channels, + int options = RubberBandStretcher::DefaultOptions, + double initialTimeRatio = 1.0, + double initialPitchScale = 1.0) +{ + return (HANDLE)new RubberBandStretcher(sampleRate, channels, options, initialTimeRatio, initialPitchScale); +} + +EXPORT void CONVENTION RubberBandStretcher_Delete(HANDLE *rbs) +{ + delete O(rbs); +} + +EXPORT void CONVENTION RubberBandStretcher_Reset(HANDLE *rbs) +{ + O(rbs)->reset(); +} + +EXPORT void CONVENTION RubberBandStretcher_SetTimeRatio(HANDLE *rbs, double ratio) +{ + O(rbs)->setTimeRatio(ratio); +} + +EXPORT void CONVENTION RubberBandStretcher_SetPitchScale(HANDLE *rbs, double scale) +{ + O(rbs)->setPitchScale(scale); +} + +EXPORT double CONVENTION RubberBandStretcher_GetTimeRatio(HANDLE *rbs) +{ + return O(rbs)->getTimeRatio(); +} + +EXPORT double CONVENTION RubberBandStretcher_GetPitchScale(HANDLE *rbs) +{ + return O(rbs)->getPitchScale(); +} + +EXPORT size_t CONVENTION RubberBandStretcher_GetLatency(HANDLE *rbs) +{ + return O(rbs)->getLatency(); +} + +EXPORT void CONVENTION RubberBandStretcher_SetTransientsOption(HANDLE *rbs, int options) +{ + O(rbs)->setTransientsOption(options); +} + +EXPORT void CONVENTION RubberBandStretcher_SetDetectorOption(HANDLE *rbs, int options) +{ + O(rbs)->setDetectorOption(options); +} + +EXPORT void CONVENTION RubberBandStretcher_SetPhaseOption(HANDLE *rbs, int options) +{ + O(rbs)->setPhaseOption(options); +} + +EXPORT void CONVENTION RubberBandStretcher_SetFormantOption(HANDLE *rbs, int options) +{ + O(rbs)->setFormantOption(options); +} + +EXPORT void CONVENTION RubberBandStretcher_SetPitchOption(HANDLE *rbs, int options) +{ + O(rbs)->setPitchOption(options); +} + +EXPORT void CONVENTION RubberBandStretcher_SetExpectedInputDuration(HANDLE *rbs, size_t samples) +{ + O(rbs)->setExpectedInputDuration(samples); +} + +EXPORT void CONVENTION RubberBandStretcher_SetMaxProcessSize(HANDLE *rbs, size_t samples) +{ + O(rbs)->setMaxProcessSize(samples); +} + +EXPORT size_t CONVENTION RubberBandStretcher_GetSamplesRequired(HANDLE *rbs) +{ + return O(rbs)->getSamplesRequired(); +} + +EXPORT void CONVENTION RubberBandStretcher_SetKeyFrameMap(HANDLE *rbs, size_t *mappingData, int numberOfMappings) +{ + std::map map; + + for (int i = 0; i < numberOfMappings; i++) + map[mappingData[i + i]] = mappingData[i + i + 1]; + + O(rbs)->setKeyFrameMap(map); +} + +EXPORT void CONVENTION RubberBandStretcher_Study(HANDLE *rbs, float *input_flat, size_t samples, int channels, bool final) +{ + std::vector input; + + for (int i = 0; i < channels; i++) + input.push_back(&input_flat[samples * i]); + + O(rbs)->study(&input[0], samples, final); +} + +EXPORT void CONVENTION RubberBandStretcher_Process(HANDLE *rbs, float *input_flat, size_t samples, int channels, bool final) +{ + std::vector input; + + for (int i = 0; i < channels; i++) + input.push_back(&input_flat[samples * i]); + + O(rbs)->process(&input[0], samples, final); +} + +EXPORT int CONVENTION RubberBandStretcher_Available(HANDLE *rbs) +{ + return O(rbs)->available(); +} + +EXPORT size_t CONVENTION RubberBandStretcher_Retrieve(HANDLE *rbs, float *output_flat, size_t samples, int channels) +{ + std::vector output; + + for (int i = 0; i < channels; i++) + output.push_back(&output_flat[samples * i]); + + return O(rbs)->retrieve(&output[0], samples); +} + +EXPORT float CONVENTION RubberBandStretcher_GetFrequencyCutoff(HANDLE *rbs, int n) +{ + return O(rbs)->getFrequencyCutoff(n); +} + +EXPORT void CONVENTION RubberBandStretcher_SetFrequencyCutoff(HANDLE *rbs, int n, float f) +{ + O(rbs)->setFrequencyCutoff(n, f); +} + +EXPORT size_t CONVENTION RubberBandStretcher_GetInputIncrement(HANDLE *rbs) +{ + return O(rbs)->getInputIncrement(); +} + +EXPORT size_t CONVENTION RubberBandStretcher_GetOutputIncrements(HANDLE *rbs, int *buffer, size_t bufferSize) +{ + std::vector increments = O(rbs)->getOutputIncrements(); + + for (size_t i = 0; (i < bufferSize) && (i < increments.size()); i++) + buffer[i] = increments[i]; + + return increments.size(); +} + +EXPORT size_t CONVENTION RubberBandStretcher_GetPhaseResetCurve(HANDLE *rbs, float *buffer, size_t bufferSize) +{ + std::vector curve = O(rbs)->getPhaseResetCurve(); + + for (size_t i = 0; (i < bufferSize) && (i < curve.size()); i++) + buffer[i] = curve[i]; + + return curve.size(); +} + +EXPORT size_t CONVENTION RubberBandStretcher_GetExactTimePoints(HANDLE *rbs, int *buffer, size_t bufferSize) +{ + std::vector timePoints = O(rbs)->getExactTimePoints(); + + for (size_t i = 0; (i < bufferSize) && (i < timePoints.size()); i++) + buffer[i] = timePoints[i]; + + return timePoints.size(); +} + +EXPORT size_t CONVENTION RubberBandStretcher_GetChannelCount(HANDLE *rbs) +{ + return O(rbs)->getChannelCount(); +} + +EXPORT void CONVENTION RubberBandStretcher_CalculateStretch(HANDLE *rbs) +{ + O(rbs)->calculateStretch(); +} + +EXPORT void CONVENTION RubberBandStretcher_SetDebugLevel(HANDLE *rbs, int level) +{ + O(rbs)->setDebugLevel(level); +} + +EXPORT void CONVENTION RubberBandStretcher_SetDefaultDebugLevel(int level) +{ + RubberBandStretcher::setDefaultDebugLevel(level); +} diff --git a/rubberband-dll/stdafx.cpp b/rubberband-dll/stdafx.cpp new file mode 100644 index 0000000..a27b824 --- /dev/null +++ b/rubberband-dll/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/rubberband-dll/stdafx.h b/rubberband-dll/stdafx.h new file mode 100644 index 0000000..2f1d393 --- /dev/null +++ b/rubberband-dll/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include + +#include + +// reference additional headers your program requires here diff --git a/rubberband-dll/targetver.h b/rubberband-dll/targetver.h new file mode 100644 index 0000000..90e767b --- /dev/null +++ b/rubberband-dll/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/rubberband-sharp/Install.ps1 b/rubberband-sharp/Install.ps1 new file mode 100644 index 0000000..b9ac711 --- /dev/null +++ b/rubberband-sharp/Install.ps1 @@ -0,0 +1,48 @@ +Param +( + $InstallPath, + $ToolsPath, + $Package, + $Project +) + +# Save current project state. +$Project.Save() + +# Load project XML. +$ProjectFullName = $Project.FullName + +$Doc = New-Object System.Xml.XmlDocument +$Doc.Load($ProjectFullName) + +$Namespace = 'http://schemas.microsoft.com/developer/msbuild/2003' + +# Find the node containing the file. The tag "Content" may be replace by "None" depending of the case, check your .csproj file. +$ContentNodes = Select-Xml "//msb:Project/msb:ItemGroup/msb:Content[starts-with(@Include, 'rubberband-dll-') and (substring(@Include, string-length(@Include) - 3) = '.dll')]" $Doc -Namespace @{msb = $Namespace} + +#check if the node exists. +If ($ContentNodes -ne $Null) +{ + $CopyNodeName = "CopyToOutputDirectory" + + ForEach ($ContentNode In $ContentNodes) + { + $NoneNode = $Doc.CreateElement("None", $Namespace) + $NoneNode.SetAttribute("Include", $ContentNode.Node.Attributes["Include"].Value) + + $CopyNode = $Doc.CreateElement($CopyNodeName, $Namespace) + $CopyNode.InnerText = "PreserveNewest" + + $NoneNode.AppendChild($CopyNode) + + $ContentNode.Node.ParentNode.ReplaceChild($NoneNode, $ContentNode.Node) + } + + $DTE = $Project.DTE + + $Project.Select("vsUISelectionTypeSelect") + + $DTE.ExecuteCommand("Project.UnloadProject") + $Doc.Save($ProjectFullName) + $DTE.ExecuteCommand("Project.ReloadProject") +} diff --git a/rubberband-sharp/RubberBandNativeMethods.cs b/rubberband-sharp/RubberBandNativeMethods.cs new file mode 100644 index 0000000..cfbd056 --- /dev/null +++ b/rubberband-sharp/RubberBandNativeMethods.cs @@ -0,0 +1,256 @@ +using System; +using System.Runtime.InteropServices; + +namespace RubberBand +{ + internal class RubberBandNativeMethods + { + public static IntPtr RubberBandStretcher_Create(IntPtr sampleRate, IntPtr channels, int options = 0, double initialTimeRatio = 1.0, double initialPitchScale = 1.0) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_Create(sampleRate, channels, options, initialTimeRatio, initialPitchScale); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_Create(sampleRate, channels, options, initialTimeRatio, initialPitchScale); + } + + public static void RubberBandStretcher_Delete(IntPtr rbs) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_Delete(rbs); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_Delete(rbs); + } + + public static void RubberBandStretcher_Reset(IntPtr rbs) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_Reset(rbs); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_Reset(rbs); + } + + public static void RubberBandStretcher_SetTimeRatio(IntPtr rbs, double ratio) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetTimeRatio(rbs, ratio); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetTimeRatio(rbs, ratio); + } + + public static void RubberBandStretcher_SetPitchScale(IntPtr rbs, double scale) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetPitchScale(rbs, scale); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetPitchScale(rbs, scale); + } + + public static double RubberBandStretcher_GetTimeRatio(IntPtr rbs) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetTimeRatio(rbs); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetTimeRatio(rbs); + } + + public static double RubberBandStretcher_GetPitchScale(IntPtr rbs) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetPitchScale(rbs); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetPitchScale(rbs); + } + + public static IntPtr RubberBandStretcher_GetLatency(IntPtr rbs) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetLatency(rbs); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetLatency(rbs); + } + + public static void RubberBandStretcher_SetTransientsOption(IntPtr rbs, int options) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetTransientsOption(rbs, options); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetTransientsOption(rbs, options); + } + + public static void RubberBandStretcher_SetDetectorOption(IntPtr rbs, int options) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetDetectorOption(rbs, options); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetDetectorOption(rbs, options); + } + + public static void RubberBandStretcher_SetPhaseOption(IntPtr rbs, int options) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetPhaseOption(rbs, options); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetPhaseOption(rbs, options); + } + + public static void RubberBandStretcher_SetFormantOption(IntPtr rbs, int options) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetFormantOption(rbs, options); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetFormantOption(rbs, options); + } + + public static void RubberBandStretcher_SetPitchOption(IntPtr rbs, int options) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetPitchOption(rbs, options); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetPitchOption(rbs, options); + } + + public static void RubberBandStretcher_SetExpectedInputDuration(IntPtr rbs, IntPtr samples) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetExpectedInputDuration(rbs, samples); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetExpectedInputDuration(rbs, samples); + } + + public static void RubberBandStretcher_SetMaxProcessSize(IntPtr rbs, IntPtr samples) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetMaxProcessSize(rbs, samples); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetMaxProcessSize(rbs, samples); + } + + public static IntPtr RubberBandStretcher_GetSamplesRequired(IntPtr rbs) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetSamplesRequired(rbs); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetSamplesRequired(rbs); + } + + public static void RubberBandStretcher_SetKeyFrameMap(IntPtr rbs, IntPtr[] mappingData, int numberOfMappings) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetKeyFrameMap(rbs, mappingData, numberOfMappings); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetKeyFrameMap(rbs, mappingData, numberOfMappings); + } + + public static void RubberBandStretcher_Study(IntPtr rbs, float[] input, IntPtr samples, int channels, bool final) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_Study(rbs, input, samples, channels, final); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_Study(rbs, input, samples, channels, final); + } + + public static void RubberBandStretcher_Process(IntPtr rbs, float[] input, IntPtr samples, int channels, bool final) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_Process(rbs, input, samples, channels, final); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_Process(rbs, input, samples, channels, final); + } + + public static int RubberBandStretcher_Available(IntPtr rbs) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_Available(rbs); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_Available(rbs); + } + + public static IntPtr RubberBandStretcher_Retrieve(IntPtr rbs, float[] output, IntPtr samples, int channels) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_Retrieve(rbs, output, samples, channels); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_Retrieve(rbs, output, samples, channels); + } + + public static float RubberBandStretcher_GetFrequencyCutoff(IntPtr rbs, int n) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetFrequencyCutoff(rbs, n); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetFrequencyCutoff(rbs, n); + } + + public static void RubberBandStretcher_SetFrequencyCutoff(IntPtr rbs, int n, float f) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetFrequencyCutoff(rbs, n, f); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetFrequencyCutoff(rbs, n, f); + } + + public static IntPtr RubberBandStretcher_GetInputIncrement(IntPtr rbs) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetInputIncrement(rbs); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetInputIncrement(rbs); + } + + public static IntPtr RubberBandStretcher_GetOutputIncrements(IntPtr rbs, int[] buffer, IntPtr bufferSize) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetOutputIncrements(rbs, buffer, bufferSize); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetOutputIncrements(rbs, buffer, bufferSize); + } + + public static IntPtr RubberBandStretcher_GetPhaseResetCurve(IntPtr rbs, float[] buffer, IntPtr bufferSize) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetPhaseResetCurve(rbs, buffer, bufferSize); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetPhaseResetCurve(rbs, buffer, bufferSize); + } + + public static IntPtr RubberBandStretcher_GetExactTimePoints(IntPtr rbs, int[] buffer, IntPtr bufferSize) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetExactTimePoints(rbs, buffer, bufferSize); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetExactTimePoints(rbs, buffer, bufferSize); + } + + public static IntPtr RubberBandStretcher_GetChannelCount(IntPtr rbs) + { + if (IntPtr.Size == 8) + return RubberBandNativeMethodsx64.RubberBandStretcher_GetChannelCount(rbs); + else + return RubberBandNativeMethodsWin32.RubberBandStretcher_GetChannelCount(rbs); + } + + public static void RubberBandStretcher_CalculateStretch(IntPtr rbs) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_CalculateStretch(rbs); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_CalculateStretch(rbs); + } + + public static void RubberBandStretcher_SetDebugLevel(IntPtr rbs, int level) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetDebugLevel(rbs, level); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetDebugLevel(rbs, level); + } + + public static void RubberBandStretcher_SetDefaultDebugLevel(int level) + { + if (IntPtr.Size == 8) + RubberBandNativeMethodsx64.RubberBandStretcher_SetDefaultDebugLevel(level); + else + RubberBandNativeMethodsWin32.RubberBandStretcher_SetDefaultDebugLevel(level); + } + } +} diff --git a/rubberband-sharp/RubberBandNativeMethodsWin32.cs b/rubberband-sharp/RubberBandNativeMethodsWin32.cs new file mode 100644 index 0000000..f49cf75 --- /dev/null +++ b/rubberband-sharp/RubberBandNativeMethodsWin32.cs @@ -0,0 +1,71 @@ +using System; +using System.Runtime.InteropServices; + +namespace RubberBand +{ + internal class RubberBandNativeMethodsWin32 + { + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_Create(IntPtr sampleRate, IntPtr channels, int options = 0, double initialTimeRatio = 1.0, double initialPitchScale = 1.0); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_Delete(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_Reset(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetTimeRatio(IntPtr rbs, double ratio); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetPitchScale(IntPtr rbs, double scale); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern double RubberBandStretcher_GetTimeRatio(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern double RubberBandStretcher_GetPitchScale(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_GetLatency(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetTransientsOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetDetectorOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetPhaseOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetFormantOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetPitchOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetExpectedInputDuration(IntPtr rbs, IntPtr samples); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetMaxProcessSize(IntPtr rbs, IntPtr samples); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_GetSamplesRequired(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetKeyFrameMap(IntPtr rbs, IntPtr[] mappingData, int numberOfMappings); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_Study(IntPtr rbs, float[] input, IntPtr samples, int channels, bool final); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_Process(IntPtr rbs, float[] input, IntPtr samples, int channels, bool final); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern int RubberBandStretcher_Available(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_Retrieve(IntPtr rbs, float[] output, IntPtr samples, int channels); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern float RubberBandStretcher_GetFrequencyCutoff(IntPtr rbs, int n); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetFrequencyCutoff(IntPtr rbs, int n, float f); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_GetInputIncrement(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_GetOutputIncrements(IntPtr rbs, int[] buffer, IntPtr bufferSize); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_GetPhaseResetCurve(IntPtr rbs, float[] buffer, IntPtr bufferSize); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_GetExactTimePoints(IntPtr rbs, int[] buffer, IntPtr bufferSize); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr RubberBandStretcher_GetChannelCount(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_CalculateStretch(IntPtr rbs); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetDebugLevel(IntPtr rbs, int level); + [DllImport("rubberband-dll-Win32", CallingConvention = CallingConvention.Cdecl)] + public static extern void RubberBandStretcher_SetDefaultDebugLevel(int level); + } +} diff --git a/rubberband-sharp/RubberBandNativeMethodsx64.cs b/rubberband-sharp/RubberBandNativeMethodsx64.cs new file mode 100644 index 0000000..c343d23 --- /dev/null +++ b/rubberband-sharp/RubberBandNativeMethodsx64.cs @@ -0,0 +1,71 @@ +using System; +using System.Runtime.InteropServices; + +namespace RubberBand +{ + internal class RubberBandNativeMethodsx64 + { + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_Create(IntPtr sampleRate, IntPtr channels, int options = 0, double initialTimeRatio = 1.0, double initialPitchScale = 1.0); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_Delete(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_Reset(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetTimeRatio(IntPtr rbs, double ratio); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetPitchScale(IntPtr rbs, double scale); + [DllImport("rubberband-dll-x64")] + public static extern double RubberBandStretcher_GetTimeRatio(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern double RubberBandStretcher_GetPitchScale(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_GetLatency(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetTransientsOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetDetectorOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetPhaseOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetFormantOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetPitchOption(IntPtr rbs, int options); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetExpectedInputDuration(IntPtr rbs, IntPtr samples); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetMaxProcessSize(IntPtr rbs, IntPtr samples); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_GetSamplesRequired(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetKeyFrameMap(IntPtr rbs, IntPtr[] mappingData, int numberOfMappings); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_Study(IntPtr rbs, float[] input, IntPtr samples, int channels, bool final); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_Process(IntPtr rbs, float[] input, IntPtr samples, int channels, bool final); + [DllImport("rubberband-dll-x64")] + public static extern int RubberBandStretcher_Available(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_Retrieve(IntPtr rbs, float[] output, IntPtr samples, int channels); + [DllImport("rubberband-dll-x64")] + public static extern float RubberBandStretcher_GetFrequencyCutoff(IntPtr rbs, int n); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetFrequencyCutoff(IntPtr rbs, int n, float f); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_GetInputIncrement(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_GetOutputIncrements(IntPtr rbs, int[] buffer, IntPtr bufferSize); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_GetPhaseResetCurve(IntPtr rbs, float[] buffer, IntPtr bufferSize); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_GetExactTimePoints(IntPtr rbs, int[] buffer, IntPtr bufferSize); + [DllImport("rubberband-dll-x64")] + public static extern IntPtr RubberBandStretcher_GetChannelCount(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_CalculateStretch(IntPtr rbs); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetDebugLevel(IntPtr rbs, int level); + [DllImport("rubberband-dll-x64")] + public static extern void RubberBandStretcher_SetDefaultDebugLevel(int level); + } +} diff --git a/rubberband-sharp/RubberBandStretcher.cs b/rubberband-sharp/RubberBandStretcher.cs new file mode 100644 index 0000000..750ee3e --- /dev/null +++ b/rubberband-sharp/RubberBandStretcher.cs @@ -0,0 +1,312 @@ +using System; +using System.Collections.Generic; + +namespace RubberBand +{ + public class RubberBandStretcher : IDisposable + { + public enum Options + { + None = 0, + + ProcessOffline = 0x00000000, + ProcessRealTime = 0x00000001, + + StretchElastic = 0x00000000, + StretchPrecise = 0x00000010, + + TransientsCrisp = 0x00000000, + TransientsMixed = 0x00000100, + TransientsSmooth = 0x00000200, + + DetectorCompound = 0x00000000, + DetectorPercussive = 0x00000400, + DetectorSoft = 0x00000800, + + PhaseLaminar = 0x00000000, + PhaseIndependent = 0x00002000, + + ThreadingAuto = 0x00000000, + ThreadingNever = 0x00010000, + ThreadingAlways = 0x00020000, + + WindowStandard = 0x00000000, + WindowShort = 0x00100000, + WindowLong = 0x00200000, + + SmoothingOff = 0x00000000, + SmoothingOn = 0x00800000, + + FormantShifted = 0x00000000, + FormantPreserved = 0x01000000, + + PitchHighSpeed = 0x00000000, + PitchHighQuality = 0x02000000, + PitchHighConsistency = 0x04000000, + + ChannelsApart = 0x00000000, + ChannelsTogether = 0x10000000, + } + + public const Options DefaultOptions = Options.None; + public const Options PercussiveOptions = Options.WindowShort | Options.PhaseIndependent; + + IntPtr _rbs; + + public RubberBandStretcher(int sampleRate, int channels, Options options = DefaultOptions, double initialTimeRatio = 1.0, double initialPitchScale = 1.0) + { + _rbs = RubberBandNativeMethods.RubberBandStretcher_Create(new IntPtr(sampleRate), new IntPtr(channels), (int)options, initialTimeRatio, initialPitchScale); + } + + public void Dispose() + { + if (_rbs != IntPtr.Zero) + { + RubberBandNativeMethods.RubberBandStretcher_Delete(_rbs); + _rbs = IntPtr.Zero; + } + } + + public void Reset() + { + RubberBandNativeMethods.RubberBandStretcher_Reset(_rbs); + } + + public void SetTimeRatio(double ratio) + { + RubberBandNativeMethods.RubberBandStretcher_SetTimeRatio(_rbs, ratio); + } + + public void SetPitchScale(double scale) + { + RubberBandNativeMethods.RubberBandStretcher_SetPitchScale(_rbs, scale); + } + + public double GetTimeRatio() + { + return RubberBandNativeMethods.RubberBandStretcher_GetTimeRatio(_rbs); + } + + public double GetPitchScale() + { + return RubberBandNativeMethods.RubberBandStretcher_GetPitchScale(_rbs); + } + + public long GetLatency() + { + return RubberBandNativeMethods.RubberBandStretcher_GetLatency(_rbs).ToInt64(); + } + + public void SetTransientsOption(Options options) + { + RubberBandNativeMethods.RubberBandStretcher_SetTransientsOption(_rbs, (int)options); + } + + public void SetDetectorOption(Options options) + { + RubberBandNativeMethods.RubberBandStretcher_SetDetectorOption(_rbs, (int)options); + } + + public void SetPhaseOption(Options options) + { + RubberBandNativeMethods.RubberBandStretcher_SetPhaseOption(_rbs, (int)options); + } + + public void SetFormantOption(Options options) + { + RubberBandNativeMethods.RubberBandStretcher_SetFormantOption(_rbs, (int)options); + } + + public void SetPitchOption(Options options) + { + RubberBandNativeMethods.RubberBandStretcher_SetPitchOption(_rbs, (int)options); + } + + public void SetExpectedInputDuration(long samples) + { + RubberBandNativeMethods.RubberBandStretcher_SetExpectedInputDuration(_rbs, new IntPtr(samples)); + } + + public void SetMaxProcessSize(long samples) + { + RubberBandNativeMethods.RubberBandStretcher_SetMaxProcessSize(_rbs, new IntPtr(samples)); + } + + public long GetSamplesRequired() + { + return RubberBandNativeMethods.RubberBandStretcher_GetSamplesRequired(_rbs).ToInt64(); + } + + public void SetKeyFrameMap(SortedDictionary map) + { + var mappingData = new List(); + + foreach (var mapping in map) + { + mappingData.Add(new IntPtr(mapping.Key)); + mappingData.Add(new IntPtr(mapping.Value)); + } + + RubberBandNativeMethods.RubberBandStretcher_SetKeyFrameMap(_rbs, mappingData.ToArray(), mappingData.Count / 2); + } + + float[] _studyBuffer = new float[1024]; + + public void Study(float[][] input, bool final) + { + for (int i = 1; i < input.Length; i++) + if (input[i].Length != input[0].Length) + throw new Exception("Invalid input data: Not all channels have the same number of samples"); + + Study(input, input[0].Length, final); + } + + public void Study(float[][] input, long samples, bool final) + { + for (int i = 0; i < input.Length; i++) + if (input[i].Length < samples) + throw new Exception("Invalid input data: Channel " + i + " does not have " + samples + " samples of data"); + + long totalSamples = input.Length * samples; + + if (totalSamples > _studyBuffer.Length) + _studyBuffer = new float[totalSamples]; + + for (int i = 0; i < input.Length; i++) + Array.Copy(input[i], 0, _studyBuffer, i * samples, samples); + + RubberBandNativeMethods.RubberBandStretcher_Study(_rbs, _studyBuffer, new IntPtr(samples), input.Length, final); + } + + float[] _processBuffer = new float[1024]; + + public void Process(float[][] input, bool final) + { + for (int i = 1; i < input.Length; i++) + if (input[i].Length != input[0].Length) + throw new Exception("Invalid input data: Not all channels have the same number of samples"); + + Process(input, input[0].Length, final); + } + + public void Process(float[][] input, long samples, bool final) + { + for (int i = 0; i < input.Length; i++) + if (input[i].Length < samples) + throw new Exception("Invalid input data: Channel " + i + " does not have " + samples + " samples of data"); + + long totalSamples = input.Length * samples; + + if (totalSamples > _processBuffer.Length) + _processBuffer = new float[totalSamples]; + + for (int i = 0; i < input.Length; i++) + Array.Copy(input[i], 0, _processBuffer, i * samples, samples); + + RubberBandNativeMethods.RubberBandStretcher_Process(_rbs, _processBuffer, new IntPtr(samples), input.Length, final); + } + + public int Available() + { + return RubberBandNativeMethods.RubberBandStretcher_Available(_rbs); + } + + float[] _outputBuffer = new float[1024]; + + public long Retrieve(float[][] output) + { + for (int i = 1; i < output.Length; i++) + if (output[i].Length != output[0].Length) + throw new Exception("Invalid output buffer: Not all channels have the same number of samples"); + + return Retrieve(output, output[0].Length); + } + + public long Retrieve(float[][] output, long samples) + { + for (int i = 0; i < output.Length; i++) + if (output[i].Length < samples) + throw new Exception("Invalid output buffer: Channel " + i + " does not have enough space for " + samples + " samples"); + + long totalSamples = output.Length * samples; + + if (totalSamples > _outputBuffer.Length) + _outputBuffer = new float[totalSamples]; + + long actualSamples = RubberBandNativeMethods.RubberBandStretcher_Retrieve(_rbs, _outputBuffer, new IntPtr(samples), output.Length).ToInt64(); + + for (int i = 0; i < output.Length; i++) + Array.Copy(_outputBuffer, i * samples, output[i], 0, actualSamples); + + return actualSamples; + } + + public float GetFrequencyCutoff(int n) + { + return RubberBandNativeMethods.RubberBandStretcher_GetFrequencyCutoff(_rbs, n); + } + + public void SetFrequencyCutoff(int n, float f) + { + RubberBandNativeMethods.RubberBandStretcher_SetFrequencyCutoff(_rbs, n, f); + } + + public long GetInputIncrement() + { + return RubberBandNativeMethods.RubberBandStretcher_GetInputIncrement(_rbs).ToInt64(); + } + + public int[] GetOutputIncrements() + { + long numberOfIncrements = RubberBandNativeMethods.RubberBandStretcher_GetOutputIncrements(_rbs, null, IntPtr.Zero).ToInt64(); + + int[] buffer = new int[numberOfIncrements]; + + RubberBandNativeMethods.RubberBandStretcher_GetOutputIncrements(_rbs, buffer, new IntPtr(buffer.Length)); + + return buffer; + } + + public float[] GetPhaseResetCurve() + { + long numberOfCurveElements = RubberBandNativeMethods.RubberBandStretcher_GetPhaseResetCurve(_rbs, null, IntPtr.Zero).ToInt64(); + + float[] buffer = new float[numberOfCurveElements]; + + RubberBandNativeMethods.RubberBandStretcher_GetPhaseResetCurve(_rbs, buffer, new IntPtr(buffer.Length)); + + return buffer; + } + + public int[] GetExactTimePoints() + { + long numberOfTimePoints = RubberBandNativeMethods.RubberBandStretcher_GetExactTimePoints(_rbs, null, IntPtr.Zero).ToInt64(); + + int[] buffer = new int[numberOfTimePoints]; + + RubberBandNativeMethods.RubberBandStretcher_GetExactTimePoints(_rbs, buffer, new IntPtr(buffer.Length)); + + return buffer; + } + + public long GetChannelCount() + { + return RubberBandNativeMethods.RubberBandStretcher_GetChannelCount(_rbs).ToInt64(); + } + + public void CalculateStretch() + { + RubberBandNativeMethods.RubberBandStretcher_CalculateStretch(_rbs); + } + + public void SetDebugLevel(int level) + { + RubberBandNativeMethods.RubberBandStretcher_SetDebugLevel(_rbs, level); + } + + public static void SetDefaultDebugLevel(int level) + { + RubberBandNativeMethods.RubberBandStretcher_SetDefaultDebugLevel(level); + } + } +} diff --git a/rubberband-sharp/rubberband-sharp.csproj b/rubberband-sharp/rubberband-sharp.csproj new file mode 100644 index 0000000..ac6e4cf --- /dev/null +++ b/rubberband-sharp/rubberband-sharp.csproj @@ -0,0 +1,10 @@ + + + + netstandard2.0 + rubberband_sharp + 1.0.0.0 + 1.0.0.0 + + + diff --git a/rubberband-sharp/rubberband-sharp.nuspec b/rubberband-sharp/rubberband-sharp.nuspec new file mode 100644 index 0000000..23aef3c --- /dev/null +++ b/rubberband-sharp/rubberband-sharp.nuspec @@ -0,0 +1,21 @@ + + + + rubberband-sharp + 1.0.0 + Rubber Band Library .NET Wrapper + JonathanG@iQmetrix.com + C# wrapper for the Rubber Band Library audio time-stretching and pitch-shifting library. + + + + + + + + + + + + + diff --git a/rubberband-sharp/rubberband-sharp.targets b/rubberband-sharp/rubberband-sharp.targets new file mode 100644 index 0000000..ea529e2 --- /dev/null +++ b/rubberband-sharp/rubberband-sharp.targets @@ -0,0 +1,12 @@ + + + + rubberband-dll-Win32.dll + PreserveNewest + + + rubberband-dll-x64.dll + PreserveNewest + + + diff --git a/rubberband.sln b/rubberband.sln index 3466f0d..eeb002f 100644 --- a/rubberband.sln +++ b/rubberband.sln @@ -10,30 +10,68 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rubberband-program", "rubbe {020CEB11-EF4E-400E-971D-A35DB69D7CF9} = {020CEB11-EF4E-400E-971D-A35DB69D7CF9} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rubberband-dll", "rubberband-dll.vcxproj", "{32C11C5C-3D27-4E57-B72C-161A48AAA95E}" + ProjectSection(ProjectDependencies) = postProject + {020CEB11-EF4E-400E-971D-A35DB69D7CF9} = {020CEB11-EF4E-400E-971D-A35DB69D7CF9} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "rubberband-sharp", "rubberband-sharp\rubberband-sharp.csproj", "{4A8CA129-DAC5-4550-87EB-80C92A92AAA3}" + ProjectSection(ProjectDependencies) = postProject + {32C11C5C-3D27-4E57-B72C-161A48AAA95E} = {32C11C5C-3D27-4E57-B72C-161A48AAA95E} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|Any CPU.ActiveCfg = Debug|Win32 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x64.ActiveCfg = Debug|x64 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x64.Build.0 = Debug|x64 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x86.ActiveCfg = Debug|Win32 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x86.Build.0 = Debug|Win32 + {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|Any CPU.ActiveCfg = Release|Win32 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x64.ActiveCfg = Release|x64 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x64.Build.0 = Release|x64 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x86.ActiveCfg = Release|Win32 {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x86.Build.0 = Release|Win32 + {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Debug|Any CPU.ActiveCfg = Debug|Win32 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Debug|x64.ActiveCfg = Debug|x64 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Debug|x64.Build.0 = Debug|x64 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Debug|x86.ActiveCfg = Debug|Win32 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Debug|x86.Build.0 = Debug|Win32 + {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Release|Any CPU.ActiveCfg = Release|Win32 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Release|x64.ActiveCfg = Release|x64 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Release|x64.Build.0 = Release|x64 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Release|x86.ActiveCfg = Release|Win32 {06838307-FEAA-4DB0-8E08-AF19698E9C40}.Release|x86.Build.0 = Release|Win32 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x64.ActiveCfg = Debug|x64 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x64.Build.0 = Debug|x64 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x86.ActiveCfg = Debug|Win32 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x86.Build.0 = Debug|Win32 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|Any CPU.ActiveCfg = Release|Win32 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x64.ActiveCfg = Release|x64 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x64.Build.0 = Release|x64 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x86.ActiveCfg = Release|Win32 + {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x86.Build.0 = Release|Win32 + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x64.ActiveCfg = Debug|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x64.Build.0 = Debug|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x86.ActiveCfg = Debug|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x86.Build.0 = Debug|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|Any CPU.Build.0 = Release|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x64.ActiveCfg = Release|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x64.Build.0 = Release|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x86.ActiveCfg = Release|Any CPU + {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE