Intel® FPGA University Program
University Program Material, Education Boards, and Laboratory Exercises
1174 Discussions

Vibrato(FM) effect on DE2

Altera_Forum
Honored Contributor II
1,156 Views

Hi, i'm trying to create effect like vibratto, flanger. Simply frequency modulation. My sampling for audio is 48khz As far as i know it can be done using circular buffer(variable delay to modify phase of signal). Ok, i've got ram megafunction: 

pamiec_pamiecFlanger: entity work.pamiecFlanger port map ( clock => lrck, data => input, address => address, wren => '1', q = output_temp);  

 

input is signal from line in, output_temp is TO line out(edited: to register and then to line out i mean), lrck is leftrigh clock of codec. 

 

then i do somethin like this:  

process(lrck, reset) begin if reset = '0' then elsif( lrck'event and lrck = '1' ) then if (address < wave(13 downto 0)) then address <= address + 1; else address <= (others => '0'); end if; end if; end process;  

 

wave is triangle from LUT , 14 bit but only 0 to 720, about 15ms delay i think, 1hz frequency. Just as it should be for simple flanger or easy to hear vibratto.  

At least i output signal from ram output <= output_temp; outside processes. 

 

In background of produced signal i hear varying frequency, on spectrum analyser it can be seen clearly. but in front of signal i've got strange noise, like i don't know how to say it. MI think it can be becouse lrck clock is way to fast, when modulating wave is low , 50, 100 for eg. my input signal is writen many times from 0 to 50 to ram. Ehh... sory, i don't know how to write it.  

 

Can you just look at the code and point me what am i doing wrong, and how to repair it ? I want hw approach, i know that nios with for example uclinux would speed it up, but i want HW and only HW.. 

 

Thanks in advance, and sorry for chaotic style of writing... 

Chris
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
364 Views

i don't fully understand what your algorithm looks like 

 

i would use a dual port RAM: 1 port writes the audio_in sequentially to each address of the RAM, then loops back to the top. the 2nd port reads the audio_out from the RAM, but the address pointer can jump based on the modulation signal. when the modulation signal is large, your read pointer may go all the way back to the address right "in front of" the write pointer. when your modulation signal is small your read pointer may go right "behind" the write pointer. this is the most basic delay structure 

 

since your read pointer is jumping around, you can get discontinuities in the audio_out waveform which sound pretty bad. i'm not sure if this is what you're hearing. you'll want to think about interpolation between multiple samples so you have a smaller discontinuity. search terms would be interpolated delay 

 

you will also want to verify that your delay buffer is working in the first place. try mixing 50/50 input signal and delayed signal with a fixed delay of maximum length (read pointer is 1 address ahead of write pointer)
0 Kudos
Altera_Forum
Honored Contributor II
364 Views

this post is old, i managed to change noise from this audio to worse noise :) 

Standard delay and echo works good. Tremolo(AM) using this wave works good too. Vibratto is a problem, simulation in matlab works good too, but implementing it in hardware is to problematic for me. The noise i hear can be heard on this mp3 : http://dark.art.pl/~kvasir/noise.mp3 It is 200hz sinus obtained from PC line out, modulated with 2hz triangle(50:50) with values 0 to 720. I think that what is heard in background IS frequency modulated signal. Any other ideas ? 

 

ps: i use 2-port ram megafunction, with read before write.
0 Kudos
Altera_Forum
Honored Contributor II
364 Views

Thanks thepancake, my main problem was that i was writing and reading from address pointer based on mod signal. now when i am writing sequentialy from 0 to 720 and back fromo 0 to... It is working, and awfull noise from as you said discontinuities appears.  

The thing is i realy don't know how to interpolate it. you know, this should be only small delay, so 720 is max delay. When accumulating address on every lrck i get 720 very fast. And modulation wave will is to slow if you know whan i mean :) Another problem.... Whole life full of problems :/
0 Kudos
Altera_Forum
Honored Contributor II
364 Views

you can try a simple linear interpolation: 

 

http://www.dsprelated.com/dspbooks/pasp/linear_interpolation.html 

 

searching linear interpolation gives a few other methods 

 

as you've found you have to listen to your algorithm to know if its any good :)
0 Kudos
Altera_Forum
Honored Contributor II
364 Views

Thanks ThePanCake. I saw this webpage and tried to recreate idea before i posted on this forum, but can't realy understand how to convert it to vhdl, or even imagine it... 

 

Addresses in memory are integers, audio samples are integers too, -32768 to 32767. 

 

You put samples into memory at incrementing addresses, with fixed delay, at for example 48000 you will get 1 second delayed input.  

When delay is floating(at lower addresses) you should get what i need.  

BUT... here is the part with interpolating. You just take two samples for example 1000 and 1100 and put in memory at addresses 1,2,3: 1000, 1050, 1100, but how will it help me ? More samples equals more memory steps, so i must read from memory twice as fast and what ?  

I can't put on output sample 1050 because my sampling will change if i am right...  

It overwhelms me..  

I know that simply asking for a piece of code is bad idea, but i think i won't understend it without that sort of help :/ 

 

Cheers..
0 Kudos
Altera_Forum
Honored Contributor II
364 Views

the example from the link is very simple, it doesn't require reading from RAM twice for every sample 

 

you will take the variable-length delay you've already written. register the output of the delay (register again if you are already registering it once). then sum the output of the delay and the registered output 

 

in a first test you could leave out the (n) and (1-n) multipliers and just let the signal grow, and send the most significant portion of the output word to the DAC. next you could add the multipliers in and experiment with fixed values or maybe even some kind of real-time control. MIDI is pretty easy to add
0 Kudos
Altera_Forum
Honored Contributor II
364 Views

Hello, i have problem with audio processing using DE2 board. I am doing my project using VHDL and combine them all together using block diagram. I've set the WM8731 configuration not to enable bypass, but i still get the clean sound from my input(i m using a guitar).I've try a lot of design but it still give me the same result. At once, i try to delete pin AUD_ADCDAT and AUD_DACDAT, the i try to run it,strangely, it still give me sound from guitar. do u have any opinion about this matter?

0 Kudos
Reply