Variable sample rate audio delay with external memory (parallel or serial)

Status
Not open for further replies.
Hi. I'm on a project to recreate a classic vintage digital audio delay that used a 12-bit hardware architecture with a variable clock for sample rate and (for that time) a large RAM. True to the original, there's no dsp involved. Or allowed actually.

My idea is to use a stable voltage-controlled oscillator to drive interrupt at a rate of approx. 10 kHz to 60 kHz. In the interrupt routine, the processor has to capture one 12-bit sample, write that to a 256k word memory, then add an offset to the current memory index and read one sample that is output to the dac, and finally increment the index counter addressing the external memory.

The idle loop has a light load, managing a 4-digit display and other housekeeping.

Basically, I'm using the microcontroller to replace a mess of TTL counters and adders, A/D and D/A converter, and an 8-bit microcontroller in the original 1980 design.

Does this sound to you like something that can work? I am thinking that parallel memory will be preferred here in consideration of relatively tight time in the ISR.

Thanks!
 
If you could live without variable samplerates, the easiest ist to use the audiolibrary + teensy-audioboard. Its 16 bits, but you could set 4 bits to zero... :)
This board has solderpads too, where you could place serial ram (20 MHz)
 
If you could live without variable samplerates, the easiest ist to use the audiolibrary + teensy-audioboard. Its 16 bits, but you could set 4 bits to zero... :)
This board has solderpads too, where you could place serial ram (20 MHz)

I'm afraid not. Variable sample rate (not resampling by dsp) is integral to this project. The conventional architecture of audio fx won't do the job here.

The challenge here is to make a faithful (but more compact and economical) re-creation of a classic device that is still in demand by professionals that uses an architecture quite different from today's norm.

Thanks for your reply, though. I hope someone here can address my question as stated.
 
The audio shield and library will have a hard time with variable sample rate.

For a simple delay, mono, and 12 bit resolution it could work with the Teensy onboard 3.1 AD and DA
They can be triggered by a clock with variable frequency.
For 256ksample memory a handful (3 or 4) of spi SRAM chips like Microchip Technology 23LC1024-I/P could be used.

At every sample two bytes must be read and two bytes written, using dma and larger larger blocks these transfers can be
scheduled to occur between samples and done with very little processor overhead. So that next sample will be in memory when needed.
 
Last edited:
Thanks. It's interesting but not really relevant.

well, sorry. i probably don't understand the question or the requirements for variable sample rate. though that's probably not relevant either then ... fwiw, when toying around with naive DDS, writing 8 linearly interpolated sine oscs to an 8 channel SPI DAC, the best i managed would be ~ 60kHz sample rate (that's using the PIT timer, not an external interrupt). so i would imagine it should be possible to capture a sample, write that to some external memory, etc.
 
well, sorry. i probably don't understand the question or the requirements for variable sample rate. though that's probably not relevant either then ... fwiw, when toying around with naive DDS, writing 8 linearly interpolated sine oscs to an 8 channel SPI DAC, the best i managed would be ~ 60kHz sample rate (that's using the PIT timer, not an external interrupt). so i would imagine it should be possible to capture a sample, write that to some external memory, etc.

No worries, mxxx. It's just that I have a particular targeted application a little off the main stream. There's lots of adventures to be had with the wonderful tools at our disposal these days.
 
No worries, mxxx. It's just that I have a particular targeted application a little off the main stream. There's lots of adventures to be had with the wonderful tools at our disposal these days.

i gathered that much. i mainly brought up the PIC/SDRAM thing because it's the only recent non-fixed rate thing i've seen, well audio/DIY, that is.

anyways, and out of curiosity ... what kind of parallel memory did you have in mind? i haven't seen a lot of modules using any sort of extra RAM; except the rebel tech owl, which is using some 44 pin package (ISSI) though, which i don't think even could be connected to a teensy. those little SPI RAMs, as mlu suggests?

also .. so how is the orgone accumulator relevant in this context? because it shows lots of stuff can be going on in the ISR?
 
My idea is to use a stable voltage-controlled oscillator to drive interrupt at a rate of approx. 10 kHz to 60 kHz. In the interrupt routine, the processor has to capture one 12-bit sample, write that to a 256k word memory, then add an offset to the current memory index and read one sample that is output to the dac, and finally increment the index counter addressing the external memory.

Ok, that sounds pretty straight-forward. You can use attachInterrupt(), which has some overhead before it jumps to your interrupt code, or configure the hardware and use attachInterruptVector() to get your interrupt routine run directly with no extra overhead. Of course, your external VCO will need to output a 3V logic signal, so if it's an analog circuit with something like a sine wave, plan on a fast comparator to shape the waveform to a well-formed 3V digital logic signal.

60 kHz gives you 16.6 us to get all this work done. Perhaps you'll start the ADC conversion at the end of each interrupt and read it at the beginning of the next? That'd avoid a wait for the ADC, which should help meet the 16 us goal. This will add 1 extra sample delay, which you could easily compensate by adjusting your RAM read position by 1 location, if just 1 extra cycle delay matters.

You'll need to connect a 384 kbyte memory. Those little 23LC1024 chips are the simplest, at least in terms of the number of wires. In theory you could use 3 chips, but 4 may be simpler, treating each word as 16 bits, so you won't need to read-modify-write. Reading or writing 2 bytes takes 6 bytes on the SPI (1 command, 3 address, 2 data). If you run the SPI at 12 Mbit/sec (a conservatively slow speed), 6 bytes takes approx 4 microseconds. Writing 2 bytes and reading 2 bytes should take half of your 16 us timing budget.

If the ADC has already completed the conversion, reading the result and starting it converting again should take very little time. Likewise, writing to the DAC pin is very quick. Interrupt entry and exit should cost less than 1 us.

If you needed to run a lot faster than 60 kHz, you'd probably have to connect a parallel interface RAM chip. But with such a slow sample rate, the SPI RAM chips should work fine.
 
The particular RAM I'm looking at is the Cypress Cy62147EV3. 4Mb and it's cost on Mouser is less than the equivalent in SPI RAM I've looked at.
It should be able to connect direct to Teensy provided you don't need all 16 bits.

I'd like to get back to discussions to illuminate the particular commercial (NOT DIY or hobbyist) project I'm engaged in now, of which continuously variable sample rate is the absolute heart and soul. I do know what I need to build here. It's my career not a hobby, and I have long experience and a reputation to go on. If it doesn't illuminate my immediate problem, let's please take it elsewhere. Thanks.
 
Another idea you might explore might involve processing 2 samples at the same time, with temporary storage in Teensy's RAM.

So on every odd-numbered interrupt, you'd write a pair of samples to RAM, where one of them would be the sample from the prior even-numbered interrupt which you temporarily store in a variable on Teensy.

On every even-numbered interrupt, you'd read a pair from RAM and store one of them into a variable on Teensy, to be written to the DAC on the next odd-numbered interrupt.

This approach would let you more easily pack pairs of samples together into 3 consecutive bytes in the RAM. It also would mean each interrupt could make a single access to the RAM, which costs 7 bytes on the SPI bus (1 command, 3 address, 3 data). That costs only 4.7 us at 12 MHz SPI clock.

You will have to deal with the fact that those little RAM chips aren't an exact multiple of 3 bytes. If you don't use the last couple bytes in each chip, and you need to have *exactly* 256K sample delay, perhaps you can make up the extra couple samples delay by using a few extra variables or a small array inside Teensy?
 
Ok, that sounds pretty straight-forward. You can use attachInterrupt(), which has some overhead before it jumps to your interrupt code, or configure the hardware and use attachInterruptVector() to get your interrupt routine run directly with no extra overhead. Of course, your external VCO will need to output a 3V logic signal, so if it's an analog circuit with something like a sine wave, plan on a fast comparator to shape the waveform to a well-formed 3V digital logic signal.

60 kHz gives you 16.6 us to get all this work done. Perhaps you'll start the ADC conversion at the end of each interrupt and read it at the beginning of the next? That'd avoid a wait for the ADC, which should help meet the 16 us goal. This will add 1 extra sample delay, which you could easily compensate by adjusting your RAM read position by 1 location, if just 1 extra cycle delay matters.

You'll need to connect a 384 kbyte memory. Those little 23LC1024 chips are the simplest, at least in terms of the number of wires. In theory you could use 3 chips, but 4 may be simpler, treating each word as 16 bits, so you won't need to read-modify-write. Reading or writing 2 bytes takes 6 bytes on the SPI (1 command, 3 address, 2 data). If you run the SPI at 12 Mbit/sec (a conservatively slow speed), 6 bytes takes approx 4 microseconds. Writing 2 bytes and reading 2 bytes should take half of your 16 us timing budget.

If the ADC has already completed the conversion, reading the result and starting it converting again should take very little time. Likewise, writing to the DAC pin is very quick. Interrupt entry and exit should cost less than 1 us.

If you needed to run a lot faster than 60 kHz, you'd probably have to connect a parallel interface RAM chip. But with such a slow sample rate, the SPI RAM chips should work fine.

Thanks, Paul. This is very on point.
 
I'd like to get back to discussions to illuminate the particular commercial (NOT DIY or hobbyist) project I'm engaged in now, of which continuously variable sample rate is the absolute heart and soul. I do know what I need to build here.

Well, ok Gary. You started this discussion and we've replied with lots of ideas.

If you already knew what you needed to build and didn't want to hear anything, why bother asking?
 
Thanks, Paul. This is very on point.

I'm not sure that starting conversion at end of the ISR buys me anything, since at 60+ khz the next interrrupt would immediately follow the previous. But something I don't get is why are we focusing on SPI RAM? A single parallel 4Mb SRAM today is cheaper than a handful of SPI. So what's the point? It seems like an attempt to force-fit a technology where it's not actually appropriate or necessary.

This is a great discusssion. However I live in Thailand and it's well after midnight here. I'm going to have to call it a day and follow up tomorrow. Thank you, everyone!
 
Well, ok Gary. You started this discussion and we've replied with lots of ideas.

If you already knew what you needed to build and didn't want to hear anything, why bother asking?

Sorry, Paull. Actually, your stream of very relevant comments followed some that were not some much and came while I was addressing those. Many thanks!
 
It's a very interesting point about the difference between attachInterrupt() and attachInterruptVector(). I need to look into that.

Peace,
Gary
 
Yes 4Mbit parallel SRAM are cheap, and comes with 19 address lines, 8 data lines and a couple of read and write strobes. Finding pins on the Teensy 3.1 to drive that will not be easy, of course you can add a couple of address and data multiplexers to drive the SRAM, and some code to manage all of that. Wont be very fast anymore, and not as cheap.

Thats the reason for a bit of talk about serial SRAM's.
 
I do know what I need to build here. It's my career not a hobby, and I have long experience and a reputation to go on. If it doesn't illuminate my immediate problem, let's please take it elsewhere. Thanks.


Sorry, but with your great experience a question like "Does this sound to you like something that can work?" sounds a bit...

But it's nice that you ask hobbyists in this hobby-forum, and you want to use hobbyists hard-and software.
It would be really much easier to help if we knew WHAT exactly you want know, in DETAIL :)
Show us your schematic and sourcecode - then, we can help better...

60KHz is not too much, not even for SPI. SPI wants less pins. But you know that.

Your statement, that sampling at the end of the interrupt does not help is WRONG. You forget that you don't have to wait (or wait less time) for the end of the conversion, this way.
But, ok, you're the expert...


Since this seems to be a commercial project, i really hope you're respecting the arduino- and library licences.
 
Last edited:
Status
Not open for further replies.
Back
Top