Started to write the 7-band-eq code.

pull/68/head
Holger Wirtz 3 years ago
parent fe556bebb5
commit 96c941166c
  1. 24
      MicroDexed.ino
  2. 33
      config.h
  3. 188
      sgtl5000_graphic_eq.hpp

@ -48,6 +48,9 @@
#include "mixer8.h" #include "mixer8.h"
#endif #endif
#endif #endif
#ifdef SGTL5000_AUDIO_ENHANCE
#include "sgtl5000_graphic_eq.hpp"
#endif
// Audio engines // Audio engines
AudioSynthDexed* MicroDexed[NUM_DEXED]; AudioSynthDexed* MicroDexed[NUM_DEXED];
@ -619,6 +622,10 @@ void setup()
audio_thru_mixer_l.gain(3, 0.0); audio_thru_mixer_l.gain(3, 0.0);
#endif #endif
#ifdef SGTL5000_AUDIO_ENHANCE
//setup_sgtl5000_graphic_7band_eq();
#endif
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("<setup end>")); Serial.println(F("<setup end>"));
#endif #endif
@ -2775,21 +2782,4 @@ int FreeMem(void)
return (char *)&_heap_end - __brkval; return (char *)&_heap_end - __brkval;
} }
#endif #endif
/*
uint32_t FreeMem(void) { // for Teensy 3.0
uint32_t stackTop;
uint32_t heapTop;
// current position of the stack.
stackTop = (uint32_t) &stackTop;
// current position of heap.
void* hTop = malloc(1);
heapTop = (uint32_t) hTop;
free(hTop);
// The difference is (approximately) the free, available ram.
return stackTop - heapTop;
}
*/
#endif #endif

@ -28,6 +28,7 @@
#include <Arduino.h> #include <Arduino.h>
#include "midinotes.h" #include "midinotes.h"
#include "teensy_board_detection.h" #include "teensy_board_detection.h"
#include "sgtl5000_graphic_eq.hpp"
// If you want to test the system with Linux and without any keyboard and/or audio equipment, you can do the following: // If you want to test the system with Linux and without any keyboard and/or audio equipment, you can do the following:
// 1. In Arduino-IDE enable "Tools->USB-Type->Serial + MIDI + Audio" // 1. In Arduino-IDE enable "Tools->USB-Type->Serial + MIDI + Audio"
@ -182,6 +183,38 @@
#define SGTL5000_LINEOUT_LEVEL 29 #define SGTL5000_LINEOUT_LEVEL 29
#endif #endif
#ifdef SGTL5000_AUDIO_ENHANCE
#define GRAPHIC_EQ_TYPE_0 bq_type_lowpass
#define GRAPHIC_EQ_CENTER_FRQ_0 115.0
#define GRAPHIC_EQ_Q_0 2.0
#define GRAPHIC_EQ_TYPE_1 bq_type_bandpass
#define GRAPHIC_EQ_CENTER_FRQ_1 330.0
#define GRAPHIC_EQ_Q_1 2.0
#define GRAPHIC_EQ_TYPE_2 bq_type_bandpass
#define GRAPHIC_EQ_CENTER_FRQ_2 990.0
#define GRAPHIC_EQ_Q_2 2.0
#define GRAPHIC_EQ_TYPE_3 bq_type_bandpass
#define GRAPHIC_EQ_CENTER_FRQ_3 2000.0
#define GRAPHIC_EQ_Q_3 2.0
#define GRAPHIC_EQ_TYPE_4 bq_type_bandpass
#define GRAPHIC_EQ_CENTER_FRQ_4 4000.0
#define GRAPHIC_EQ_Q_4 2.0
#define GRAPHIC_EQ_TYPE_5 bq_type_bandpass
#define GRAPHIC_EQ_CENTER_FRQ_5 9900.0
#define GRAPHIC_EQ_Q_5 2.0
#define GRAPHIC_EQ_TYPE_6 bq_type_highpass
#define GRAPHIC_EQ_CENTER_FRQ_6 11000.0
#define GRAPHIC_EQ_Q_6 2.0
#endif
//************************************************************************************************* //*************************************************************************************************
//* UI //* UI
//************************************************************************************************* //*************************************************************************************************

@ -0,0 +1,188 @@
#ifdef SGTL5000_AUDIO_ENHANCE
#include <Arduino.h>
#include <Audio.h>
extern AudioControlSGTL5000 sgtl5000_1;
typedef struct biquad_coefficients_s {
float32_t a0;
float32_t a1;
float32_t a2;
float32_t b1;
float32_t b2;
} biquad_coefficients_t;
typedef struct biquad_params_s {
uint8_t filter_type;
float32_t Fc;
float32_t Q;
} biquad_params_t;
enum {
bq_type_lowpass = 0,
bq_type_highpass,
bq_type_bandpass,
bq_type_notch,
bq_type_peak,
bq_type_lowshelf,
bq_type_highshelf
};
#define NUM_GRAPHIC_EQ_BANDS 7
biquad_coefficients_t biquad_coefficients[NUM_GRAPHIC_EQ_BANDS];
biquad_params_t biquad_params[NUM_GRAPHIC_EQ_BANDS];
void set_sgtl5000_7band_eq(uint8_t band, uint8_t filter_type, float32_t Fc, float32_t Q);
void set_sgtl5000_7band_eq_gain(uint8_t band, float32_t peakGainDB);
void setup_sgtl5000_graphic_7band_eq(void);
void calcBiquadCoefficients(biquad_coefficients_t* biquad_coefficients, uint8_t filter_type, float32_t Fc, float32_t Q, float32_t peakGain);
void set_sgtl5000_7band_eq(uint8_t band, uint8_t filter_type, float32_t Fc, float32_t Q)
{
biquad_params[band].filter_type = filter_type;
biquad_params[band].Fc = Fc;
biquad_params[band].Q = Q;
calcBiquadCoefficients(&biquad_coefficients[band], filter_type, Fc, Q, 0.0);
//sgtl5000_1.eqFilter(band, biquad_coefficients);
}
void set_sgtl5000_7band_eq_gain(uint8_t band, float32_t peakGainDB)
{
calcBiquadCoefficients(&biquad_coefficients[band], biquad_params[band].filter_type, biquad_params[band].Fc, biquad_params[band].Q, peakGainDB);
//sgtl5000_1.eqFilter(band, biquad_coefficients);
}
void setup_sgtl5000_graphic_7band_eq(void)
{
//sgtl5000_1.eqFilterCount(7); // enable 7 bands
set_sgtl5000_7band_eq(0, GRAPHIC_EQ_TYPE_0, GRAPHIC_EQ_CENTER_FRQ_0, GRAPHIC_EQ_Q_0);
set_sgtl5000_7band_eq(1, GRAPHIC_EQ_TYPE_1, GRAPHIC_EQ_CENTER_FRQ_1, GRAPHIC_EQ_Q_1);
set_sgtl5000_7band_eq(2, GRAPHIC_EQ_TYPE_2, GRAPHIC_EQ_CENTER_FRQ_2, GRAPHIC_EQ_Q_2);
set_sgtl5000_7band_eq(3, GRAPHIC_EQ_TYPE_3, GRAPHIC_EQ_CENTER_FRQ_3, GRAPHIC_EQ_Q_3);
set_sgtl5000_7band_eq(4, GRAPHIC_EQ_TYPE_4, GRAPHIC_EQ_CENTER_FRQ_4, GRAPHIC_EQ_Q_4);
set_sgtl5000_7band_eq(5, GRAPHIC_EQ_TYPE_5, GRAPHIC_EQ_CENTER_FRQ_5, GRAPHIC_EQ_Q_5);
set_sgtl5000_7band_eq(6, GRAPHIC_EQ_TYPE_6, GRAPHIC_EQ_CENTER_FRQ_6, GRAPHIC_EQ_Q_6);
}
// Taken from https://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
//
// Biquad.h
//
// Created by Nigel Redmon on 11/24/12
// EarLevel Engineering: earlevel.com
// Copyright 2012 Nigel Redmon
//
// For a complete explanation of the Biquad code:
// http://www.earlevel.com/main/2012/11/25/biquad-c-source-code/
//
// License:
//
// This source code is provided as is, without warranty.
// You may copy and distribute verbatim copies of this document.
// You may modify and use this source code to create binary code
// for your own purposes, free or commercial.
//
void calcBiquadCoefficients(biquad_coefficients_t* biquad_coefficients, uint8_t filter_type, float32_t Fc, float32_t Q, float32_t peakGain)
{
float32_t norm;
float32_t V = pow(10, fabs(peakGain) / 20.0);
float32_t K = tan(M_PI * Fc);
switch (filter_type) {
case bq_type_lowpass:
norm = 1 / (1 + K / Q + K * K);
biquad_coefficients->a0 = K * K * norm;
biquad_coefficients->a1 = 2 * biquad_coefficients->a0;
biquad_coefficients->a2 = biquad_coefficients->a0;
biquad_coefficients->b1 = 2 * (K * K - 1) * norm;
biquad_coefficients->b2 = (1 - K / Q + K * K) * norm;
break;
case bq_type_highpass:
norm = 1 / (1 + K / Q + K * K);
biquad_coefficients->a0 = 1 * norm;
biquad_coefficients->a1 = -2 * biquad_coefficients->a0;
biquad_coefficients->a2 = biquad_coefficients->a0;
biquad_coefficients->b1 = 2 * (K * K - 1) * norm;
biquad_coefficients->b2 = (1 - K / Q + K * K) * norm;
break;
case bq_type_bandpass:
norm = 1 / (1 + K / Q + K * K);
biquad_coefficients->a0 = K / Q * norm;
biquad_coefficients->a1 = 0;
biquad_coefficients->a2 = -biquad_coefficients->a0;
biquad_coefficients->b1 = 2 * (K * K - 1) * norm;
biquad_coefficients->b2 = (1 - K / Q + K * K) * norm;
break;
case bq_type_notch:
norm = 1 / (1 + K / Q + K * K);
biquad_coefficients->a0 = (1 + K * K) * norm;
biquad_coefficients->a1 = 2 * (K * K - 1) * norm;
biquad_coefficients->a2 = biquad_coefficients->a0;
biquad_coefficients->b1 = biquad_coefficients->a1;
biquad_coefficients->b2 = (1 - K / Q + K * K) * norm;
break;
case bq_type_peak:
if (peakGain >= 0) { // boost
norm = 1 / (1 + 1 / Q * K + K * K);
biquad_coefficients->a0 = (1 + V / Q * K + K * K) * norm;
biquad_coefficients->a1 = 2 * (K * K - 1) * norm;
biquad_coefficients->a2 = (1 - V / Q * K + K * K) * norm;
biquad_coefficients->b1 = biquad_coefficients->a1;
biquad_coefficients->b2 = (1 - 1 / Q * K + K * K) * norm;
}
else { // cut
norm = 1 / (1 + V / Q * K + K * K);
biquad_coefficients->a0 = (1 + 1 / Q * K + K * K) * norm;
biquad_coefficients->a1 = 2 * (K * K - 1) * norm;
biquad_coefficients->a2 = (1 - 1 / Q * K + K * K) * norm;
biquad_coefficients->b1 = biquad_coefficients->a1;
biquad_coefficients->b2 = (1 - V / Q * K + K * K) * norm;
}
break;
case bq_type_lowshelf:
if (peakGain >= 0) { // boost
norm = 1 / (1 + sqrt(2) * K + K * K);
biquad_coefficients->a0 = (1 + sqrt(2 * V) * K + V * K * K) * norm;
biquad_coefficients->a1 = 2 * (V * K * K - 1) * norm;
biquad_coefficients->a2 = (1 - sqrt(2 * V) * K + V * K * K) * norm;
biquad_coefficients->b1 = 2 * (K * K - 1) * norm;
biquad_coefficients->b2 = (1 - sqrt(2) * K + K * K) * norm;
}
else { // cut
norm = 1 / (1 + sqrt(2 * V) * K + V * K * K);
biquad_coefficients->a0 = (1 + sqrt(2) * K + K * K) * norm;
biquad_coefficients->a1 = 2 * (K * K - 1) * norm;
biquad_coefficients->a2 = (1 - sqrt(2) * K + K * K) * norm;
biquad_coefficients->b1 = 2 * (V * K * K - 1) * norm;
biquad_coefficients->b2 = (1 - sqrt(2 * V) * K + V * K * K) * norm;
}
break;
case bq_type_highshelf:
if (peakGain >= 0) { // boost
norm = 1 / (1 + sqrt(2) * K + K * K);
biquad_coefficients->a0 = (V + sqrt(2 * V) * K + K * K) * norm;
biquad_coefficients->a1 = 2 * (K * K - V) * norm;
biquad_coefficients->a2 = (V - sqrt(2 * V) * K + K * K) * norm;
biquad_coefficients->b1 = 2 * (K * K - 1) * norm;
biquad_coefficients->b2 = (1 - sqrt(2) * K + K * K) * norm;
}
else { // cut
norm = 1 / (V + sqrt(2 * V) * K + K * K);
biquad_coefficients->a0 = (1 + sqrt(2) * K + K * K) * norm;
biquad_coefficients->a1 = 2 * (K * K - 1) * norm;
biquad_coefficients->a2 = (1 - sqrt(2) * K + K * K) * norm;
biquad_coefficients->b1 = 2 * (K * K - V) * norm;
biquad_coefficients->b2 = (V - sqrt(2 * V) * K + K * K) * norm;
}
break;
}
return;
}
#endif
Loading…
Cancel
Save