Skip to content

Commit

Permalink
Fix errors and misleading results
Browse files Browse the repository at this point in the history
  • Loading branch information
sevagh committed Apr 25, 2019
1 parent 84815b6 commit 521481b
Show file tree
Hide file tree
Showing 20 changed files with 26 additions and 877 deletions.
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ lib:
src/mpm.cpp \
src/swipe.cpp \
src/autocorrelation.cpp \
src/parabolic_interpolation.cpp \
src/capi.cpp
src/parabolic_interpolation.cpp

install: lib
cp -r include/pitch_detection /usr/local/include
Expand Down
79 changes: 14 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### Pitch detection algorithms

Autocorrelation-based C++ pitch detection algorithms with **O(nlogn) or lower** running time and a C API:
Autocorrelation-based C++ pitch detection algorithms with **O(nlogn) or lower** running time:

* McLeod pitch method - [2005 paper](http://miracle.otago.ac.nz/tartini/papers/A_Smarter_Way_to_Find_Pitch.pdf) - [visualization](./misc/mcleod)
* YIN(-FFT) - [2002 paper](http://audition.ens.fr/adc/pdf/2002_JASA_YIN.pdf) - [visualization](./misc/yin)
Expand All @@ -18,24 +18,24 @@ Suggested usage of this library can be seen in the utility [wav_analyzer](./wav_

All testing files are [here](./degraded_audio_tests) - the progressive degradations are described by the respective numbered JSON file, generated using [audio-degradation-toolbox](https://github.com/sevagh/audio-degradation-toolbox). The original clip is a Viola playing E3 from the [University of Iowa MIS](http://theremin.music.uiowa.edu/MIS.html).

The results come from parsing the output of wav_analyzer to count how many slices of the input clip were in the ballpark of the expected value of 164.81 - I considered anything 160-169 to be acceptable:
The results come from parsing the output of wav_analyzer to count how many 0.1s slices of the input clip were in the ballpark of the expected value of 164.81 - I considered anything 160-169 to be acceptable:

| Degradation level | MPM # correct | YIN # correct | SWIPE' # correct |
| ------------- | ------------- | ------------- | ------------- |
| 0 | 60 | 61 | 28 |
| 1 | 59 | 54 | 25 |
| 2 | 51 | 46 | 23 |
| 3 | 50 | 47 | 23 |
| 4 | 49 | 27 | 10 |
| 5 | 49 | 28 | 14 |
| 0 | 26 | 22 | 5 |
| 1 | 23 | 21 | 13 |
| 2 | 19 | 21 | 9 |
| 3 | 18 | 19 | 7 |
| 4 | 19 | 19 | 6 |
| 5 | 18 | 19 | 5 |

### Build and install

Using this project should be as easy as `make && sudo make install` on Linux with a modern GCC - I don't officially support other platforms.

This project depends on [ffts](https://github.com/anthonix/ffts) and BLAS/LAPACK. To run the tests, you need [googletest](https://github.com/google/googletest), and run `make -C test/ && ./test/test`. To run the bench, you need [google benchmark](https://github.com/google/benchmark), and run `make -C test/ bench && ./test/bench`.

Build and install pitch_detection, run the tests, and build the examples:
Build and install pitch_detection, run the tests, and build the sample application, wav_analyzer:

```
# build libpitch_detection.so
Expand All @@ -51,20 +51,14 @@ make -C test clean all
# install the library and headers to `/usr/local/lib` and `/usr/local/include`
sudo make install
# build and run C++ example
make -C examples/cpp clean all
./examples/cpp/example
# build and run C example
make -C examples/c clean all
./examples/c/example
# build and run C++ sample
make -C wav_analyzer clean all
./wav_analyzer/wav_analyzer
```

### Usage

#### C++

Read the [C++ header](./include/pitch_detection/pitch_detection.h) and [C++ example](./examples/cpp).
Read the [header](./include/pitch_detection/pitch_detection.h) and [sample wav_analyzer](./wav_analyzer).

The namespaces are `pitch` and `pitch_alloc`. The functions and classes are templated for `<double>` and `<float>` support.

Expand All @@ -77,6 +71,7 @@ std::vector<double> audio_buffer(8092);

double pitch_yin = pitch::yin<double>(audio_buffer, 48000);
double pitch_mpm = pitch::mpm<double>(audio_buffer, 48000);
double pitch_swipe = pitch::swipe<double>(audio_buffer, 48000);

std::vector<std::pair<double, double>> pitches_pyin = pitch::pyin<double>(audio_buffer, 48000);
std::vector<std::pair<double, double>> pitches_pmpm = pitch::pmpm<double>(audio_buffer, 48000);
Expand All @@ -92,49 +87,3 @@ for (int i = 0; i < 10000; ++i) {
auto pitches_pmpm = ma.probabilistic_pitches(audio_buffer, 48000);
}
```
#### C
Read the [C header](./include/pitch_detection/cpitch_detection.h) and [C example](./examples/c).
In C, the `pitch` and `pitch_alloc` namespaces becomes `pitch_` and `pitch_alloc_` prefixes. `double` and `float` templates are now explicit structs and functions with `d/D` and `f/F` in the name.
Also, to represent `std::vector<std::pair<T, T>>` pitch candidates, there are some custom structs:
```c
struct pitch_candidates_d_t {
long n_candidates;
struct pitch_probability_pair_d_t *candidates;
};
struct pitch_probability_pair_d_t {
double pitch;
double probability;
};
```

Here are the above C++ examples, transliterated using the C API:

```c
#include <cpitch_detection.h>

double audio_buffer[8092];

double pitch_yin = pitch_yin_d(audio_buffer, 8092, 48000);
double pitch_mpm = pitch_mpm_d(audio_buffer, 8092, 48000);

//pyin and pmpm emit struct
struct pitch_candidates_d_t * pitches_pmpm = pitch_pmpm_d(audio_buffer, 8092, 48000);
struct pitch_candidates_d_t * pitches_pyin = pitch_pyin_d(audio_buffer, 8092, 48000);

struct Mpm_d_t ma = NewMpmD(8092);
struct Yin_d_t ya = NewYinD(8092);

for (int i = 0; i < 10000; ++i) {
double pitch_yin = ya.pitch(audio_buffer, 48000);
double pitch_mpm = ma.pitch(audio_buffer, 48000);

struct pitch_candidates_d_t * pitches_pmpm = pitch_alloc_pmpm_d(ma, audio_buffer, 48000);
struct pitch_candidates_d_t * pitches_pyin = pitch_alloc_pyin_d(ya, audio_buffer, 48000);
}
```
Binary file removed docs/hmm.png
Binary file not shown.
3 changes: 1 addition & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ <h2>2 - How should I get started?</h2>
<p>Try to write your own autocorrelation-based pitch detection algorithm, e.g. with <a href="https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.correlate.html">scipy</a>. Use the <a href="https://github.com/sevagh/pitch-detection/blob/master/wav_analyzer/wav_analyzer.cpp">wav_analyzer</a> utility to see what it might look like in C++ to open an audio file and send it chunk by chunk to a pitch detection algorithm. If you prefer Python, here's a tiny <a href="https://github.com/sevagh/pitch-detection/blob/master/misc/samples/get_raw_audio.py">Python snippet</a> which uses Pydub to extract audio from a file.</p>
<h2>3 - What's next?</h2>
<p>Read the <a href="https://www.eecs.qmul.ac.uk/~simond/pub/2014/MauchDixon-PYIN-ICASSP2014.pdf">Probabilistic YIN paper</a>, and the similar <a href="https://github.com/sevagh/pitch-detection/blob/master/misc/probabilistic-mcleod">Probabilistic McLeod pitch method doc</a>.</p>
<p>Explore my <a href="https://github.com/sevagh/hmm-pitch-smoothing">HMM pitch smoothing</a> code which demonstrates HMM-based pitch smoothing techniques -</p>
<img src="hmm.png" width="800px">
<p>Explore my <a href="https://github.com/sevagh/hmm-pitch-smoothing">HMM pitch smoothing</a> code which demos HMM-based pitch smoothing techniques.</p>
</body>
</html>
1 change: 0 additions & 1 deletion examples/c/.gitignore

This file was deleted.

12 changes: 0 additions & 12 deletions examples/c/Makefile

This file was deleted.

93 changes: 0 additions & 93 deletions examples/c/example.c

This file was deleted.

1 change: 0 additions & 1 deletion examples/cpp/.gitignore

This file was deleted.

12 changes: 0 additions & 12 deletions examples/cpp/Makefile

This file was deleted.

88 changes: 0 additions & 88 deletions examples/cpp/example.cpp

This file was deleted.

Loading

0 comments on commit 521481b

Please sign in to comment.