Added T4_1 for version string.
pull/109/head
Holger Wirtz 3 years ago
parent 0e9f481041
commit 2c2807a991
  1. 54
      MicroDexed.ino
  2. 17
      UI.hpp
  3. 133
      mixer8.cpp
  4. 70
      mixer8.h
  5. 203
      template_mixer.hpp

@ -43,13 +43,11 @@ using namespace TeensyTimerTool;
#else
#include "effect_freeverbf.h"
#endif
#include "template_mixer.hpp"
#include "UI.hpp"
#if NUM_DRUMS > 0
#include "drums.h"
#include "drumset.h"
#if NUM_DRUMS > 4
#include "mixer8.h"
#endif
#endif
#ifdef SGTL5000_AUDIO_ENHANCE
#include "control_sgtl5000plus.h"
@ -64,34 +62,34 @@ AudioSynthWaveform* chorus_modulator[NUM_DEXED];
AudioFilterBiquad* modchorus_filter[NUM_DEXED];
#endif
AudioEffectModulatedDelay* modchorus[NUM_DEXED];
AudioMixer4* chorus_mixer[NUM_DEXED];
AudioMixer4* delay_fb_mixer[NUM_DEXED];
AudioMixer<4>* chorus_mixer[NUM_DEXED];
AudioMixer<4>* delay_fb_mixer[NUM_DEXED];
AudioEffectDelay* delay_fx[NUM_DEXED];
AudioMixer4* delay_mixer[NUM_DEXED];
AudioMixer<4>* delay_mixer[NUM_DEXED];
#endif
AudioEffectMonoStereo* mono2stereo[NUM_DEXED];
AudioMixer4 microdexed_peak_mixer;
AudioMixer<4> microdexed_peak_mixer;
AudioAnalyzePeak microdexed_peak;
#if defined(USE_FX)
AudioMixer4 reverb_mixer_r;
AudioMixer4 reverb_mixer_l;
AudioMixer<4> reverb_mixer_r;
AudioMixer<4> reverb_mixer_l;
#ifdef USE_PLATEREVERB
AudioEffectPlateReverb reverb;
#else
AudioEffectFreeverbStereoFloat freeverb;
#endif
#endif
AudioMixer4 master_mixer_r;
AudioMixer4 master_mixer_l;
AudioMixer<4> master_mixer_r;
AudioMixer<4> master_mixer_l;
AudioAmplifier volume_r;
AudioAmplifier volume_l;
AudioEffectStereoMono stereo2mono;
AudioAnalyzePeak master_peak_r;
AudioAnalyzePeak master_peak_l;
#if defined(TEENSY_AUDIO_BOARD) && defined(SGTL5000_AUDIO_THRU)
AudioMixer4 audio_thru_mixer_r;
AudioMixer4 audio_thru_mixer_l;
AudioMixer<4> audio_thru_mixer_r;
AudioMixer<4> audio_thru_mixer_l;
#endif
// Drumset
@ -99,19 +97,19 @@ AudioMixer4 audio_thru_mixer_l;
//AudioPlayMemory* Drum[NUM_DRUMS];
AudioPlayArrayResmp* Drum[NUM_DRUMS];
#if NUM_DRUMS < 5
AudioMixer4 drum_mixer_r;
AudioMixer4 drum_mixer_l;
AudioMixer<4> drum_mixer_r;
AudioMixer<4> drum_mixer_l;
#else
AudioMixer8 drum_mixer_r;
AudioMixer8 drum_mixer_l;
AudioMixer<8> drum_mixer_r;
AudioMixer<8> drum_mixer_l;
#endif
#ifdef USE_FX
#if NUM_DRUMS < 5
AudioMixer4 drum_reverb_send_mixer_r;
AudioMixer4 drum_reverb_send_mixer_l;
AudioMixer<4> drum_reverb_send_mixer_r;
AudioMixer<4> drum_reverb_send_mixer_l;
#else
AudioMixer8 drum_reverb_send_mixer_r;
AudioMixer8 drum_reverb_send_mixer_l;
AudioMixer<8> drum_reverb_send_mixer_r;
AudioMixer<8> drum_reverb_send_mixer_l;
#endif
#endif
#endif
@ -133,7 +131,7 @@ AudioControlWM8731master wm8731_1;
AudioOutputPT8211 pt8211_1;
#elif defined(TEENSY_DAC_SYMMETRIC)
AudioOutputAnalogStereo dacOut;
AudioMixer4 invMixer;
AudioMixer<4> invMixer;
#elif defined(TEENSY_DAC)
AudioOutputAnalogStereo dacOut;
#endif
@ -241,10 +239,10 @@ void create_audio_dexed_chain(uint8_t instance_id)
modchorus_filter[instance_id] = new AudioFilterBiquad();
#endif
modchorus[instance_id] = new AudioEffectModulatedDelay();
chorus_mixer[instance_id] = new AudioMixer4();
delay_fb_mixer[instance_id] = new AudioMixer4();
chorus_mixer[instance_id] = new AudioMixer<4>();
delay_fb_mixer[instance_id] = new AudioMixer<4>();
delay_fx[instance_id] = new AudioEffectDelay();
delay_mixer[instance_id] = new AudioMixer4();
delay_mixer[instance_id] = new AudioMixer<4>();
#endif
dynamicConnections[nDynamic++] = new AudioConnection(*MicroDexed[instance_id], 0, microdexed_peak_mixer, instance_id);
@ -2225,7 +2223,7 @@ float get_sample_reverb_send(uint8_t sample)
uint8_t find_drum_number_from_note(uint8_t note)
{
uint8_t number=0;
uint8_t number = 0;
for (uint8_t d = 0; d < NUM_DRUMSET_CONFIG - 1; d++)
{
if (note == drum_config[d].midinote)
@ -2438,8 +2436,10 @@ void generate_version_string(char* buffer, uint8_t len)
strncat(buffer, "-3.5", 4);
#elif defined(TEENSY3_6)
strncat(buffer, "-3.6", 4);
#elif defined(TEENSY4)
#elif defined(TEENSY4_0)
strncat(buffer, "-4.0", 4);
#elif defined(TEENSY4_0)
strncat(buffer, "-4.1", 4);
#endif
#if defined(USE_FX)
strncat(buffer, "FX", 2);

@ -38,6 +38,7 @@
#else
#include "effect_freeverbf.h"
#endif
#include "template_mixer.hpp"
#include "drumset.h"
#define _LCDML_DISP_cols LCD_cols
@ -129,26 +130,26 @@ extern AudioControlSGTL5000 sgtl5000;
#if defined(USE_FX)
extern AudioSynthWaveform* chorus_modulator[NUM_DEXED];
extern AudioEffectModulatedDelay* modchorus[NUM_DEXED];
extern AudioMixer4* chorus_mixer[NUM_DEXED];
extern AudioMixer4* delay_fb_mixer[NUM_DEXED];
extern AudioMixer<4>* chorus_mixer[NUM_DEXED];
extern AudioMixer<4>* delay_fb_mixer[NUM_DEXED];
extern AudioEffectDelay* delay_fx[NUM_DEXED];
extern AudioMixer4* delay_mixer[NUM_DEXED];
extern AudioMixer<4>* delay_mixer[NUM_DEXED];
#endif
extern AudioEffectMonoStereo* mono2stereo[NUM_DEXED];
extern AudioMixer4 microdexed_peak_mixer;
extern AudioMixer<4> microdexed_peak_mixer;
extern AudioAnalyzePeak microdexed_peak;
#if defined(USE_FX)
extern AudioMixer4 reverb_mixer_r;
extern AudioMixer4 reverb_mixer_l;
extern AudioMixer<4> reverb_mixer_r;
extern AudioMixer<4> reverb_mixer_l;
#ifdef USE_PLATEREVERB
extern AudioEffectPlateReverb reverb;
#else
extern AudioEffectFreeverbStereoFloat freeverb;
#endif
#endif
extern AudioMixer4 master_mixer_r;
extern AudioMixer4 master_mixer_l;
extern AudioMixer<4> master_mixer_r;
extern AudioMixer<4> master_mixer_l;
extern AudioEffectStereoMono stereo2mono;
extern AudioAnalyzePeak master_peak_r;
extern AudioAnalyzePeak master_peak_l;

@ -1,133 +0,0 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <Arduino.h>
#include "mixer8.h"
#include "utility/dspinst.h"
#if defined(__ARM_ARCH_7EM__)
#define MULTI_UNITYGAIN 65536
static void applyGain(int16_t *data, int32_t mult)
{
uint32_t *p = (uint32_t *)data;
const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);
do {
uint32_t tmp32 = *p; // read 2 samples from *data
int32_t val1 = signed_multiply_32x16b(mult, tmp32);
int32_t val2 = signed_multiply_32x16t(mult, tmp32);
val1 = signed_saturate_rshift(val1, 16, 0);
val2 = signed_saturate_rshift(val2, 16, 0);
*p++ = pack_16b_16b(val2, val1);
} while (p < end);
}
static void applyGainThenAdd(int16_t *data, const int16_t *in, int32_t mult)
{
uint32_t *dst = (uint32_t *)data;
const uint32_t *src = (uint32_t *)in;
const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);
if (mult == MULTI_UNITYGAIN) {
do {
uint32_t tmp32 = *dst;
*dst++ = signed_add_16_and_16(tmp32, *src++);
tmp32 = *dst;
*dst++ = signed_add_16_and_16(tmp32, *src++);
} while (dst < end);
} else {
do {
uint32_t tmp32 = *src++; // read 2 samples from *data
int32_t val1 = signed_multiply_32x16b(mult, tmp32);
int32_t val2 = signed_multiply_32x16t(mult, tmp32);
val1 = signed_saturate_rshift(val1, 16, 0);
val2 = signed_saturate_rshift(val2, 16, 0);
tmp32 = pack_16b_16b(val2, val1);
uint32_t tmp32b = *dst;
*dst++ = signed_add_16_and_16(tmp32, tmp32b);
} while (dst < end);
}
}
#elif defined(KINETISL)
#define MULTI_UNITYGAIN 256
static void applyGain(int16_t *data, int32_t mult)
{
const int16_t *end = data + AUDIO_BLOCK_SAMPLES;
do {
int32_t val = *data * mult;
*data++ = signed_saturate_rshift(val, 16, 0);
} while (data < end);
}
static void applyGainThenAdd(int16_t *dst, const int16_t *src, int32_t mult)
{
const int16_t *end = dst + AUDIO_BLOCK_SAMPLES;
if (mult == MULTI_UNITYGAIN) {
do {
int32_t val = *dst + *src++;
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
} else {
do {
int32_t val = *dst + ((*src++ * mult) >> 8); // overflow possible??
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
}
}
#endif
void AudioMixer8::update(void)
{
audio_block_t *in, *out=NULL;
unsigned int channel;
for (channel=0; channel < 8; channel++) {
if (!out) {
out = receiveWritable(channel);
if (out) {
int32_t mult = multiplier[channel];
if (mult != MULTI_UNITYGAIN) applyGain(out->data, mult);
}
} else {
in = receiveReadOnly(channel);
if (in) {
applyGainThenAdd(out->data, in->data, multiplier[channel]);
release(in);
}
}
}
if (out) {
transmit(out);
release(out);
}
}

@ -1,70 +0,0 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef mixer8_h_
#define mixer8_h_
#include "Arduino.h"
#include "AudioStream.h"
class AudioMixer8 : public AudioStream
{
#if defined(__ARM_ARCH_7EM__)
public:
AudioMixer8(void) : AudioStream(8, inputQueueArray) {
for (int i=0; i<8; i++) multiplier[i] = 65536;
}
virtual void update(void);
void gain(unsigned int channel, float gain) {
if (channel >= 8) return;
if (gain > 32767.0f) gain = 32767.0f;
else if (gain < -32767.0f) gain = -32767.0f;
multiplier[channel] = gain * 65536.0f; // TODO: proper roundoff?
}
private:
int32_t multiplier[8];
audio_block_t *inputQueueArray[8];
#elif defined(KINETISL)
public:
AudioMixer8(void) : AudioStream(8, inputQueueArray) {
for (int i=0; i<8; i++) multiplier[i] = 256;
}
virtual void update(void);
void gain(unsigned int channel, float gain) {
if (channel >= 8) return;
if (gain > 127.0f) gain = 127.0f;
else if (gain < -127.0f) gain = -127.0f;
multiplier[channel] = gain * 256.0f; // TODO: proper roundoff?
}
private:
int16_t multiplier[8];
audio_block_t *inputQueueArray[8];
#endif
};
#endif

@ -0,0 +1,203 @@
// Taken from https://github.com/manicken/Audio/tree/templateMixer
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
* open source software by purchasing Teensy or other PJRC products.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef template_mixer_h_
#define template_mixer_h_
#include "Arduino.h"
#include "AudioStream.h"
#define AudioMixer4 AudioMixer<4>
#if defined(__ARM_ARCH_7EM__)
#define MULTI_UNITYGAIN 65536
#define MULTI_UNITYGAIN_F 65536.0f
#define MAX_GAIN 32767.0f
#define MIN_GAIN -32767.0f
#define MULT_DATA_TYPE int32_t
#elif defined(KINETISL)
#define MULTI_UNITYGAIN 256
#define MULTI_UNITYGAIN_F 256.0f
#define MAX_GAIN 127.0f
#define MIN_GAIN -127.0f
#define MULT_DATA_TYPE int16_t
#endif
// because of the template use applyGain and applyGainThenAdd functions
// must be in this file and NOT in cpp file
#if defined(__ARM_ARCH_7EM__)
static void applyGain(int16_t *data, int32_t mult)
{
uint32_t *p = (uint32_t *)data;
const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);
do {
uint32_t tmp32 = *p; // read 2 samples from *data
int32_t val1 = signed_multiply_32x16b(mult, tmp32);
int32_t val2 = signed_multiply_32x16t(mult, tmp32);
val1 = signed_saturate_rshift(val1, 16, 0);
val2 = signed_saturate_rshift(val2, 16, 0);
*p++ = pack_16b_16b(val2, val1);
} while (p < end);
}
static void applyGainThenAdd(int16_t *data, const int16_t *in, int32_t mult)
{
uint32_t *dst = (uint32_t *)data;
const uint32_t *src = (uint32_t *)in;
const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);
if (mult == MULTI_UNITYGAIN) {
do {
uint32_t tmp32 = *dst;
*dst++ = signed_add_16_and_16(tmp32, *src++);
tmp32 = *dst;
*dst++ = signed_add_16_and_16(tmp32, *src++);
} while (dst < end);
} else {
do {
uint32_t tmp32 = *src++; // read 2 samples from *data
int32_t val1 = signed_multiply_32x16b(mult, tmp32);
int32_t val2 = signed_multiply_32x16t(mult, tmp32);
val1 = signed_saturate_rshift(val1, 16, 0);
val2 = signed_saturate_rshift(val2, 16, 0);
tmp32 = pack_16b_16b(val2, val1);
uint32_t tmp32b = *dst;
*dst++ = signed_add_16_and_16(tmp32, tmp32b);
} while (dst < end);
}
}
#elif defined(KINETISL)
static void applyGain(int16_t *data, int32_t mult)
{
const int16_t *end = data + AUDIO_BLOCK_SAMPLES;
do {
int32_t val = *data * mult;
*data++ = signed_saturate_rshift(val, 16, 0);
} while (data < end);
}
static void applyGainThenAdd(int16_t *dst, const int16_t *src, int32_t mult)
{
const int16_t *end = dst + AUDIO_BLOCK_SAMPLES;
if (mult == MULTI_UNITYGAIN) {
do {
int32_t val = *dst + *src++;
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
} else {
do {
int32_t val = *dst + ((*src++ * mult) >> 8); // overflow possible??
*dst++ = signed_saturate_rshift(val, 16, 0);
} while (dst < end);
}
}
#endif
template <int NN> class AudioMixer : public AudioStream
{
public:
AudioMixer(void) : AudioStream(NN, inputQueueArray) {
for (int i=0; i<NN; i++) multiplier[i] = MULTI_UNITYGAIN;
}
void update();
/**
* this sets the individual gains
* @param channel
* @param gain
*/
void gain(unsigned int channel, float gain);
/**
* set all channels to specified gain
* @param gain
*/
void gain(float gain);
private:
MULT_DATA_TYPE multiplier[NN];
audio_block_t *inputQueueArray[NN];
};
// the following Forward declarations
// must be defined when we use template
// the compiler throws some warnings that should be errors otherwise
static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b);
static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b);
static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift);
static inline uint32_t pack_16b_16b(int32_t a, int32_t b);
static inline uint32_t signed_add_16_and_16(uint32_t a, uint32_t b);
template <int NN> void AudioMixer<NN>::gain(unsigned int channel, float gain) {
if (channel >= NN) return;
if (gain > MAX_GAIN) gain = MAX_GAIN;
else if (gain < MIN_GAIN) gain = MIN_GAIN;
multiplier[channel] = gain * MULTI_UNITYGAIN_F; // TODO: proper roundoff?
}
template <int NN> void AudioMixer<NN>::gain(float gain) {
for (int i = 0; i < NN; i++) {
if (gain > MAX_GAIN) gain = MAX_GAIN;
else if (gain < MIN_GAIN) gain = MIN_GAIN;
multiplier[i] = gain * MULTI_UNITYGAIN_F; // TODO: proper roundoff?
}
}
template <int NN> void AudioMixer<NN>::update() {
audio_block_t *in, *out=NULL;
unsigned int channel;
for (channel=0; channel < NN; channel++) {
if (!out) {
out = receiveWritable(channel);
if (out) {
int32_t mult = multiplier[channel];
if (mult != MULTI_UNITYGAIN) applyGain(out->data, mult);
}
} else {
in = receiveReadOnly(channel);
if (in) {
applyGainThenAdd(out->data, in->data, multiplier[channel]);
release(in);
}
}
}
if (out) {
transmit(out);
release(out);
}
}
#endif
Loading…
Cancel
Save