[SOLVED] Steaming Audio 44.1kHz Delta Sigma DAC --> FPGA

Status
Not open for further replies.

derrick_chi

Junior Member level 3
Joined
Mar 21, 2006
Messages
26
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,595
Hi All

I am having a problem with a DAC and I need a little help. I am attempting to stream audio from an iPhone via Bluetooth. I have an FPGA connected to the Bluetooth chip via an I2S interface, so as the audio comes in I am passing it along to the Delta Sigma DAC and from there of course out to an audio jack. The audio data is 16bits signed twos complement data, the however DAC expects an unsigned input so I am complementing all negative number before I pass them along to the DAC. The DAC is being updated at 44.1kHz. Still the music coming out the speakers sounds really bad, the voices sound robotic, there is loads of static as well. Any idea as to what the problem might be?

  • FPGA:Spartan 6
  • DAC CLK Freq: 300Mhz
  • Bit Width: 16bits
  • Sample Rate 44.1kHz

Data Flow Description: New samples are applied to the DAC inputs at 44.1kHz, , the previous sample is left on the input until the new sample arrives. The DAC is summing the entire time.

** A little note on the DAC


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
‘timescale 100 ps / 10 ps
‘define MSBI 7 // Most significant Bit of DAC input
//This is a Delta-Sigma Digital to Analog Converter
 
module dac(DACout, DACin, Clk, Reset);
output DACout; // This is the average output that feeds low pass filter
reg DACout; // for optimum performance, ensure that this ff is in IOB
input [‘MSBI:0] DACin; // DAC input (excess 2**MSBI)
input Clk;
input Reset;
reg [‘MSBI+2:0] DeltaAdder; // Output of Delta adder
reg [‘MSBI+2:0] SigmaAdder; // Output of Sigma adder
reg [‘MSBI+2:0] SigmaLatch; // Latches output of Sigma adder
reg [‘MSBI+2:0] DeltaB; // B input of Delta adder
 
always @(SigmaLatch) DeltaB = {SigmaLatch[‘MSBI+2], SigmaLatch[‘MSBI+2]} << (‘MSBI+1);
always @(DACin or DeltaB) DeltaAdder = DACin + DeltaB;
always @(DeltaAdder or SigmaLatch) SigmaAdder = DeltaAdder + SigmaLatch;
 
always @(posedge Clk or posedge Reset)
begin
  if(Reset)
    begin
      SigmaLatch <= #1 1’bl << (‘MSBI+1);
      DACout <= #1 1‘b0;
    end
  else
    begin
      SigmaLatch <== #1 SigmaAdder;
      DACout      <= #1 SigmaLatch[‘MSBI+2];
    end
end
 
endmodule

 

You shouldn't be complementing, you should be offsetting all the samples by adding 32768 before feeding your DAC.
This way the zero signal output will be half rail and the audio can swing both ways.

I have not looked closely at the code, Verilog is not my thing.

Regards, Dan.
 

HUH???:shock: Good grief, this is the first time I've heard this, forgive my ignorance, can you please explain why I shouldn't be complementing but adding 32768 --> hex -->0x8000?

Well you did already give an explanation, however I do have one other question, should I be adding --> (0x8000 + Sample) or XORing --> (0x8000 xor Sample)? I think the xor gives the same result in this case?

Thanks for all of your help!
 
Last edited:

Well your input range is -32768 -> 32767 correct?

Your DAC expects to see 0 -> 65535, the addition of 32768 to your signed value (note +32768 needs 17 bits as a signed integer) will yield a value having a range of 0 -> 65535 (17 bits as a signed value) which you then convert to unsigned (16 bits), with audio silence being somewhere in the middle of that range.

Audio DACs all have an output corresponding to zero (audio sample value) input of mid scale, you then remove the DC component with a series cap.

If you think about it the process MUST be linear (anything else introduces mixing products), which addition is, but complement only some of the time most certainly is not.
If +1 produces output 20 & zero produces output 15 then -1 should surely produce output 10, not go back up to output 20, generally anytime you find yourself doing different things depending on the sign of a sample you are introducing a non linear element and that is usually not what you want.

Addition not xor!

Regards, Dan.
 

PROBLEM SOLVED!!!!!!!

Thanks Dan, you are aces in my book!!!
 

Dan

I have another question. I'd like to be able to increase and decrease the volume digitally. I've read a little bit on this and it seems that while this is not the optimal way to change the volume that it can be done. I was wondering if you might have an idea on how this can be done or if you can point me to literature which proscribes a method that I can implement in an FPGA?
 

Take your signed sample stream, multiply by a scale factor and, if you are feeling fancy dither to reduce the word length back to 16 bits, otherwise just truncate.....
The scale factor sets the volume (in a rather non linear way), you may wish the scale factor to be setup as some sort of fixed point representation (4.10 or such should do).
Lipshitz and vanderkooy published the classic paper on dithered word length reduction in JAES as I recall.

Hopefully your FPGA has some sort of DSP block or other hardware multiplier, writing a booth multiplier is a pain.

I would suggest that a book on basic audio DSP would be appropriate, there is nothing FPGA specific here.

Regards, Dan.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…