From: John_H on
Fei Liu wrote:
> Alan Nishioka wrote:
>> On Apr 11, 7:02 pm, kevin93 <ke...(a)whitedigs.com> wrote:
>>> On Apr 11, 2:32 pm, Fei Liu <fei....(a)gmail.com> wrote:
>>>
>>>> Hello
>>>> I am working on playing simple 11 kbytes/second 8bit WAV data
>>>> through my
>>>> FPGA stereo jack. I used the following synthesis to play the sound data
>>>> delivered through the serial interface. I also used the mono_dac demo
>>>> module.
>>>> My problem is I am getting a very high noise to signal ratio although I
>>>> can hear the speech. The sound file plays crystal clear on my host
>>>> computer.
>>> <.. snip ..>
>>>
>>>> //PWM audio(
>>>> // .clk(clk),
>>>> // .PWM_in(rx_data),
>>>> // .PWM_out(aud_l)
>>>> //);
>>>> wire audio;
>>>> FD fd_aud_lt_inst (.D(audio),.Q(aud_l),.C(clk));
>>>> mono_dac mono(
>>>> .signed_data(rx_data),
>>>> .volume(3'b100),
>>>> .audio(audio),
>>>> .clk(clk)
>>>> );
>>> <.. snip ..>
>>>
>>> 8-bit WAV files use offset binary rather than signed values (i.e. 0 is
>>> the most negative, 128 is mid-scale 255 is full-scale)
>>>
>>> kevin
>>
>> And to convert signed to offset or to convert offset to signed you
>> just have to invert the top bit (MSB). Since it is so easy, it might
>> be worth it to just try it and see if it works.
>>
>> Alan Nishioka
>
> Hmm, it doesn't seem to work. I use libsndfile and libserial to decode
> and deliver data to serial port in this code:
>
> static const sf_count_t nframes = 16;
> signed char data;
> char ptr[nframes];
> int count = 0;
>
> while(sfh.readRaw(ptr, nframes)){
> count ++;
> if(!(count%1000)) printf("Frames: %d\n", count);
> int i = 0;
> while(i < nframes){
> data = ptr[i];
> data -= 0x80;
> my_serial_stream << data;
> i++;
> }
> }
>
> I just get a load of noise. I analyzed the signal sent to serial port
> (from the Tx output), there is no glitch.
>
> Fei

Do you suppose "my serial stream" might present the data backwards from
what you expect? See if you can generate a nice, clean tone with a
square wave - 0x00 for a few cycles then 0xff for a few cycles. If
that's clean, try 0x00 paired with 0x01 then 0x00 and 0x80. See which
of those two is audible.

Good luck. Troubleshooting is where the real thought comes in.

- John_H

From: Fei Liu on
Fei Liu wrote:
> Hello
> I am working on playing simple 11 kbytes/second 8bit WAV data through my
> FPGA stereo jack. I used the following synthesis to play the sound data
> delivered through the serial interface. I also used the mono_dac demo
> module.
>
> My problem is I am getting a very high noise to signal ratio although I
> can hear the speech. The sound file plays crystal clear on my host
> computer.
>
> Another problem I have with simple WAV file is I don't know how to
> extract volume information. So I hardwired 3'b100 as the volume.
>
> I could use some help figuring out the source of the high noise. Is this
> caused by timing issue?
>
> Fei
>
> WAV file info:
> File : 11k8bitpcm.wav
> Length : 152312
> RIFF : 152304
> WAVE
> fmt : 16
> Format : 0x1 => WAVE_FORMAT_PCM
> Channels : 1
> Sample Rate : 11025
> Block Align : 1
> Bit Width : 8
> Bytes/sec : 11025
> data : 152267
> End
>
> ----------------------------------------
> Sample Rate : 11025
> Frames : 152267
> Channels : 1
> Format : 0x00010005
> Sections : 1
> Seekable : TRUE
> Duration : 00:00:13.811
> Signal Max : 128 (0.00 dB)
>
> `include "timescale.v"
>
> module serial_snd(
> clk,
> rx,
> tx,
> led0,
> led1,
> led2,
> aud_l,
> aud_r
> );
>
> parameter clk_freq=50000000;
> parameter blink_freq = 25;
>
> (* LOC="E12" *) input clk;
> (* LOC="F16" *) input rx;
> (* LOC="E15" *) output tx;
> (* LOC="R20" *) output led0;
> (* LOC="T19" *) output led1;
> (* LOC="U20" *) output led2;
> (* LOC="Y10" *) output aud_l;
> (* LOC="V10" *) output aud_r;
>
> wire data_ready;
> wire RxD_idle;
> wire [7:0] rx_data;
> reg [blink_freq:0] count = 0;
>
> // serial port receiver
> async_receiver #(.clk_freq(clk_freq)) ar(
> .clk(clk),
> .RxD(rx),
> .RxD_data_ready(data_ready),
> .RxD_data(rx_data),
> .RxD_idle(RxD_idle)
> );
>
> // Serial port transmitter
> async_transmitter #(.clk_freq(clk_freq)) serializer(
> .clk(clk),
> .TxD(tx),
> .TxD_start(data_ready),
> .TxD_data(rx_data)
> );
>
> // Blink LED0 with a frequency slightly slower than once per second
> assign led0 = count[blink_freq];
> assign led2 = RxD_idle;
>
> // LED1 lights on when there is incoming data from serial line, it lasts
> 2^20 clks
> state_holder #(.clk_hold(20)) bl(clk, data_ready, led1);
>
> //PWM audio(
> // .clk(clk),
> // .PWM_in(rx_data),
> // .PWM_out(aud_l)
> //);
> wire audio;
> FD fd_aud_lt_inst (.D(audio),.Q(aud_l),.C(clk));
>
> mono_dac mono(
> .signed_data(rx_data),
> .volume(3'b100),
> .audio(audio),
> .clk(clk)
> );
>
> assign aud_r = 8'bz;
>
> always @(posedge clk) begin
> count <= count + 1;
> end
>
> endmodule

Ah I found the problem, it's because the rx_data is only valid for a
single clk after data_ready signal is high. So the fix is quite simple,
use a register to buffer rx_data when data is available! Because xapp154
chipset requires audio in signal to hold for 2**(MSBL+1) clks after it
changes.

Fei