Tutorial on Autocorrelation? [closed] - algorithm

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
Ive recently been considering using Autocorrelation for Pitch Detection. However, I am finding it difficult on finding good sources of where to learn autocorrelation, by this I mean sources that make it easy to understand autocorrelation step-by-step.
Im not that very good a programmer yet and also not really big on formulas so the sources that I find are really difficult to understand.
Basically, what I know now is the concept of autocorrelation is like a compare-and-contrast method of a signal? But I would really appreciate it if I can have more understanding of the autocorrelation algorithm.
Thank you very much!
UPDATE: Here is a sample code I got from a site. Maybe you can use it as reference. Ive tested this code and it does return the correct pitch properly (albeit there are some incorrect ones here and there)
maxOffset = sampleRate / minFreq;
minOffset = sampleRate / maxFreq;
for (int lag = maxOffset; lag >= minOffset; lag--)
{
float corr = 0; // this is calculated as the sum of squares
for (int i = 0; i < framesize; i++)
{
int oldIndex = i - lag;
float sample = ((oldIndex < 0) ? prevBuffer[frames + oldIndex] : buffer[oldIndex]);
corr += (sample * buffer[i]);
}
if (corr > maxCorr)
{
maxCorr = corr;
maxLag = lag;
}
}
return sampleRate / maxLag;

Here's what I hope is a simple explanation.
Firstly consider how sonar works - you send out a known signal and then compare a received signal with the original - the signals are compared over a range of possible delays and the best match corresponds to the round trip time for the reflected signal.
OK - now think of a periodic signal, such as a sustained middle C note on a piano. If you compare the note with itself at a range of different delays you will get a match for any delay which corresponds to the pitch period of the note. This is essentially what autocorrelation is: comparing a signal with itself over a range of possible delays and getting a peak wherever signal matches the delayed version of itself. For most musical notes the first such peak corresponds to exactly one pitch period, and so you can deduce the pitch from this (pitch or frequency = reciprocal of delay).

Related

Determining the level of dissonance between two frequencies [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Using continued fractions, I'm generating integer ratios between frequencies to a certain precision, along with the error (difference from integer ratio to the real ratio). So I end up with things like:
101 Hz with 200 Hz = 1:2 + 0.0005
61 Hz with 92 Hz = 2:3 - 0.0036
However, I've run into a snag on actually deciding which of these will be more dissonant than others. At first I thought low numbers = better, but something like 1:51 would likely be not very dissonant since it's a frequency up 51 octaves from the other. It might be a screaming high, ear bleeding pitch, but I don't think it would have dissonance.
It seems to me that it must be related to the product of the two sides of the ratio compared to the constituents somehow. 1 * 51 = 51, which doesn't "go up much" from one side. 2 * 3 = 6, which I would think would indicate higher dissonance than 1:51. But I need to turn this feeling into an actual number, so I can compare 5:7 vs 3:8, or any other combinations.
And how could I work error into this? Certainly 1:2 + 0 would be less dissonant than 1:2 + 1. Would it be easier to apply an algorithm that works for the above integer ratios directly to the frequencies themselves? Or does having the integer ratio with an error allow for a simpler calculation?
edit: Thinking on it, an algorithm that could extend to any set of N frequencies in a chord would be awesome, but I get the feeling that would be much more difficult...
edit 2: Clarification:
Let's consider that I am dealing with pure sine waves, and either ignoring the specific thresholds of the human ear or abstracting them into variables. If there are severe complications, then they are ignored. My question is how it could be represented in an algorithm, in that case.
Have a look at Chapter 4 of http://homepages.abdn.ac.uk/mth192/pages/html/maths-music.html. From memory:
1) If two sine waves are just close enough for the human ear to be confused, but not so close that the human ear cannot tell they are different, there will be dissonance.
2) Pure sine waves are extremely rare - most tones have all sorts of harmonics. Dissonance is very likely to occur from colliding harmonics, rather than colliding main tones - to sort of follow your example, two tones many octaves apart are unlikely to be dissonant because their harmonics may not meet, whereas with just a couple of octaves different and loads of harmonics a flute could sound out of tune with a double bass. Therefore dissonance or not depends not only on the frequencies of the main tones, but on the harmonics present, and this has been experimentally demonstrated by constructing sounds with peculiar pseudo-harmonics.
The answer is in Chapter 4 of Music: a Mathematical Offering. In particular, see the following two figures:
consonance / dissonance plotted against the x critical bandwidth in 4.3. History of consonance and dissonance
dissonance vs. frequency in 4.5. Complex tones
Of course you still have to find a nice way to turn these data into a formula / program that gives you a measure of dissonance but I believe this gives you a good start. Good luck!
This will help:
http://www.acs.psu.edu/drussell/demos/superposition/superposition.html
You want to look at superposition.
Discrete or Fast Fourier Transform is the most generic means to get what you're asking for.

cost of == operator vs < or > operators [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
This is really just sort of an academic question, I'm just curious to know which one is faster. I'm guessing the difference is negligible but still, I'd like to know.
if( (x == 1) || (x == 2) )
vs
if (x < 3)
thanks!
In the form you provided there is evident difference in complexity: the first code uses 3 operators, then the second -- just one. But OK, lets put this code of and assume you want to compare > (or <) and == (!=). If you have ever faced assembler while examing your programs (but i bet you didn't) you would notice such code
if (x < 3) /* action */;
being translated to smth like (for x86 CPU):
cmp %eax, 3 // <-- compare EAX and 3. It modifies flags register(*1) (namely ZF, CF, SF and so on)
jge ##skip // <-- this instruction tells CPU to jump when some conditions related to flags are met(*2).
// So this code is executed when jump is *not* made (when x is *not*
// greater or equal than 3.
/* here is action body */
##skip:
// ...
Now consider this code:
if (x == 3) /* action */;
It will give almost the same assembly (of course, it may differ from mine, but not semantically):
cmp %eax, 3
jne ##skip // < -- here is the only difference
/* action is run when x is equal to 3 */
##skip:
...
Both of this operators (jge and jne and others jumps) do their job with the same speed (because CPUs are made so, but it obviously depends on its architecture). The more impact on performance does distance of jump (difference between code positions), cache misses (when processor wrongly predicted the jump), and so on. Some instructions are more effective even (use less bytes for example), but remember the only thing: do not pay them so much attention. It always better to make algorythmic optimizations, don't do savings on matches. Let the compiler do it for you -- it is really more competent in such questions. Focus on your algorythms, code readablity, program architecture, fault-tolerance.. Make speed the last factor.
(*1): http://en.wikipedia.org/wiki/FLAGS_register_%28computing%29
(*2): http://www.unixwiz.net/techtips/x86-jumps.html

Matlab code optimization [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
f = #(w) test(w, phis, t, r_coeff);
function test(w, phis, t, r_coeff)
M = size(phis, 2);
expt = exp(-t .* (phis * w'));
coeff = expt .* t .^ 2 ./ (1 + expt) .^ 2;
averaging_coef = 1.0 / M; % mean replace
G = bsxfun(#times, phis', coeff' * averaging_coef) * phis + 2 * r_coeff * eye(M);
end
w - size is (1xM)
phis - size is (NxM)
t - size is (Nx1)
r_coeff is const
Help me please to optimize this piece of code, because function f runs a thousand times and N is around 300-800, M have mostly the same size. When I'm doing this * phis performance goes down.
As you can see it depends only on w - which I don't know.
It already is fairly well "optimized". Just because you want it to run faster does not make that possible.
You can buy/find/borrow/lease a faster/bigger computer. You can choose to solve smaller problems. You can just let it run overnight. Or you can change your problem to be something simpler and approximate, that runs more quickly.
This is what happens in research problems. They expand to the limits of your capability and just a bit more, because solving something easy is not worth a paper or a thesis. Computers make it easy to gather much data too, so problems get surprisingly large very quickly.
A special, rare skill in mathematics and modeling is knowing how to simplify your problem, deleting terms that are not truly important, while retaining the same basic behavior that you wish to study. This often involves linear approximations to nonlinear terms.

Time delay estimation between two audio signals

I have two audio recordings of a same signal by 2 different microphones (for example, in a WAV format), but one of them is recorded with delay, for example, several seconds.
It's easy to identify such a delay visually when viewing these signals in some kind of waveform viewer - i.e. just spotting first visible peak in every signal and ensuring that they're the same shape:
(source: greycat.ru)
But how do I do it programmatically - find out what this delay (t) is? Two digitized signals are slightly different (because microphones are different, were at different positions, due to ADC setups, etc).
I've digged around a bit and found out that this problem is usually called "time-delay estimation" and it has myriads of approaches to it - for example, one of them.
But are there any simple and ready-made solutions, such as command-line utility, library or straight-forward algorithm available?
Conclusion: I've found no simple implementation and done a simple command-line utility myself - available at https://bitbucket.org/GreyCat/calc-sound-delay (GPLv3-licensed). It implements a very simple search-for-maximum algorithm described at Wikipedia.
The technique you're looking for is called cross correlation. It's a very simple, if somewhat compute intensive technique which can be used for solving various problems, including measuring the time difference (aka lag) between two similar signals (the signals do not need to be identical).
If you have a reasonable idea of your lag value (or at least the range of lag values that are expected) then you can reduce the total amount of computation considerably. Ditto if you can put a definite limit on how much accuracy you need.
Having had the same problem and without success to find a tool to sync the start of video/audio recordings automatically,
I decided to make syncstart (github).
It is a command line tool. The basic code behind it is this:
import numpy as np
from scipy import fft
from scipy.io import wavfile
r1,s1 = wavfile.read(in1)
r2,s2 = wavfile.read(in2)
assert r1==r2, "syncstart normalizes using ffmpeg"
fs = r1
ls1 = len(s1)
ls2 = len(s2)
padsize = ls1+ls2+1
padsize = 2**(int(np.log(padsize)/np.log(2))+1)
s1pad = np.zeros(padsize)
s1pad[:ls1] = s1
s2pad = np.zeros(padsize)
s2pad[:ls2] = s2
corr = fft.ifft(fft.fft(s1pad)*np.conj(fft.fft(s2pad)))
ca = np.absolute(corr)
xmax = np.argmax(ca)
if xmax > padsize // 2:
file,offset = in2,(padsize-xmax)/fs
else:
file,offset = in1,xmax/fs
A very straight forward thing todo is just to check if the peaks exceed some threshold, the time between high-peak on line A and high-peak on line B is probably your delay. Just try tinkering a bit with the thresholds and if the graphs are usually as clear as the picture you posted, then you should be fine.

How to write correct code at the first time? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 13 years ago.
I usually make lots of mistakes (logic errors, syntax errors) in the first attempt to accomplish some programming tasks. I have to write unit test to detect those bugs. This is especially problematic when I am in an interview. In that situation, I am under pressure and I can not test my code with compiler and unit test.
My question is that how can I write correct code in the first place? I know it is difficult. Is there any pragmatic approach to reduce bugs at the first time?
I was required to write a function that receives a pointer to an int array and the size of the array. Fill that array with prime number. It's not a difficult problem at all. But I made lots of mistakes at the first time and keep finding out new bugs. Since it was a phone interview I was asked to type the answer and send it thought mail.
My first try
void prim(int * array, int size)
{ bool isPrime = true;
for (int i=0;i<size;i++)
{
for (int j = 2;j<i/2;j++)
{ if (i%j==0){
isPrime = ture;
*array = i;
array++;
} } } }
It was a really bad idea to write code in gmail. I will never do it again. I knew the program needs two for loops. However there are some big problems in the code
'i' should not increase at the end of first loop.
if i%j==0, isPrime should be false
the array operation should be put at the end of loop when we find a prime
My second try, I added isPrime test, fixed some errors and resubmitted it.
void prim(int * array, int size)
{
bool isPrime = true;
for (int i=0;i<size;i++)
{
isPrime = true;
for (int j = 2;j<i/2;j++)
{
if (i%j==0){
isPrime = false;
}
if (isPrime)
{
*array = i;
array++;
}
}
}
There are still some fundamental errors in the code. But my time is up, I try to fix them in my third try.
void prime(int * array, int size)
{
assert(array != null)
assert(size>0)
bool isPrime = true;
for (int i=0;i<size;)
{
isPrime = true;
for (int j = 2;j<i/2;j++)
{
if (i%j==0){
isPrime = false;
}
if (isPrime)
{
*array = i;
array++;
i++;
}
}
}
Finally. After the interview, I felt that I really massed up. I copied the code into my IDE, fixed all the bugs and tested it. I sent this to my interviewer and said sorry about that. I was really surprised by how many errors I could make in such a small problem.
Final Version
#include <iostream>
#include <assert.h>
using namespace std;
void prime(int * array, int size)
{
assert(array != 0);
assert(size>0);
if (size == 1){
*array=2;
return;
}
else {
*array=2;
array++;
}
bool isPrime = true;
int testNum = 3;
for (int i=1;i<size;)
{
isPrime = true;
for (int j = 2;j<testNum;j++)
{
if (testNum%j==0){
isPrime = false;
break;
}
}
if (isPrime)
{
*array = testNum;
array++;
i++;
}
testNum++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int t[5]={0,};
int sample[5]={2,3,5,7,11};
prime(t,5);
for (int i=0;i<5;i++){
assert(t[i]==sample[i]);
}
return 0;
}
lots of practice :)
although i dont think a few minor syntax errors will bother an interviewer too much - as long as your theory is sound.
You won't like the answer, which is: be a programmer for 20 years.
Write comments first.
Writing comments will help you specify the main objective of your code and will help later, if your code needs revision in the future.
As for the interview, it will also help interviewer better understand the idea you are writing even if your code is a little bit buggy.
You seem to be asking two questions
How do I answer coding questions at interviews?
How do I write good clean code?
Answering the first question is easier than the second. Please note that if you don't tell the interviewers about possible problems they're likely to presume that you don't realize there are errors, and you won't know to correct them. Here are some suggestions
tell the interviewer that you expect there may be syntax errors on your first cut
describe your algorithm in words
write pseudo code first
write functions top down
talk your way through the problem with the interviewer
tell the interviewer how you correct the errors
As for the second question, practice. Practice. Write lots of code. And yes, test driven development is a very good idea.
I will tell you what works on me. An on-the-fly error detector addon will help you very much.
I use Resharper. Before using it i had too many error at compilation time.
2 weeks ago i had to use a clean visual studio (resharper not installed) and I compiled the source with almost no errors.
Some people say that this tool makes programmer lazy, but i don't agree.
You need to simply program A LOT, start with really basic programs, then more complex ones.
Also during my first years at the uni, when we had introduction to programming in Pascal and C we had to "code" on paper all the time. At first I found it stupid, now I remember all the mistakes (tests were constructed so they would contain all the most common mistakes, like if(x = y) etc.) so I started coding on paper in Java recently (though I'm still a java beginner).
Now I code all sorts of things (whenever I find a decent idea I code it) and I think it's the only way to improve.
how can I write correct code in the first place
If this question had a trivial answer, we wouldn't have day jobs.
While there is some academic work on the "proveability" of software programs, there's no substitute for a logical thinking and attention to detail -- particularly if all you have is a whiteboard and a marker.
As others have mentioned interviewers generally give some leeway for syntax errors but gross logical mistakes are less likely to be ignored.
Slow is smooth, Smooth is fast
- Unknown
Take your time and think about the code. As you work/practice you will make less mistakes and you will get faster in your coding. Just like anything else when you rush to do something and don't think you make mistakes. The more you do that thing the more it becomes a reaction instead of a thought.
Practice. If you usually use an IDE at work or at school, spend one day every other week coding without it.
If you can give an example of the types of errors you're prone to, folks can probably give much more specific advice.
Practise, use the right tools for the job, write lots of code, learn your tools, write more code, read books about programming, write even more code. You get the idea. Programming is hard work, and there aren't really any shortcuts.
That said, anybody giving a coding task at an interview expecting a result which will compiles cleanly and works out-of-the box is clearly mad, and you do not want to work there. Good managers use coding tasks to see how you approach a problem.

Resources