Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a7a6621
New P3
JudithAviles Apr 20, 2026
4804b25
P3
JudithAviles Apr 24, 2026
5a6f167
P3.2
JudithAviles Apr 24, 2026
6456e95
Funcions get_pitch i unvoiced()
JudithAviles May 3, 2026
64d6b1d
Fixed functions
JudithAviles May 8, 2026
2d6883f
.
JudithAviles May 8, 2026
eac4b11
"End of session, docopt"
JudithAviles May 8, 2026
63cb019
perdona judith :'(
Tomasprr May 15, 2026
2d738c6
docopt modificat per rebre inputs
Tomasprr May 15, 2026
4e41ec7
strip get_pitch CLI down to core options (--min-f0, --max-f0, --frame…
Tomasprr May 15, 2026
92fc919
Merge main into Aviles_Parramon
Tomasprr May 15, 2026
07ed771
.
JudithAviles May 15, 2026
39d6c9c
pre i post processat total de 90.57 amb parametres -40,0.25 i 0.35 en…
Tomasprr May 16, 2026
b751b49
..
Tomasprr May 16, 2026
63129e4
Low-pass filter, filtre de mediana, center-clipping, documentation up…
JudithAviles May 16, 2026
9986f58
Merge remote-tracking branch 'refs/remotes/origin/Aviles_Parramon' in…
JudithAviles May 16, 2026
9116e21
Error correction + parameter adjustement, 91,4%
JudithAviles May 16, 2026
544710e
Fet mètodes AMDF i cepstrum, afegit sistema per poder escollir quin m…
JudithAviles May 16, 2026
28e2098
cepstrum arreglat i codis per als grafics python creats
Tomasprr May 17, 2026
da282d2
arreglat una cosa del path
Tomasprr May 17, 2026
5da03e2
canviat el path perque ara funcioni per tothom
Tomasprr May 17, 2026
2ba1e00
Updated README with code snippets, graphs, parameter table, and docum…
Tomasprr May 17, 2026
99d5951
Delete build directory (únic per cada usuari, no s'ha de compartir en…
JudithAviles May 17, 2026
b09b749
Delete .vscode directory (únic per cada usuari, no s'ha de compartir …
JudithAviles May 17, 2026
815c164
.
JudithAviles May 17, 2026
af42e91
..
JudithAviles May 17, 2026
17f5d7c
...
JudithAviles May 17, 2026
bdab6ee
Merge branch 'Aviles_Parramon' of https://github.com/JudithAviles/P3 …
JudithAviles May 17, 2026
1a54c64
Ajust final de paràmetres, percentatge final 91.48%
JudithAviles May 17, 2026
aebf4d3
README Repasado
JudithAviles May 17, 2026
83e55a3
.
JudithAviles May 17, 2026
2692625
.
JudithAviles May 17, 2026
fa6c3da
.
JudithAviles May 17, 2026
ed4ae5e
README Corregido
JudithAviles May 17, 2026
fa3a942
README Corregido
JudithAviles May 17, 2026
c297003
Added get_pitch_-h.png
JudithAviles May 17, 2026
dcb9d2c
\
Tomasprr May 17, 2026
1a992ac
\
Tomasprr May 17, 2026
b81654d
README Final
JudithAviles May 17, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ __MAC*
*DS_Store
*Zone.Identifier
*bak
handoff.md
163 changes: 146 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,70 @@ Ejercicios básicos

* Complete el cálculo de la autocorrelación e inserte a continuación el código correspondiente.

```cpp
// Autocorrelation computation (biased)
if (r[0] == 0.0F) //to avoid log() and divide zero
r[0] = 1e-10;
void PitchAnalyzer::autocorrelation(const vector<float> &x, vector<float> &r) const {
for (unsigned int l = 0; l < r.size(); ++l) {
r[l] = 0;
int N = x.size();
for (int n = l; n < N; ++n){
r[l] += x[n]*x[n-l];
}
r[l] = r[l]/N;
}
if (r[0] == 0.0F) r[0] = 1e-10;
}
```
Formula: r[l] = (1/N) * sum(x[n] * x[n-l]) for n=l to N

* Inserte una gŕafica donde, en un *subplot*, se vea con claridad la señal temporal de un segmento de
unos 30 ms de un fonema sonoro y su periodo de pitch; y, en otro *subplot*, se vea con claridad la
autocorrelación de la señal y la posición del primer máximo secundario.

NOTA: es más que probable que tenga que usar Python, Octave/MATLAB u otro programa semejante para
hacerlo. Se valorará la utilización de la biblioteca matplotlib de Python.

* Determine el mejor candidato para el periodo de pitch localizando el primer máximo secundario de la
autocorrelación. Inserte a continuación el código correspondiente.
hacerlo. Se valorará la utilización de la biblioteca matplotlib de Python.

![30ms segment + autocorrelation](prueba_autocorr.png)

* Determine el mejor candidato para el periodo de pitch localizando el primer máximo secundario de la
autocorrelación. Inserte a continuación el código correspondiente.

```cpp
// Find maximum autocorrelation in pitch range
vector<float> r(npitch_max);
autocorrelation(x, r);
vector<float>::const_iterator iR = r.begin(), iRMax = r.begin() + npitch_min;
for(iR = iRMax; (iR < r.begin()+npitch_max-1 && iR < r.end()); iR++){
if(*iR > *iRMax){
iRMax = iR;
}
}
unsigned int lag = iRMax - r.begin();
float f0 = (float) samplingFreq/(float) lag;
```

* Implemente la regla de decisión sonoro o sordo e inserte el código correspondiente.

```cpp
// Unvoiced decision rule
bool PitchAnalyzer::unvoiced(float pot, float r1norm, float rmaxnorm, float zcr) const {
// pot: power in dB = 10*log10(r[0])
// r1norm: r[1]/r[0] - correlation at lag 1
// rmaxnorm: r[lag_max]/r[0] - correlation at pitch period
// zcr: zero crossing rate

if (pot < pot_threshold || zcr < zcr_threshold*samplingFreq/2){
return true;
} else if (r1norm >= r1norm_threshold && rmaxnorm >= rmaxnorm_threshold){
return false;
} else{
return true;
}
}
```

* Puede serle útil seguir las instrucciones contenidas en el documento adjunto `código.pdf`.

- Una vez completados los puntos anteriores, dispondrá de una primera versión del estimador de pitch. El
Expand All @@ -40,22 +92,42 @@ Ejercicios básicos
(r[0]), la autocorrelación normalizada de uno (r1norm = r[1] / r[0]) y el valor de la
autocorrelación en su máximo secundario (rmaxnorm = r[lag] / r[0]).

Puede considerar, también, la conveniencia de usar la tasa de cruces por cero.
![Wavesurfer parameters](prueba_wavesurfer.png)

*Parámetros: pot (umbral -42 dB), r1norm (umbral 0.48), rmaxnorm (umbral 0.34). Nosotros también hemos considerado*
*utilizar la tasa de cruces por cero zcr (umbral 0.012).*

Puede considerar, también, la conveniencia de usar la tasa de cruces por cero.

Recuerde configurar los paneles de datos para que el desplazamiento de ventana sea el adecuado, que
en esta práctica es de 15 ms.

- Use el estimador de pitch implementado en el programa `wavesurfer` en una señal de prueba y compare
su resultado con el obtenido por la mejor versión de su propio sistema. Inserte una gráfica
ilustrativa del resultado de ambos estimadores.

Aunque puede usar el propio Wavesurfer para obtener la representación, se valorará
el uso de alternativas de mayor calidad (particularmente Python).
en esta práctica es de 15 ms.

- Use el estimador de pitch implementado en el programa `wavesurfer` en una señal de prueba y compare
su resultado con el obtenido por la mejor versión de su propio sistema. Inserte una gráfica
ilustrativa del resultado de ambos estimadores.

![F0 comparison: our estimator vs Wavesurfer reference](prueba_comparison.png)

Aunque puede usar el propio Wavesurfer para obtener la representación, se valorará
el uso de alternativas de mayor calidad (particularmente Python).

*Podemos observar que nuestra estimación es muy cercana a la obtenida por Wavesurfer. Únicamente se detecta tono en los segmentos apropiados y los segmentos sordos son etiquetados apropiadamente, con una pequeña cantidad de error en las secciones de traspaso de sordo a sonoro y de sonoro a sordo. El tono estimado en sí también es muy correcto, aunque comete algún error en los picos y cambios repentinos a causa del postprocesado aplicado (el filtro de mediana y la prevención de errores).*

* Optimice los parámetros de su sistema de estimación de pitch e inserte una tabla con las tasas de error
y el *score* TOTAL proporcionados por `pitch_evaluate` en la evaluación de la base de datos
`pitch_db/train`..

| alpha0 (dB) | alpha1 (r1/r0) | alpha2 (rmax/r0) | alpha3 (zcr) | TOTAL Score |
|-------------|----------------|-----------------|-----------------|-------------|
| -42 | 0.48 | 0.34 |0.012 | **91.48%** |
| -42 | 0.48 | 0.34 |0.011 | 91.47% |
| -43 | 0.48 | 0.34 |0.012 | 91.46% |
| -43 | 0.48 | 0.34 |0.011 | 91.45% |
| -41 | 0.46 | 0.32 |0.009 | 91.19% |

*Parámetros optimizados: alpha0=-42, alpha1=0.48, alpha2=0.34, alpha3=0.012.*
*Hemos optimizado los parámetros a través del script* `grid_search.sh`*, el cual nos ha permitido comprobar múltiples combinaciones de diferentes valores para cada parámetro para encontrar la que nos daría el score máximo. Antes de utilizar* `grid_search` *se ha hecho una búsqueda inicial de valores apropiados manual para reducir la cantidad de valores a buscar en* `grid_search` *y reducir su tiempo de computación.*

Ejercicios de ampliación
------------------------

Expand All @@ -69,6 +141,13 @@ Ejercicios de ampliación
* Inserte un *pantallazo* en el que se vea el mensaje de ayuda del programa y un ejemplo de utilización
con los argumentos añadidos.

![Pantallazo de `get_pitch -h`](get_pitch_-h.png)

Ejemplo de uso:
```bash
get_pitch --alpha0=-40 --alpha1=0.45 --alpha2=0.35 --alpha3=0.015 --method=cepstrum entrada.wav salida.f0
```

- Implemente las técnicas que considere oportunas para optimizar las prestaciones del sistema de estimación
de pitch.

Expand All @@ -89,10 +168,60 @@ Ejercicios de ampliación
Incluya, a continuación, una explicación de las técnicas incorporadas al estimador. Se valorará la
inclusión de gráficas, tablas, código o cualquier otra cosa que ayude a comprender el trabajo realizado.

También se valorará la realización de un estudio de los parámetros involucrados. Por ejemplo, si se opta
por implementar el filtro de mediana, se valorará el análisis de los resultados obtenidos en función de
la longitud del filtro.

También se valorará la realización de un estudio de los parámetros involucrados. Por ejemplo, si se opta
por implementar el filtro de mediana, se valorará el análisis de los resultados obtenidos en función de
la longitud del filtro.

## Técnicas Implementadas

### Preprocesado
- **Filtro paso bajo (LPF)**: Filtro de averaging (3x1) para suavizar la señal.

Para implementar el filtro paso bajo se han probado diferentes tipos de LPF y diferentes tamaños para estos.

Probamos a implementar un filtro butterworth de orden 4, pero, además de incrementar el coste computacional del programa, no fue muy efectivo, y causaba un aumento en la tasa de segmentos sordos identificados como sonoros.

Como alternativa, hemos implementado un filtro pasabajo más simple y fácil de optimizar: un filtro de averaging. Hemos probado diferentes tamaños (2x1, 3x1, 5x1) y determinado que 3x1 es el mejor. Con 2x1 no se tiene en cuenta la muestra posterior y acaba causando fine errors. En cambio, con tamaño 5x1 se hace media entre demasiadas muestras y se aplana demasiado la señal. Con 3x1 evitamos estos dos problemas.

- **Normalización**: Ajuste de amplitud al rango [-1, 1].

Ajustar la amplitud del rango nos permite aplicar los thresholds y procesados de manera objetiva, sin ser afectados por las variaciones en amplitud máxima entre diferentes señales.

- **Center Clipping**: Umbral C_L=0.01 para reducir efectos de formantes.

Center clipping reduce el efecto de los formantes y limpia la autocorrelación para identificar más fácilmente el pico correspondiente al periodo de la señal. Al haber normalizado previamente la señal podemos aplicar un center clipping apropiado para toda señal de entrada.

### Métodos de estimación
- **Autocorrelación**: Método por defecto (`--method=autocorr`)
- **AMDF**: Average Magnitude Difference Function (`--method=amdf`).

La AMDF es un método computacionalmente menos costoso a la autocorrelación pero parecido a este. Nos permite encontrar el pitch encontrando el argumento para el cual este es mínimo (fuera del origen). Tiene resultados buenos, pero como el center clipping no es tan efectivo para AMDF, los resultados con la autocorrelación son mejores.

- **Cepstrum**: Análisis cepstral (`--method=cepstrum`).

El cepstrum también nos permite estimar el tono encontrando su valor máximo (fuera del origen). Aunque tiene la posibilidad de también dar muy buenos resultados, hemos preferido utilizar la autocorrelación, ya que el calcular el cepstrum impone una carga computacional más grande sobre el programa y su run-time es demasiado grande (~3 min para `run_get_pitch`).

### Postprocesado
- **Filtro de mediana**: Tamaño 3 (óptimo), elimina valores atípicos aislados.

Al igual que con el filtro averaging, hemos probado diferentes tamaños para el filtro de mediana para encontrar el óptimo. Encontramos los mismos problemas que con el filtro averaging, y como el caso anterior, el filtro de tamaño 3 es óptimo para evitar desplazamientos de la señal y evitar aplanar demasiado. También se probó el filtro de tamaño 7, con resultados catastróficos (<15%). Aun así, podemos observar en los resultados que el filtro de mediana de tamaño 3 acaba eliminando algunos picos y saltos que realmente existían en la señal.

- **Corrección de errores**: Elimina picos anormales (>360Hz diferencia).

En el caso de que múltiples muestras consecutivas tengan valores erróneos, la corrección de errores nos permite ajustar el tono de salida para evitar saltos repentinos demasiado grandes para ser correctos. Se compara el tono estimado del segmento con el del segmento anterior y, si la distancia entre estos supera el threshold, se determina que existe un error y se escoge de entre las dos muestras el valor más cercano a la media de la señal, y se asigna este a ambas.

### Parámetros optimizados
| Parámetro | Valor | Descripción |
|-----------|-------|-------------|
| alpha0 | -42 dB | Umbral de potencia |
| alpha1 | 0.48 | r1/r0 normalizado |
| alpha2 | 0.34 | rmax/r0 normalizado |
| zc3 | 0.012*fm/2 | Tasa de cruces por cero |

Como se ha comentado en apartados previos, se ha utilizado el script `grid_search` para optimizar los parámetros y encontrar la combinación más óptima de estos.

![Pantallazo de `get_pitch -h`](grid_search.png)


Evaluación *ciega* del estimador
-------------------------------
Expand Down
Binary file added get_pitch_-h.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added grid_search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added help_capture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
134 changes: 134 additions & 0 deletions pitch_db/train/rl002.f0
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
0
0
0
0
0
0
0
0
0
0
0
0
0
0
115.607
115.607
0
0
0
143.885
143.885
152.672
158.73
163.934
163.934
163.934
256.41
256.41
240.964
0
0
0
0
0
0
0
0
143.885
143.885
142.857
139.86
134.228
129.87
125
120.482
116.279
113.636
0
0
0
0
0
111.732
111.732
111.732
111.732
105.263
0
0
0
0
0
0
0
118.343
118.343
116.959
116.959
117.647
117.647
117.647
117.647
117.647
118.343
118.343
118.343
116.959
114.943
0
0
0
0
0
0
0
0
0
0
131.579
131.579
128.205
120.482
114.943
106.952
101.01
95.6938
92.5926
91.3242
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Loading