diff --git a/MicroDexed.ino b/MicroDexed.ino index 0684f79..7ac0846 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -35,6 +35,7 @@ #include "effect_modulated_delay.h" #include "effect_stereo_mono.h" #include "effect_mono_stereo.h" +#include "mixer8.h" #ifdef USE_PLATEREVERB #include "effect_platervbstereo.h" #else @@ -61,8 +62,8 @@ AudioEffectMonoStereo* mono2stereo[NUM_DEXED]; AudioMixer4 microdexed_peak_mixer; AudioAnalyzePeak microdexed_peak; #if defined(USE_FX) -AudioMixer4 reverb_mixer_r; -AudioMixer4 reverb_mixer_l; +AudioMixer8 reverb_mixer_r; +AudioMixer8 reverb_mixer_l; #ifdef USE_PLATEREVERB AudioEffectPlateReverb reverb; #else @@ -85,6 +86,14 @@ AudioMixer4 audio_thru_mixer_r; AudioMixer4 audio_thru_mixer_l; #endif +// Drumset +#ifdef NUM_DRUMS +AudioPlaySdRaw* Drum[NUM_DRUMS]; +AudioEffectMonoStereo* drum_mono2stereo[NUM_DRUMS]; +AudioMixer8 drum_mixer_r; +AudioMixer8 drum_mixer_l; +#endif + // Audio chain tail #if defined(USE_FX) #ifdef USE_PLATEREVERB @@ -161,6 +170,16 @@ AudioConnection patchCord23(audio_thru_mixer_r, 0, i2s1, 0); AudioConnection patchCord24(audio_thru_mixer_l, 0, i2s1, 1); #endif +#ifdef NUM_DRUMS +#ifdef USE_FX +AudioConnection patchCord25(drum_mixer_r, 0, reverb_mixer_r, 4); +AudioConnection patchCord26(drum_mixer_l, 0, reverb_mixer_l, 4); +#else +AudioConnection patchCord25(drum_mixer_r, 0, master_mixer_r, 2); +AudioConnection patchCord26(drum_mixer_l, 0, master_mixer_l, 2); +#endif +#endif + // // Dynamic patching of MicroDexed objects // @@ -172,10 +191,9 @@ AudioConnection * dynamicConnections[NUM_DEXED * 16]; #else AudioConnection * dynamicConnections[NUM_DEXED * 5]; #endif -void create_audio_engine_chain(uint8_t instance_id) +void create_audio_dexed_chain(uint8_t instance_id) { MicroDexed[instance_id] = new AudioSynthDexed(MAX_NOTES / NUM_DEXED, SAMPLE_RATE); - //[instance_id] = new AudioEffectDynamics(); mono2stereo[instance_id] = new AudioEffectMonoStereo(); #if defined(USE_FX) chorus_modulator[instance_id] = new AudioSynthWaveform(); @@ -216,6 +234,27 @@ void create_audio_engine_chain(uint8_t instance_id) dynamicConnections[nDynamic++] = new AudioConnection(*mono2stereo[instance_id], 1, master_mixer_l, instance_id); } +// +// Dynamic patching of Drum objects +// +#ifdef NUM_DRUMS +uint16_t nDrumDynamic = 0; +AudioConnection* dynamicDrumConnections[NUM_DRUMS * 3]; +void create_audio_drum_chain(uint8_t instance_id) +{ + Drum[instance_id] = new AudioPlaySdRaw(); + drum_mono2stereo[instance_id] = new AudioEffectMonoStereo(); + + dynamicDrumConnections[nDrumDynamic++] = new AudioConnection(*Drum[instance_id], 0, *drum_mono2stereo[instance_id], 0); + dynamicDrumConnections[nDrumDynamic++] = new AudioConnection(*drum_mono2stereo[instance_id], 0, drum_mixer_r, instance_id); + dynamicDrumConnections[nDrumDynamic++] = new AudioConnection(*drum_mono2stereo[instance_id], 1, drum_mixer_l, instance_id); + + drum_mono2stereo[instance_id]->panorama(0.0); + drum_mixer_r.gain(instance_id, 1.0); + drum_mixer_l.gain(instance_id, 1.0); +} +#endif + uint8_t sd_card = 0; Sd2Card card; SdVolume volume; @@ -384,7 +423,7 @@ void setup() Serial.print(F("Creating MicroDexed instance ")); Serial.println(instance_id, DEC); #endif - create_audio_engine_chain(instance_id); + create_audio_dexed_chain(instance_id); } #ifdef DEBUG @@ -398,6 +437,18 @@ void setup() } #endif +#ifdef NUM_DRUMS + // create dynamic Drum instances + for (uint8_t instance_id = 0; instance_id < NUM_DRUMS; instance_id++) + { +#ifdef DEBUG + Serial.print(F("Creating Drum instance ")); + Serial.println(instance_id, DEC); +#endif + create_audio_drum_chain(instance_id); + } +#endif + #if defined(USE_FX) // Init effects for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) @@ -494,8 +545,13 @@ void setup() master_mixer_r.gain(1, 0.0); master_mixer_l.gain(1, 0.0); #endif +#ifdef NUM_DRUMS + master_mixer_r.gain(2, 1.0); + master_mixer_l.gain(2, 1.0); +#else master_mixer_r.gain(2, 0.0); master_mixer_l.gain(2, 0.0); +#endif master_mixer_r.gain(3, 0.0); master_mixer_l.gain(3, 0.0); @@ -619,6 +675,7 @@ void loop() ******************************************************************************/ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { + // Check for MicroDexed for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { if (checkMidiChannel(inChannel, instance_id)) @@ -650,6 +707,50 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) } } } + +#ifdef NUM_DRUMS + // Check for Drum + if (inChannel == DRUM_MIDI_CHANNEL) + { +#ifdef DEBUG + Serial.print(F("Drum ")); + Serial.println(inNumber - 48, DEC); +#endif + switch (inNumber - 48) + { + case 0: + Drum[0]->play("drm/bd01.raw"); + break; + case 1: + Drum[1]->play("drm/cp02.raw"); + break; + case 2: + Drum[2]->play("drm/sd15.raw"); + break; + case 6: + Drum[3]->play("drm/hh01.wav"); + break; + case 8: + Drum[3]->play("drm/hh02.wav"); + break; + case 10: + Drum[3]->play("drm/oh02.wav"); + break; + case 5: + Drum[4]->play("drm/lt01.raw"); + break; + case 7: + Drum[5]->play("drm/ht01.raw"); + break; + case 13: + Drum[6]->play("drm/rd01.raw"); + break; + case 15: + Drum[7]->play("drm/rd02.raw"); + break; + } + } +#endif } void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) @@ -1930,6 +2031,9 @@ void set_fx_params(void) freeverb.damping(mapfloat(configuration.fx.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); #endif + reverb_mixer_r.gain(4, 1.0); + reverb_mixer_l.gain(4, 1.0); + master_mixer_r.gain(3, pseudo_log_curve(mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0))); master_mixer_l.gain(3, pseudo_log_curve(mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0))); diff --git a/UI.hpp b/UI.hpp index d6e366c..85b8cb6 100644 --- a/UI.hpp +++ b/UI.hpp @@ -30,6 +30,7 @@ #include "disp_plus.h" #include "effect_modulated_delay.h" #include "effect_stereo_mono.h" +#include "mixer8.h" #ifdef USE_PLATEREVERB #include "effect_platervbstereo.h" #else @@ -84,8 +85,8 @@ extern AudioEffectMonoStereo* mono2stereo[NUM_DEXED]; extern AudioMixer4 microdexed_peak_mixer; extern AudioAnalyzePeak microdexed_peak; #if defined(USE_FX) -extern AudioMixer4 reverb_mixer_r; -extern AudioMixer4 reverb_mixer_l; +extern AudioMixer8 reverb_mixer_r; +extern AudioMixer8 reverb_mixer_l; #ifdef USE_PLATEREVERB extern AudioEffectPlateReverb reverb; #else diff --git a/addon/SD/drm/bd01.raw b/addon/SD/drm/bd01.raw new file mode 100644 index 0000000..3c56d4f Binary files /dev/null and b/addon/SD/drm/bd01.raw differ diff --git a/addon/SD/drm/bd02.raw b/addon/SD/drm/bd02.raw new file mode 100644 index 0000000..95cd3c2 Binary files /dev/null and b/addon/SD/drm/bd02.raw differ diff --git a/addon/SD/drm/bd03.raw b/addon/SD/drm/bd03.raw new file mode 100644 index 0000000..7b345d1 Binary files /dev/null and b/addon/SD/drm/bd03.raw differ diff --git a/addon/SD/drm/bd04.raw b/addon/SD/drm/bd04.raw new file mode 100644 index 0000000..33cf2da Binary files /dev/null and b/addon/SD/drm/bd04.raw differ diff --git a/addon/SD/drm/bd05.raw b/addon/SD/drm/bd05.raw new file mode 100644 index 0000000..cc95ee5 Binary files /dev/null and b/addon/SD/drm/bd05.raw differ diff --git a/addon/SD/drm/bd06.raw b/addon/SD/drm/bd06.raw new file mode 100644 index 0000000..8ecb3db Binary files /dev/null and b/addon/SD/drm/bd06.raw differ diff --git a/addon/SD/drm/bd07.raw b/addon/SD/drm/bd07.raw new file mode 100644 index 0000000..d6ca432 Binary files /dev/null and b/addon/SD/drm/bd07.raw differ diff --git a/addon/SD/drm/bd08.raw b/addon/SD/drm/bd08.raw new file mode 100644 index 0000000..89a2cfc Binary files /dev/null and b/addon/SD/drm/bd08.raw differ diff --git a/addon/SD/drm/bd09.raw b/addon/SD/drm/bd09.raw new file mode 100644 index 0000000..bb121f8 Binary files /dev/null and b/addon/SD/drm/bd09.raw differ diff --git a/addon/SD/drm/bd10.raw b/addon/SD/drm/bd10.raw new file mode 100644 index 0000000..21d151e Binary files /dev/null and b/addon/SD/drm/bd10.raw differ diff --git a/addon/SD/drm/cp01.raw b/addon/SD/drm/cp01.raw new file mode 100644 index 0000000..5e3339c Binary files /dev/null and b/addon/SD/drm/cp01.raw differ diff --git a/addon/SD/drm/cp02.raw b/addon/SD/drm/cp02.raw new file mode 100644 index 0000000..38987af Binary files /dev/null and b/addon/SD/drm/cp02.raw differ diff --git a/addon/SD/drm/cr01.raw b/addon/SD/drm/cr01.raw new file mode 100644 index 0000000..edfd4eb Binary files /dev/null and b/addon/SD/drm/cr01.raw differ diff --git a/addon/SD/drm/cr02.raw b/addon/SD/drm/cr02.raw new file mode 100644 index 0000000..1240777 Binary files /dev/null and b/addon/SD/drm/cr02.raw differ diff --git a/addon/SD/drm/hh01.raw b/addon/SD/drm/hh01.raw new file mode 100644 index 0000000..775e954 Binary files /dev/null and b/addon/SD/drm/hh01.raw differ diff --git a/addon/SD/drm/hh02.raw b/addon/SD/drm/hh02.raw new file mode 100644 index 0000000..224b24b Binary files /dev/null and b/addon/SD/drm/hh02.raw differ diff --git a/addon/SD/drm/ht01.raw b/addon/SD/drm/ht01.raw new file mode 100644 index 0000000..ec83a9c Binary files /dev/null and b/addon/SD/drm/ht01.raw differ diff --git a/addon/SD/drm/ht02.raw b/addon/SD/drm/ht02.raw new file mode 100644 index 0000000..b882daa Binary files /dev/null and b/addon/SD/drm/ht02.raw differ diff --git a/addon/SD/drm/lt01.raw b/addon/SD/drm/lt01.raw new file mode 100644 index 0000000..26308a2 Binary files /dev/null and b/addon/SD/drm/lt01.raw differ diff --git a/addon/SD/drm/lt02.raw b/addon/SD/drm/lt02.raw new file mode 100644 index 0000000..6c6ff35 Binary files /dev/null and b/addon/SD/drm/lt02.raw differ diff --git a/addon/SD/drm/mt01.raw b/addon/SD/drm/mt01.raw new file mode 100644 index 0000000..977e695 Binary files /dev/null and b/addon/SD/drm/mt01.raw differ diff --git a/addon/SD/drm/mt02.raw b/addon/SD/drm/mt02.raw new file mode 100644 index 0000000..bba2b57 Binary files /dev/null and b/addon/SD/drm/mt02.raw differ diff --git a/addon/SD/drm/oh01.raw b/addon/SD/drm/oh01.raw new file mode 100644 index 0000000..c7f0121 Binary files /dev/null and b/addon/SD/drm/oh01.raw differ diff --git a/addon/SD/drm/oh02.raw b/addon/SD/drm/oh02.raw new file mode 100644 index 0000000..d2b80ee Binary files /dev/null and b/addon/SD/drm/oh02.raw differ diff --git a/addon/SD/drm/rd01.raw b/addon/SD/drm/rd01.raw new file mode 100644 index 0000000..3cc3ab5 Binary files /dev/null and b/addon/SD/drm/rd01.raw differ diff --git a/addon/SD/drm/rd02.raw b/addon/SD/drm/rd02.raw new file mode 100644 index 0000000..4b3996e Binary files /dev/null and b/addon/SD/drm/rd02.raw differ diff --git a/addon/SD/drm/rs01.raw b/addon/SD/drm/rs01.raw new file mode 100644 index 0000000..05a9662 Binary files /dev/null and b/addon/SD/drm/rs01.raw differ diff --git a/addon/SD/drm/sd01.raw b/addon/SD/drm/sd01.raw new file mode 100644 index 0000000..df5222d Binary files /dev/null and b/addon/SD/drm/sd01.raw differ diff --git a/addon/SD/drm/sd02.raw b/addon/SD/drm/sd02.raw new file mode 100644 index 0000000..842cbe8 Binary files /dev/null and b/addon/SD/drm/sd02.raw differ diff --git a/addon/SD/drm/sd03.raw b/addon/SD/drm/sd03.raw new file mode 100644 index 0000000..353faf5 Binary files /dev/null and b/addon/SD/drm/sd03.raw differ diff --git a/addon/SD/drm/sd04.raw b/addon/SD/drm/sd04.raw new file mode 100644 index 0000000..16e9fb4 Binary files /dev/null and b/addon/SD/drm/sd04.raw differ diff --git a/addon/SD/drm/sd05.raw b/addon/SD/drm/sd05.raw new file mode 100644 index 0000000..2bb1f8c Binary files /dev/null and b/addon/SD/drm/sd05.raw differ diff --git a/addon/SD/drm/sd06.raw b/addon/SD/drm/sd06.raw new file mode 100644 index 0000000..b6eee84 Binary files /dev/null and b/addon/SD/drm/sd06.raw differ diff --git a/addon/SD/drm/sd07.raw b/addon/SD/drm/sd07.raw new file mode 100644 index 0000000..8be15fa Binary files /dev/null and b/addon/SD/drm/sd07.raw differ diff --git a/addon/SD/drm/sd08.raw b/addon/SD/drm/sd08.raw new file mode 100644 index 0000000..f293dc4 Binary files /dev/null and b/addon/SD/drm/sd08.raw differ diff --git a/addon/SD/drm/sd09.raw b/addon/SD/drm/sd09.raw new file mode 100644 index 0000000..c41363e Binary files /dev/null and b/addon/SD/drm/sd09.raw differ diff --git a/addon/SD/drm/sd10.raw b/addon/SD/drm/sd10.raw new file mode 100644 index 0000000..bf2a793 Binary files /dev/null and b/addon/SD/drm/sd10.raw differ diff --git a/addon/SD/drm/sd11.raw b/addon/SD/drm/sd11.raw new file mode 100644 index 0000000..ce1e42d Binary files /dev/null and b/addon/SD/drm/sd11.raw differ diff --git a/addon/SD/drm/sd12.raw b/addon/SD/drm/sd12.raw new file mode 100644 index 0000000..f20b8fb Binary files /dev/null and b/addon/SD/drm/sd12.raw differ diff --git a/addon/SD/drm/sd13.raw b/addon/SD/drm/sd13.raw new file mode 100644 index 0000000..9801bd7 Binary files /dev/null and b/addon/SD/drm/sd13.raw differ diff --git a/addon/SD/drm/sd14.raw b/addon/SD/drm/sd14.raw new file mode 100644 index 0000000..6e00d27 Binary files /dev/null and b/addon/SD/drm/sd14.raw differ diff --git a/addon/SD/drm/sd15.raw b/addon/SD/drm/sd15.raw new file mode 100644 index 0000000..6648b86 Binary files /dev/null and b/addon/SD/drm/sd15.raw differ diff --git a/config.h b/config.h index 28d5678..bdeaf6f 100644 --- a/config.h +++ b/config.h @@ -108,6 +108,10 @@ // FX-CHAIN ENABLE/DISABLE #define USE_FX 1 +// NUMBER OF SAMPLEDRUMS +#define NUM_DRUMS 8 // Max is currently 8! +#define DRUM_MIDI_CHANNEL 1 + // CHORUS parameters #define MOD_DELAY_SAMPLE_BUFFER int32_t(TIME_MS2SAMPLES(20.0)) // 20.0 ms delay buffer. #define MOD_WAVEFORM WAVEFORM_TRIANGLE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE @@ -145,11 +149,19 @@ //************************************************************************************************* #define SAMPLE_RATE 44100 #ifdef USE_FX +#ifdef NUM_DRUMS +#define AUDIO_MEM (SAMPLE_RATE * NUM_DEXED * DELAY_MAX_TIME / 128000 + 36) + NUM_DRUMS * 3 +#else // #define AUDIO_MEM 380 // T_4.1, 2 Instances, 0.5ms delay #define AUDIO_MEM (SAMPLE_RATE * NUM_DEXED * DELAY_MAX_TIME / 128000 + 36) +#endif +#else +#ifdef NUM_DRUMS +#define AUDIO_MEM NUM_DEXED * 15 + NUM_DRUMS * 3 #else #define AUDIO_MEM NUM_DEXED * 15 #endif +#endif #ifdef TEENSY_AUDIO_BOARD /* diff --git a/mixer8.cpp b/mixer8.cpp new file mode 100644 index 0000000..4c3d14a --- /dev/null +++ b/mixer8.cpp @@ -0,0 +1,132 @@ +/* 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 +#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); + } +} diff --git a/mixer8.h b/mixer8.h new file mode 100644 index 0000000..c23213f --- /dev/null +++ b/mixer8.h @@ -0,0 +1,69 @@ +/* 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