Metadata-Version: 2.4
Name: bedcmmPitch
Version: 0.1.0
Summary: Pitch detection using periodicity analysis
Author: WATARU YASUHARA
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: LICENSE.ja
Requires-Dist: numpy>=2.0.2
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

# bedcmmPitch
**Research / Evaluation / PoC use only.**
## Pitch Detection Algorithm

This repository provides a pitch detection algorithm based on a periodicity analysis method.  
It is intended for research and Proof of Concept (PoC) use.
Robust to spike-like noise and impulsive artifacts.

The implementation includes two main functions:
- `calc_Pitch`: computes pitch values
- `calc_bedcmm`: outputs intermediate periodicity analysis results

## Installation

### Install from PyPI

```bash
pip install bedcmmPitch
```

### Optional: Build Cython extension from source

```bash
python setup.py build_ext --inplace
```

## Example

```python
import numpy as np
from bedcmmPitch import calc_Pitch

fs = 44100
t = np.arange(fs) / fs
x = np.sin(2*np.pi*440*t)

pitch, score = calc_Pitch(x)

print(np.nanmean(pitch))
```

## Robustness to Spike Noise (Comparison with pYIN)

We compared this method with pYIN implemented in librosa under spike noise conditions.


### Results

#### Time-series comparison (spike ratio = 1000)
![timeseries_comp](https://raw.github.com/YASUHARA-Wataru/bedcmmPitch/main/pic/spike_ratio_1000.png)

- YIN shows large pitch errors under spike noise
- pYIN is more stable but still degrades
- bedcmm remains stable

#### Detection rate vs spike noise
![detect_ratio_comp](https://raw.github.com/YASUHARA-Wataru/bedcmmPitch/main/pic/spike_ratio_measure_ratio.png)

Detection rate is defined as the ratio of frames where
the pitch error is within ±5% of the ground truth.

### Experimental Setup
- Signal: 220 Hz sine wave
- Sampling rate: 44.1 kHz
- Spike noise: random impulses with varying amplitude ratio (see `simulation_test.py`)
- Window size: 2048
- Hop size: 256

### Notes
- pYIN uses default parameters from librosa
- bedcmm uses default parameters unless otherwise noted
- Reproducible scripts are available in `simulation_test.py`.

### Summary
bedcmm shows significantly higher robustness to spike noise compared to pYIN.

## About bedcmm

`bedcmm` is a periodicity analysis method used as the core of this pitch detection algorithm.

For more details, please refer to the original repository:
https://github.com/YASUHARA-Wataru/bedcmm
---

## Requirements

- numpy

Cython is only required when building from source.

## Functions

### calc_Pitch

**Input (default):**
- `data` : 1D array (signal data)
- `fs (44100)` : float (sampling rate)
- `window_size (2048)` : int (window size)
- `hop_size (256)` : int (hop size)
- `fmin(65)` : float(calculation min freq)
- `fmax(2000)` : float(calculation max freq)
- `pp_mode ('positive+negative')` : str (preprocessing mode: `'positive'`, `'negative'`, `'positive+negative'`, `'threshold_diff'`)
- `pp_threshold (0)` : float (preprocessing threshold, used in `'threshold_diff'` mode)
- `bedcmm_smooth (3)` : int (smoothing size for bedcmm result; 1 means no smoothing)
- `pitch_detect_mode ('peak')` : str (peak detection mode: `'score'`, `'static'`, `'maximum'`, `'peak'`)
- `pitch_detect_thre (0.85)` : float (threshold for peak detection)
- `interpolator_mode ('parabolic')` : str (peak interpolation mode: `'parabolic'`, `'centroid'`, `'gaussian'`, `'no'`)

**Output:**
- Pitch data: 1D array
- Score data: 1D array (bedcmm score)

---

### calc_bedcmm

**Input:**
- `data` : 1D array (signal data)
- `fs (44100)` : float (sampling rate)
- `window_size (2048)` : int (window size)
- `hop_size (256)` : int (hop size)
- `fmin(None)` : float(calculation min freq)
- `fmax(None)` : float(calculation max freq)
- `pp_mode ('positive')` : str (preprocessing mode)
- `pp_threshold (0)` : float (used in `'threshold_diff'` mode)

**Output:**
- bedcmm data: 2D array (time, bedcmm)
- mean data: 1D array (time)

---

## Calculation speed
The benchmark script is ```speed_test.py```.
Real-time factor ≈ 1.0 indicates near real-time processing.
Values may slightly vary depending on the execution environment.

### Cython
preprocessing mode 'positive+negative'(default)(Accurate:Robust to noise and outliers)
```
=== Benchmark Result ===
 audio_sec  proc_sec  real_time_factor
        10   10.9753            1.0975
        20   23.1892            1.1595
        30   31.2636            1.0421
```

preprocessing mode 'positive' (Fast:Reduced computation, slightly less robust)
```
=== Benchmark Result ===
 audio_sec  proc_sec  real_time_factor
        10    4.6133            0.4613
        20   11.0052            0.5503
        30   17.7401            0.5913
```

## Notes

It is recommended to use the default parameters.

Default calculation pitch range is 65[Hz] to 2000[Hz].

You may observe differences depending on parameter settings, so feel free to experiment if needed.

- When `pitch_detect_mode = 'score'`, the threshold is calculated as:  
  (mean of input signal) × `pitch_detect_threshold`

- When `pitch_detect_mode = 'static'`, `pitch_detect_threshold` is used directly as a threshold.

- When `pitch_detect_mode = 'peak'`, the threshold is:  
  (maximum peak value of bedcmm) × `pitch_detect_threshold`

- When `pitch_detect_mode = 'maximum'`, it may not function properly unless `pitch_range` is restricted.

- The default `pp_mode` prioritizes accuracy but is computationally expensive.  
  For faster computation, you can use `'positive'` or `'negative'`.

- When using `pp_mode = 'threshold_diff'`, all values must be non-negative; otherwise, the scoring mechanism may not function correctly.

---

## for Development fast Installation

1. Copy the `bedcmmPitch` folder into your working directory  
2. Copy `setup.py` into your working directory  
3. Ensure the following libraries are installed:
   - numpy
   - cython
   - setuptools  
   - (optional) matplotlib (for visualization)

   If not installed, use `pip` or `uv` to install them.

4. In your working directory, run:

```bash
python setup.py build_ext --inplace
```


5. Run `main.py` to verify functionality

*Note:* Step 4 can be skipped; the pure Python implementation will still work.

---

## License

This repository is available **for research, evaluation, and Proof of Concept (PoC) purposes only**.

### Permitted Use

- Research use
- Algorithm evaluation and validation
- Proof of Concept (PoC)

PoC usage is allowed **without time limitation**.

### Restrictions

The following uses are prohibited:

- Commercial use (including integration into products or services, or any monetized usage)
- Use in production environments (including integration into operational systems)

### Commercial Use

If you wish to use this software for commercial purposes or in a production environment,  
a **separate commercial license agreement is required**.

Please contact via Issues or direct email for inquiries.

### Disclaimer

This software is provided "AS IS", without warranty of any kind.  
The author shall not be held liable for any damages arising from the use of this software.

---

*For detailed terms, please refer to the `LICENSE` file.*

---

## Contact
For commercial use, please contact us with a brief description of your use case.
fapow.contact[at]gmail.com

## Patent Notice

This repository includes technology related to a patented method in Japan.

The patent rights are currently granted in Japan only.
However, this does not grant any rights for commercial use of this software or the underlying technology.

For any commercial or production use, please contact the author.
