Page 1 of 4

hi-fi ish looper

Posted: Wed Apr 04, 2012 6:57 pm
by cloudscapes
work-in-progress. already posted on DIY stomp, but maybe I'll do the same here. a whole lot of discussion going on in original thread too, but I guess I can update here as I go along.

*****************************************************

I thought I'd try something. For years I've wanted to build my dream looper. When I first started DIY stompboxes and noise-generators 6-ish years ago, I never in my right mind would I have guessed I'd be doing projects at the complexity I am now! And original ones at that! But still, these last few years, I've been gearing up (mentally) to tackle something huge (to my eyes). Looping is not only an important part of my music, but the ability to manipulate loops on the fly as well. I've tried many loopers. While many were excellent, they all lacked something another had that I thought was fantastic! So here I am now, thinking about how to combine those very best features and add a few of my own.

And I thought I'd start a thread about it, and log it as I make progress. :)

I've only just started, and there will be many firsts for me in this project as well, so I'll try and keep it informative. How I made certain decisions and not others.There isn't a whole lot of information out there when it comes to non-ISD based loopers. Maybe this thread will contribute in some tiny bit. A reference of things that come up for such a project, to others. A mixture of technical and laypersons theory, and I will try and keep the theory to a maximum! But mostly, it will be a curiosity! It will also be a learning experience. I don't claim to be an expert, and I will make mistakes and errors in judgment. I'm learning as I go along with this ambitious project.

So really, what do I want?

- Hi-fi. 16bit 44khz is my goal.
- Variable fidelity/sampling rate for stepless time/pitch effects.
- Overdub with variable feedback. No question.
- Resonant LP / HP filter, and an automatic antialiasing filter
- Complete mixer to be able to mix from selectable inputs
- Same-pitch time stretching
- Automatic & manual "scrubbing"
- Ping-pong scrubbing, or "freeze" effects
- Reverse
- Loop cropping / trimming. Defining start-end loop points in realtime.
- Modulation
- Clickless seams


Will not do / not smart enough to do:

- Undo
- SD card storage
- Multitrack or stereo
- BPM or time-sensitive quantization


What have I done so far:

A simple breadboarded setup that can pass 12bit audio at around 100khz!  ;D It doesn't do anything but pass audio, no recording or feature whatsoever. Just raw analog-to-digital conversion and back again. I'm concentrating on getting simple audio right before I do any sort of recording, playback, logic or feature.

What I'm using so far:

I've started using MikroC, which is a C compiler for various microcontrollers. This is a very big step for me. Up 'till now, I had been using 8-bit AVRs and Bascom. While great for LFOs, presets and automation, they simply don't have the horsepower to do anything but telephone-quality audio. I've experimented quite a bit with audio on them, but I don't know assembly, so wasn't hitting good samplerates. What I made were fun little glitchy noise boxes that sample and loop, but in no way were they going to satisfy my looping needs. Bascom (basic) only supports AVRs, so I need to learn a new environment, and while I'm at it, language. A common language like C opens up future possibilities for other platforms as well, unlike Basic. So now, I learn. I'm still very much at the beginning of the language fundamentals of C.

Another new thing for me will be heavy use of surfacemount packages. I've done a few before, but with AVRs and most pedal builds, it wasn't really needed. With high-speed audio and data, it will be needed, and often in tiny pitch (0.5mm). I'm considering buying a cheap stereo microscope to aid me in this and other projects.

Image

CPU:

A PIC32 board from Mikroelectronica. A little expensive but it's in an easy to use footprint on a DIP40 stamp and packs a punch! The chip on it is 32bit and clocks at 80MHz.

Digital-to-analog:

A PT8211 16bit DAC. Same company who make our beloved 2399 delay ic! Easily found for cheap (2 bucks a chip on ebay) and in an easy to use package (DIP8 or SOIC8), and specced to deliver better than CD-quality sound. I've tested it, it sounds good, it's cheap, it's fast, it works, I'm set!

Analog-to-digital:

Currently an MCP3201. It's easy to find and cheap, but is "only" 12bit and is quite slow. I can get decent samplerates with it, but data/SPI transfer isn't fast at all, so it doesn't leave the CPU much free time to do logic. I'm using it at the moment because I know it and I had some at hand. Must find something else. I've orded a couple LTC1864 which is, according to the datasheet, an extremely fast 16bit ADC in a nice SOIC8 package! Pretty expensive though, at $14 each. According to how hard my PIC32 is currently chugging, and if my math is right, I will be able to get 200khz sampling speeds at 16bit, just raw audio pass-through! That should leave my PIC32 with tons of time to perform logic and whatnot if I'm aiming for 44khz!

RAM:

This was the hard one. I've made some calculations. How much looping time do I want? Well, 10 seconds is a nice round number! Lessee..

- 1 sample at 16bit uses up two bytes.
- At 44khz, 44000-ish samples per second, one second uses up 88000 bytes, or 88KB.
- 10 seconds needs 880KB, or 1MB if we're rounding up for easy findability.


I've used Microchips 23k256 RAM ics a few times. They are in nice DIP8 packages, use fast and easy SPI communication, but they are only 32KB. Forget it. So I hop onto Mouser and Digikey to see what my RAM options are. This takes several days of reading datasheets and measuring options, actually. I have to filter out anythign that comes in BGA. So, a few kinds of RAM:

- FRAM. SPI communication, fast, easy package, but still small storage quantity
at 128KB and costs a leg at $28 for that little amount. Scratch that.

- Parallel RAM. Cheap-ish, common, easy to understand, VERY fast as its parallel
instead of serial com, but uses a ton of pins. 8 data pins + 20 address pins + 2-3
extra. I need over 30 free pins on my CPU! If I was using a large PIC32, I could do that,
but I'm not. I'm using a 64-pin micro on a 40-pin stamp, and not all of those 40 pins are
the right "kind". Also, I don't want the headache of routing the PCB for all those traces.
Still... parallel RAM is the de facto standard when it comes to consumer audio looping
and sampling at high-speed. Better order a couple, in case.

- Flash memory. Cheap, easy to use, nice packages, but a little slow, and limited write
cycles. 100,000 or so. If I'd be using this as a traditional looper, that might be enough,
but I have to plan for the time where I set the loop-trimming to 5 milliseconds and hit
record. There, I just burnt through 10% of the chips available rewrites in a second! ;D
Scratch that.

- MRAM. Specifically MR25H40. Hmm... doesn't seem to be a common type of memory.
But oooOOOHH! Look at these specs! Lightning-fast SPI com, zero read/write time, infinite
rewrites, and available as a 512KB! $14 is a bit pricey, but I'm willing to spend that much
if I only have to use one or two of them in the project! But... wait.... ohhhh
effffffffffffffffffffffffffffffff..................................

DFN package. That's nearly as bad as BGA.It's like... THERE ARE NO PINS! The pins are tiny little exposed metal UNDER the 8-pin square. Anyways, I order a couple, ball a bit of solder directly on the "pads", tin a SOIC-to-DIP adapter's pads (same footprint), and melt the balled-DFN onto the tinned adapter. It seems to have worked. Okay, I can do this. The specs make it worth it! Oooohh, data retention under no power even!

Speed test:

I have the digital oscilloscope (a cheap 25mhz Owon) hooked up to the circuit. The red lines represent the SPI clock hooked up to the slow 12bit ADC. The yellow lines are the clock on the fast DAC and MRAM. The green line I added represents a single sample. It represents an elapsed time of almost 30us. That's 30 millionths of a second! That's a short amount of time to us humans, but to a 32bit 80MHz microcontroller, a lot can be done in that amount of time. Here is how many millionths of a second my PIC32 hs to work with for each sample:

- 44khz = 23us per sample
- 33khz = 30us per sample
- 22khz = 45us per sample


Considering that, at the time I took this picture, I guess it was sampling at about 35khz, which in all honesty to my ears, sounds mostly fine.

Image

The two large red blocks represent 8 clock pulses (for a total of 16, which is what the ADC needs to sample a single 12bits). They're just tight together which is why they look like one single huge pulse. The yellow represent the SPI clock hooked up to the much much faster 16bit DAC and MRAM ic! All 8 of the yellow lines have 8 little clock pulses of their own. Just so much more tightly together they appear as a single line! The first two of those blocks (16 pulses) are for the fast 16bit DAC, and the other 6 (48 pulses) for the MRAM.Once I get my new fast ADC, those two large red blocks will shrink to the size of the tiny yellow ones, and the PIC32 will have much more free time for logic/features, and/or will be able to achieve even higher samplerates!

I can measure how long it takes to read or write to the MRAM, about 4us, how long it takes to output to the DAC, 2us, and how long it currently takes to sample from the ADC, 8us.

It's half past midnight so I'll stop now. In a day or three, I'll write about why I chose to use a seperate ADC and DAC rather than use an audio codec chip, which is what's comonly used. Also, what I've learned about antialias filtering! Also, I'll fill in some links to stuff.

****************

Testing new parts:

As I've said, this project has a lot of new things for me! New kinds of fast parts, a new language and environment, a brand new type of microcontroller. I didn't just plug new parts together and hoped I could get it working!  ;)

I know AVRs (8bit micros) fairly well, so when I purchased the new MRAM and 16bit DAC, I hooked those up to the AVR instead to see if I knew how to use them, figure out the routines, data order, control bits, etc. It made debugging and discovering a new part FAR easier. There were issues, but I could remove the AVR from the equation because I knew how to use these. Once I had a set of rules on how to use my new ics, I could move on to the new language and PIC32 and "translate" those rules. The AVR is far far too slow for decent audio.

Inspiration:

Looping is my main part of my solo sets. I use loopers as instruments if at all possible, and not just as stomp-and-forget boxes. I've used so many, and sold them after a while. I did keep four of them, though! And they're kind of my main inspiration for this project, feature-wise.

- Timefactor. Awesome looper! Has loop cropping/trimming and is pretty flexible! Wish they would of gone the extra mile with the crazy features, though!

- Stereo Memory Man / Hazarai. My simple workhorse looper when I don't need something complex. I like the filter on it and how fast one can lay down a loop.

- 2880. Not too many crazy features, but the UI design is something I admire! I think I prefer the tabletop format. I wish I could make mine multitrack, but for the moment, best focus on a single track.

- PDS-8000. Just love it!


Separate ADC / DAC vs codec IC:

I think a standard for these types of applications is a dedacated codec IC which incorporates ADC/DAC as well as audio-optimized filtering and stuff. I know my 2880 uses one of the Texas Instrument ones, maybe the PCM3001 (from memory), and I've seen them in a lot of other products where audio quality was important. They're an "all-in-one" audio solution to be connected to a microcontroller or CPU, which only handles the thinking. They're generally not too expensive, and have a lot of built-in audio features that normally I'd need a lot of external components for, but I chose not to go this route for one reason. They also all require a secondary clock that's hundreds of times higher frequency than the SPI/data transfer clock.

An SPI clock is a clock signal that drives the "engine" of a part to deliver or recieve data in that specific timing. This can be a variable speed, but is usually multiples of two. Some parts can send/recieve data to and from the PIC32  very quickly, while others require a slower clock running parallel to the data stream. Codecs are a bit more difficult, as they require a secondary clock that's exactly 256 or 512 times the samplerate (well into the MHz), and it has to be in sync with the SPI clock at all times! The SPI clock has to scale along with the samplerate, and that I simply can't do. I've read about it, and it's way way over my head. There are strict rules in place when it comes to codec timing and control. Maybe someday I will get familiar enough with this language and environment that I'll be able to use a codec, but at the moment, I'd rather find another way. Separate ADC and DAC it is. They are much "looser" in terms of these kinds of things, and are operated simply by SPI which I know pretty well. No additional clock required. No strict scaling of the SPI clock relative to the samplerate.

Using an ADC/DAC combo over a codec however brigns on another challenge. Antialias filtering. A codec IC wwhen properly controlled will filter the sample "stepping" in digital audio and will adjust the filter according to your samplerate. This is very helpful to have in a single chip! But since I'm going to be using an ADC/DAC combo, I'll have to devise external fitlering to get rid of the jaggies, and I'll need to sweep the filter when I tune the loop down to a slower speed. I'll probably end up using a MAX7404 ic which is a filter-on-a-chip controllable by either capacitor or clock input. If I use a clock, it won't have to be scaled perfectly with the SPI clock or samplerate. I can just wing it, use my ear. Much easier! More on that AA filter some other time.

Using an ADC/DAC combo vs a codec is moves much of the work involved from programming in the new environment (not my strength), over to external components and "winging it". Fine with me!

Display:

I'm gonna need some sort of visual feedback, though I haven't figured out what I want yet. An LCD would be nice, but I don't yet know how to cut squares in metal.

Controls (so far)

Here are the controls and features I will be trying to implement. The how's are mostly already clear.


Knob –Speed (PIC32)
Knob –Forward/freeze/reverse (555)
Knob –Freeze granularity (555)
Knob –Start point (PIC32)
Knob –End point (PIC32)
Knob –Drift (PIC32)

Knob –Filter cutoff (analog)
Knob –Filter resonance (analog)
Toggle –Filter post/pre feedback (analog)

Knob –Modulation speed (AVR)
Knob –Modulation depth (AVR)

Knob –Feedback
Knob –Input gain
Knob –Wet
Knob -Dry

Button –Record/play
Button –Bypass/erase


The stuff in brackets is how its gonna be done. PIC32 means the pot will be directly connected to the micro and will be handled in code. Analog means just that, and AVR means I have a little 8pin modulation AVR I like to use for these kinds of thing. It’ll PWM a push and pull into the Speed pot’s ADC.

The Forward/freeze/reverse and freeze granularity is what I think I’m most excited about. Here’s how:

Forward / freeze / reverse

Nearly all (or all) loopers I know of manage reverse in one way. A button, or a toggle switch. Off it goes forward, on it goes in reverse. I want something a bit more special than that. I want a knob that has totally variable states between:

- full speed forward
- slower speed forward (no pitch change)
- very slow forward (still no pitch change)
- freeze
- very slow reverse  (still no pitch change)
- slow speed reverse (etc..)
- full speed reverse


Here’s how I’m gonna do it. The PIC32 will have a digital input pin. Low pin is forward, high pin is backwards. Then I attach a 555 with controllable speed and PWM! This image is a representation of the PWM signal to be generated by the 555 and fed into the PIC32 forward/reverse toggle pin.

Image

Each segment is a short period of time. For the sake of the argument, lets say 5 milliseconds. On full forward, there are no pulses, just a low signal. The PIC32 interprets that as forward playback.

Turn the pot a bit and the 555 generates a little duty cycle. In this example, 25%. The PIC32 interprets that as mostly forward playback, with 25% rewind. Since this is done very quickly, every couple of milliseconds, our ears and brains will interpret that as “slower speed”, and it will preserve the pitch.

If the pot is in the center, then the forward and reverse duty cycle are the same, and a “freeze” is achieved. Turn it even more, and the reverse state is longer than the forward state and so you start to go back in time. An additional potentiometer can be

This is not a “perfect” method of pitch-preserving time stretching. That would probably involve blending microsamples and advanced DSP stuff that I’m no where near ready to try. This is a hack, but it works! I’ve tried it on an AVR sampler a year and a half ago. This time, it’ll be fine-tuned and hi-fi.

Crossfade

Another thing I want to implement is some kind of realtime crossfade at the loop point. Not an audible one, though. Just enough to get rid of the nastiest of the pop/click at loop point. Say 100 samples worth. How I incision doing this:

As soon as a new loop recording is done, all samples are saved but the actual played loop will be 100 samples shorter. Only a couple milliseconds worth, it won't make a difference to the ear. As the loop playback hits (total loop length - 100), it adds (first of extra samples / 100), to the current one and divides the result again by 1.5 or 2 (I'll have to experiment with that whether I want a linear crossfade or log). The next sample adds a little bit more of the second of extra samples. And so on. Not the most efficient of algorithms so I'll figure something better out. But that's the gist of it.

It'll be realtime and not "cooked" into the saved samples, because I want to be able to move the loop point around dynamically.

Re: hi-fi ish looper

Posted: Wed Apr 04, 2012 7:00 pm
by cloudscapes
And an update on the original post, I'm now passing full 16bit audio at 66khz with plenty of clock cycles to spare

Re: hi-fi ish looper

Posted: Wed Apr 04, 2012 7:16 pm
by kbit
Reading through this made me think of the "face mash" scene in The Social Network.
While I don't understand a lot of the technicalities, I'm definitely very intrigued by this.

I saw in your example of of RAM size you mentioned 10 seconds of loop time; is that how much maximum time you're aiming for or was that just an example?

Re: hi-fi ish looper

Posted: Wed Apr 04, 2012 7:19 pm
by Dr. Sherman Sticks M.D.
:love: :love: :love:

this sounds really awesome man.

similar to u, most of the loopers i've tried did not entirely do it for me, and i always wished i could meld all the awesome features together into one.

the start/end points remind me of the mark button on the roland sp's, which is a dope feature, but the sp is not at all a live looper.

my looper of choice right now is my monome and a max patch called mash. its the closest i've come to simple yet abound with useful features.

i'm really diggin alot of the ideas u are putting forth. i think i would definately have to scoop one of these when the time comes.

Re: hi-fi ish looper

Posted: Thu Apr 05, 2012 1:11 am
by Fuzz_Pi
I am in need of a good looper...

Good luck with this man, way beyond me

Re: hi-fi ish looper

Posted: Thu Apr 05, 2012 2:27 am
by multi_s
looks pretty slick

Codecs are a bit more difficult, as they require a secondary clock that's exactly 256 or 512 times the samplerate (well into the MHz), and it has to be in sync with the SPI clock at all times! The SPI clock has to scale along with the samplerate, and that I simply can't do. I've read about it, and it's way way over my head. There are strict rules in place when it comes to codec timing and control. Maybe someday I will get familiar enough with this language and environment that I'll be able to use a codec, but at the moment, I'd rather find another way. Separate ADC and DAC it is. They are much "looser" in terms of these kinds of things, and are operated simply by SPI which I know pretty well. No additional clock required. No strict scaling of the SPI clock relative to the samplerate.


just a heads up regarding codecs if you go there in the future: the SPI or I2C or whatever method you use for control/functional setup does not have to be synchronized with the master clock for the audio signal, or any of the signals related to the digital audio. They are totally separate. On decent codecs you can directly attach a crystal to the codec and then set the codec as the master clock for audio so you dont have to generate any crazy fast clocks off the pic and all the audio clock synchronization is done automatically by the codec. Some really cheap codecs do not have this crystal/I2S master option (mostly seems like NXP doesnt do that but wolfson and TI for example do for the most part). The device becomes an SPI slave but an I2S master.

I am pretty sure all the PIC dev boards that have codecs on them use wolfson codecs so if you ever decide to try using a codec i presume somewhere on line you can likely find software libraries by microchip to interface PIC32/dsPIC33 with them without necessarily having to figure out how the hell I2S works or to use as an example when learning.


As for the 555 why not do it all in software?

Say you have a 10 bit adc... sample the ADC value into some variable 'myPot' which will be in between 0 and 1023. Have another variable in your code called 'myCount' that starts at 0 when you turn the device on and increments at each sample played. if 'myCount' is ever greater than 1023, reset it to zero. Now its easy, if 'myCount' is less than 'myPot', play backwards, if 'myCount' is greater than 'myPot' play forwards.

saves a chip but i guess it consumes an ADC channel?

good luck.

Re: hi-fi ish looper

Posted: Thu Apr 05, 2012 9:05 am
by cloudscapes
(test to see if I can post from work)

Re: hi-fi ish looper

Posted: Thu Apr 05, 2012 9:22 am
by cloudscapes
hey man!

I'd been getting conflicting information regarding codec use off of various forums. and the datasheets go into great detail but often omit really simple theory, "for babies", you know. ;) I need the "for babies" datasheets when it comes to codecs.

I've looked a bit at codec examples for pic32's that have the i2s protocol, it's all been buffered or frame mode spi so far! if I understand correctly, frame mode is input/output in batches of 256 or 512 or whatever, and at the end of the frame move the data off the codec or DMA or something and into your program. I don't think I can do that. I have trouble wrapping my head around the "gap" between a collection of samples and my program. I've got a mindset of *get sample*, *is in program*, *get next sample*, etc.

I prefer the brute force approach, and so far my program is doing exactly that. an interrupt at the samplerate I want, and each time a single sample is taken, the dac is written to and ram is overwritten. I'm not saying it's the best way (far from it), but it's a way I understand. :(

with a crystal on the codec and as a master clock, wouldn't that mean it would be a fixed samplerate? I need a variable samplerate and a filter that scales with it (the codec's filter cotuff is driven by the master clock). right now, with my ADC/DAC setup, I'm ranging it between 66khz and 1khz.

the 555 is because I'm lazy. if I can replace a whole bunch of code and wasted clock cycles with a single 8 pin ic and a couple passives, I probably will. the priority for the pic32 is speed, so the less code I use, the better. again, I might not be thinking this through correctly. this project is also a learning excersise.

I may actually do the speed/rate modulation in code, though! compared to what the forward/reverse modulation would need, I think it would be much lighter on this chip. an update only every 10ms or so. I've already got a 10ms interrupt for pot input and whatnot.

I still haven't totally dismissed the use of codecs yet. I just have crazy requirements (variable samplerate, word mdoe instead of framed mode) and a low skill level that make their use difficult.

Re: hi-fi ish looper

Posted: Thu Apr 05, 2012 1:52 pm
by multi_s
cloudscapes wrote:I'd been getting conflicting information regarding codec use off of various forums. and the datasheets go into great detail but often omit really simple theory, "for babies", you know. ;) I need the "for babies" datasheets when it comes to codecs.


yep i found this too. i basically figured it out by researching I2S on wikipedia and looking at app notes from TI, not by using CODEC spec sheets specifically. Somewhere on one of the dspic33 data sheets there is an OK explanation of how to actually do it but I found that it took several reads before i was able to do anything that wasnt exactly the setup they provided. I think it is maybe in the GP80X one, or any of the models that include the 'DCI' module peripheral.

IIRC if you DONT use DMA there is still a small peripheral buffer on this DCI module. Similar to how when you sample from an ADC it goes into ADCBUFX if you are not using DMA. So it is possible to use a CODEC without any fancy pantsy shit (one sample at a time) but ya either way it is more complex then your setup and i totally understand your logic in selection.

Achieving variable rate playback witha fixed rate DAC say is pretty easy but again i agree not as easy as just being able to fuck with the hrmmm 'master clock' of the whole sampling system from a programming point of view. If you are trying to learn how to, a good exercise is maybe to make a dsp based chorus/vibrato with a fixed rate sampling/playback. If you can understand how to do that, it is the same principle . From this perspective you dont really need to play with the input cutoff filters, although you are certainly correct that their cutoff is proportional to the master clock on the codec.



cloudscapes wrote:the 555 is because I'm lazy. if I can replace a whole bunch of code and wasted clock cycles with a single 8 pin ic and a couple passives, I probably will. the priority for the pic32 is speed, so the less code I use, the better. again, I might not be thinking this through correctly. this project is also a learning excersise.


not sure 2 if statements is a 'whole bunch' of code but to each thier own.(:

Re: hi-fi ish looper

Posted: Sun Apr 15, 2012 6:58 pm
by cloudscapes
for the moment, I'll still go with the seperate ADC/DAC approach. ordered a couple MAX297 filters which have a max cutoff of 50khz. I can drive them with either a freq*50 clock or with an external cap. I'll use PWM to vary the cap scaled to the frequency just like I did in a much older much lo-fi er avr looper I did.

looper is on haitus for a couple weeks so that I can finish building handfuls of vibratos

Re: hi-fi ish looper

Posted: Mon Apr 16, 2012 2:23 am
by Officer Bukowski
Just thought I'd point out that your new avatar is so far beyond radical I can hardly even believe my eyes.

Re: hi-fi ish looper

Posted: Mon Apr 16, 2012 7:47 am
by cloudscapes
Officer Bukowski wrote:Just thought I'd point out that your new avatar is so far beyond radical I can hardly even believe my eyes.


Image

google image "louis wain" for more. he was a schizophrenic who drew psychedelic cats

Image

Image

Image

Re: hi-fi ish looper

Posted: Sun Apr 22, 2012 9:38 pm
by cloudscapes
didn't have much time to work on this lately because of job and because I'm building vibratos for a while, but tonight I made this:

Image

Re: hi-fi ish looper

Posted: Mon Apr 23, 2012 10:16 pm
by cloudscapes
revised design, assuming I can cut squares in metal without hacking a finger off

Image

Re: hi-fi ish looper

Posted: Wed Apr 25, 2012 3:04 pm
by smallsnd/bigsnd
super rad progress! congratulations so far on what seems to be a insurmountable amount of learning...