I’m trying to program a DSP-Unit, which allows Time-Shifting (TDHS). This allows to change the speed of a song w/o changing the pitch. I though this could be done by changing the frenquency of a stream with FSOUND_Stream_SetFrequency and a DSP-Unit, which corrects the pitch of the streamdata. I must admit that I don’t really know, what this streamdata exactly is. For easy DSP’s I had no need of it, because FSOUND_DSP_MixBuffers had done everything.
So my question is:
Can anybody tell me, how I have to manipulate the newbuffer in the DSP, to correct the pitch caused by the FSOUND_Stream_SetFrequency?
- Lenherr asked 14 years ago
I have found some code once that did a frequency scale based on FFT and iFFT.
You can’t use the FFT fmod returns because it is only updated every 20 ms, and you will need a better FFT to get a quality iFFT.
The code I found had an oversampling value, but you had to set it pretty high to get a quality result.
The problem with this source was that it could not be done realtime on a K7-1Ghz.
Altough once you get FFT and iFFT working it is the easiest way to implement a lot of effects, I think it is too CPU intensive for realtime processing.
Just as there are easier filters for equalizers, there are easier filters to change pitch I think.
I haven’t found one that does it successfuly though…
I found some C code that required about 25% of my processor (Athlon 800 MHz) to do FFT and iFFT. It was based on Don Cross’ work, but I’ve lost the source code and also the link to the page. However I think that C code was pretty unoptimized because of educational purposes, so 25% was a relatively high processor usage.
Try to search with a search engine on the Internet for Don Cross, I think you will find what you need.
The only drawback of those routines was that the buffer had to be a multiple of 2 (512 is ok, 1024 is ok, 2048 is ok, 3072 isn’t)
I think I found the code you mentioned:
But I don’t know how I could change the buffersize. As you said the number of samples has to be a power of two, but the DSP always gets a bufferlength of 8820. I tried a few things out with FSOUND_SetBufferSize(int ms) but this didn’t affect anything.
What shall I do?
Here is a link to a site that has a very efficient FFT and iFFT code. the code is free. Note that I didn’t tested it yet, so I don’t know what i does on any processor.
It seems to accept any buffer length (not only power of 2)
Here it is: http://www.fftw.org
- Mortimer answered 14 years ago
Lenherr, that’s the problem!
FMOD DSP buffersize is determined by FMOD and not by the user!
Usually for sampling frequency of 44100 buffers are 1024 samples long (4096 bytes).
A question: are you using FMOD 3.5? I ask this because since version 3.5 buffers are always a multiply of 256.
Yes I’m using fmod 3.5. But I get always 8820 samples in my DSP’s, that’s not really a multiply of 256 (8820/256=34,453125). So something must be wrong there, something with my ability of reading numbers or anything with the fact that the buffersize is always a multiply of 256.
An other thing: I’ve looked a bit at the FFTW (Fastest Fourier Transform in the West) (http://www.fftw.org):
It supports any bufferlength especially when its factors are 2,3,5,7.
This means I could use it for my buffer (8820=2233577) without problems. But something else came in my mind:
If I can FFT these 8820 samples of one DSP-call, and if I can manipulate them as I like, and if I can iFFT the whole calculated date and write them in the buffer, won’t there be always a little tick (or noise) at the beginning of the next 8820 samples?
I thought about the method buffering myself, but with both methods (power of 2 and not) I have a new, big problem:
Let’s say I divide the data I’m given by the DSP-Chain into chunks with size n. To prevent the clicks I let them overlap and fade between them. This way I’m able to prevent the clicks between the chunks of one DSP-Call, but then I have to do the step from the first DSP-Call to the Second. For this step the first DSP-Call needs some data, which is given to the second DSP-Call.
This means that I cannot prevent the click between the two DSP-Calls, because the first call would need data of the second.
8820 samples are given to my DSP-Handler, this means always after 8820 samples a click occurs -> all 8820/44100=0.2 seconds an inexorably click
Any ideas for this? (please have one, I haven’t)
maybe you can take the second part of buffer1 and the first part of buffer2 to fill the first part of buffer2, then you take the first part of buffer2 and the second part of buffer2 to fill the second part of buffer2, then you use the second part of buffer2 and the first part of buffer3 for the first part of buffer3, …
You basically run behind half a buffer.
The only problem with this is that it will increase latency…
Please login first to submit.