[posted] AudioToy - modular 8x8 channel Teensy 4.0 pro-grade audio mixer hardware

palmerr

Well-known member
AudioToy is a set of modules to complement an 8x8 CS42448-based Teensy 4.0 audio board, providing fully balanced, software gain-controlled input and output modules.

Fully balanced or unbalanced microphone, line and instrument inputs are supported and the output stages can drive 600 ohm loads at +8dBm. Only a 5V supply is required.

All hardware information is available for open access at https://github.com/palmerr23/AudioToy with full schematics, BoM, Gerbers and design notes provided.

An ESP32 provides WiFi connectivity for remote control.

Top view
audiotoy2s.jpg
From the front
audioToy1s.jpg
Front panel
audioToy front.png
Rear panel
AudioToy back.png
 
great work!
does it have differential in & out circuits? had a look to the repo but the schematics are hard to read, I'm used to 'op-amp stage' style instead of ICs,
 
M4ngu,

Hard to read in what sense? Too small? Not enough information?

They're in currently standard Eagle schematic format, and that's a bit hard to change!

I'm not sure what 'op-amp stage style' is, can you post an image of a small section of a schematic in that style?

R
 
Hi palmeer,
with 'op-amp stage' style I mean this:
Captura de pantalla 2021-09-16 a las 9.49.32.png
instead of this:
Captura de pantalla 2021-09-16 a las 9.50.41.png
for me it's way easier to see what's going on looking at the first one.
Cheers!
 
Yes, I agree wholeheartedly with your preference with 'op amp' style schematics. They are much easier to decipher.

Sadly, I'm limited to what the manufacturers (or more commonly with these 'box' symbols, SamacSys or some other 3rd party who create Eagle libraries under contract).

With the MCP604, I could easily have used an alternate 4 op amp chip as the pinouts are pretty standard. Sorry for the inconvenience!

My pet peeve on this issue is 3 terminal regulators which seem to come with all sorts of weird symbols.
 
On the 'differential' issue - yes fully differential in and out, other than inputs 7-8, which are only differential at the preamp stage, reverting to single ended at the ADC.

I couldn't find a readily available 2-channel ADC that would work in auto-detect slave mode that had differential inputs. Paul's design has the same issue.
 
I want to give a try to the differential IO circuit on a project I'm working on, indeed I would like to totally remove the caps for the DC offset (that can be solved with software calibration), that way the module could output slow LFOs, and DC input voltages would work too (to use audio ins as CV in too)
 
Yes, it's relatively straightforward to add DC bias to a single-ended input, but a little more complex for balanced. Of course, for LFOs, balanced isn't relevant.

Small input offsets will remain, which as you say can be digitally removed - the CS42448 provides some help in doing this with a programmable ADC High-Pass Filter for DC Offset Calibration, with Freeze capability (Sect 4.2.3, 6.6.2)

Outputs are more straightforward as you have direct control of the values, and VQ does most of the work.

You'll need to provide better protection for the ADCs than is currently in place (I can't find any reference in the CS42448 literature about input protection diodes), if you're going to put DC voltages into the front end. Watch out for non-linearities that can be caused by a diode's reverse and forward current leakage - most are by no means "perfect" devices, especially zeners!

If you need help with the circuitry, I'd be happy to provide some pointers. Just put a reference to your thread for the project into this thread and I'll join you in the other one.
 
Hi @palmerr, I'm finally working on the differential output circuit, and wondering if you could provide some help here, I'm not very good in electronics (neither in code xD)
this is the circuit in the manual, I would like to make it DC coupled so removed the 22uF from the output (blue circle) but no idea if the other one (red circle) has to be removed too, what do you think?
Captura de pantalla 2021-10-20 a las 13.41.24.png
also I want modular level output, not line level. I usually do it with an op-amp x4 gain circuit (non inverting op-amp circuit with 100k in the feedback loop and 33k from negative input to ground), but I would like to do it by changing the values of some resistors in that circuit, any suggestion about about this?
Captura de pantalla 2021-10-20 a las 13.50.05.png
 
Hi @palmerr, I'm finally working on the differential output circuit, and wondering if you could provide some help here, I'm not very good in electronics (neither in code xD)
this is the circuit in the manual, I would like to make it DC coupled so removed the 22uF from the output (blue circle) but no idea if the other one (red circle) has to be removed too, what do you think?
View attachment 26226
also I want modular level output, not line level. I usually do it with an op-amp x4 gain circuit (non inverting op-amp circuit with 100k in the feedback loop and 33k from negative input to ground), but I would like to do it by changing the values of some resistors in that circuit, any suggestion about about this?
View attachment 26227

M4ngu

You are correct that removing the blue-circled capacitor will provide a DC output. You are also correct that the red-circled capacitor needs to be removed to provide a ground reference for the + input. There will probably be a few millivolts residual DC offset, however. This can be removed in software by trimming the output value. It usually only takes a few counts up or down. If you're going for the usual 0-10V modular output swing, you'll need 12V or more on a TL074, and a negative supply as TL074s don't drive their outputs close to the rails. The humble LM358 might be a good choice if you want to avoid a negative rail, as it drives to the negative rail. BTW, +12/-5 rails are perfectly OK, they don't need to be balanced voltages.

The gain is set by the ratio of R37 to R40. These should be 4:1 for 4 x gain. Then, R41 = R40 and R43 = R37 to balance the +ve leg. R42 and R38 are there to set the roll-off of one section of the 2 pole filters with C44/45. They should be OK as they are if you change R40/R41 values rather than R37/R43. If you change those, modify C42/43 inverse proportionally to keep the corner frequency of the other filter the same.

Happy hunting!
 
Thanks Palmerr,
I made a simulation yesterday and found a nice result with ±5v and minimal offset in the output but that was by tweaking values of R37 & R43,
so this morning I made another simulation and got it by changing only R40 & R41 (for not to affect the filter properties, as you suggest).
In the simulation I'm using 2 voltage sources with the properties of the outputs, so it should be ok:
Captura de pantalla 2021-10-21 a las 10.21.18.png
btw I've removed the last pull-down resistor
Captura de pantalla 2021-10-21 a las 9.57.26.png
 
I'm working now on the input,
to get signal scaled from 10vpp (±5v) to 2,8vpp with an offset of +2,5v and without low pass filter,
think I have it, any thoughts?
Captura de pantalla 2021-10-21 a las 13.12.45.png
 
I'm working now on the input,
to get signal scaled from 10vpp (±5v) to 2,8vpp with an offset of +2,5v and without low pass filter,
think I have it, any thoughts?
View attachment 26249

OK, you've reverted to a basic, non-inverting op amp here, which has the advantages of simplicity, but also some drawbacks.

You've totally done away with the -ve DAC output here which allow your zero point to be non-specified. Your voltage divider will only approximate the 0 sample level and will drift over time. Running it from a power rail will introduce noise into the output. Instead of biasing from v+ use VQ from your DAC if it's available. Remember to check its output impedance, as it may need to be buffered before use.

I haven't checked your filter/feedback values in detail, but 634 ohms feedback resistor seems quite small, if you still need x4 gain and a high cutoff filter. A quick calculation suggests that the pole will be around 0.5MHz, way too high to be of any use. You need to run the AC signal input at various frequencies to check gain, or better a a bode plot which will ensure you have adequate phase margin to avoid oscillation (unlikely with this simple setup and a feedback capacitance).

91 ohm output resistor makes sense to limit the output short circuit current, and the feedback arrangement "cancels it out".

The final 2.9nF capacitor to ground is a bad idea. One always assumes an unknown capacitance on the next stage, so relying on 2.9nF being anywhere accurate is likely to lead to sadness.
 
Hi Palmerr,
the INPUT circuit is based on the one proposed by the manual, so the value for the capacitors should be ok,
I'm trying to achieve the same result but without low pass filter and a higher input voltage,
Captura de pantalla 2021-10-23 a las 10.17.25.png
Eurorack rails are ±12v, the +5v would be regulated by a LDO but using a +2,5v voltage reference will be better
 
M4ngu,

Sorry, I missed the word "input" in your message and went straight to the schematic.

If we're still talking about an ADC with -ve inputs, then a more straightforward way to achieve the desired outcome is to use a voltage divider on the signal and take it to the -ve input; and tie VQ to the positive input through a suitable resistor (to minimise input offsets the value is the parallel resistance of the voltage divider). The filter arrangement is fine. for an input, and the capacitor to ground is sized for the the 34k input impedance of the CS42448.

Using buffered VQ is better than a separate reference as any drift will be the same for the ADC and opamp, minimising the need for dynamic offset trimming.
 
Can i have a look at your code somewhere? I’m interested in the communication part between teensy and esp.

MaltWhiskey,

The code is fairly straightforward - it uses serial transmission.

All packets are of this format:
Code:
struct chanNamePktO{		// output channel names
	int8_t  pktType = PT_ONAMES;
	uint8_t	groupID;		// which controller (multiple sets) is being managed?
	char    name[OUTCHANS][NAMELEN];		// this is the output channel name
}; //outChan

and they're wrapped in different headers for transmission by UDP or serial.

The serial header is:
Code:
#define PRELEN 4
#define PREAMBLE "MIXX"	
struct serialHeader {
	char     sPreamble[PRELEN] ;
	uint8_t  crc;
	uint16_t pktLen; // no need for a group ID, serial comms is always between an ESP32 controller and a Teensy audio processor
};

the code to synchronise packets is
Code:
// returns length of data read
int getmySerialPkt(universalBuf *bufp)
{
	int pktlen;
	uint8_t crc;
	short int i;
	char ch, pre[PRESTRINGLEN] = SERIALPREAMBLE;	
	serialHeader sh;
	char tempBuf[72];
		
	// scan for PREAMBLE using a simple state-variable machine
	int8_t foundCh = 0;
	int chRead = 0;
	if (!mySerial.available())
		return PT_NONE;
	while (mySerial.available())  // read until no further data available, move to next phase if preamble is found
	{
		ch = mySerial.read();
		if (chRead < 72) tempBuf[chRead] = ch;
		chRead++;
		if (ch == pre[foundCh])
		{	
			sh.sPreamble[foundCh] = ch; // just for debugging
			foundCh++;
		}
		else
			foundCh = 0;
		if (foundCh >= PRELEN) // read correct preamble
			break;
		delayMicroseconds(byteTime);	// wait for another byte to get here
		for (i = 0; i < SERIALWAITFOR; i++)
			if (!mySerial.available())			
				delayMicroseconds(byteTime); // wait a bit longer, transmit may be interrupted				
		if (!mySerial.available())
		{
			Serial.println("GMS header timeout");
			return PT_BAD;	
		}
	}
	if (foundCh < PRELEN)
	{
		Serial.println("GMS bad hdr");
		mySerial.flush(); // dump the rest of chars in buffer
		return PT_BAD;	// found no preamble in available data
	}
	// from here on we know the sizes of data, so use blocking code
	// serialTimeout determines the max inter-character gap
	
	// get rest of header
	i = mySerial.readBytes((char *)&sh.crc, sizeof(sh)-PRELEN);	
	
	if(crc == sh.crc)	
	{
		parseInPkt(bufp, sh.pktLen);
		return bufp->pktType;
	}
	Serial.println("GMS bad CRC");
	return PT_BAD;
}

the crc algorithm is a straight crc8, easily obtainable from multiple sources.

The standard serial receive buffer is
Code:
#define RX_BUFFER_SIZE 64
so I buffer input in a much larger on, so that the code doesn't block on larger packets.

There's a trade off between block latency rate and how often you need to service the routine (< 64 bytes at the data rate). I use 115200 quite reliably. Haven't tried higher rates, but there's no reason that they shouldn;t work reliably.

Have fun!

Richard
 
On request, I have updated the repository with JLPCB assembly files (CPL and BOM) for those who might want to go down that path.

For those that are interested in assembled boards, banding together for a production run could significantly lower the unit costs.

Richard
 
palmerr,

Can you tell me what the input impedance of your AudioToy is? I understand the goal for guitar preamps is to have ~1M impedance, ~2k for Microphones, and ~10k for line levels. Does this sound about right?

So it appears that the inputs on your toy is XLR=Microphone preamp and 1/4"=line level input. Does it accept guitars?

Jay
 
Jay,

The Line/instrument preamps have very high impedance (FET op amps) > 1M. So, yes to guitars on those inputs.

The line inputs on the Mic / line boards are 35k, so not good for electric guitars, but fine after most pedals.

Mic inputs are relatively Low-Z, suitable for dynamic or electret mics. No phantom power is provided, as a core design factor for this project was that it should have a single +5V supply.

As for general input impedances, yes they are about right, though "pro" balanced lines should be terminated at 600 ohms.

BTW: TS472s are in global zero supply, so it won't be possible to build the mic boards until they are back in stock. I've had some on backorder from Mouser for nearly 12 months, and they don't have even a planned production date.

Richard
 
Back
Top