Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleaned up whitespace #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.DS_Store
*.o
Test_Yin
Test_Yin
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ OBJECTS= Test_Yin.o Yin.o

# --- targets
all: Test_Yin
Test_Yin: $(OBJECTS)
Test_Yin: $(OBJECTS)
$(CC) -o Test_Yin $(OBJECTS) $(LIBS)

Test_Yin.o: Test_Yin.c Yin.h
$(CC) $(CFLAGS) -c Test_Yin.c

Yin.o: Yin.c Yin.h
$(CC) $(CFLAGS) -c Yin.c
$(CC) $(CFLAGS) -c Yin.c


# --- remove binary and executable files
clean:
rm -f Test_Yin $(OBJECTS)
rm -f Test_Yin $(OBJECTS)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ Thanks to [JorenSix](https://github.com/JorenSix/) for the original C++ implemen

The [YIN algorithm](http://audition.ens.fr/adc/pdf/2002_JASA_YIN.pdf) is a popular algorithm for tracking pitch (or the fundamental frequecy) of a monophonic audio signal. This project is an implementation of the Yin algorithm in C, suitable for embedded systems.

The code was ported to C from C++ from the [The Pidato Experiment](https://github.com/JorenSix/). The Pidato project was originally written for the Arduino platform, hence the C++. This is an attempt to port the algorithm implemented in the Pidato project to a more generic module in pure C, and has been used sucessfully in both embedded systems and high level applications.
The code was ported to C from C++ from the [The Pidato Experiment](https://github.com/JorenSix/). The Pidato project was originally written for the Arduino platform, hence the C++. This is an attempt to port the algorithm implemented in the Pidato project to a more generic module in pure C, and has been used sucessfully in both embedded systems and high level applications.
2 changes: 1 addition & 1 deletion TestAudio/audioExtract.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
audioData = []

# Extract all the samples from the audio file into an array
for i in range(0,length):
for i in range(0,length):
waveData = waveFile.readframes(1)
data = struct.unpack("<h", waveData)
audioData.append(data[0])
Expand Down
14 changes: 7 additions & 7 deletions Test_Yin.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@


/* Audio array with samples from .wav file
* contains
* #define NUM_SAMPLES 176400
* int audio[176400] = {...}
* contains
* #define NUM_SAMPLES 176400
* int audio[176400] = {...}
*/
#include "audioData.h"

Expand All @@ -25,11 +25,11 @@ int main(int argc, char** argv) {

while (pitch < 10 ) {
Yin_init(&yin, buffer_length, 0.05);
pitch = Yin_getPitch(&yin, audio);
pitch = Yin_getPitch(&yin, audio);
buffer_length++;
}


printf("Pitch is found to be %f with buffer length %i and probabiity %f\n",pitch, buffer_length, Yin_getProbability(&yin) );
return 0;
}
}
39 changes: 18 additions & 21 deletions Yin.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/**
* Step 1: Calculates the squared difference of the signal with a shifted version of itself.
* @param buffer Buffer of samples to process.
* @param buffer Buffer of samples to process.
*
* This is the Yin algorithms tweak on autocorellation. Read http://audition.ens.fr/adc/pdf/2002_JASA_YIN.pdf
* for more details on what is in here and why it's done this way.
Expand All @@ -22,7 +22,7 @@ void Yin_difference(Yin *yin, int16_t* buffer){
for(tau = 0 ; tau < yin->halfBufferSize; tau++){

/* Take the difference of the signal with a shifted version of itself, then square it.
* (This is the Yin algorithm's tweak on autocorellation) */
* (This is the Yin algorithm's tweak on autocorellation) */
for(i = 0; i < yin->halfBufferSize; i++){
delta = buffer[i] - buffer[i + tau];
yin->yinBuffer[tau] += delta * delta;
Expand All @@ -35,7 +35,7 @@ void Yin_difference(Yin *yin, int16_t* buffer){
* Step 2: Calculate the cumulative mean on the normalised difference calculated in step 1
* @param yin #Yin structure with information about the signal
*
* This goes through the Yin autocorellation values and finds out roughly where shift is which
* This goes through the Yin autocorellation values and finds out roughly where shift is which
* produced the smallest difference
*/
void Yin_cumulativeMeanNormalizedDifference(Yin *yin){
Expand All @@ -58,7 +58,7 @@ void Yin_cumulativeMeanNormalizedDifference(Yin *yin){
int16_t Yin_absoluteThreshold(Yin *yin){
int16_t tau;

/* Search through the array of cumulative mean values, and look for ones that are over the threshold
/* Search through the array of cumulative mean values, and look for ones that are over the threshold
* The first two positions in yinBuffer are always so start at the third (index 2) */
for (tau = 2; tau < yin->halfBufferSize ; tau++) {
if (yin->yinBuffer[tau] < yin->threshold) {
Expand Down Expand Up @@ -95,26 +95,26 @@ int16_t Yin_absoluteThreshold(Yin *yin){
* @return [description]
*
* The 'best' shift value for autocorellation is most likely not an interger shift of the signal.
* As we only autocorellated using integer shifts we should check that there isn't a better fractional
* As we only autocorellated using integer shifts we should check that there isn't a better fractional
* shift value.
*/
float Yin_parabolicInterpolation(Yin *yin, int16_t tauEstimate) {
float betterTau;
int16_t x0;
int16_t x2;

/* Calculate the first polynomial coeffcient based on the current estimate of tau */
if (tauEstimate < 1) {
x0 = tauEstimate;
}
}
else {
x0 = tauEstimate - 1;
}

/* Calculate the second polynomial coeffcient based on the current estimate of tau */
if (tauEstimate + 1 < yin->halfBufferSize) {
x2 = tauEstimate + 1;
}
}
else {
x2 = tauEstimate;
}
Expand All @@ -123,19 +123,19 @@ float Yin_parabolicInterpolation(Yin *yin, int16_t tauEstimate) {
if (x0 == tauEstimate) {
if (yin->yinBuffer[tauEstimate] <= yin->yinBuffer[x2]) {
betterTau = tauEstimate;
}
}
else {
betterTau = x2;
}
}
}
else if (x2 == tauEstimate) {
if (yin->yinBuffer[tauEstimate] <= yin->yinBuffer[x0]) {
betterTau = tauEstimate;
}
}
else {
betterTau = x0;
}
}
}
else {
float s0, s1, s2;
s0 = yin->yinBuffer[x0];
Expand Down Expand Up @@ -191,32 +191,29 @@ void Yin_init(Yin *yin, int16_t bufferSize, float threshold){
float Yin_getPitch(Yin *yin, int16_t* buffer){
int16_t tauEstimate = -1;
float pitchInHertz = -1;

/* Step 1: Calculates the squared difference of the signal with a shifted version of itself. */
Yin_difference(yin, buffer);

/* Step 2: Calculate the cumulative mean on the normalised difference calculated in step 1 */
Yin_cumulativeMeanNormalizedDifference(yin);

/* Step 3: Search through the normalised cumulative mean array and find values that are over the threshold */
tauEstimate = Yin_absoluteThreshold(yin);

/* Step 5: Interpolate the shift value (tau) to improve the pitch estimate. */
if(tauEstimate != -1){
pitchInHertz = YIN_SAMPLING_RATE / Yin_parabolicInterpolation(yin, tauEstimate);
}

return pitchInHertz;
}

/**
* Certainty of the pitch found
* Certainty of the pitch found
* @param yin Yin object that has been run over a buffer
* @return Returns the certainty of the note found as a decimal (i.e 0.3 is 30%)
*/
float Yin_getProbability(Yin *yin){
return yin->probability;
}



6 changes: 3 additions & 3 deletions Yin.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/**
* @struct Yin
* @breif Object to encapsulate the parameters for the Yin pitch detection algorithm
* @breif Object to encapsulate the parameters for the Yin pitch detection algorithm
*/
typedef struct _Yin {
int16_t bufferSize; /**< Size of the audio buffer to be analysed */
Expand All @@ -35,12 +35,12 @@ void Yin_init(Yin *yin, int16_t bufferSize, float threshold);
float Yin_getPitch(Yin *yin, int16_t* buffer);

/**
* Certainty of the pitch found
* Certainty of the pitch found
* @param yin Yin object that has been run over a buffer
* @return Returns the certainty of the note found as a decimal (i.e 0.3 is 30%)
*/
float Yin_getProbability(Yin *yin);



#endif
2 changes: 1 addition & 1 deletion audioData.h
Original file line number Diff line number Diff line change
Expand Up @@ -1500,4 +1500,4 @@ int16_t audio[1500] = {
-25,
-26,
-27,
-28};
-28};