Byte Mixer Suggestions

Requests, not necessarily related to fpga4fun...

Byte Mixer Suggestions

Postby Oneironaut » Fri May 14, 2010 12:31 am


I am finishing up a sound generator design and am now faced with the task of mixing 4 or more 8 bit "voice" registers into one single 8 bit "dac" output register.

Currently I use...

Code: Select all
mixer <= (voice1[15:8] + voice2[15:8] + voice3[15:8] + voice4[15:8]) /4;
dac <= mixer;

"mixer" is a 16 bit register.

which works, but does drop the output significantly as compared to assigning dac to a single voice.

I am looking for suggestions on a better way to mix together 8 bit voices into a single 8 bit output. I cannot change the number of bits in the dac or voices, but can certainly change the number of bits in any of the mixing math.

Posts: 67
Joined: Tue Oct 21, 2008 6:56 pm

Postby NickH » Sat May 15, 2010 12:01 pm


I think, in general, you're already doing the best thing. But here's a couple of random suggestions...

1. If it's very unlikely that all voices will be playing at full volume at the same time, you might get away with dividing by 2 instead of 4, with clipping (but it will sound unpleasant when it clips):
Code: Select all
wire [9:0] sum = voice1[15:8] + voice2[15:8] + voice3[15:8] + voice4[15:8];
always @(posedge clk)
   dac <= (sum>=10'h300) ? 8'hFF : (sum<10'h100) ? 8'h00 : {~sum[8],sum[7:1]};

2. If you can run your DAC at a high sample-rate (e.g. >= 96kHz) you might be able to improve resolution by dithering (but this will add faint tones, and it only really works if voices go exactly to 16'h8000 when they're quiet):
Code: Select all
reg [9:0] remain;
wire [18:0] sum = voice1 + voice2 + voice3 + voice4 + remain;
always @(posedge dac_clk) begin
   dac    <= (sum[18]) ? 8'hFF : sum[17:10];
   remain <= sum[9:0];

There are more advanced kinds of dithering (see Noise Shaping, or the links on Jean's PWM page).
You could even try both tricks (clipping and dithering) at the same time.

BTW, I'm assuming that the signals are all unsigned / positive, and that the inputs are 16 bit.


Posts: 88
Joined: Tue Sep 02, 2008 1:53 pm

Postby Oneironaut » Sun May 16, 2010 8:00 pm

Thanks for the info.
Posts: 67
Joined: Tue Oct 21, 2008 6:56 pm

Postby Oneironaut » Wed Jun 30, 2010 8:33 pm


After much hacking, I found a better way to send multiple bytes into a single DAC.... time slicing.

At 40MHz, I just made set up a 3 bit counter and sent bytes to the DAC on each cycle so that all 8 bytes had 40MHz/8 of time.

This sounds perfect and has no fidelity loss as compared to the mathematical mixing.

I guess in a way, this is basically PWM, but since it sounds better, it is better.

Posts: 67
Joined: Tue Oct 21, 2008 6:56 pm

Return to Help requests