From dfd01d467ad9ed97d029aedf8cae8259feb71c1e Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Wed, 1 Feb 2023 08:58:36 +0100 Subject: [PATCH] Fixes for external delay (see https://forum.pjrc.com/threads/29276-Limits-of-delay-effect-in-audio-library?p=319880#post319880) --- .theia/launch.json | 17 ++ MicroDexed.ino | 2 +- .../examples/AudioDelay8M/AudioDelay8M.ino | 37 +-- .../src/effect_delay_ext8.cpp | 231 +----------------- .../effect_delay_ext8/src/effect_delay_ext8.h | 48 +--- 5 files changed, 52 insertions(+), 283 deletions(-) create mode 100644 .theia/launch.json diff --git a/.theia/launch.json b/.theia/launch.json new file mode 100644 index 0000000..7ffdef3 --- /dev/null +++ b/.theia/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + "version": "0.2.0", + "configurations": [ + { + "cwd": "${workspaceFolder}", + "executable": "./bin/executable.elf", + "name": "Debug with ST-Util", + "request": "launch", + "type": "cortex-debug", + "runToEntryPoint": "main", + "showDevDebugOutput": "none", + "servertype": "stutil" + } + ] +} diff --git a/MicroDexed.ino b/MicroDexed.ino index 66e3ab7..033d258 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -242,7 +242,7 @@ FLASHMEM void create_audio_dexed_chain(uint8_t instance_id) { chorus_mixer[instance_id] = new AudioMixer<2>(); delay_fb_mixer[instance_id] = new AudioMixer<2>(); #if defined(USE_DELAY_8M) - delay_fx[instance_id] = new AudioEffectDelayExternal8(AUDIO_MEMORY8_PSRAM_8MB, DELAY_MAX_TIME); + delay_fx[instance_id] = new AudioEffectDelayExternal8(AUDIO_MEMORY_PSRAM64, DELAY_MAX_TIME); #else delay_fx[instance_id] = new AudioEffectDelay(); #endif diff --git a/third-party/effect_delay_ext8/examples/AudioDelay8M/AudioDelay8M.ino b/third-party/effect_delay_ext8/examples/AudioDelay8M/AudioDelay8M.ino index 8182615..87f4f48 100644 --- a/third-party/effect_delay_ext8/examples/AudioDelay8M/AudioDelay8M.ino +++ b/third-party/effect_delay_ext8/examples/AudioDelay8M/AudioDelay8M.ino @@ -1,21 +1,22 @@ +#include #include #include #include #include // GUItool: begin automatically generated code -AudioSynthWaveformSine sine1; //xy=382,432 -AudioAmplifier amp1; //xy=606,441 -AudioEffectDelayExternal8 delayExt1(AUDIO_MEMORY8_PSRAM_8MB,20000); //xy=770,321 -AudioMixer4 mixer1; //xy=983,386 -AudioOutputI2S i2s1; //xy=1131,343 -AudioConnection patchCord1(sine1, amp1); -AudioConnection patchCord2(amp1, delayExt1); -AudioConnection patchCord3(amp1, 0, mixer1, 1); -AudioConnection patchCord4(delayExt1, 0, mixer1, 0); -AudioConnection patchCord5(mixer1, 0, i2s1, 0); -AudioConnection patchCord6(mixer1, 0, i2s1, 1); -AudioControlSGTL5000 sgtl5000; //xy=943,541 +AudioSynthWaveformSine sine1; //xy=382,432 +AudioAmplifier amp1; //xy=606,441 +AudioEffectDelayExternal8 delayExt1(AUDIO_MEMORY_PSRAM64, 20000); //xy=770,321 +AudioMixer4 mixer1; //xy=983,386 +AudioOutputI2S i2s1; //xy=1131,343 +AudioConnection patchCord1(sine1, amp1); +AudioConnection patchCord2(amp1, delayExt1); +AudioConnection patchCord3(amp1, 0, mixer1, 1); +AudioConnection patchCord4(delayExt1, 0, mixer1, 0); +AudioConnection patchCord5(mixer1, 0, i2s1, 0); +AudioConnection patchCord6(mixer1, 0, i2s1, 1); +AudioControlSGTL5000 sgtl5000; //xy=943,541 // GUItool: end automatically generated code @@ -32,19 +33,19 @@ void setup() { sgtl5000.dacVolume(1.0); sgtl5000.unmuteHeadphone(); sgtl5000.unmuteLineout(); - sgtl5000.volume(0.8,0.8); // Headphone volume + sgtl5000.volume(0.8, 0.8); // Headphone volume sgtl5000.audioProcessorDisable(); sgtl5000.autoVolumeDisable(); sgtl5000.surroundSoundDisable(); sgtl5000.enhanceBassDisable(); - delayExt1.delay(0,333); - delayExt1.delay(1,664); - delayExt1.delay(2,1000); + delayExt1.delay(0, 333); + delayExt1.delay(1, 664); + delayExt1.delay(2, 1000); sine1.amplitude(1.0); sine1.frequency(440); sine1.phase(0.0); - mixer1.gain(0,0.5); - mixer1.gain(1,1.0); + mixer1.gain(0, 0.5); + mixer1.gain(1, 1.0); amp1.gain(1.0); Serial.println(""); diff --git a/third-party/effect_delay_ext8/src/effect_delay_ext8.cpp b/third-party/effect_delay_ext8/src/effect_delay_ext8.cpp index c5b3140..1e1b573 100644 --- a/third-party/effect_delay_ext8/src/effect_delay_ext8.cpp +++ b/third-party/effect_delay_ext8/src/effect_delay_ext8.cpp @@ -24,51 +24,10 @@ * THE SOFTWARE. */ -/* Added AUDIO_MEMORY_PSRAM_8MB - * see https://forum.pjrc.com/threads/29276-Limits-of-delay-effect-in-audio-library/page5?highlight=APS6404L-3SQR - * wirtz@parasitstudio.de - */ #include +#include "extmem.h" #include "effect_delay_ext8.h" -//#define INTERNAL_TEST - -// While 20 MHz (Teensy actually uses 16 MHz in most cases) and even 24 MHz -// have worked well in testing at room temperature with 3.3V power, to fully -// meet all the worst case timing specs, the SPI clock low time would need -// to be 40ns (12.5 MHz clock) for the single chip case and 51ns (9.8 MHz -// clock) for the 6-chip memoryboard with 74LCX126 buffers. -// -// Timing analysis and info is here: -// https://forum.pjrc.com/threads/29276-Limits-of-delay-effect-in-audio-library?p=97506&viewfull=1#post97506 -#define SPISETTING SPISettings(20000000, MSBFIRST, SPI_MODE0) - -// Use these with the audio adaptor board (should be adjustable by the user...) -//#define SPIRAM_MOSI_PIN 7 -//#define SPIRAM_MISO_PIN 12 -//#define SPIRAM_SCK_PIN 14 - -//#define SPIRAM_CS_PIN 6 - -//#define SPIRAM_MOSI_PIN 11 //----------------- -//#define SPIRAM_MISO_PIN 12 // for Teensy 4.1 audio board -//#define SPIRAM_SCK_PIN 13 // -//#define SPIRAM_CS_PIN 36 //----------------- - // -#define SPIRAM_MOSI_PIN 50 //----------------- https://forum.pjrc.com/attachment.php?attachmentid=20853&d=1593888859 -#define SPIRAM_MISO_PIN 54 // for Teensy 4.1 -#define SPIRAM_SCK_PIN 49 //----------------- -#define SPIRAM_CS_PIN 52 // CS??? -//#define SPIRAM_CS_PIN 36 // CS0-2 -//#define SPIRAM_CS_PIN 37 // CS0-1 -//#define SPIRAM_CS_PIN 44 // CS2 -//#define SPIRAM_CS_PIN 10 // CS0 -//#define SPIRAM_CS_PIN 0 // CS1 -//#define SPIRAM_CS_PIN 38 // CS1-0 - // -#define MEMBOARD_CS0_PIN 2 -#define MEMBOARD_CS1_PIN 3 -#define MEMBOARD_CS2_PIN 4 void AudioEffectDelayExternal8::update(void) { @@ -77,7 +36,7 @@ void AudioEffectDelayExternal8::update(void) // grab incoming data and put it into the memory block = receiveReadOnly(); - if (memory_type >= AUDIO_MEMORY8_UNDEFINED) { + if (memory_type >= AUDIO_MEMORY_UNDEFINED) { // ignore input and do nothing if undefined memory type release(block); return; @@ -134,189 +93,3 @@ void AudioEffectDelayExternal8::update(void) } } -uint32_t AudioEffectDelayExternal8::allocated[2] = {0, 0}; - -void AudioEffectDelayExternal8::initialize(AudioEffectDelayMemoryType8_t type, uint32_t samples) -{ - uint32_t memsize, avail; - - activemask = 0; - head_offset = 0; - memory_type = type; - - SPI.setMOSI(SPIRAM_MOSI_PIN); - SPI.setMISO(SPIRAM_MISO_PIN); - SPI.setSCK(SPIRAM_SCK_PIN); - SPI.setCS(SPIRAM_CS_PIN); // added for Teensy 4.1 - // - SPI.begin(); - - if (type == AUDIO_MEMORY8_23LC1024) { -#ifdef INTERNAL_TEST - memsize = 8000; -#else - memsize = 65536; -#endif - pinMode(SPIRAM_CS_PIN, OUTPUT); - digitalWriteFast(SPIRAM_CS_PIN, HIGH); - } else if (type == AUDIO_MEMORY8_MEMORYBOARD) { - memsize = 393216; - pinMode(MEMBOARD_CS0_PIN, OUTPUT); - pinMode(MEMBOARD_CS1_PIN, OUTPUT); - pinMode(MEMBOARD_CS2_PIN, OUTPUT); - digitalWriteFast(MEMBOARD_CS0_PIN, LOW); - digitalWriteFast(MEMBOARD_CS1_PIN, LOW); - digitalWriteFast(MEMBOARD_CS2_PIN, LOW); - } else if (type == AUDIO_MEMORY8_CY15B104) { -#ifdef INTERNAL_TEST - memsize = 8000; -#else - memsize = 262144; -#endif - pinMode(SPIRAM_CS_PIN, OUTPUT); - digitalWriteFast(SPIRAM_CS_PIN, HIGH); - } else if (type == AUDIO_MEMORY8_PSRAM_8MB) { - #ifdef INTERNAL_TEST - memsize = 8000; - #else - memsize = (2^23); // 8388608 bytes - #endif - pinMode(SPIRAM_CS_PIN, OUTPUT); - digitalWriteFast(SPIRAM_CS_PIN, HIGH); - } else { - return; - } - avail = memsize - allocated[type]; - if (avail < AUDIO_BLOCK_SAMPLES*2+1) { - memory_type = AUDIO_MEMORY8_UNDEFINED; - return; - } - if (samples > avail) samples = avail; - memory_begin = allocated[type]; - allocated[type] += samples; - memory_length = samples; - - zero(0, memory_length); -} - - -#ifdef INTERNAL_TEST -static int16_t testmem[8000]; // testing only -#endif - -void AudioEffectDelayExternal8::read(uint32_t offset, uint32_t count, int16_t *data) -{ - uint32_t addr = memory_begin + offset; - -#ifdef INTERNAL_TEST - while (count) { *data++ = testmem[addr++]; count--; } // testing only -#else - if (memory_type == AUDIO_MEMORY8_23LC1024 || - memory_type == AUDIO_MEMORY8_CY15B104 || - memory_type == AUDIO_MEMORY8_PSRAM_8MB) - { - addr *= 2; - SPI.beginTransaction(SPISETTING); - digitalWriteFast(SPIRAM_CS_PIN, LOW); - SPI.transfer16((0x03 << 8) | (addr >> 16)); - SPI.transfer16(addr & 0xFFFF); - while (count) { - *data++ = (int16_t)(SPI.transfer16(0)); - count--; - } - digitalWriteFast(SPIRAM_CS_PIN, HIGH); - SPI.endTransaction(); - } else if (memory_type == AUDIO_MEMORY8_MEMORYBOARD) { - SPI.beginTransaction(SPISETTING); - while (count) { - uint32_t chip = (addr >> 16) + 1; - digitalWriteFast(MEMBOARD_CS0_PIN, chip & 1); - digitalWriteFast(MEMBOARD_CS1_PIN, chip & 2); - digitalWriteFast(MEMBOARD_CS2_PIN, chip & 4); - uint32_t chipaddr = (addr & 0xFFFF) << 1; - SPI.transfer16((0x03 << 8) | (chipaddr >> 16)); - SPI.transfer16(chipaddr & 0xFFFF); - uint32_t num = 0x10000 - (addr & 0xFFFF); - if (num > count) num = count; - count -= num; - addr += num; - do { - *data++ = (int16_t)(SPI.transfer16(0)); - } while (--num > 0); - } - digitalWriteFast(MEMBOARD_CS0_PIN, LOW); - digitalWriteFast(MEMBOARD_CS1_PIN, LOW); - digitalWriteFast(MEMBOARD_CS2_PIN, LOW); - SPI.endTransaction(); - } -#endif -} - -void AudioEffectDelayExternal8::write(uint32_t offset, uint32_t count, const int16_t *data) -{ - uint32_t addr = memory_begin + offset; - -#ifdef INTERNAL_TEST - while (count) { testmem[addr++] = *data++; count--; } // testing only -#else - if (memory_type == AUDIO_MEMORY8_23LC1024 || - memory_type == AUDIO_MEMORY8_PSRAM_8MB ) { - addr *= 2; - SPI.beginTransaction(SPISETTING); - digitalWriteFast(SPIRAM_CS_PIN, LOW); - SPI.transfer16((0x02 << 8) | (addr >> 16)); - SPI.transfer16(addr & 0xFFFF); - while (count) { - int16_t w = 0; - if (data) w = *data++; - SPI.transfer16(w); - count--; - } - digitalWriteFast(SPIRAM_CS_PIN, HIGH); - SPI.endTransaction(); - } else if (memory_type == AUDIO_MEMORY8_CY15B104) { - addr *= 2; - - SPI.beginTransaction(SPISETTING); - digitalWriteFast(SPIRAM_CS_PIN, LOW); - SPI.transfer(0x06); //write-enable before every write - digitalWriteFast(SPIRAM_CS_PIN, HIGH); - asm volatile ("NOP\n NOP\n NOP\n NOP\n NOP\n NOP\n"); - digitalWriteFast(SPIRAM_CS_PIN, LOW); - SPI.transfer16((0x02 << 8) | (addr >> 16)); - SPI.transfer16(addr & 0xFFFF); - while (count) { - int16_t w = 0; - if (data) w = *data++; - SPI.transfer16(w); - count--; - } - digitalWriteFast(SPIRAM_CS_PIN, HIGH); - SPI.endTransaction(); - } else if (memory_type == AUDIO_MEMORY8_MEMORYBOARD) { - SPI.beginTransaction(SPISETTING); - while (count) { - uint32_t chip = (addr >> 16) + 1; - digitalWriteFast(MEMBOARD_CS0_PIN, chip & 1); - digitalWriteFast(MEMBOARD_CS1_PIN, chip & 2); - digitalWriteFast(MEMBOARD_CS2_PIN, chip & 4); - uint32_t chipaddr = (addr & 0xFFFF) << 1; - SPI.transfer16((0x02 << 8) | (chipaddr >> 16)); - SPI.transfer16(chipaddr & 0xFFFF); - uint32_t num = 0x10000 - (addr & 0xFFFF); - if (num > count) num = count; - count -= num; - addr += num; - do { - int16_t w = 0; - if (data) w = *data++; - SPI.transfer16(w); - } while (--num > 0); - } - digitalWriteFast(MEMBOARD_CS0_PIN, LOW); - digitalWriteFast(MEMBOARD_CS1_PIN, LOW); - digitalWriteFast(MEMBOARD_CS2_PIN, LOW); - SPI.endTransaction(); - } -#endif -} diff --git a/third-party/effect_delay_ext8/src/effect_delay_ext8.h b/third-party/effect_delay_ext8/src/effect_delay_ext8.h index d9fb838..553aa18 100644 --- a/third-party/effect_delay_ext8/src/effect_delay_ext8.h +++ b/third-party/effect_delay_ext8/src/effect_delay_ext8.h @@ -23,39 +23,28 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -/* Added AUDIO_MEMORY_PSRAM_8MB - * see https://forum.pjrc.com/threads/29276-Limits-of-delay-effect-in-audio-library/page5?highlight=APS6404L-3SQR - * wirtz@parasitstudio.de - */ #ifndef effect_delay_ext8_h_ #define effect_delay_ext8_h_ #include "Arduino.h" #include "AudioStream.h" #include "spi_interrupt.h" +#include "extmem.h" -enum AudioEffectDelayMemoryType8_t { - AUDIO_MEMORY8_23LC1024 = 0, // 128k x 8 S-RAM - AUDIO_MEMORY8_MEMORYBOARD = 1, - AUDIO_MEMORY8_CY15B104 = 2, // 512k x 8 F-RAM - AUDIO_MEMORY8_PSRAM_8MB = 3, // 8192k x 8 PS-RAM - AUDIO_MEMORY8_UNDEFINED = 4 -}; -class AudioEffectDelayExternal8 : public AudioStream +class AudioEffectDelayExternal8 : public AudioStream, public AudioExtMem { public: - AudioEffectDelayExternal8() : AudioStream(1, inputQueueArray) { - initialize(AUDIO_MEMORY8_23LC1024, 65536); - } - AudioEffectDelayExternal8(AudioEffectDelayMemoryType8_t type, float milliseconds=1e6) - : AudioStream(1, inputQueueArray) { - uint32_t n = (milliseconds*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f; - initialize(type, n); - } - + AudioEffectDelayExternal8(AudioEffectDelayMemoryType_t type, float milliseconds=1e6) + : AudioStream(1, inputQueueArray), + AudioExtMem(type, (milliseconds*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f), + activemask(0) + {} + AudioEffectDelayExternal8() : AudioEffectDelayExternal8(AUDIO_MEMORY_23LC1024) {} + + ~AudioEffectDelayExternal8() {} void delay(uint8_t channel, float milliseconds) { - if (channel >= 8 || memory_type >= AUDIO_MEMORY8_UNDEFINED) return; + if (channel >= 8 || memory_type >= AUDIO_MEMORY_UNDEFINED) return; if (milliseconds < 0.0f) milliseconds = 0.0f; uint32_t n = (milliseconds*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f; n += AUDIO_BLOCK_SAMPLES; @@ -63,30 +52,19 @@ public: n = memory_length - AUDIO_BLOCK_SAMPLES; delay_length[channel] = n; uint8_t mask = activemask; - if (activemask == 0) AudioStartUsingSPI(); + if (activemask == 0 && IS_SPI_TYPE) AudioStartUsingSPI(); activemask = mask | (1<= 8) return; uint8_t mask = activemask & ~(1<