diff --git a/FMPX generator/FMPX generator.cpp b/FMPX generator/FMPX generator.cpp
index 02e8285..7620cde 100644
--- a/FMPX generator/FMPX generator.cpp
+++ b/FMPX generator/FMPX generator.cpp
@@ -3,9 +3,10 @@
#include "portaudio.h"
#include "PaDSPFunc.h"
#include "PaMPXFunc.h"
+#include "PaFilterFunc.h"
#define INPUT_DEVICE_INDEX 16
-#define OUTPUT_DEVICE_INDEX 47
+#define OUTPUT_DEVICE_INDEX 39
int main() {
@@ -83,6 +84,11 @@ int main() {
{6910, -24.8, 0, 2, 1, 100} // Example parameters for Band 3
// Add more bands with their parameters
};
+ float* piloToneBuffer = new float[framesPerBuffer];
+ float* stereoToneBuffer = new float[framesPerBuffer];
+ generateSineWave(piloToneBuffer, framesPerBuffer, 192000, 19000, 0.08f);
+ generateSineWave(stereoToneBuffer, framesPerBuffer, 192000, 38000, 1);
+
while (true) {
err = Pa_ReadStream(inputStream, buffer, framesPerBuffer);
@@ -91,13 +97,17 @@ int main() {
break;
}
- AudioBuffer audio{ buffer, framesPerBuffer * inputParameters.channelCount };
- multibandCompressor(audio, bands);
+ //AudioBuffer audio{ buffer, framesPerBuffer * inputParameters.channelCount };
+ //multibandCompressor(audio, bands);
//limiterProcess(buffer, framesPerBuffer, limiter);
// Normalize the output to prevent extreme volume fluctuations
+ //LowPassFilter filter(192000, 15000, 64);
+
+ //filter.apply(buffer, framesPerBuffer);
+
float maxSample = 1.0f;
for (int i = 0; i < framesPerBuffer * inputParameters.channelCount; ++i) {
if (fabsf(buffer[i]) > maxSample) {
@@ -114,22 +124,36 @@ int main() {
// Merge stereo channels into mono
float* monoBuffer = new float[framesPerBuffer];
float* subtractBuffer = new float[framesPerBuffer];
+ float* stereoMultipledBuffer = new float[framesPerBuffer];
+ float* mixedBuffer = 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
}
+ for (int i = 0; i < framesPerBuffer; ++i) {
+ stereoMultipledBuffer[i] = stereoToneBuffer[i] * subtractBuffer[i];
+ }
+
+ const float* mixbuffers[3] = {monoBuffer, piloToneBuffer, stereoMultipledBuffer };
+
+
+
+ mix(mixedBuffer, mixbuffers, 3, framesPerBuffer);
- err = Pa_WriteStream(outputStream, subtractBuffer, framesPerBuffer);
+ err = Pa_WriteStream(outputStream, mixedBuffer, framesPerBuffer);
if (err != paNoError) {
std::cout << "PortAudio output stream error: " << Pa_GetErrorText(err) << std::endl;
break;
}
delete[] monoBuffer;
delete[] subtractBuffer;
+ delete[] mixedBuffer;
+ delete[] stereoMultipledBuffer;
}
diff --git a/FMPX generator/FMPX generator.vcxproj b/FMPX generator/FMPX generator.vcxproj
index 3815ae4..6db6fb6 100644
--- a/FMPX generator/FMPX generator.vcxproj
+++ b/FMPX generator/FMPX generator.vcxproj
@@ -129,6 +129,7 @@
+
@@ -138,6 +139,7 @@
+
diff --git a/FMPX generator/FMPX generator.vcxproj.filters b/FMPX generator/FMPX generator.vcxproj.filters
index b324938..fcf6a4c 100644
--- a/FMPX generator/FMPX generator.vcxproj.filters
+++ b/FMPX generator/FMPX generator.vcxproj.filters
@@ -24,6 +24,9 @@
Source Files
+
+ Source Files
+
@@ -41,6 +44,9 @@
Header Files
+
+ Header Files
+
diff --git a/FMPX generator/PaDSPFunc.cpp b/FMPX generator/PaDSPFunc.cpp
index f2307dc..c6a352f 100644
--- a/FMPX generator/PaDSPFunc.cpp
+++ b/FMPX generator/PaDSPFunc.cpp
@@ -1,4 +1,5 @@
#include
+#include
struct AudioBuffer {
float* data; // Audio data
@@ -10,7 +11,7 @@ struct Band {
float threshold;
float gain;
float ratio;
- float attackTime; // Attack time in milliseconds
+ float attackTime; // Attack time in millsiseconds
float releaseTime; // Release time in milliseconds
float currentGain; // Current gain level for dynamic changes
float envelope; // Envelope for dynamic changes
@@ -95,6 +96,8 @@ struct Limiter {
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
@@ -127,4 +130,4 @@ void limiterProcess(float* buffer, int size, Limiter& limiter) {
buffer[i] *= limitedGain;
}
}
-}
\ No newline at end of file
+}
diff --git a/FMPX generator/PaDSPFunc.h b/FMPX generator/PaDSPFunc.h
index e480dc8..5df4fef 100644
--- a/FMPX generator/PaDSPFunc.h
+++ b/FMPX generator/PaDSPFunc.h
@@ -1,6 +1,7 @@
#ifndef PADSPFUNC_H
#define PADSPFUNC_H
#include
+#include
void audioCompressor(float* audioBuffer, int bufferSize, float threshold, float ratio);
diff --git a/FMPX generator/PaFilterFunc.cpp b/FMPX generator/PaFilterFunc.cpp
new file mode 100644
index 0000000..d1c2015
--- /dev/null
+++ b/FMPX generator/PaFilterFunc.cpp
@@ -0,0 +1,40 @@
+#include "PaFilterFunc.h"
+#include
+
+LowPassFilter::LowPassFilter(double sampleRate, double cutoffFreq, int order) {
+ coefficients = calculateCoefficients(sampleRate, cutoffFreq, order);
+ delayLine.resize(coefficients.size(), 0.0);
+}
+
+std::vector LowPassFilter::calculateCoefficients(double sampleRate, double cutoffFreq, int order) {
+ std::vector coeffs(order + 1);
+ double omegaC = 2.0 * M_PI * cutoffFreq / sampleRate;
+
+ for (int n = 0; n <= order; ++n) {
+ if (n == order / 2) {
+ coeffs[n] = omegaC / M_PI;
+ }
+ else {
+ coeffs[n] = sin(omegaC * (n - order / 2)) / (M_PI * (n - order / 2));
+ }
+ }
+
+ return coeffs;
+}
+
+void LowPassFilter::apply(float* buffer, int bufferSize) {
+ for (int i = 0; i < bufferSize; ++i) {
+ double output = 0.0;
+ delayLine[0] = buffer[i];
+
+ for (size_t j = 0; j < coefficients.size(); ++j) {
+ output += coefficients[j] * delayLine[j];
+ }
+
+ for (size_t j = coefficients.size() - 1; j >= 1; --j) {
+ delayLine[j] = delayLine[j - 1];
+ }
+
+ buffer[i] = static_cast(output);
+ }
+}
\ No newline at end of file
diff --git a/FMPX generator/PaFilterFunc.h b/FMPX generator/PaFilterFunc.h
new file mode 100644
index 0000000..2cbafa2
--- /dev/null
+++ b/FMPX generator/PaFilterFunc.h
@@ -0,0 +1,18 @@
+#ifndef PAFILTERFUNC_H
+#define M_PI 3.14159265358979323846
+#include
+
+class LowPassFilter {
+public:
+ LowPassFilter(double sampleRate, double cutoffFreq, int order);
+ void apply(float* buffer, int bufferSize);
+
+private:
+ std::vector calculateCoefficients(double sampleRate, double cutoffFreq, int order);
+
+ std::vector coefficients;
+ std::vector delayLine;
+};
+
+
+#endif
diff --git a/FMPX generator/PaMPXFunc.cpp b/FMPX generator/PaMPXFunc.cpp
index 7156fcf..cd3993f 100644
--- a/FMPX generator/PaMPXFunc.cpp
+++ b/FMPX generator/PaMPXFunc.cpp
@@ -1,40 +1,24 @@
-#include
-#include
+#include
-// Function to mix left and right channels (L + R)
-std::vector mixChannels(const std::vector& leftChannel, const std::vector& rightChannel) {
- // Ensure both channels have the same size
- if (leftChannel.size() != rightChannel.size()) {
- std::cerr << "Channels have different sizes. Mixing aborted." << std::endl;
- return {};
+void generateSineWave(float* buffer, int frames, int sampleRate, float frequency, float amplitude = 0.5f) {
+ const float twoPi = 2.0f * 3.14159f;
+ float phaseIncrement = (frequency / sampleRate) * twoPi;
+ float phase = 0.0f;
+
+ for (int i = 0; i < frames; ++i) {
+ buffer[i] = amplitude * sin(phase);
+ phase += phaseIncrement;
+ if (phase > twoPi) {
+ phase -= twoPi;
+ }
}
-
- std::vector 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 subtractChannels(const std::vector& leftChannel, const std::vector& rightChannel) {
- // Ensure both channels have the same size
- if (leftChannel.size() != rightChannel.size()) {
- std::cerr << "Channels have different sizes. Subtraction aborted." << std::endl;
- return {};
+void mix(float* mixedBuffer, const float* buffers[], int numBuffers, int frames) {
+ for (int i = 0; i < frames; ++i) {
+ mixedBuffer[i] = 0.0f; // Initialize mixed buffer with zeros
+ for (int j = 0; j < numBuffers; ++j) {
+ mixedBuffer[i] += buffers[j][i]; // Accumulate samples from each buffer
+ }
}
-
- std::vector 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;
}
\ No newline at end of file
diff --git a/FMPX generator/PaMPXFunc.h b/FMPX generator/PaMPXFunc.h
index cc8aebe..d3407d9 100644
--- a/FMPX generator/PaMPXFunc.h
+++ b/FMPX generator/PaMPXFunc.h
@@ -1,9 +1,10 @@
#ifndef PAMPXFUNC_H
#define PAMPXFUNC_H
-#include
+#include
-std::vector mixChannels(const std::vector& leftChannel, const std::vector& rightChannel);
-std::vector subtractChannels(const std::vector& leftChannel, const std::vector& rightChannel);
+void generateSineWave(float* buffer, int frames, int sampleRate, float frequency, float amplitude = 0.5f);
+
+void mix(float* mixedBuffer, const float* buffers[], int numBuffers, int frames);
#endif