diff --git a/FMPX generator/FMPX generator.cpp b/FMPX generator/FMPX generator.cpp
index f8b3f5a..cc7c57b 100644
--- a/FMPX generator/FMPX generator.cpp
+++ b/FMPX generator/FMPX generator.cpp
@@ -4,10 +4,13 @@
#include "PaDSPFunc.h"
#include "PaMPXFunc.h"
#include "PaFilterFunc.h"
+#include "rtfir.hpp"
-#define INPUT_DEVICE_INDEX 16
+
+#define INPUT_DEVICE_INDEX 4
#define OUTPUT_DEVICE_INDEX 39
+#define CompositeClipper true;
int main() {
PaError err;
@@ -86,9 +89,11 @@ int main() {
};
float* piloToneBuffer = new float[framesPerBuffer];
float* stereoToneBuffer = new float[framesPerBuffer];
+
SignalGenerator::GenerateSineWave(piloToneBuffer, framesPerBuffer, 19000, 0.08f);
SignalGenerator::GenerateSineWave(stereoToneBuffer, framesPerBuffer, 38000, 1);
-
+
+
std::cout << "MPX encoder is running" << std::endl;
while (true) {
@@ -102,9 +107,6 @@ int main() {
//AudioBuffer audio{ buffer, framesPerBuffer * inputParameters.channelCount };
//multibandCompressor(audio, bands);
- //LowPassFilter filter(192000, 15000, 64);
-
- //filter.apply(buffer, framesPerBuffer);
// MPX Processing here
@@ -119,10 +121,27 @@ int main() {
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
}
+
+ // limit mono signal
+ /*
+ float maxSample2 = 2.5f;
+ for (int i = 0; i < framesPerBuffer; ++i) {
+ if (fabsf(subtractBuffer[i]) > maxSample2) {
+ maxSample2 = fabsf(subtractBuffer[i]);
+ }
+ }
+
+ if (maxSample2 > 1.0f) {
+ for (int i = 0; i < framesPerBuffer; ++i) {
+ subtractBuffer[i] /= maxSample2;
+ }
+ }
+ */
for (int i = 0; i < framesPerBuffer; ++i) {
stereoMultipledBuffer[i] = stereoToneBuffer[i] * subtractBuffer[i];
}
// limit mono signal
+ /*
float maxSample = 2.0f;
for (int i = 0; i < framesPerBuffer; ++i) {
if (fabsf(monoBuffer[i]) > maxSample) {
@@ -135,27 +154,26 @@ int main() {
monoBuffer[i] /= maxSample;
}
}
- // limit mono signal
- float maxSample2 = 2.5f;
- for (int i = 0; i < framesPerBuffer; ++i) {
- if (fabsf(stereoMultipledBuffer[i]) > maxSample2) {
- maxSample2 = fabsf(stereoMultipledBuffer[i]);
- }
- }
-
- if (maxSample2 > 1.0f) {
- for (int i = 0; i < framesPerBuffer; ++i) {
- stereoMultipledBuffer[i] /= maxSample2;
- }
- }
-
-
+ */
// mix mpx
const float* mixbuffers[3] = {monoBuffer, piloToneBuffer, stereoMultipledBuffer };
mix(mixedBuffer, mixbuffers, 3, framesPerBuffer);
-
+ if (CompositeClipper) {
+ float maxSample = 2.0f;
+ for (int i = 0; i < framesPerBuffer; ++i) {
+ if (fabsf(mixedBuffer[i]) > maxSample) {
+ maxSample = fabsf(mixedBuffer[i]);
+ }
+ }
+
+ if (maxSample > 1.0f) {
+ for (int i = 0; i < framesPerBuffer; ++i) {
+ mixedBuffer[i] /= maxSample;
+ }
+ }
+ }
err = Pa_WriteStream(outputStream, mixedBuffer, framesPerBuffer);
@@ -167,7 +185,7 @@ int main() {
delete[] subtractBuffer;
delete[] mixedBuffer;
delete[] stereoMultipledBuffer;
-
+ //delete[] lowpassed15KBuffer;
}
delete[] buffer;
diff --git a/FMPX generator/FMPX generator.vcxproj b/FMPX generator/FMPX generator.vcxproj
index 6db6fb6..4959fdf 100644
--- a/FMPX generator/FMPX generator.vcxproj
+++ b/FMPX generator/FMPX generator.vcxproj
@@ -131,6 +131,7 @@
+
@@ -141,6 +142,7 @@
+
diff --git a/FMPX generator/FMPX generator.vcxproj.filters b/FMPX generator/FMPX generator.vcxproj.filters
index fcf6a4c..536240d 100644
--- a/FMPX generator/FMPX generator.vcxproj.filters
+++ b/FMPX generator/FMPX generator.vcxproj.filters
@@ -27,6 +27,9 @@
Source Files
+
+ Source Files
+
@@ -47,6 +50,9 @@
Header Files
+
+ Header Files
+
diff --git a/FMPX generator/PaFilterFunc.cpp b/FMPX generator/PaFilterFunc.cpp
index fd44283..0ed6091 100644
--- a/FMPX generator/PaFilterFunc.cpp
+++ b/FMPX generator/PaFilterFunc.cpp
@@ -1,40 +1 @@
-#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);
- }
-}
+#include "PaFilterFunc.h"
\ No newline at end of file
diff --git a/FMPX generator/PaFilterFunc.h b/FMPX generator/PaFilterFunc.h
index 2cbafa2..58b103b 100644
--- a/FMPX generator/PaFilterFunc.h
+++ b/FMPX generator/PaFilterFunc.h
@@ -1,18 +1,5 @@
#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
+#endif // AUDIO_FILTER_H
\ No newline at end of file
diff --git a/FMPX generator/rtfir.cpp b/FMPX generator/rtfir.cpp
new file mode 100644
index 0000000..af83b53
--- /dev/null
+++ b/FMPX generator/rtfir.cpp
@@ -0,0 +1,144 @@
+#include
+#include
+#include
+#include
+#include "rtfir.hpp"
+
+// Some math.h implementations don't define M_PI
+#ifndef M_PI
+ #define M_PI 3.14159265358979323846
+#endif
+
+
+/*!\brief Constructor for base FIR object
+ * \param Taps Number of taps in the filter
+ */
+RTFIR::RTFIR(const unsigned int &Taps){
+ coeff=new double[Taps];
+ buffer=new double[Taps];
+ memset(buffer,0,Taps*sizeof(double));
+ taps=Taps;
+}
+
+/*!\brief Deconstructor for base FIR object
+ */
+RTFIR::~RTFIR(){
+ delete [] coeff;
+ delete [] buffer;
+}
+
+/*!\brief Filters input data
+ * \param Sample Sample to filter
+ * \return Filtered sample
+ */
+double RTFIR::Filter(const double &Sample){
+ // Roll back samplebuffer
+ memmove(&buffer[1],&buffer[0],(taps-1)*sizeof(*buffer));
+ buffer[0]=Sample;
+
+ // Perform multiplication
+ double output=0;
+ for(unsigned int i=0;i RTFIR::GetCoefficients() const{
+ std::vector c;
+ c.resize(taps);
+ for(unsigned int i=0;i0.5){
+ throw std::invalid_argument("Frequencies must be normalized");
+ }
+ else{
+ int W=Taps/2;
+ for(int i=-W;i0.5){
+ throw std::invalid_argument("Frequencies must be normalized");
+ }
+ else{
+ int W=Taps/2;
+ for(int i=-W;i0.5 || High<0.0 || High>0.5){
+ throw std::invalid_argument("Frequencies must be normalized");
+ }
+ else{
+ int W=Taps/2;
+ for(int i=-W;i0.5 || High<0.0 || High>0.5){
+ throw std::invalid_argument("Frequencies must be normalized");
+ }
+ else{
+ int W=Taps/2;
+ for(int i=-W;i
+#include
+
+class RTFIR {
+ protected:
+ double *coeff; //!< Coefficients of the FIR filter
+ double *buffer; //!< Sample buffer for FIR filter
+ unsigned int taps; //!< Number of coefficients of the FIR filter
+ public:
+ RTFIR(const unsigned int &Taps);
+ ~RTFIR();
+ double Filter(const double &x);
+ std::vector GetCoefficients() const;
+};
+
+class RTFIR_lowpass : public RTFIR {
+ public:
+ RTFIR_lowpass(const unsigned int &Taps,const double &Freq);
+};
+
+class RTFIR_highpass : public RTFIR {
+ public:
+ RTFIR_highpass(const unsigned int &Taps,const double &Freq);
+};
+
+class RTFIR_bandpass : public RTFIR {
+ public:
+ RTFIR_bandpass(const unsigned int &Taps,const double &Freq1,const double &Freq2);
+};
+
+class RTFIR_bandstop : public RTFIR {
+ public:
+ RTFIR_bandstop(const unsigned int &Taps,const double &Freq1,const double &Freq2);
+};
+
+
+#endif
+