Is there a vDSP function for 1D vector resampling? - iphone

I would like be able to use a vector as an envelope to apply fft equalization to rather large chunks of sound, with varying sizes.
To be able to multiply the frequency domain bins by the envelope, the envelope needs to have the same resolution as the fft data, which will vary with the size of the sound chunks.
So, I need a function to resample my envelope vector. Do you know whether vDSP features a function for that purpose? I browsed the reference back and forth, but found nothing. Which doesn't mean there is nothing there - it's easy to miss something while searching the vDSP reference...
It's not that I couldn't implement something myself, but if there was a vDSP function, it would propably be much faster than anything I could possibly come up with. Which is relevant as this project is targeted at iOS devices as well.
And there's no need to reinvent the wheel :)
Thanks!!

If I understand correctly, you have a 1D array of envelope values which you want to vector multiply with a 1D array of frequency bins. The problem you are trying to solve is to scale the envelope array to the same length as the FFT array. It would be helpful to know how you are generating the envelope array in the first place, can you not simply generate it at the correct length? If so, problem solved :)
If not, then how about using vDSP_vtabi to generate the envelope vector from the lookup table of values that you currently have? You can generate the lookup table input vector A using vDSP_vramp.
This seems rather complicated and expensive to me though, with a fair amount of buffer mallocing / reallocing. It might be simpler to calculate how many FFT samples should be multiplied by each envelope value, then loop for each envelope sample using vDSP_vsmul to multiply chunks of the FFT vector by the envelope value.
Which solution will perform better really depends a lot on the relative sizes of each vector. It would also be helpful to know why the FFT vectors are different sizes, and how you are generating the envelope array in the first place to give a more accurate answer.

I'd suggest to go through a different way.
Because your input signal comes from hardware at a fixed sample rate and you exactly
know the number of envelope values , just make a sample rate conversion using
AudioConverterFillComplexBuffer
It's fast and it take care about filtering and interpolation when resampling.

Related

Wrong Amplitude after FFT [Matlab] [duplicate]

I am trying to use FFT to decode morse code, but I'm finding that when I examine the resulting frequency bin/bucket I'm interested in, the absolute value is varying quite significantly even when a constant tone is presented. This makes it impossible for me to use the rise and fall around a threshold and therefore decode audio morse.
I've even tried the simple example that seems to be copied everywhere, but it also varies...
I can't work out what I'm doing wrong, and my maths is not clever enough to understand all the formulas associated with FFT.
I now it must be possible, but I can't find out how... can anyone help please?
Make sure you are using the magnitude of the FFT result, not just the real or imaginary component of a complex result.
In general, when a longer constant amplitude sinusoid is fed to a series of shorter FFTs (windowed STFT), the magnitude result will only be constant if the period of the sinusoid is exactly integer periodic in the FFT length. e.g.
f_tone modulo (f_sampling_rate / FFT_length) == 0
If you are only interested in the magnitude of one selected tone frequency, the Goertzel algorithm would serve as a more efficient filter than a full FFT. And, depending on the setup and length restrictions required by your chosen FFT library, it may be easier to vary the length of a Goertzel to match the requirements for your target tone frequency, as well as the time/frequency resolution trade-off needed.

MATLAB, averaging multiple fft's ,coherent integration

I have audio record.
I want to detect sinusoidal pattern.
If i do regular fft i have result with bad SNR.
for example
my signal contents 4 high frequencies:
fft result:
To reduce noise i want to do Coherent integration as described in this article: http://flylib.com/books/en/2.729.1.109/1/
but i cant find any MATLAB examples how to do it. Sorry for bad english. Please help )
I look at spectra almost every day, but I never heard of 'coherent integration' as a method to calculate one. As also mentioned by Jason, coherent integration would only work when your signal has a fixed phase during every FFT you average over.
It is more likely that you want to do what the article calls 'incoherent integration'. This is more commonly known as calculating a periodogram (or Welch's method, a slightly better variant), in which you average the squared absolute value of the individual FFTs to obtain a power-spectral-density. To calculate a PSD in the correct way, you need to pay attention to some details, like applying a suitable Fourier window before doing each FFT, doing the proper normalization (so that the result is properly calibrated in i.e. Volt^2/Hz) and using half-overlapping windows to make use of all your data. All of this is implemented in Matlab's pwelch function, which is part of the signal-processing toolbox. See my answer to a similar question about how to use pwelch.
Integration or averaging of FFT frames just amounts to adding the frames up element-wise and dividing by the number of frames. Since MATLAB provides vector operations, you can just add the frames with the + operator.
coh_avg = (frame1 + frame2 + ...) / Nframes
Where frameX are the complex FFT output frames.
If you want to do non-coherent averaging, you just need to take the magnitude of the complex elements before adding the frames together.
noncoh_avg = (abs(frame1) + abs(frame2) + ...) / Nframes
Also note that in order for coherent averaging to work the best, the starting phase of the signal of interest needs to be the same for each FFT frame. Otherwise, the FFT bin with the signal may add in such a way that the amplitudes cancel out. This is usually a tough requirement to ensure without some knowledge of the signal or some external triggering so it is more common to use non-coherent averaging.
Non-coherent integration will not reduce the noise power, but it will increase signal to noise ratio (how the signal power compares to the noise power), which is probably what you really want anyway.
I think what you are looking for is the "spectrogram" function in Matlab, which computes the short time Fourier transform(STFT) of an input signal.
STFT
Spectrogram

fastest way to display huge 2D data in MATLAB

I have a huge ~9Gb .bin file.
Reading data with fread(), getting 2D array A ~ 10^9 points.
Trying to display with imagesc() as simple as:
figure(1)
imagesc(x,y,A)
It takes ~ 800 seconds for me and I can't see anything on the figure.
I am sure that I read the file right. Checked with smaller ones.
So I wonder is there a way to display such a huge data with less effort for my PC?
Perhaps use some kind of downsampling on A. To do it right you'd have to apply a low-pass filter followed by decimation, but the low-pass filter may take very long in your case. So, even if it's subject to possible aliasing, you can try to just take a sample out of n and plot that:
n = 10; %// choose as suits you best
imagesc(x(1:n:end), y(1:n:end), A(1:n:end,1:n:end))
It is quite hard to answer your question without knowing the nature of the data.
Here are some ideas:
If your data is an image, you should downscale it using on of the known methods, or crop it.
If you know that your data is smooth, you can sample it without introducing aliasing.
Show some kind of statistics on your data, instead of showing the data itself.

Resampling data with minimal loss of information in time-domain

I am trying to resample/recreate already recorded data for plotting purposes. I thought this is best place to ask the question (besides dsp.se).
The data is sampled at high frequency, contains to much data points and not suitable for plotting in time domain (not enough memory). i want to sample it with minimal loss. The sampling interval of the resulting data doesn't need to be same (well it is again for plotting purposes, not analysis) although input data in equally sampled.
When we use the regular resample command from matlab/octave, it can distort stiff pieces of the curve.
What is the best approach here?
For reference I put two pictures found in tex.se)
First image is regular resample
Second image is a better resampled data that can well behave around peaks.
You should try this set of files from the File Exchange. It computes optimal lookup table based on either the maximum set of points or a given error. You can choose from natural, linear, or spline for the interpolation methods. Spline will have the smallest table size but is slower than linear. I don't use natural unless I have a really good reason.
Sincerely,
Jason

Choosing Real vs Complex 2D FFTs using apple Accelerate framework

Can anyone advise on the correct FFT to be using (Real or Complex)? I have looked here but still have questions.
I want to do image correlation to identify the location of a sub image within a master image. I understand the basics of FFTs and iFFTs.
The plan:
Perform an FFT on a master image. 512x512
Take complex conjugate of sub image.
Perform an FFT on the sub image. 30x30 but padded with zeros to 512x512
Complex Multiply the two resulting matrixes
Perform iFFT on result
Even though the result should be (mostly) real, take the magnitude of resulting matrix
Look for maximum value which should correspond to maximum correlation.
I am having trouble getting the results that I anticipate.
If I use the real 2d fft (vDSP_fft2dzrip), the result is in a packed format that makes it hard to use a vDSP_zvmul to multiply to two result matrixes.
If I use the complex fft (vDSP_fft2dzip), I fail to get any correlation at all.
The apple examples and most of the audio examples don't do anything with the results of the forward FFT other than do the inverse.
Can anyone help me get started with image correlation? First question...can I use the complex FFT and avoid the packed format?
The only difference between a real and complex FFT is that the real FFT can be slightly more efficient by using a clever packing scheme that transforms a 2^n real FFT into a 2^(n-1) complex FFT. The results should be the same in both cases. So I would stick with the complex FFT for simplicity if I were you, at least until you have everything working.
Have you also taken a look at vImageConvolve_ARGB8888? It seems to do what you are trying to do, with a lot less effort :)