mirror of
https://github.com/damp11113/EasyMPX.git
synced 2025-04-27 06:28:10 +00:00
Add project files.
This commit is contained in:
parent
a2072c5293
commit
cda55995da
146
FMPX generator/FMPX generator.cpp
Normal file
146
FMPX generator/FMPX generator.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include "portaudio.h"
|
||||||
|
#include "PaDSPFunc.h"
|
||||||
|
#include "PaMPXFunc.h"
|
||||||
|
|
||||||
|
#define INPUT_DEVICE_INDEX 16
|
||||||
|
#define OUTPUT_DEVICE_INDEX 47
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
PaError err;
|
||||||
|
PaStream* inputStream, * outputStream;
|
||||||
|
PaStreamParameters inputParameters, outputParameters;
|
||||||
|
const PaDeviceInfo* inputInfo;
|
||||||
|
const PaDeviceInfo* outputInfo;
|
||||||
|
|
||||||
|
Pa_Initialize();
|
||||||
|
|
||||||
|
inputInfo = Pa_GetDeviceInfo(INPUT_DEVICE_INDEX);
|
||||||
|
outputInfo = Pa_GetDeviceInfo(OUTPUT_DEVICE_INDEX);
|
||||||
|
|
||||||
|
// Set input parameters
|
||||||
|
inputParameters.device = INPUT_DEVICE_INDEX;
|
||||||
|
inputParameters.channelCount = 2;
|
||||||
|
inputParameters.sampleFormat = paFloat32; // Example: float32 format
|
||||||
|
inputParameters.suggestedLatency = inputInfo->defaultHighInputLatency;
|
||||||
|
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||||
|
|
||||||
|
// Set output parameters
|
||||||
|
outputParameters.device = OUTPUT_DEVICE_INDEX;
|
||||||
|
outputParameters.channelCount = 1;
|
||||||
|
outputParameters.sampleFormat = paFloat32; // Example: float32 format
|
||||||
|
outputParameters.suggestedLatency = outputInfo->defaultHighOutputLatency;
|
||||||
|
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||||
|
|
||||||
|
// Open input audio stream
|
||||||
|
err = Pa_OpenStream(&inputStream, &inputParameters, NULL, 192000,
|
||||||
|
paFramesPerBufferUnspecified, paClipOff, NULL, NULL);
|
||||||
|
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cerr << "PortAudio input stream error: " << Pa_GetErrorText(err) << std::endl;
|
||||||
|
Pa_Terminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open output audio stream
|
||||||
|
err = Pa_OpenStream(&outputStream, NULL, &outputParameters, 192000,
|
||||||
|
paFramesPerBufferUnspecified, paClipOff, NULL, NULL);
|
||||||
|
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cerr << "PortAudio output stream error: " << Pa_GetErrorText(err) << std::endl;
|
||||||
|
Pa_CloseStream(inputStream);
|
||||||
|
Pa_Terminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start input audio stream
|
||||||
|
err = Pa_StartStream(inputStream);
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cerr << "PortAudio input stream start error: " << Pa_GetErrorText(err) << std::endl;
|
||||||
|
Pa_CloseStream(inputStream);
|
||||||
|
Pa_CloseStream(outputStream);
|
||||||
|
Pa_Terminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start output audio stream
|
||||||
|
err = Pa_StartStream(outputStream);
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cerr << "PortAudio output stream start error: " << Pa_GetErrorText(err) << std::endl;
|
||||||
|
Pa_CloseStream(inputStream);
|
||||||
|
Pa_CloseStream(outputStream);
|
||||||
|
Pa_Terminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int framesPerBuffer = 4096;
|
||||||
|
float* buffer = new float[framesPerBuffer * inputParameters.channelCount];
|
||||||
|
std::vector<Band> bands = {
|
||||||
|
{137, -20.2, 1, 3, 1, 100}, // Example parameters for Band 1
|
||||||
|
{1147, -17.6, 0, 2, 1, 100}, // Example parameters for Band 2
|
||||||
|
{6910, -24.8, 0, 2, 1, 100} // Example parameters for Band 3
|
||||||
|
// Add more bands with their parameters
|
||||||
|
};
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
err = Pa_ReadStream(inputStream, buffer, framesPerBuffer);
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cout << "PortAudio input stream error: " << Pa_GetErrorText(err) << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioBuffer audio{ buffer, framesPerBuffer * inputParameters.channelCount };
|
||||||
|
multibandCompressor(audio, bands);
|
||||||
|
|
||||||
|
//limiterProcess(buffer, framesPerBuffer, limiter);
|
||||||
|
|
||||||
|
// Normalize the output to prevent extreme volume fluctuations
|
||||||
|
|
||||||
|
float maxSample = 1.0f;
|
||||||
|
for (int i = 0; i < framesPerBuffer * inputParameters.channelCount; ++i) {
|
||||||
|
if (fabsf(buffer[i]) > maxSample) {
|
||||||
|
maxSample = fabsf(buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxSample > 1.0f) {
|
||||||
|
for (int i = 0; i < framesPerBuffer * inputParameters.channelCount; ++i) {
|
||||||
|
buffer[i] /= maxSample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge stereo channels into mono
|
||||||
|
float* monoBuffer = new float[framesPerBuffer];
|
||||||
|
float* subtractBuffer = new float[framesPerBuffer];
|
||||||
|
for (int i = 0, j = 0; i < framesPerBuffer * inputParameters.channelCount; i += 2, ++j) {
|
||||||
|
monoBuffer[j] = 0.5f * (buffer[i] + buffer[i + 1]); // Average the two channels
|
||||||
|
}
|
||||||
|
for (int i = 0, j = 0; i < framesPerBuffer * inputParameters.channelCount; i += 2, ++j) {
|
||||||
|
subtractBuffer[j] = 0.5f * (buffer[i] - buffer[i + 1]); // Average the two channels
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
err = Pa_WriteStream(outputStream, subtractBuffer, framesPerBuffer);
|
||||||
|
if (err != paNoError) {
|
||||||
|
std::cout << "PortAudio output stream error: " << Pa_GetErrorText(err) << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete[] monoBuffer;
|
||||||
|
delete[] subtractBuffer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
// Stop and close streams
|
||||||
|
Pa_StopStream(inputStream);
|
||||||
|
Pa_CloseStream(inputStream);
|
||||||
|
Pa_StopStream(outputStream);
|
||||||
|
Pa_CloseStream(outputStream);
|
||||||
|
Pa_Terminate();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
158
FMPX generator/FMPX generator.vcxproj
Normal file
158
FMPX generator/FMPX generator.vcxproj
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{51241d04-3bd0-4fa5-8bae-05c9618b01eb}</ProjectGuid>
|
||||||
|
<RootNamespace>FMPXgenerator</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="FMPX generator.cpp" />
|
||||||
|
<ClCompile Include="PaDSPFunc.cpp" />
|
||||||
|
<ClCompile Include="PaMPXFunc.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\..\..\..\radioconda\pkgs\portaudio-19.6.0-h63175ca_9\Library\bin\portaudio.dll" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\..\radioconda\pkgs\portaudio-19.6.0-h63175ca_9\Library\include\portaudio.h" />
|
||||||
|
<ClInclude Include="PaDSPFunc.h" />
|
||||||
|
<ClInclude Include="PaMPXFunc.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Library Include="..\..\..\..\radioconda\pkgs\portaudio-19.6.0-h63175ca_9\Library\lib\portaudio.lib" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
<Import Project="..\packages\portaudio.redist.0.19.1\build\native\portaudio.redist.targets" Condition="Exists('..\packages\portaudio.redist.0.19.1\build\native\portaudio.redist.targets')" />
|
||||||
|
<Import Project="..\packages\portaudio.0.19.1\build\native\portaudio.targets" Condition="Exists('..\packages\portaudio.0.19.1\build\native\portaudio.targets')" />
|
||||||
|
</ImportGroup>
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\packages\portaudio.redist.0.19.1\build\native\portaudio.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\portaudio.redist.0.19.1\build\native\portaudio.redist.targets'))" />
|
||||||
|
<Error Condition="!Exists('..\packages\portaudio.0.19.1\build\native\portaudio.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\portaudio.0.19.1\build\native\portaudio.targets'))" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
50
FMPX generator/FMPX generator.vcxproj.filters
Normal file
50
FMPX generator/FMPX generator.vcxproj.filters
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="FMPX generator.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="PaDSPFunc.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="PaMPXFunc.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
<None Include="..\..\..\..\radioconda\pkgs\portaudio-19.6.0-h63175ca_9\Library\bin\portaudio.dll">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\..\radioconda\pkgs\portaudio-19.6.0-h63175ca_9\Library\include\portaudio.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="PaDSPFunc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="PaMPXFunc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Library Include="..\..\..\..\radioconda\pkgs\portaudio-19.6.0-h63175ca_9\Library\lib\portaudio.lib">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</Library>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
130
FMPX generator/PaDSPFunc.cpp
Normal file
130
FMPX generator/PaDSPFunc.cpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct AudioBuffer {
|
||||||
|
float* data; // Audio data
|
||||||
|
int size; // Size of audio buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Band {
|
||||||
|
float frequency; // Center frequency of the band
|
||||||
|
float threshold;
|
||||||
|
float gain;
|
||||||
|
float ratio;
|
||||||
|
float attackTime; // Attack time in milliseconds
|
||||||
|
float releaseTime; // Release time in milliseconds
|
||||||
|
float currentGain; // Current gain level for dynamic changes
|
||||||
|
float envelope; // Envelope for dynamic changes
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to process a single band with dynamic gain changes (attack and release)
|
||||||
|
void processBandWithDynamicGain(float* buffer, int size, Band& band) {
|
||||||
|
const float attackCoef = 1.0f - expf(-1.0f / (0.001f * band.attackTime * 44100.0f)); // Calculate attack coefficient
|
||||||
|
const float releaseCoef = 1.0f - expf(-1.0f / (0.001f * band.releaseTime * 44100.0f)); // Calculate release coefficient
|
||||||
|
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
float input = buffer[i];
|
||||||
|
|
||||||
|
// Envelope follower for dynamic gain adjustment (simulating RMS detection)
|
||||||
|
float envelopeLevel = fabsf(input);
|
||||||
|
|
||||||
|
if (envelopeLevel > band.envelope) {
|
||||||
|
band.envelope += attackCoef * (envelopeLevel - band.envelope);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
band.envelope += releaseCoef * (envelopeLevel - band.envelope);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply compression with dynamic gain based on negative threshold
|
||||||
|
float gainReduction = 1.0f;
|
||||||
|
if (band.envelope < band.threshold) { // Check if the envelope level is below the negative threshold
|
||||||
|
float excessDB = 20.0f * log10f(band.threshold / band.envelope);
|
||||||
|
gainReduction = band.gain + (1.0f - band.ratio) * excessDB; // Calculate gain reduction based on ratio
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[i] *= gainReduction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to split audio into bands and compress each band with dynamic gain
|
||||||
|
void multibandCompressor(AudioBuffer& audio, std::vector<Band>& bands) {
|
||||||
|
std::vector<std::vector<float>> bandBuffers(bands.size(), std::vector<float>(audio.size));
|
||||||
|
|
||||||
|
// Split audio into frequency bands
|
||||||
|
for (int i = 0; i < audio.size; ++i) {
|
||||||
|
for (size_t j = 0; j < bands.size(); ++j) {
|
||||||
|
// Split audio into frequency bands (in this simplified example)
|
||||||
|
// Replace with appropriate band-splitting logic
|
||||||
|
bandBuffers[j][i] = audio.data[i]; // Simulated band splitting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each band separately with dynamic gain changes
|
||||||
|
for (size_t i = 0; i < bands.size(); ++i) {
|
||||||
|
processBandWithDynamicGain(bandBuffers[i].data(), audio.size, bands[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recombine bands
|
||||||
|
for (int i = 0; i < audio.size; ++i) {
|
||||||
|
float mixedValue = 0.0f;
|
||||||
|
for (size_t j = 0; j < bands.size(); ++j) {
|
||||||
|
mixedValue += bandBuffers[j][i]; // Simulated band recombination
|
||||||
|
}
|
||||||
|
audio.data[i] = mixedValue; // Replace with proper recombination logic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void audioCompressor(float* audioBuffer, int bufferSize, float threshold, float ratio) {
|
||||||
|
for (int i = 0; i < bufferSize; ++i) {
|
||||||
|
// Apply compression algorithm to each sample
|
||||||
|
if (audioBuffer[i] > threshold) {
|
||||||
|
audioBuffer[i] = threshold + (audioBuffer[i] - threshold) / ratio;
|
||||||
|
}
|
||||||
|
else if (audioBuffer[i] < -threshold) {
|
||||||
|
audioBuffer[i] = -threshold + (audioBuffer[i] + threshold) / ratio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Limiter {
|
||||||
|
float threshold;
|
||||||
|
float margin;
|
||||||
|
float attackTime; // Attack time in milliseconds
|
||||||
|
float releaseTime; // Release time in milliseconds
|
||||||
|
float ratio;
|
||||||
|
float currentGain; // Current gain level for dynamic changes
|
||||||
|
float envelope; // Envelope for dynamic changes
|
||||||
|
};
|
||||||
|
|
||||||
|
void limiterProcess(float* buffer, int size, Limiter& limiter) {
|
||||||
|
const float attackCoef = 1.0f - expf(-1.0f / (0.001f * limiter.attackTime * 44100.0f)); // Calculate attack coefficient
|
||||||
|
const float releaseCoef = 1.0f - expf(-1.0f / (0.001f * limiter.releaseTime * 44100.0f)); // Calculate release coefficient
|
||||||
|
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
float input = buffer[i];
|
||||||
|
|
||||||
|
// Envelope follower for dynamic gain adjustment (simulating RMS detection)
|
||||||
|
float envelopeLevel = fabsf(input);
|
||||||
|
|
||||||
|
if (envelopeLevel > limiter.envelope) {
|
||||||
|
limiter.envelope += attackCoef * (envelopeLevel - limiter.envelope);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
limiter.envelope += releaseCoef * (envelopeLevel - limiter.envelope);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply limiting with dynamic gain
|
||||||
|
if (limiter.envelope > limiter.threshold) {
|
||||||
|
float reductionDB = limiter.threshold + limiter.margin - limiter.envelope;
|
||||||
|
float gainReduction = powf(10.0f, reductionDB / 20.0f); // Convert dB reduction to linear gain
|
||||||
|
|
||||||
|
// Apply compression with dynamic gain
|
||||||
|
float softKnee = 1.0f / limiter.ratio; // Soft knee effect
|
||||||
|
float softKneeCoefficient = 1.0f - expf(-softKnee); // Soft knee coefficient
|
||||||
|
|
||||||
|
float gain = 1.0f / (1.0f + softKneeCoefficient * (gainReduction - 1.0f));
|
||||||
|
float limitedGain = (gainReduction < gain) ? gainReduction : gain;
|
||||||
|
|
||||||
|
buffer[i] *= limitedGain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
FMPX generator/PaDSPFunc.h
Normal file
40
FMPX generator/PaDSPFunc.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef PADSPFUNC_H
|
||||||
|
#define PADSPFUNC_H
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
void audioCompressor(float* audioBuffer, int bufferSize, float threshold, float ratio);
|
||||||
|
|
||||||
|
struct AudioBuffer {
|
||||||
|
float* data;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Band {
|
||||||
|
float frequency;
|
||||||
|
float threshold;
|
||||||
|
float gain;
|
||||||
|
float ratio;
|
||||||
|
float attackTime;
|
||||||
|
float releaseTime;
|
||||||
|
float currentGain;
|
||||||
|
float envelope;
|
||||||
|
};
|
||||||
|
|
||||||
|
void processBandWithDynamicGain(float* buffer, int size, Band& band);
|
||||||
|
void multibandCompressor(AudioBuffer& audio, std::vector<Band>& bands);
|
||||||
|
|
||||||
|
|
||||||
|
struct Limiter {
|
||||||
|
float threshold;
|
||||||
|
float margin;
|
||||||
|
float attackTime; // Attack time in milliseconds
|
||||||
|
float releaseTime; // Release time in milliseconds
|
||||||
|
float ratio;
|
||||||
|
float currentGain; // Current gain level for dynamic changes
|
||||||
|
float envelope; // Envelope for dynamic changes
|
||||||
|
};
|
||||||
|
|
||||||
|
void limiterProcess(float* buffer, int size, Limiter& limiter);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
40
FMPX generator/PaMPXFunc.cpp
Normal file
40
FMPX generator/PaMPXFunc.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// Function to mix left and right channels (L + R)
|
||||||
|
std::vector<float> mixChannels(const std::vector<float>& leftChannel, const std::vector<float>& rightChannel) {
|
||||||
|
// Ensure both channels have the same size
|
||||||
|
if (leftChannel.size() != rightChannel.size()) {
|
||||||
|
std::cerr << "Channels have different sizes. Mixing aborted." << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> mixedChannel;
|
||||||
|
mixedChannel.reserve(leftChannel.size()); // Reserve space for the mixed channel
|
||||||
|
|
||||||
|
// Perform mixing (L + R)
|
||||||
|
for (size_t i = 0; i < leftChannel.size(); ++i) {
|
||||||
|
mixedChannel.push_back(leftChannel[i] + rightChannel[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mixedChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to subtract left from right channel (L - R)
|
||||||
|
std::vector<float> subtractChannels(const std::vector<float>& leftChannel, const std::vector<float>& rightChannel) {
|
||||||
|
// Ensure both channels have the same size
|
||||||
|
if (leftChannel.size() != rightChannel.size()) {
|
||||||
|
std::cerr << "Channels have different sizes. Subtraction aborted." << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> subtractedChannel;
|
||||||
|
subtractedChannel.reserve(leftChannel.size()); // Reserve space for the subtracted channel
|
||||||
|
|
||||||
|
// Perform subtraction (L - R)
|
||||||
|
for (size_t i = 0; i < leftChannel.size(); ++i) {
|
||||||
|
subtractedChannel.push_back(leftChannel[i] - rightChannel[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return subtractedChannel;
|
||||||
|
}
|
9
FMPX generator/PaMPXFunc.h
Normal file
9
FMPX generator/PaMPXFunc.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef PAMPXFUNC_H
|
||||||
|
#define PAMPXFUNC_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
std::vector<float> mixChannels(const std::vector<float>& leftChannel, const std::vector<float>& rightChannel);
|
||||||
|
std::vector<float> subtractChannels(const std::vector<float>& leftChannel, const std::vector<float>& rightChannel);
|
||||||
|
|
||||||
|
#endif
|
11
FMPX generator/PaProcessFunc.cpp
Normal file
11
FMPX generator/PaProcessFunc.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
void audioCompressor(float* audioBuffer, int bufferSize, float threshold, float ratio) {
|
||||||
|
for (int i = 0; i < bufferSize; ++i) {
|
||||||
|
// Apply compression algorithm to each sample
|
||||||
|
if (audioBuffer[i] > threshold) {
|
||||||
|
audioBuffer[i] = threshold + (audioBuffer[i] - threshold) / ratio;
|
||||||
|
}
|
||||||
|
else if (audioBuffer[i] < -threshold) {
|
||||||
|
audioBuffer[i] = -threshold + (audioBuffer[i] + threshold) / ratio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
FMPX generator/packages.config
Normal file
5
FMPX generator/packages.config
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="portaudio" version="0.19.1" targetFramework="native" />
|
||||||
|
<package id="portaudio.redist" version="0.19.1" targetFramework="native" />
|
||||||
|
</packages>
|
31
FMPXGEN.sln
Normal file
31
FMPXGEN.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.4.33122.133
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FMPX generator", "FMPX generator\FMPX generator.vcxproj", "{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Release|x64.Build.0 = Release|x64
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{51241D04-3BD0-4FA5-8BAE-05C9618B01EB}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {C351DBD9-F255-499D-957D-CB8219086FD5}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
Loading…
x
Reference in New Issue
Block a user