proyecto fin de grado - archivo digital upmoa.upm.es/52707/1/tfg_carlos_nistal_hurle.pdfcomo la...

124
1 ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA Y SISTEMAS DE TELECOMUNICACIÓN PROYECTO FIN DE GRADO TÍTULO: Implementación de un modificador de tono (pitch-shifter), basado en algoritmo de phase-vocoder, sobre Raspberry Pi AUTOR: Carlos Nistal Hurlé TITULACIÓN: Grado en Ingeniería de Sonido e Imagen TUTOR: Antonio Mínguez Olivares DEPARTAMENTO: Teoría de la Señal y Comunicaciones VºBº Miembros del Tribunal Calificador: PRESIDENTE: Eduardo Nogueira Díaz TUTOR: Antonio Mínguez Olivares SECRETARIO: Danilo Simón Zorita Fecha de lectura: Calificación: El Secretario,

Upload: others

Post on 09-Apr-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1

ESCUELATÉCNICASUPERIORDEINGENIERÍAYSISTEMASDE

TELECOMUNICACIÓN

PROYECTOFINDEGRADOTÍTULO:

Implementacióndeunmodificadordetono(pitch-shifter),basadoenalgoritmodephase-vocoder,sobreRaspberryPi

AUTOR:

CarlosNistalHurléTITULACIÓN:

GradoenIngenieríadeSonidoeImagenTUTOR:

AntonioMínguezOlivaresDEPARTAMENTO:

TeoríadelaSeñalyComunicaciones

VºBºMiembrosdelTribunalCalificador:

PRESIDENTE:

EduardoNogueiraDíazTUTOR:

AntonioMínguezOlivares

SECRETARIO:

DaniloSimónZoritaFechadelectura:Calificación:ElSecretario,

Page 2: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

2

RESUMEN Este proyecto consiste en el diseño e implementación de un efecto de modificación de tono, o pitch-shifter, sobre el ordenador de placa reducida de bajo coste Raspberry Pi, empleando el algoritmo de phase-vocoder. El dispositivo permite la variación del tono de cualquier señal de entrada en tiempo real, preservando las demás características de la señal original. El cambio en el tono se realiza en dos pasos: contracción/expansión temporal, o time-stretching, y re-muestreo. Para llevar a cabo el time-stretching se hace uso del algoritmo de phase-vocoder que, a través de un procesado en el dominio de la frecuencia, modifica la duración de la señal manteniendo su tono original. Una vez contraída/estirada, la señal es devuelta a su duración original a través de un re-muestreo con interpolación, consiguiendo así variar el tono manteniendo la duración. Para la implementación del efecto sobre la Raspberry Pi fue preciso configurar la tarjeta para asumir la funcionalidad de un procesador DSP. Para ello se instaló el software Pure Data (Pd), un lenguaje gráfico de programación orientado a aplicaciones audiovisuales desarrollado por Miller Puckette en la década de 1990. Pd actuó como capa software intermedia entre el interfaz de audio y el programa implementado, facilitando sustancialmente la programación. La implementación se llevó a cabo en lenguaje C, haciendo uso del API de Pd. A lo largo de esta memoria se expone el proceso de diseño e implementación del sistema, indicado los diferentes requisitos que debe cumplir para hacer posible su aplicación práctica y proponiendo soluciones de ingeniería para cumplir con los mismos.

Page 3: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3

ABSTRACTThis project consists of the implementation of a pitch-shifter effect on theRaspberry Pi single-board computer using the phase-vocoder algorithm. Thisdeviceallowsshiftingthepitchofanyinputsignalinreal-timewhilepreservingtherestofitsoriginalfeatures.Pitchshiftingisachievedintwosteps:time-stretchingandre-sampling.Aphase-vocoder algorithm is used to time-stretch the signal. This algorithm performsprocessing in the frequency domain in order to stretch the input signal to adifferentdurationwhilepreservingitspitch.Thesignalisthenre-sampledbacktoitsoriginalduration,accomplishingthedesiredpitch-shift.To implement this effect, the Raspberry Pi was configured to work as DSPprocessor; for this purpose thePureData (Pd) softwarewas installed. Pd is avisual programing language developed by Miller Puckette in the 1990’s forcreating interactive computermusic andmultimediaworks. In this project, Pdactsasanintermediatesoftwarelayerbetweentheaudiointerfaceandtheeffect,which makes programming considerably easier. The effect was coded in ClanguageusingPd’sAPI.The design and implementation process of the pitch-shifter will be shown throughout this report, pointing out the main requisites that must be met to be used in real-world applications, as well as offering technical solutions to satisfy these.

Page 4: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4

ACRÓNIMOS ABTA: Adaptive Base Transform Algorithm DFT: Transformada discreta de Fourier (Discrete Fourier Transform) DSP: Digital Signal Processing FFT: Transformada rápida de Fourier (Fast Fourier Transform) GPIO: General Purpose Input/Output HDMI: High Definition Multimedia Interface IDFT: Transformada inversa discreta de Fourier (Inverse Discrete Fourier Transform) MCFE: Multiple Component Feature Extraction Pd: Pure Data (P)SOLA: (Pitch) Synchronized Overlap-Add SoC: System-on-a-chip SSH: Secure Shell STFT: Short Time Fourier Transform TDHS : Time Domain Harmonic Scaling VNC: Virtual Network Computing

Page 5: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5

Esta página se ha dejado en blanco intencionadamente

Page 6: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6

ÍNDICE 1. INTRODUCCIÓN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.1. Introducción a la modificación del tono, o pitch-shifting . . . . . . . . . . . . . . . 12 1.2. Antecedentes, marco tecnológico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.3. Especificaciones y restricciones de diseño . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.4. Estructura del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2. OBJETIVOS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3. FUNDAMENTO TEÓRICO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.1. CONTRACCIÓN/EXPANSIÓN TEMPORAL, O TIME-STRETCHING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.2. EL PHASE VOCODER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.2.1. Análisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.2.2. Procesado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.2.3. Síntesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.3. RE-MUESTREO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4. CONFIGURACIÓN Y PUESTA EN MARCHA . . . . . . . . . . . . . . . . . 34

4.1. Raspberry Pi 2 model B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.2. Pure Data y creación de Externals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.2.1. Configuración del proyecto en XCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.2.2. Compilación con XCode y test en Pd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

Page 7: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

7

4.2.3. Compilación en la Raspberry Pi, creación del archivo Makefile . . . . . . . . . . 50 4.2.4. API de Pd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

4.3. Guía de configuración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.3.1. Instalación del sistema operativo Rapsbian . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.3.2. Configuración del adaptador wi-fi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.3.3. Control remoto de la Raspberry Pi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.3.4. Configuración del interfaz de audio Focusrite Scarlett 2i2 . . . . . . . . . . . . . . 64 4.3.5. Instalación y configuración de Pure Data . . . . . . . . . . . . . . . . . . . . . . . . . . 69

5. IMPLEMENTACIÓN DEL PITCH SHIFTER . . . . . . . . . . . . . . . . . . . . 70 5.1. Recursos necesarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .70 5.2. Time-stretching empleando el algoritmo de phase-vocoder . . . . . . . . . . . . . 73

5.2.1. Análisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 5.2.2. Procesado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.2.3. Síntesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

5.3. Re-muestreo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

6. RESULTADOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 6.1. Prototipo en MatLab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

6.1.1. Señal sinusoidal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 6.1.2. Señal de guitarra acústica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 6.1.3. Señal percusiva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 6.1.4. Prueba auditiva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

6.2. External de Pd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 6.2.1. Señal sinusoidal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 6.2.2. Señal de guitarra acústica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 6.2.3. Señal percusiva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 6.2.4. Prueba auditiva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

7. CONCLUSIONES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

8. REFERENCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 9. APÉNDICES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

9.1. APÉNDICE I: Función prototipo del pitch-shifter en código MatLab . . . . 101 9.1.1. Función createFrames.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 9.1.2. Función overlap_add.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 9.1.3. Función pichShifter.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

9.2. APÉNDICE II: Código fuente, en lenguaje C, del pitch-shifter implementado como un external de Pure Data . . . . . . . . . 112

Page 8: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

8

1. INTRODUCCIÓN Un concepto fundamental en música es el de tono. El tono es la sensación auditiva o atributo psicológico de los sonidos que los caracteriza como más agudos o más graves, en función de la frecuencia. A lo largo de la historia se han empleado diferentes métodos para efectuar modificaciones sobre el tono del sonido emitido por un determinado instrumento. Al principio esto se lograba exclusivamente mediante procedimientos mecánicos. En el caso de los instrumentos de viento, por ejemplo, pueden lograrse ligeras modificaciones ajustando la boquilla o, en algunos casos como la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común la modificación de la afinación variando la tensión de las cuerdas o mediante el uso de la cejilla (Figura 1.1a). Todos estos métodos presentan grandes limitaciones: con la cejilla solo es posible modificar el tono de forma ascendente, y siempre en incrementos de un semitono. En los instrumentos de viento el cambio suele ser mínimo, únicamente con fines de afinación. Sin embargo, en muchas situaciones resulta deseable efectuar cambios de mayor cuantía, tanto ascendentes como descendentes, de manera rápida y precisa. También es interesante poder modificar el tono de instrumentos que carecen de estos mecanismos, como por ejemplo un xilófono.

Page 9: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

9

(a) La cejilla permite variar ascendentemente el tono de la guitarra en intervalos de semitono

(b) La trompeta modifica su tono con las bombas de afinación.

Figura 1.1: Ejemplos de métodos mecánicos para la variación de tono sobre instrumentos musicales de cuerda (a) y viento (b).

Page 10: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

10

Más tarde, con la introducción de las tecnologías de registro de señales de audio en cinta, se patentaron multitud de dispositivos electrónicos que permitían variar de manera electro-mecánica el tono de una señal previamente grabada.

Figura 1.2: Sistema de modificación de tono de cinta con cabezas rotatorias La mayoría de estos diseños se basaban en la idea de registrar la señal de audio en una cinta para después reproducirla empleando un bloque rotatorio en el que la cabeza de registro de lectura gira a distinta velocidad que la de grabación. Ajustando la relación entre estas velocidades era posible aumentar o disminuir el tono de la señal. En la Figura 1.2 se presenta como ejemplo uno de estos diseños, patentado por Fairbanks, Everitt y Jaeger en 1952 [21]. Con la explosión del audio digital y el procesado de señal se desarrollaron métodos para efectuar cambios de tono de forma electrónica. El hardware H910 Harmonizer [22], desarrollado en 1974 por la compañía estadounidense Eventide, fue el primer procesador digital de audio en realizar funciones de modificación de tono (Figura 1.3).

Page 11: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

11

Figura 1.3: El H910 Harmonizer, de Eventide

Uno de los algoritmos más populares para este propósito es el de phase-vocoder que, mediante un proceso de análisis, procesado y síntesis, permite modificar el tono de una señal en tiempo real sin alterar su duración. El cometido de este proyecto es implementar un modificador de tono en tiempo real, o pitch-shifter, sobre la tarjeta de bajo coste Raspberry Pi 2 [9], empleando un algoritmo de phase-vocoder.

Figura 1.4: Ejemplo de un set up empleando la Raspberry Pi En lo que resta de capítulo se hará una breve introducción a la modificación de tono, se comentará el marco tecnológico actual y los antecedentes en este campo, se establecerán unas especificaciones y restricciones sobre el diseño y, por último, se describirá la estructura del proyecto.

Page 12: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

12

1.1 INTRODUCCIÓN A LA MODIFICACION DE TONO, O PITCH-SHIFTING Más allá del cambio de tono obtenido a través de un simple re-muestreo, la modificación de tono -o pitch-shifting- es un proceso por el que el tono de una señal es alterado sin variar su duración. En la práctica habitualmente esto se logra modificando la duración de un sonido mediante alguna de las técnicas que se discutirán a continuación, para después efectuar un re-muestreo y cambiar el tono en la medida que se desee. No debe confundirse modificación de tono con modificación de frecuencia. La segunda consiste en desplazar el espectro modulando la señal con una exponencial compleja, lo que produce un sonido metálico e inarmónico. Esto puede tener interés como efecto especial, pero es una forma incorrecta de cambiar el tono de una señal. Por el contrario, la modificación de tono produce un escalado en el espectro, modificando la distancia de cada una de las componentes espectrales al origen de frecuencias. El proceso recíproco del pitch-shifting es la compresión/expansión temporal, o time-stretching que, dejando intacto el tono de la señal, modifica su duración, o tempo. Es un técnica muy útil a la hora de combinar pistas de audio con diferentes tempos en un proyecto de producción musical. Hoy en día existen varios métodos razonablemente eficaces e “inocuos” para llevar a cabo expansión/compresión temporal o modificación de tono, pero la mayoría de ellos sólo serán eficaces para cierto tipo de señales, y dentro de un límite. Un buen algoritmo permite variar un promedio de 5 semitonos, o una compresión/expansión del 130%. Si el procesado se aplica a instrumentos aislados el límite aumenta hasta el 200%, sin pérdida de calidad perceptible, lo que equivale a una octava. La mayoría de algoritmos de compresión/expansión están basados en dos esquemas principales clásicos: Phase Vocoder y Time Domain Harmonic Scaling (TDHS). El phase-vocoder fue diseñado en 1966 por Flanagan y Golden [2], e implementado por Portnoff diez años después [3]. Emplea la transformada de Fourier de tiempo corto, o STFT (Short Time Fourier Transform) que es una versión de la DFT aplicada a porciones cortas -frames- de la señal de audio. Los frames se corresponden con bloques de señal entrelazados en cierto grado, y son enventanados antes de transformarse al dominio de la frecuencia. En un proceso inverso, los frames son devueltos al dominio del tiempo, nuevamente enventanados, y sumados de forma entrelazada. Variando la cantidad de solapamiento entre frames al realizar la suma entrelazada se obtienen señales de mayor o menor duración que la señal de entrada.

Page 13: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

13

Sin embargo, modificar la distancia relativa entre frames generará incoherencias de fase que se traducirán en discontinuidades temporales. Estas serán percibidas como clics. El algoritmo actúa mediante un procesado en el dominio de la frecuencia, que logra corregir estas incoherencias.

Figura 1.1.1 : Flujo de procesado en el algoritmo de phase-vocoder

Page 14: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

14

El uso del phase vocoder se ciñe fundamentalmente al ámbito científico y educativo, pretendiendo poner de manifiesto las limitaciones de la transformada de Fourier, aunque ha adquirido popularidad en los últimos años gracias a mejoras que han permitido reducir en gran medida los “artefactos” de los que aqueja el algoritmo clásico. Éste introduce una considerable cantidad de “artefactos” perceptibles como smearing (emborronamiento) en señales con transitorios rápidos y reverberación en general, incluso a bajos ratios de compresión/expansión. Como se comentó anteriormente, la otra técnica principal para efectuar time-stretching es el escalado harmónico en el dominio del tiempo, o TDHS. Está basada en un método propuesto por Rabiner y Schafer en 1978 [4]. Se basa en gran medida en la correcta estimación de la frecuencia fundamental del sonido que está siendo procesado. En una de las numerosas implementaciones posibles, se calcula la auto-correlación de tiempo corto y se obtiene la frecuencia fundamental encontrando el máximo. La duración se modifica al realizar la suma entrelazada de los frames de entrada, mediante el método (P)SOLA, (Pitch) Synchronized Overlap-Add [5]. Esto permite variar velocidad a la que se reproduce la señal de entrada, manteniendo el alineamiento con el periodo estimado por el método anterior. Este algoritmo funciona bien con señales con una componente espectral principal prominente, siendo aconsejado su uso para cualquier tipo de señal aislada. Cuando se trata de una señal mezcla de varias fuentes, el método sólo funcionará de forma satisfactoria si el tamaño del segmento entrelazado se incrementa hasta conseguir un múltiplo de ciclos y por tanto promediando el error de fase sobre un segmento más largo, haciéndolo así menos audible. El principal reto de la TDHS es estimar la componente espectral fundamental de la señal, particularmente en casos en que ésta no está presente. Se han propuesto numerosos algoritmos de estimación [7].

Page 15: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

15

1.2 ANTECEDENTES Y MARCO TECNOLÓGICO Debido a la cantidad de “artefactos” introducidos por los dos métodos de procesado clásicos, en los últimos años han surgido nuevos enfoques más sofisticados para abordar el problema de la modificación de tono. Un problema destacable que afecta tanto al procesado mediante TDHS como al phase-vocoder es la alta localización de las funciones base en un dominio, bien en tiempo o en frecuencia, y la falta de localización en el dominio recíproco. En el caso del phase-vocoder, por ejemplo, las funciones base son sinusoides que en el dominio de la frecuencia se representan por deltas de Dirac y por tanto están totalmente localizadas en dicho dominio. Por el contrario las sinusoides no están localizadas en el dominio del tiempo (se extienden hasta el infitinto), lo que contribuye al inherente emborronamiento de la señal si no se toman medidas adicionales. Los bloques de muestras empleados en el procesado TSHS pueden considerarse deslocalizados en el dominio de la frecuencia lo que, aplicado a señales multi-tonales, da lugar a distorsión. Entre los nuevos enfoques que aspiran a mitigar estos problemas existen diferentes vertientes: - Mejora de las técnicas existentes Los estudios científicos actuales se centran en mejorar los métodos de variación del tono, tanto los basados en procesado en tiempo como en frecuencia, investigando como eliminar las causas que producen los artefactos en ambos dominios. La creciente capacidad de procesado de las CPU ha hecho posible implementar múltiples mejoras sobre el algoritmo original de phase-vocoder en productos comerciales. Una de estas modificaciones fue concebida por Miller Puckette en 1995 [6], y consiste en sincronizar las fases a lo largo de un frame de análisis. Esto supone un seguimiento e identificación de los armónicos individuales, lo que es sí mismo supone un problema, pero da lugar a resultados más naturales que el algoritmo básico de phase-vocoder. Un producto comercial que emplea este tipo de procesado es el algoritmo Pitch n’ Time de Serato (Figura 1.2.1).

Page 16: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

16

Figura 1.2.1: Efecto de compresión/expansión temporal y modificación de tono Pitch’n Time de Serato.

- Algoritmo de transformación adaptativo ABTA (Adaptive Base Transform Algorithm)

Desarrollado por Prosoniq [7], plantea una representación de la señal en términos de señales base más complejas, con una buena localización tanto en el dominio del tiempo como en el de la frecuencia. La señal es transformada en base a la propiedad MCFE (Multiple Component Feature Extraction), cuyos detalles son secreto comercial. Un ejemplo de producto comercial empleando esta tecnología es el Orange Vocoder [8] de Prosoniq (Figura 1.2.3).

Page 17: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

17

- Técnicas multi-resolución con wavelets Esta tecnología se aprovecha de la buena localización de los wavelets, tanto en el dominio del tiempo como en el de la frecuencia para implementar un algoritmo de manipulación de tono y duración que emplea un procesado adaptativo en tiempo o en frecuencia, en función de las características de la señal de entrada [7]. Adicionalmente, los parámetros de localización en el dominio del tiempo o de la frecuencia son definibles por el usuario, pudiendo optar entre las propiedades de coherencia de fase de un procesado en tiempo, o la buena resolución espectral del phase-vocoder.

Figura 1.2.3: Orange Vocoder de Prosoniq.

Page 18: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

18

1.3 ESPECIFICACIONES Y RESTRICCIONES DE DISEÑO Para que nuestro sistema de modificación de tono sea operativo y pueda tener aplicaciones prácticas en el ámbito de la creación musical, debe satisfacer una serie de especificaciones que deberán ser tenidas en cuenta durante el diseño y desarrollo del producto: - Portable: Debido a los múltiples ámbitos de aplicación del producto -desde producciones en estudio hasta el uso en actuaciones en directo- el sistema deberá ser ligero y portable. - Rápido y sencillo: No deberá estar compuesto de muchos elementos hardware, su montaje debe ser rápido, sencillo e intuitivo para el usuario final. - Asequible: El sistema deberá ser de bajo coste, en la medida en que no repercuta sobre la calidad del resultado final. Se dará preferencia al software de libre distribución, y los elementos hardware serán de una gama asequible –de una calidad suficiente para respetar las demás restricciones de diseño- con el fin de garantizar el acceso al producto a usuarios domésticos. En este sentido Raspberry Pi y Pure Data constituyen excelentes elecciones para hardware y software, respectivamente. - Realizable: Como se comentó con anterioridad, el desarrollo de algoritmos de modificación de tono es un campo completamente abierto y en constante evolución. Los algoritmos modernos son de una enorme complejidad y en muchos casos están sometidos a secreto comercial. Se sale por completo del alcance de este proyecto el pretender diseñar un algoritmo que pueda ser competitivo frente a los productos actualmente disponibles en el mercado; se optará por implementar la versión clásica del algoritmo de phase-vocoder. - En tiempo real: El sistema está concebido para aplicaciones en directo por lo que, idealmente, la latencia que introduzca no deberá superar los 8-10 milisegundos. Retardos superiores serían percibidos por el músico e interferirían con su interpretación. Con más 30 milisegundos de latencia el producto sería inutilizable. - Preciso: Para que el producto pueda tener aplicaciones musicales, el error en la modificación de tono debe ser lo bastante bajo para no ser percibido por el músico.

Page 19: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

1. INTRODUCCIÓN

19

1.4 ESTRUCTURA DEL PROYECTO El proyecto está estructurado en tres partes. En la primera parte, correspondiente al capítulo 3, se hace un estudio teórico del proceso de modificación de tono basado en el algoritmo de phase-vocoder, a lo largo del cual se formula matemáticamente el algoritmo. En la segunda parte (capítulo 4) se detalla el proceso de puesta a punto de los elementos hardware y software que componen el proyecto. Por último, en los capítulos 5 y 6, se describe el diseño e implementación del algoritmo y se presentan los resultados de las pruebas realizadas para comprobar su correcta realización.

Page 20: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

2. OBJETIVOS

20

2. OBJETIVOS El objetivo último del proyecto es la implementación de un efecto DSP de variación de tono en tiempo real, o pitch-shifter, sobre la tarjeta Raspberry Pi, empleando un algoritmo de phase-vocoder. Esta tarea se abordará a través de la realización de una serie de hitos, o sub-objetivos, que se enumera a continuación:

• Estudio de la teoría de señales discretas y de la modificaciones de tono de señales empleando el algoritmo phase-vocoder.

• Formulación matemática del algoritmo. • Codificación de prototipo en MatLab. • Configuración de la Raspberry Pi como procesador DSP. • Implementación del algoritmo de modificación de tono. • Comprobación del efecto de modificar los diferentes parámetros del Phase-

Vocoder sobre el espectro de las señales estudiadas. • Determinación de los valores idóneos, en función del tipo de señal de entrada,

para evitar “artefactos” en la salida. También se pretende que este trabajo pueda servir de apoyo o punto de partida a otros estudiantes en el desarrollo de nuevas aplicaciones y proyectos.

Page 21: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

21

3. FUNDAMENTO TEÓRICO Hasta ahora se ha llevado a cabo una introducción a los diferentes métodos de modificación de tono y se ha justificado la elección del phase-vocoder como algoritmo a implementar en nuestro proyecto. En el presente capítulo se establecerán todas las herramientas matemáticas para tal propósito [1]. Como se anticipó, el proceso de modificación del tono se lleva a cabo en dos pasos: 1: Estiramiento temporal (time-stretching) 2: Re-muestreo A través del time-stretching logramos modificar la duración de la señal de audio manteniendo el tono. El re-muestreo devuelve la señal a su duración original a la vez que provoca un cambio en el tono. Con estos dos procesos logramos nuestro propósito inicial: modificar el tono preservando la duración. Aclaremos estos conceptos a través de un ejemplo: Supongamos que queremos aumentar el tono una señal de guitarra en un semitono (esto equivaldría a una cejilla sobre el primer traste). El factor de escala 𝛼 se define como el factor multiplicativo sobre el espectro de la señal necesario para expandir o contraerlo en cierta medida. En nuestro caso, para lograr aumentar un semitono debemos aplicar un factor

Page 22: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

22

𝛼 = 2!/!", lo que podríamos lograr fácilmente sub-muestreando la señal por un ratio de 2!!/!" (esto equivaldría a reproducir la secuencia 2!/!" veces más rápido). Pero recordemos que el objetivo de un pitch-shifter es también preservar la duración; antes debemos estirar temporalmente la señal aumentando su duración por el mismo factor 2!/!". Esto se ilustra en la figura 3.1. A continuación se detallarán los procesos de time-stretching y re-muestreo:

Figura 3.1: La señal original, de duración L, es expandida temporalmente según un factor de

escala de 𝟐𝟏/𝟏𝟐 sin modificar la amplitud de sus componentes espectrales

Page 23: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

23

3.1 CONTRACCIÓN/EXPANSIÓN TEMPORAL, O TIME-STRETCHING Como dijimos, el objetivo del time-stretching es modificar la duración de una señal de audio manteniendo su tono, o más precisamente, su espectro o respuesta en frecuencia. Para ello dividiremos nuestra señal en frames de 𝑁 muestras, solapados entre sí. Este solapamiento nos permite variar la distancia entre frames para comprimir o estirar la señal, según se ilustra en la Figura 3.2.a. Pero variar la distancia entre los frames, y por tanto el solapamiento entre los mismos, genera discontinuidades temporales en la señal resultante, según se ilustra en la Figura 3.2 b.

(a) (b)

Figura 3.2: La contracción/expansión temporal se logra variando la distancia relativa entre los frames entrelazados (a). Al sumar de forma entrelazada los bloques se producen incoherencias de

fase (b) Estas discontinuidades generarán clics perceptibles y desagradables para el oído humano. Es preciso corregirlas de algún modo; aquí es donde entra en juego el algoritmo de phase-vocoder.

Page 24: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

24

3.2 EL PHASE-VOCODER

Figura 3.2.1: Diagrama de bloques del phase-vocoder

El phase-vocoder, cuyo diagrama de bloques queda reflejado en la Figura 3.2.1, tiene como objetivo corregir las discontinuidades temporales que surgen de modificar la distancia relativa entre frames. En el dominio de la frecuencia estas discontinuidades se traducen en incoherencias de fase entre las componentes espectrales de los frames adyacentes (Figura 3.2.2) . El phase-vocoder corrige estas incoherencias, de forma que la señal estirada o contraída es continua en el dominio del tiempo. Este proceso se lleva a cabo en tres fases: análisis, procesado y síntesis, según ilustra la Figura 3.2.3.

Page 25: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

25

Figura 3.2.2: Al variar la distancia relativa entre frames se producen incoherencias de fase entre las componentes espectrales de los frames consecutivos.

Figura 3.2.3: El phase-vocoder consta de tres etapas: análisis, procesado y síntesis.

Page 26: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

26

3.2.1 Análisis En la fase de análisis se efectúa la STFT cada uno de los frames entrantes. Según se señaló anteriormente, este proceso consiste en efectuar la DFT sobre porciones cortas de señal aplicando una determinada ventana antes y después de la transformación. Emplear una ventana rectangular provocaría una elevada fuga espectral, ya que multiplicar por un pulso rectangular equivale, en frecuencia, a convolucionar con una función tipo sinc. En cambio, una ventana Hanning concentra más energía en el lóbulo central, en torno al origen de frecuencias, y se asemeja más al caso ideal de una delta, que permitiría la perfecta reconstrucción de la señal (Figura 3.2.1.1).

Figura 3.2.1.1: Ventana rectangular vs ventana Hanning

Una vez enventanado, cada frame es transformado al dominio de la frecuencia aplicando una FFT. Este proceso viene descrito por la Ecuación 3.2.1.1:

𝑋! 𝑘 ! = 𝑥[𝑛 + 𝑖 ∙ ℎ𝑜𝑝!]!!!

!!!

𝑤 𝑛 𝑒!!!!"#! 𝑘 = 0,1,2,… ,𝑁 − 1

Ecuación 3.2.1.1: Expresión para el cálculo de la STFT.

Page 27: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

27

donde (𝑋![𝑘])! corresponde al espectro discreto de análisis del i-ésimo frame y el

índice k hace referencia al número de bin correspondiente a una frecuencia 𝑘 !!!

;

𝑥[𝑛 + 𝑖 ∙ (ℎ𝑜𝑝!)] es la señal temporal del i-ésimo frame y ℎ𝑜𝑝! representa el salto de análisis, es decir, la distancia de separación entre frames adyacentes en la fase de análisis; 𝑤[𝑛] representa a la ventana Hanning. Para aumentar la resolución las ventanas se solapan en un 75%, lo que equivale a un salto de análisis de 𝑁/4. Es importante adelantar la importancia de ℎ𝑜𝑝! ya que será su relación con el salto de síntesis ℎ𝑜𝑝! lo que controle la cantidad de time-stretching que se aplicará a la señal, y finalmente determine la modificación de tono sobre la señal original. 3.2.2 Procesado Como ya adelantamos, en la fase final de síntesis se pretende variar la distancia temporal entre frames, lo que equivale a establecer un salto de síntesis ℎ𝑜𝑝! diferente del de análisis. Esto, dijimos, da lugar a discontinuidades temporales en la señal resultante, a menos que se adopten medidas. Es durante la fase de procesado cuando se realiza una corrección sobre la fase de cada frame para evitar estas discontinuidades. Como sabemos, al aplicar una FFT de longitud N a una señal discreta, el espectro resultante está representado por bins de frecuencia que van desde 0 hasta !!!

!𝑓!.

Imaginemos, por simplificar, que nos centramos exclusivamente en el primer bin de

frecuencia, lo que equivale a procesar una señal sinusoidal de frecuencia !!!

(Figura

3.2.2.1). Una vez aclarado este ejemplo es sencillo extender el razonamiento a cada bin.

Page 28: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

28

Figura 3.2.2.1: Señal sinusoidal cuya frecuencia, !!!

, coincide con la del primer bin (a) Señal con

frecuencia ligeramente superior a la anterior Desplazar un frame respecto al anterior un tiempo Δ𝑡! supone, en el dominio de la frecuencia, aplicar un desfase producto de la frecuencia de la sinusoide (en nuestro

ejemplo !!!

) y Δ𝑡!. De este modo, puede expresarse la fase de síntesis del “frame” i,

(𝜙![𝑘])!, en función de la fase de síntesis del “frame” anterior, (𝜙![𝑘])!!!, en la siguiente expresión recursiva:

(𝜙![𝑘])! = (𝜙![𝑘])!!! + Δ𝑡! ∙ (𝜔!"#$[𝑘])!

Ecuación 3.2.2.1: Expresión para el cálculo de la fase de síntesis del frame i

Idealmente, para construir nuestra señal contraída o estirada en tiempo, en frecuencia bastaría con mantener el módulo de la respuesta en frecuencia de análisis de cada frame y corregir la fase según la ecuación anterior:

(𝑋![𝑘])! = (𝑋![𝑘])! ∠(𝑋![𝑘])! = (𝜙![𝑘])!

Ecuación 3.2.2.2: Amplitud y fase del frame de síntesis Esto es cierto cuando la frecuencia de la sinusoide coincide exactamente con la frecuencia del bin. En ese caso contrario debemos idear algún método para estimar la pulsación verdadera 𝜔!"#$ . Consideremos para ello una sinusoide de frecuencia ligeramente superior a la del primer bin. (Figura 3.2.2.1b). En este caso la energía se

Page 29: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

29

distribuirá entre los bins cercanos, aunque la mayoría seguirá concentrada en el primero. Empleando la información de fase será posible lograr una mejor estimación de la frecuencia de la sinusoide. Como muestra la figura, la señal se divide en bloques de N muestras; por simplicidad, en este ejemplo no se considerará el solapamiento. Analicemos la diferencia de fase entre frames sucesivos. Para la primera sinusoide, de

frecuencia !!!

, el periodo de la señal coincide con la longitud del frame por lo que no

existe diferencia de fase entre frames consecutivos. En cambio la segunda sinusoide, al tener frecuencia ligeramente superior, alcanza el i-ésimo frame con un desfase respecto al anterior que podemos calcular fácilmente. A partir de este desfase será posible hallar la frecuencia 𝜔!"#$. Definamos (Δ𝜙![𝑘])! como la diferencia de fase entre el frame i-1 y el frame i. La frecuencia verdadera vendrá dada por la siguiente expresión:

(𝜔!"#$[𝑘])! =(Δ𝜙![𝑘])!

Δ𝑡!

Ecuación 3.2.2.3: Expresión para el cálculo de la frecuencia verdadera

Sin embargo, para llegar a este resultado no hemos tenido en consideración el hecho de que la información de fase que la FFT proporciona está empaquetada (está limitada al intervalo (–𝜋,𝜋)). Para obtener 𝜔!"#$ es necesario primero calcular la desviación de frecuencia (∆𝜔[𝑘])! y empaquetarla. Esta cantidad se suma a la frecuencia 𝜔!"#[𝑘] del bin para obtener la 𝜔!"#$ del frame i. Este proceso se ilustra en las ecuaciones 3.2.2.4 a 3.2.2.6:

(Δ𝜔[𝑘])! =(Δ𝜙![𝑘])!

Δ𝑡!− 𝜔!"#[𝑘]

Ecuación 3.2.2.4: Cálculo de la desviación de frecuencia

(Δ𝜔!"#$$%&[𝑘])! = 𝑚𝑜𝑑 Δ𝜔 𝑘 ! + 𝜋 , 2𝜋 –𝜋

Ecuación 3.2.2.5: Cálculo de la desviación de frecuencia empaquetada

(𝜔!"#$[𝑘])! = 𝜔!"# 𝑘 + (Δ𝜔!"#$$%&[𝑘])!

Ecuación 3.2.2.6: Frecuencia verdadera, teniendo en cuenta el empaquetado

Page 30: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

30

Ahora podemos determinar la fase de cada frame (Ecuación 3.2.2.7) introduciendo la corrección de fase necesaria para evitar discontinuidades, de forma similar a la ecuación 3.2.2.1, sólo que ahora el resultado es válido para sinusoides de cualquier frecuencia.

(𝜙![𝑘])! = (𝜙![𝑘])!!! + Δ𝑡! ∙ (𝜔!"#$[𝑘])!

Ecuación 3.2.2.7: Expresión para el cálculo de la fase de síntesis del frame i

La fase del frame i-1 ya ha sido calculada previamente, ya que el algoritmo es recursivo. Para el primer frame pude tomarse la fase de análisis ∠(𝑋![𝑘])! =∠(𝑋![𝑘])!. El espectro de síntesis puede obtenerse ahora a partir de la Ecuación 3.2.2.8.

(𝑋![𝑘])! = (𝑋![𝑘])! ∠(𝑋![𝑘])! = (𝜙![𝑘])!

Ecuación 3.2.2.8: Amplitud y fase del frame de síntesis

De esta forma obtenemos una nueva señal en el dominio de la frecuencia, cuyas componentes espectrales tienen la misma amplitud que las de la señal original, pero han sido adecuadamente desplazadas en fase para evitar discontinuidades temporales al realizar la suma entrelazada. Como adelantamos anteriormente, el factor de contracción/estiramiento viene dado por el cociente ℎ𝑜𝑝!/ℎ𝑜𝑝!.

3.2.3 Síntesis

Sólo falta ya devolver nuestra señal sintetizada al dominio del tiempo, esto se lleva a cabo durante el proceso de síntesis. Para ello basta aplicar a cada frame la transformada discreta inversa de Fourier IDFT y multiplicar por una ventana Hanning para suavizar la señal, lo que equivale a computar la ISTFT (Ecuación 3.2.3.1).

𝑞! 𝑛 =1𝑁 𝑋! 𝑘 ! 𝑒

!! !!"#!

!!!

!!!

𝑤 𝑛 𝑛 = 0,1,2,… ,𝑁 − 1

Ecuación 3.2.3.1:Ecuación de síntesis

Donde 𝑞![𝑛] representa la señal temporal del frame i. Entrelazando los diferentes frames obtenemos la señal resultante. Para ello desplazamos cada frame a su posición y lo multiplicamos por un escalón unitario cuya duración es igual a la del frame, según indica la Ecuación 3.2.3.2.

Page 31: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

31

𝑦 𝑛 = 𝑞! 𝑛 − 𝑖 ∙ ℎ𝑜𝑝! 𝑢 𝑛 − 𝑖 ∙ ℎ𝑜𝑝! − 𝑢 𝑛 − 𝑖 ∙ ℎ𝑜𝑝! − 𝑁 !!!

!!!

Ecuación 3.2.3.2: Suma entrelazada de los frames de síntesis

donde L representa el número total de frames de la secuencia de audio procesada.

Por fin tenemos nuestra señal estirada o contraída en el tiempo, ahora sólo queda reproducirla a una velocidad adecuada para que recupere su duración original y su tono varíe en la cuantía deseada. Esto es equivalente a re-muestrear la señal.

3.3 RE-MUESTREO

Llegados a este punto, nuestra señal ha sido estirada o comprimida según un factor 𝛼 = ℎ𝑜𝑝!/ℎ𝑜𝑝!, manteniendo su tonalidad original. Ahora es preciso re-muestrear la señal con el fin de devolverla a su duración original y generar el cambio de tono deseado. Para ello tomaremos 1 de cada 𝛼 muestras, descartando el resto.

Volvamos a nuestro ejemplo de la guitarra. Supongamos que deseamos variar su tono en una octava de forma ascendente. Esto equivale a multiplicar por 2 la frecuencia de sus componentes espectrales. Para ello primero estiraremos la señal por un factor 𝛼 = 2, como detallamos en la sección anterior. Después tomaremos 1 de cada 2 muestras y descartaremos el resto, según muestra la Figura 3.3.1. De esta forma devolveremos la señal a su duración original y lograremos aumentar su tono en una octava.

Page 32: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

32

Figura 3.3.1: Elección de las muestras durante el re-muestreo con interpolación

Supongamos ahora que tan sólo queremos aumentar la frecuencia en un semitono. En este caso 𝛼 = 2!/!", que no es entero. Resulta claro que no bastará con descartar muestras; será necesario interpolar la señal para elegir nuestras muestras.

Page 33: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

3. FUNDAMENTO TEÓRICO

33

Figura 3.3.2: Elección de las muestras durante el re-muestreo con interpolación Empleando la Ecuación 3.3.1 generaremos la secuencia resultante 𝑦 𝑛 :

𝑦 𝑛 = 𝑦ℎ𝑜𝑝!ℎ𝑜𝑝!

⋅ 𝑛

Ecuación 3.3.1: Expresión para el re-muestreo con interpolación donde 𝑦 𝑛 es la función de variable continua resultado de interpolar linealmente las muestras de 𝑦 𝑛 (Figura 3.3.2). Ya tenemos las herramientas matemáticas necesarias para implementar nuestro algoritmo. En el siguiente capítulo detallaremos la puesta a punto necesaria para convertir nuestra Raspberry Pi en un procesador DSP en tiempo real.

Page 34: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

34

4. CONFIGURACIÓN Y PUESTA EN MARCHA En este capítulo se describirán las principales características del hardware utilizado para implementar nuestro modificador de tono: la tarjeta Raspberry Pi 2. Además se explicarán todos los pasos necesarios para su correcta configuración como procesador de audio en tiempo real. Por último, se hará una descripción del lenguaje de programación Pure Data, justificando su idoneidad en nuestro proyecto.

4.1 RASPBERRY PI 2 MODEL B

Figura 4.1: Esquema de la Raspberry Pi

Page 35: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

35

Raspberry Pi es una serie de ordenadores de placa reducida, de bajo coste y reducido tamaño, desarrollada en el Reino Unido por la fundación Raspberry Pi [9]. Inicialmente concebido para fomentar la enseñanza de programación en colegios y países en desarrollo, rápidamente adquirió una gran popularidad y actualmente se emplea en ámbitos muy distintos de los previstos originalmente, como por ejemplo la robótica o el procesamiento de audio. El primer modelo en comercializarse, la Raspberry Pi 1 model A, fue lanzado al mercado en 2012. A partir de entonces han visto la luz 5 modelos en total, el último la Raspberry Pi 3 model B. Para nuestro proyecto se empleó la Raspberry Pi 2 model B. A continuación se detallan sus principales características: - Memoria RAM:

1GB

- Conexiones:

4 puertos USB 2.0.

Puerto Ethernet.

3,5mm Jack para salida de audio y video compuesto.

HDMI

GPIO: contiene 40 pines de conexión.

SoC (System-on-a-chip): Broadcom BCM2836 diseñado especialmente para aplicaciones multimedia.

- Procesador:

900 MHz 32-bit quad-core ARM Cortex-A7

- GPU:

Broadcom VideoCore IV @ 250 MHz

OpenGL ES 2.0

MPEG-2 and VC-1, 1080p30 H.264/MPEG-4 AVC (BCM2837: 1080p60)

- Micro SD:

Constituye la unidad de almacenamiento del sistema operativo y de los datos de usuario

Page 36: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

36

- Fuente de alimentación:

5V mediante micro USB. La Raspberry PI tiene un consumo energético de 600mA (3W).

- Dimensiones:

85.60 mm × 56.5 mm × 17 mm

- Sistemas operativos soportados:

RISC OS y GNU/Linux: Debian (Raspbian), Fedora (Pidora), Arch Linux (Arch Linux ARM), Slackware Linux.

4.2 PURE DATA Y CREACIÓN DE EXTERNALS Pure Data (Pd) [10] es un lenguaje gráfico de programación, desarrollado por Miller Puckette en los año 90, orientado a la creación de música por ordenador y a trabajos multimedia. Aunque Puckette es su principal autor, trata de un software libre al que contribuye con nuevas extensiones una diversa comunidad de creadores: artistas audiovisuales, desarrolladores, investigadores, músicos... Se distribuye bajo una licencia similar a BSD y es soportado por los sistemas operativos GNU/Linux, Mac OS X, iOS, Android y Windows. Pd es muy similar en diseño y aplicaciones al lenguaje Max [11], también desarrollado por Puckette, y en cierta medida compatible con Max/MSP, el sucesor comercial de Max. Al igual que su predecesor Max, Pd es un ejemplo de lenguaje de programación basado en flujo de datos. En este tipo de programas las funciones u “objetos”, representados por cajas, son conectados entre sí en un entorno gráfico que modela el flujo de señales de control y de audio. Pd posee una colección modular de objetos, denominados externals, que son empleados como bloques de construcción e interconectados entre sí sobre un lienzo, o patch, durante el desarrollo de programas. Estos patches son compartidos entre la comunidad Pd, y cualquier usuario puede utilizarlos sin necesidad de poseer grandes conocimientos de programación. Además, existe la posibilidad de codificar nuevos externals en lenguaje C a través de un API público, lo cual dota al programa de gran flexibilidad y escalabilidad. En la Figura 4.2.1 se presenta un ejemplo de patch en Pure Data. Se observan varios objetos: un conversor analógico/digital (adc~) de cuya salida se obtiene la señal de

Page 37: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

37

entrada a las entradas del interfaz de audio una vez digitalizada.; un conversor digital analógico (dac~) que dará salida al flujo de señal y al cual irá conectado el último elemento de la cadena en nuestro patch; un oscilador (osc~) que aporta una sinusoide con una frecuencia que se le introduce como parámetro (en este caso son 1000Hz); y, por último, un sumador de señal de audio (+~). En la salida se tendrá una sinusoide de 1kHz sumada con la señal de entrada de la tarjeta de audio del ordenador. Esto no es más que un sencillo ejemplo. Sin embargo, es evidente el potencial y la flexibilidad que ofrece este lenguaje de programación, sobre todo si se tiene en cuenta que es posible desarrollar en lenguaje C nuevos objetos y funciones.

Figura 4.2.1: Ejemplo de un patch de Pure Data.

Existen cinco tipos de elementos en Pd:

Objetos: Al añadir un objeto al patch aparece una caja en la que escribiremos el nombre del mismo y, si es perteneciente a la librería de Pd, será reconocido e instanciado. Los objetos que trabajan con señales de audio incluyen el símbolo “~” al final de su nombre. La librería de Pd incluye algunos objetos predefinidos aunque, como se dijo, es posible acceder libremente a librerías más extensas de objetos desarrollados por terceros.

Números: permite almacenar datos numéricos para pasar como argumento a otros objetos.

Mensajes: Contienen información que se pasa a los objetos.

Símbolo: Guarda un símbolo hasta que se detecta que se ha recibido otro símbolo (por ejemplo, un bang).

Page 38: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

38

Comentarios: Comentarios y anotaciones acerca de los objetos.

En este proyecto Pd ejerce un importante papel ya que sirve de soporte para implementar nuestro algoritmo DSP: se encarga de tomar la señal de entrada, procesarla y ofrecerla en la salida, evitándonos el mal trago de tener que interactuar directamente con los conversores de la tarjeta de audio. Una de los principales ventajas de Pd es su relativa sencillez y la flexibilidad que ofrece. Como se mencionó anteriormente, es perfectamente compatible con Linux y su versión Raspbian para Raspberry Pi.

Como anticipamos, Pd actúa como capa intermedia o interfaz entre el hardware de la tarjeta de audio y el software de nuestro algoritmo DSP codificado sobre un external de Pd. Funciona de la siguiente forma: rellena el buffer de entrada de Pd con bloques consecutivos de N’ muestras tomadas del conversor AD del interfaz de audio y los entrega a la salida del objeto adc~. El tamaño del buffer de entrada es configurable desde el menú de audio de Pd. Cada bloque seguirá el flujo de procesado que haya sido diseñado gráficamente en el patch de Pd, para terminar entrando en el objeto dac~ que entregará el bloque final procesado a la salida del interfaz de audio. En este caso, el procesado lo efectuará un único objeto, el external en el que irá codificado el algoritmo de modificación de tono, que en adelante llamaremos pitchShifter~. Por lo tanto, nuestro patch de Pd se reduce únicamente a los conversores adc~ y dac~ interconectados a través del objeto pitchShifter~, según muestra la figura 4.2.2.

Figura 4.2.2: Nuestro sencillo patch de Pd: conversor a/d (adc~), conversor d/a (dac~) y el external pitchShifter~ )

Page 39: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

39

De modo que Pd sirve como soporte para codificar nuestro algoritmo sin necesidad de tener en cuenta otras consideraciones. Aunque, como se verá a continuación, para codificar externals es preciso emplear el API de Pd correctamente.

Los externals son objetos externos al programa, codificados en lenguaje C. Para su implementación es preciso el empleo del API de Pd, además de seguir una serie de directrices. Lo más rápido y sencillo es partir de la plantilla proporcionada por Pd o bien del código fuente de alguno de los external aportados por la comunidad de Pd (existen diversas web en las acceder a los códigos fuente). En nuestro caso se optó por la segunda opción y se partió del código de un tercero, que tenía algunos elemento en común con nuestro algoritmo [12]. Para crear un external primero será necesario configurar el entorno de desarrollo, IDE, elegido para el proyecto. En este caso se empleó XCode de Apple [13] ya que el desarrollo de pitchShifter~ se llevó a cabo fuera de la Raspberry por cuestiones de comodidad. A continuación se detalla el proceso de configuración de XCode. 4.2.1 Configuración del proyecto en XCode XCode es un software gratuito de desarrollo de aplicaciones para usuarios de sistemas operativos Mac OS X. Será la herramienta empleada para implementar nuestro pitch-shifter. Antes de abrir XCode será necesario establecer el directorio de trabajo. Se creará una carpeta llamada ”pd_externals”. Dentro, se pegará una copia del código fuente de Pd, disponible en GitHub [24] y se creará otra carpeta llamada “test_pd”, según indica la Figura 4.2.1.1.

Figura 4.2.1.1: Establecimiento del directorio de trabajo

Page 40: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

40

Ya es posible abrir XCode y crear un nuevo proyecto. Como template se seleccionará Library (Figura 4.2.1.2), como nombre del producto “PitchShifter”, como framework “None (C/C++ Library)” y por último, como type, “Dynamic”.

Figura 4.2.1.2: Creación de un nuevo proyecto en XCode

Figura 4.2.1.3: Atributos del nuevo proyecto en XCode

Page 41: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

41

A continuación se guardará el proyecto en la carpeta de trabajo, “pd_externals”; de esta forma se creará una nueva carpeta, llamada “PitchShifter” donde se almacenará todo el código fuente.

Figura 4.2.1.4: Establecimiento del directorio de trabajo

Figura 4.2.1.5: Se creará automáticamente la carpeta del proyecto XCode

A continuación será preciso configurar el proyecto. En la pestaña “Build Settings”, bajo la etiqueta Arquitectures/Arquitectures, se seleccionará “Universal (32/64-bit Intel)”. En la etiqueta Build active architecture only seleccionaremos “No”.

Page 42: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

42

Figura 4.2.1.6: Como arquitectura se seleccionará Universal (32/64-bit Intel)

Figura 4.2.1.7: Se desactivará Build Active Arquitecture Only

En la etiqueta Linking/Other Linker Flags haremos doble clic y, tras pulsar “+” teclearemos “-undefined dynamic_lookup”.

Figura 4.2.1.8: En Other Linker Flags se introducirá –undefined dynamic_lookup

Page 43: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

43

Más abajo, en la etiqueta Packaging, bajo Executable Extensions teclearemos “pd_darwin” y bajo Prefix borraremos “lib”.

Figura 4.2.1.9: Como extensión se introducirá pd_darwin

En “Project Name” introduciremos el nombre del external, tal y como lo declararemos en nuestro patch de Pd, en este caso, “pitchShifter~”.

Figura 4.2.1.10: El nombre del producto será pitchShifter~

Page 44: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

44

A continuación será necesario incorporar a nuestro proyecto la cabecera que contiene el API de Pd. Para ello abriremos con XCode el fichero “m_pd.h” , contenido en la carpeta “src” dentro de la copia del código fuente de Pd existente un nuestro directorio de trabajo, y copiaremos su contenido.

Figura 4.2.1.11: Localizaremos la cabecera m_pd.h dentro del código fuente de Pd

Figura 4.2.1.12: Copiaremos su contenido

Page 45: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

45

Cerraremos este archivo y crearemos en nuestro proyecto uno nuevo, de tipo cabecera, que nombraremos “m_pd.h”. Es preciso asegurarse de que esté enlazado con nuestro programa.

Figura 4.2.1.13: Crearemos un nuevo archivo de cabecera

Figura 4.2.1.14: Guardaremos la cabecera bajo el nombre m_pd.h asegurándonos de que está enlazada con el proyecto.

Page 46: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

46

Borraremos todo su contenido y pegaremos el código de “m_pd.h”, guardado en el porta-papeles.

Figura 4.2.1.15: Pegaremos el contenido de m_pd.h

Sólo queda ya crear un nuevo archivo con extensión “.c”, también enlazado con nuestro proyecto, en el que pegaremos el código de partida, bien sea la plantilla proporcionada por Pd o el código de un tercero, como es nuestro caso.

Figura 4.2.1.16: Crearemos un nuevo archivo .c que contendrá el código de nuestro external

Page 47: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

47

Figura 4.2.1.17: Nombraremos el archivo pitchShifter~

Figura 4.2.1.18: Guardaremos el archivo en la carpeta del proyecto

4.2.2 Compilación con XCode y test en Pd Antes de comenzar a programar es necesario comprobar que el proyecto de partida compila, como cabría esperar, y crear un programa de prueba en Pd para asegurarnos de que nuestro external es reconocido. En XCode, limpiaremos el proyecto (cmd+shift+k) y compilaremos (cmd+b). Si todo ha ido bien, se habrá generado un fichero llamado “pitchShifter~.pd_darwin” al cual podremos acceder haciendo clic derecho sobre el panel de proyecto y seleccionando “Show in finder”.

Page 48: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

48

Figura 4.2.1.19: Localizaremos nuestro external y lo copiaremos a la carpeta test_pd

Éste es nuestro external; lo copiaremos y lo pegaremos en la carpeta “test_pd” dentro de nuestro directorio de trabajo. Para probarlo, abriremos Pd y crearemos un nuevo patch (cmd+n) que guardaremos como “pitchShifter_main” en la carpeta “test_pd”. En él, crearemos nuevos objetos según el esquema de la figura 4.2.2. Al crear el objeto pitchShifter~, su caja deberá tener como contorno una línea continua, si la línea es discontinua significa que Pd no ha reconocido el external. Partiendo de una plantilla correctamente programada no deberá ser ese el caso.

(a) (b)

Figura 4.2.1.20: Crearemos una nueva instancia de nuestro external en un patch de Pd. Si, por algún motivo no es reconocido por Pd, el contorno de su representación gráfica será una línea

discontinua (a). Si el objeto se crea correctamente su contorno será continuo (b)

Page 49: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

49

Figura 4.2.1.21: Nuestro patch de Pd

Una vez nuestro programa esté listo y funcione correctamente en el ordenador de desarrollo, querremos trasladarlo a la Raspberry Pi. No será tan simple como copiar el fichero “pitchShifter~.pd_darwin” e incorporarlo a un nuevo patch de Pd en la Raspberry. La Raspberry posee un procesador ARM, mientras que del ordenador de desarrollo es Intel, de forma que el archivo no es reconocido. Es preciso llevar el código fuente a la Raspberry y compilarlo ahí, según se describe en el siguiente apartado. 4.2.3 Compilación en la Raspberry Pi, creación del archivo Maquile Para compilar nuestro proyecto en la Raspberry Pi iniciaremos la misma y crearemos un nuevo directorio llamado pd_externals, al igual que hicimos en el ordenador de desarrollo. Allí copiaremos igual que antes el código fuente de Pd y crearemos una carpeta llamada test_pd donde guardaremos una copia del código fuente de nuestro proyecto (pitchShifter.c). Por último, será necesario descargar la biblioteca pd-lib-builder, disponible en GitHub, y copiarla también a nuestro directorio de trabajo, que mostrará el siguiente aspecto:

Figura 4.2.3.1: Directorio de trabajo en la Raspberry Pi

Page 50: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

50

La biblioteca pd-lib-builder nos ayudará en el proceso de compilado en la Raspberry, bastará con configurar correctamente el archivo Maquile. Para ello abriremos el editor de texto y crearemos un nuevo archivo que guardaremos en la carpeta test_pd bajo el nombre de Makefile (sin extensión). En él teclearemos el contenido de la figura 4.2.3.2 y guardaremos.

Figura 4.2.3.2: Archivo Makefile

Para compilar el programa abriremos el terminal y nos situaremos en el directorio de trabajo.

Figura 4.2.3.3: En el terminal, seleccionamos el directorio test_pd A continuación teclearemos el siguiente comando:

Figura 4.2.3.4: Compilación del external con el comando make

Page 51: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

51

Si no ha habido ningún error durante la compilación, se habrá generado el fichero pitchShifter~.pd_linux en el cual está contenido nuestro external.

Figura 4.2.3.5: Si todo ha ido bien, nuestro proyecto habrá compilado, generándose el fichero pitchShifter~.pd_linux

Figura 4.2.3.6: Aspecto final del directorio de trabajo Para probarlo, crearemos un patch de Pd, de la misma forma que hicimos en el apartado anterior.

Page 52: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

52

Figura 4.2.3.6: Nuestro external en un patch de Pd 4.2.4 API de Pd Ya somos capaces de crear externals con XCode, compilarlos tanto en la máquina de desarrollo como en la Raspberry Pi, y ejecutarlos sobre un patch de Pd. Casi estamos en disposición de comenzar a implementar nuestro algoritmo de pitch-Shifter. Sin embargo, antes es preciso familiarizarse con el API de Pd. En este apartado describiremos los principales elementos y herramientas de este interfaz, y la forma en que estos deben estar estructurados en el código. Siempre comenzaremos nuestro código incluyendo el archivo de cabecera m_pd.h donde está contenido el API de Pd. A continuación se declarará la clase de nuestro proyecto, de tipo t_class (Figura 4.2.4.1). El siguiente elemento de código es una estructura en la que declararemos todos los atributos o variables que vayamos a requerir en la implementación de nuestro external. La variable de tipo t_object es obligatoria y debe situarse siempre en primer lugar. Sirve para almacenar propiedades del objeto u otros datos tales como entradas y salidas.

Page 53: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

53

Figura 4.2.4.1: Los atributos de clase se declaran dentro de una estructura

A continuación se declaran las distintas funciones auxiliares que vayan a ejecutarse en la función principal, o método perform, con el fin organizar y compartimentar el código. Estas funciones pueden crearse libremente, aunque siempre deben tener como argumente el puntero a un objeto de nuestra clase (Figura 4.2.4.2).

Figura 4.2.4.2: Ejemplo de una función auxiliar

El siguiente pasó será definir el método de puesta a punto que Pd ejecutará al crear un nuevo objeto. Ésta es la función seta, en la que se instancia la clase llamando al método class_new, el cual se encarga de crear la clase y devolver un puntero a la misma. El constructor, que codificaremos más adelante, es invocado en (t_newmethod)helloworld_new y se encarga de inicializar el objeto y los atributos. El siguiente argumento es un destructor que no se usa. Los últimos argumentos tienen que ver con la representación gráfica; en general se mantendrá su valor por defecto.

Por último, la función setup debe añadir los métodos auxiliares que se hayan declarado.

Figura 4.2.4.3:

Es preciso ahora declarar un constructor a través del método new: void *Objeto_new(void) (Figura 4.2.4.4). El constructor será invocado por el método setup, cuando el usuario de Pd cree un nuevo objeto, a través de la llamada a class_new.

Page 54: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

54

Figura 4.2.4.4: Declaración del constructor, o método new Los ejemplos vistos hasta ahora son de clases que no tratan con señales. Para codificar un external capaz de procesar señales de audio es preciso incorporar métodos especiales y seguir algunas reglas. Como ya se dijo, el nombre del external debe estar acompañado del símbolo “~”.

Deberán también declararse e inicializarse las entradas y salidas. El macro CLASS_MAINSIGNALIN, ejecutado en la función setup, activará la entrada principal de señal, aún cuando ésta no haya sido declarada explícitamente. Por contra, cualquier salida o entrada adicional deberá ser declarada en la estructura e inicializada en el constructor.

Figura 4.2.4.6: Ejemplo de función setup para clases de señal

En la figura 4.2.4.7 tenemos un ejemplo de la declaración de entradas y salidas. En él se declaran punteros a la salida x_out y la entrada adicional x_in3, la cual podrá tener como entrada una señal de audio, o bien de control.

Figura 4.2.4.7: Ejemplo de declaración de entrada y salida para clase de señal En la función del constructor las salidas y entradas deben ser inicializadas. Un ejemplo de la sintaxis empleada se muestra en la Figura 4.2.4.8, para una explicación más detallada se recomienda recurrir a la bibliografía [14]. Si se desea almacenar el

Page 55: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

55

valor que se recibe por una de las entradas de datos en una variable, debe emplearse la sintaxis de la figura para x_in3.

Figura 4.2.4.8: Ejemplo de constructor para clases de señal

Otro elemento común a todas las clases que manejan señales es un método para el procesado de señal, dsp (Figura 4.2.4.9). Cuando se enciende el motor de audio de Pd aquellos objetos que incluyan este método serán reconocidos como clases de señal e incorporarán sus rutinas al flujo DSP. El método dsp consta de dos argumentos: un puntero a la clase y el puntero a un array de señales. Las señales están organizadas de manera que en su representación gráfica quedarán ordenadas de izquierda a derecha.

Dentro del método dsp se hace una llamada a la función dsp_add, que incorpora al árbol DSP la rutina declarada en el primer argumento. El siguiente argumento es el número de punteros a diversas variables que se pasarán como siguientes argumentos. En el ejemplo de la figura XX sp[0] es la primera señal de entrada, sp[1] la segunda y sp[2] apunta a la señal de salida, ambas ubicadas en vectores de longitud s_n.

Figura 4.2.4.9: Método dsp para funciones de señal

El método perform es el corazón de cualquier clase de señal. Es en él donde se realiza el procesado, podría entenderse como el equivalente al clásico bucle infinito dentro del método principal. Como argumento se le pasa el puntero a un array de enteros. Este array contiene los punteros pasados a través de dsp_add. Como salida debe devolver el puntero a un número entero que apunta a la dirección de memoria debajo

Page 56: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

56

de los punteros de la rutina almacenados. De modo que el número retornado será igual al argmento de la rutina perfom, más el número punteros declarado como segundo argumento de la función dsp, más uno (Figura 4.2.4.10).

Figura 4.2.4.10: El método perform es la función principal de cualquier external que trabaje con

señal

A continuación, se incluye el código que realiza el procesado que deseamos implementar. Este debe estar dentro de un bucle donde la variable n, cuyo valor corresponde con el tamaño del buffer de entrada de Pd, hará de límite del contador.

Llegados a este punto ya disponemos de las herramientas necesarias para comenzar a planificar la implementación de nuestro pitch-shifter. Se hará en el siguiente capítulo.

4.3 GUÍA DE CONFIGURACIÓN 4.3.1 Instalación del sistema operativo Raspbian La Raspberry carece de un disco duro integrado y precisa de una tarjeta micro SD para almacenar el sistema operativo y el resto de datos. Para la instalación del sistema operativo deberá volcarse el programa de instalación NOOBS (disponible a través de la web de Raspberry Pi) en cualquier tarjeta micro SD disponible, o bien adquirir una tarjeta con NOOBS preinstalado. En este caso se optó por la opción preinstalada. Para instalar el sistema operativo basta con insertar la tarjeta micro SD con el programa NOOBS en la ranura de la Raspberry, conectar teclado, ratón y pantalla, enchufar el cable de alimentación y, una vez iniciado el programa de instalación, seleccionar el sistema operativo deseado y hacer clic en instalar, según se indica en la figura 4.3.1.1:

Page 57: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

57

Figura 4.3.1.1: Programa NOOBS de instalación del sistema operativo Raspbian Para este proyecto elegimos el sistema operativo Raspbian, que es el recomendado por el fabricante. Está basado en el SO de distribución libre Debian (Linux) y adaptado al hardware de la Raspberry Pi. Además viene con más de 35000 paquetes de software pre-compilado. Raspbian no está afiliado con la fundación Raspberry Pi, fue creado por un pequeño equipo de desarrolladores entusiastas de la Raspberry sin ánimo de lucro. 4.3.2 Configuración del adaptador wi-fi Una vez instalado Raspbian debemos conectar la Raspberry a la red para poder descargar los diferentes paquetes y actualizaciones. Para ello se arrancará con el adaptador wifi USB conectado. Tras iniciarse el sistema se comprobará que el adaptador ha sido detectado, ejecutando el comando dmesg | more en el terminal y buscando el dispositivo bajo la etiqueta USB. A continuación editaremos el fichero /etc/network/interfaces con el editor de texto Nano incorporado en Raspbian, mediante el siguiente comando:

sudo nano /etc/network/interfaces Debemos comentar el siguiente código, añadiendo el signo #, resultando:

Page 58: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

58

#iface wlan0 inet manual #wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

#auto wlan1 #allow-hotplug wlan1 #iface wlan1 inet manual #wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

En su lugar añadiremos:

iface wlan0 inet dhcp wpa-ssid “Network_ID” wpa-psk “Password”

Por último guardaremos los cambios y ejecutaremos el siguiente comando:

sudo service networking reload De esta forma queda configurada la red WIFI y, si todo ha salido bien, dispondremos de internet en la Raspberry. En este punto resulta interesante anotar la dirección IP de la Raspberry, que necesitaremos para controlarla de forma remota. Podemos saberla empleando el comando ifconfig. 4.3.3 Control remoto de la Raspberry Pi - SSH (Secure Shell) Para emprender cualquier tipo de proyecto en la Raspberry resulta conveniente poder acceder a su sistema operativo a través de otro ordenador. Para controlar la Raspberry de forma remota a través de otra máquina pude emplearse el protocolo SSH (Secure Shell) . Con un simple cable ethernet podemos controlar la línea de comandos de la Raspberry. Es necesario conocer la IP de la Raspberry. La forma más sencilla es conectar a una pantalla al puerto HDMI y utilizar el comando ifconfig en el terminal. También necesitaremos activar el protocolo a través del panel de control de Raspbian, dentro del apartado de interfaces, según indica la Figura 4.3.3.1.

Page 59: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

59

Figura 4.3.3.1: Activación del protocolo SSH en el panel de control Una vez averiguada la IP y activado SSH, deben seguirse los siguientes pasos:

1) Conectar la máquina directamente a la interfaz de red de la Raspberry mediante un cable ethernet.

2) Iniciar la Raspberry Pi. 3) Introducir el siguiente comando en la línea de comandos de la máquina con la

que vamos a controlar la Raspberry: ssh {IP Raspberry} –l pi (Figura 4.3.3.2).

Figura 4.3.3.2: Inicialización de la comunicación con la Raspberry a través del protocolo SSH De esta forma tenemos acceso a la línea de comandos de la Raspberry desde nuestro ordenador anfitrión.

Page 60: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

60

- VNC (Virtual Network Computing) Existe otra forma de controlar de forma remota la Raspberry Pi, más conveniente para nuestro proyecto, ya que nos dará acceso al entorno gráfico de Raspbian. Con la tarjeta encendida y conectada en red es posible emplear un software de control remoto de tipo VNC desde un ordenador para trabajar con nuestro dispositivo en modo escritorio. Para ello es necesario instalar un servidor VNC en nuestra Raspberry Pi, y disponer de un programa como TightVNC o RealVNC, que pemita la conexión VNC desde otro ordenador.

Para Activar un servidor VNC en la Raspberry Pi debemos primero instalarlo; con la versión de Raspbian Jessie es posible usar el comando apt en el terminal de la siguiente forma:

sudo apt-get update

Una vez haya finalizado la ejecución de la anterior orden ejecutaremos el siguiente comando:

sudo apt-get install tightvncserver

Esta orden instala el servidor VNC en la Raspberry Pi. Una vez acabado el proceso ejecutaremos el servidor VNC con la orden

vncserver :1

Este comando pone en marcha el servidor VNC para que otra máquina pueda conectarse. La primera vez que ejecutamos este programa deberemos introducir una nueva contraseña, que requeriremos cada vez que nos conectemos con la Raspberry.

Existen diversos programas cliente VNC para instalar en la máquina anfitriona, aunque se recomienda RealVNC o TigthVNC, ambos muy similares, de sencillo uso y libre distribución.

Una vez instalado el programa (TigthVNC en este ejemplo) lo ejecutaremos, abriéndose una ventana como la de la figura 4.3.3.3a.

Page 61: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

61

(a)

(b)

Figura 4.3.3.3: Panel de control de TightVNC (a). Configuración de la conexión (b) Deberemos introducir la dirección IP del servidor VNC al que nos queremos conectar, que será la IP de nuestra Raspberry Pi, seguido de “:1”, como se muestra en la Figura 4.3.3.3b. Presionaremos el botón Connect, e introduciremos la contraseña escogida al instalar el Servidor VNC que se nos requerirá en una nueva ventana (Figura 4.3.3.3). Tras pulsar OK tendremos acceso al escritorio de la Raspberry pi (Figura 4.3.3.4).

Page 62: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

62

Figura 4.3.3.4: Ya tenemos acceso al escritorio de la Raspberry Pi Es posible que aparezca un mensaje de error en el escritorio, el cual ignoraremos (Figura 4.3.3.5).

Figura 4.3.3.5: Mensaje de error, que ignoraremos

Para que el servidor VNC se ejecute de forma automática siempre que encendemos la Raspberry Pi, crearemos un fichero que ejecute el programa cada vez que se inicie en

modo escritorio. Desde la Raspberry Pi abrimos una pantalla del terminal accederemos a la carpeta .config, mediante:

Page 63: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

63

cd /home/pi

Intro

cd .config

ahora crearemos la carpeta autostart dentro del directorio .config, con el comando:

mkdir autostart

Aaccederemos a la carpeta mediante

cd autostart

y abriremos el editor de texto nano para crear un fichero con las órdenes necesarias:

nano tightvnc.desktop

Se abrirá la pantalla del editor nano, donde introduciremos las líneas de código siguientes:

[Desktop Entry]

Type=Application

Name=TightVNC

Exec=vncserver :1

StartupNotify=false

Tras guardar con ctrl+x y presionar Enter, saldremos del editor nano con ctrl+x. Ahora si reiniciamos la Raspberry Pi en modo escritorio automáticamente se iniciará el servidor VNC y nos podremos conectar desde otra máquina.

Page 64: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

64

4.3.4 CONFIGURACIÓN DEL INTERFAZ DE AUDIO FOCUSRITE SCARLETT 2I2 Como se dijo, el interfaz de audio incorporado en la Raspberry Pi es de bajas prestaciones y carece de entradas, de manera que nos vemos forzados a emplear un interfaz externo USB. Antes de elegir uno en concreto es necesario comprobar que sea compatible con la Raspberry Pi [15], como es el caso de la tarjeta Focusrite Scarlett 2i2 [16], que se empleará en nuestro proyecto.

Figura 4.3.4.1: Interfaz de audio Scarlett 2i2 de Focusrite

La Scarlett 2i2 es una interfaz de audio USB de precio asequible y tamaño reducido comercializada por la prestigiosa firma británica Focusrite. A continuación se enumeran sus principales características:

• 2 entradas micrófono/línea/instrumento combinado con XLR Neutrik ¼” y jack TRS

• 2 interruptores de línea/instrumento • 2 knobs de ganancia • Interruptor de alimentación phantom de 48V • Conversores AD/DA de 24bit/96khz • Salida de auriculares ¼ TRS jack • Knob de volumen general y de auriculares • Alimentación por USB • Compatible con MAC, Windows y Lynux • Tamaño reducido y total portabilidad

Page 65: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

65

Dadas sus especificaciones resulta ideal para nuestro cometido ya que consta de las suficientes entradas/salidas y cumple los requisitos de portabilidad, sencillez, precio asequible y alto rendimiento. Para configurar la tarjeta correctamente la conectaremos primero al puerto USB de la Raspberry Pi, y arrancaremos esta última. En el terminal, comprobaremos que ha sido reconocida ejecutando el comando lsusb, que enumera todos los dispositivos USB conectados a la Raspberry Pi (4.3.4.2).

Figura 4.3.4.2: Listado de dispositivos USB A continuación averiguaremos el alias que Raspbian ha asignado a nuestro interfaz de audio, mediante el comando aplay –L. Tras ejecutarlo aparecerá una larga lista, en la que debemos localizar la Scarlett y apuntar su alias, en este caso “USB” (Figura 4.3.4.3).

Page 66: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

66

Figura 4.3.4.3: Es preciso localizar el alias de la Scarlett, en este caso USB Ahora será necesario acceder al archivo de configuración .asound.rc y modificarlo para que establezca la Scarlett como interfaz por defecto. Para ello ejecutaremos el comando:

sudo nano .asoundrc, Y, con el editor nano, sustituiremos el contenido del archivo por el siguiente código (Figura 4.3.4.4): pcm.!default plughw:USB ctl.!default plughw:USB donde, como se dijo, USB es el alias de la Scarlett.

Page 67: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

67

Figura 4.3.4.4: Edición del archivo .asoundrc

De esta forma nuestra tarjeta de sonido quedará configurada como interfaz principal. Para asegurarnos de que se ha realizado el proceso correctamante podemos reproducir uno de los sonidos de prueba de Raspbian, mediante el siguiente comando: aplay /usr/share/scratch/Media/Sounds/Vocals/Singer1.wav Si la interfaz está correctamente configurada aparecerá el mensaje de la figura 4.3.4.4 y oiremos a su salida un breve clip con la voz de una cantante de ópera.

Figura 4.3.4.4: Edición del archivo .asoundrc

Page 68: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

68

Para seleccionar el interfaz en Pd bastará con ir a file/preferences/Audio Settings y seleccionar el interfaz Scarlett 2i2 USB. 4.3.5 Instalación y configuración de Pure Data En este apartado se guiará al lector durante el proceso instalación Pure Data en Raspbian. Existen diferentes versiones de Pd. Las principales versiones disponibles son Pure Data y Pd-extended. La segunda incluye librerías, extensiones y documentación, aunque actualmente se encuentra descatalogada. Será suficiente con instalar la versión básica de Pure Data.

Para ello se accederá al terminal de Raspbian, donde se introducirá el siguiente comando:

sudo apt-get install puredata

Si el programa se ha instalado correctamente, podremos ejecutarlo a través del menú de inicio de Raspbian, según se indica en la Figura 4.3.5.1.

Figura 4.3.5.1: Se ejecuta Pd a través del menú de inicio

Para configurar correctamente Pd se accederá al menú de preferencias Audio Settings, según se indica en la Figura 4.3.5.2

Page 69: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

4. CONFIGURACIÓN Y PUESTA EN MARCHA

69

Figura 4.3.5.2: Acceso al menú de configuración de audio

Aparecerá una ventana como la de la Figura 4.2.5.3. En primer lugar, se puede seleccionar la frecuencia de muestreo con la que se desea trabajar y elegir el tamaño del buffer donde Pd almacena los bloques de muestras que toma de la entrada. Se recomienda seleccionar un tamaño de bloque de 64 muestras, de forma que la latencia sea reducida. También es posible seleccionar el interfaz de audio, en nuestro caso la Scarlett 2i2.

Figura 4.3.5.3: Preferencias de audio de Pd

Page 70: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

70

5. IMPLEMENTACIÓN DEL PITCH SHIFTER Es el momento de poner en común todos los conceptos y herramientas vistas hasta el momento. En este capítulo se detallará todo el proceso de desarrollo del external pichShifter~, dividiendo el contenido en varias secciones. En la primera se plantearán las variables y recursos de entrada/salida necesarios para implementar nuestro algoritmo. Las siguientes secciones y subsecciones se corresponden con las fases del proceso de modificación de tono. En cada una de ellas se planteará un posible pseudo-código que implemente la correspondiente fase del algoritmo. Además se presentarán los códigos resultado de la implementación del prototipo en MatLab y del external en C .

5.1 Recursos necesarios Para la implementación del modificador de tono precisaremos declarar una serie de variables que representen a aquellas contenidas en las ecuaciones matemáticas que queremos implementar, más algunas otras inherentes a la programación. Pd define en su API algunos tipos de datos como t_float, adecuado para almacenar muestras en el dominio de la frecuencia, o t_sample para muestras en el dominio del tiempo. A continuación se enumeran todas las variables empleadas, comentadas una a una:

Page 71: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

71

t_object x_obj; // Objeto de Pd t_float sr; // Frecuencia de muestreo t_float n; //Tamaño del Buffer de entrada de Pd int dsp_tick; // Contador para rellenar el buffer de

entrada del programa, de tamaño distinto del de Pd

int buffer_limit; //Límite del contador anterior int overlap_in; // window/hop_in int frame_size; // Tamaño del frame, en muestras (por defecto 1024) int frame_size_half; // Medio frame int hop_in; //Tamaño del hop de entrada en muestras int hop_out; //Tamaño del hop de salida en muestras t_float amp_scalar; //Factor multiplicativo para el

enventanado t_float *hann; // Ventana Hanning t_sample *input_buf; // Array para almacenar el buffer

de entrada t_sample *input_buf_windowed; // Array para almacenar el

frame enventanado t_float *signal_R; //Array para almacenar la parte REAL de la DFT t_float *signal_I; //Array para almacenar la parte IMAGINARIA de la DFT t_float *signal_mag; // Array para almacenar la magnitud de la DFT

Page 72: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

72

t_float *signal_phase; //Array para almacenar fase de la DFT t_float *prev_signal_mag; // Magnitud del frame anterior t_float *prev_signal_phase; // Fase del frame anterior t_float *phase_dif; // Diferencia de fase entre frames consecutivos t_float *true_freq; // Frecuencia verdadera t_float *cumulative_phase; // Fase acumulada t_float semitones; // Cantidad de semitonos (positiva o negativa) que se va a modificar el tono t_float alpha; // Relación entre los hops de entrada y de salida: hop_out/hop_in t_sample *vocoder_output; // Señal de salida del Phase-Vocoder, estirada o contraída t_sample *final_output; // Señal re-muestreada, de vuelta a su duración original t_sample *overlap_add_buffer; t_inlet *semitones_in; // Entrada para controlar el tono, en pasos de semitono t_outlet *x_out; // Buffer de salida de Pd t_float x_f; // Variable de control

Page 73: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

73

5.2 TIME-STRETCHING EMPLEANDO ALGORITMO DE PHASE-VOCODER 5.2.1 Análisis Como se explicó en capítulos anteriores, durante la fase de análisis se toman frames, de tamaño frame_size, se enventanan y se computa su DFT. Para ello será necesario crear un buffer de entrada, input_buf, de tamaño frame_size. Puesto que deseamos que los frames estén solapados en un 75%, debemos procesar uno nuevo cada vez que el buffer acumule hop_in = frame_size/4 muestras. Sin embargo, Pd entrega la señal en bloques de n muestras (como dijimos, este valor es configurable, por defecto son 64 muestras). Debemos esperar a que el buffer se rellene implementando un contador, dsp_tick, que se incrementará cada vez que entre un bloque de n muestras. Una vez que el contador alcance el límite buffer_limit, el buffer de entrada se habrá actualizado hop_in muestras y dispondremos de un nuevo frame. Este límite se calcula mediante: buffer_limit = hop_in/n; Por ejemplo, para frame_size = 1024, hop_in = 1024/4 = 256 y n = 64, obténdríamos un límite de 4. Es decir, tendríamos que esperar la entrega de 4 bloques de 64 muestas para actualizar el buffer de entrada en 256 muestras y poder entregar un nuevo frame a la etapa de análisis. Para ello puede implementarse el siguiente bloque de pseudo-código, que se ejecutará en bucle en dentro del método perform: //Desplazar el contenido previo del buffer a la izda. para(i=0 hasta frame_size – n -1) i nput_buf[i] = input_buf[n+i]; //Escribir último bloque para(i=0 hasta n) x->signal_buf[window-n+i] = in[i];

Page 74: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

74

//Cuando se completa un bloque de tamaño hop_in, se pasa un nuevo frame a la etapa de análisis si(x->dsp_tick>=x->buffer_limit) { //Análisis //... //... } dsp_tick = dsp_tick + 1; Solucionada esta cuestión ya disponemos de un nuevo frame que analizar. El primer paso será enventanar la señal, para ello deberá generarse un vector que contenga la ventana Hanning que vamos a emplear: //Inicializar ventana Hanning para(i=0, hasta frame_size) hann[i] = 0.5 * (1 - cos(2*PI*i/frame_size)); A continuación se multiplicará el frame por la ventana y se almacenará el resultado en un nuevo array, input_buf_windowed. //Enventanar la señal para(i=0 hasta frame_size -1) input_buf_windowed[i] = input_buf[i] * hann[i]; Una vez enventanado el frame, se computará su DFT, almacenando el resultado complejo separado en sus partes real e imaginaria. //Calcular la DFT y desdoblar en partes real e imaginaria para( i=0, hasta frame_size_half) { signal_R[i] = Re( fft(input_buf_windowed)[i] ); signal_I[i] = Im( fft(input_buf_windowed)[i] ); } Ya disponemos del frame en el dominio de la frecuencia, separado en componentes

Page 75: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

75

real e imaginaria. Queda concluida así la fase de análisis; podemos proceder con la fase más crítica y delicada de nuestro algoritmo, el procesado. 5.2.2 Procesado Una vez representado un frame en el dominio de la frecuencia se procederá a aplicar las correcciones de fase necesarias para evitar incoherencias. Este proceso se lleva a cabo en el siguiente fragmento de pseudo-código para(i=0, hasta frame_size-1) { //Calcular módulo y fase de la FFT signal_mag[i] = abs(signal_R[i]+I*signal_I[i]); signal_phase[i] = arg(signal_R[i]+I*signal_I[i]);

//Calcular la diferencia de fase entre frames consecutivos phase_dif[i] = signal_phase[i] - prev_signal_phase[i];

//Almacenar la fase del frame actual prev_signal_phase[i] = signal_phase[i]; //Eliminar la diferencia de fase esperada phase_dif[i] = phase_dif[i] - hop_in*2.0*M_PI*i/frame_size; //Representar la diferencia de fase en el intervalo –PI-PI phase_dif[i] = x->phase_dif[i] + M_PI; x->phase_dif[i] = phase_dif[i] – floor(phase_dif[i]/(2.0*M_PI)) * 2.0*M_PI - M_PI; //Calcular la frecuencia verdadera true_freq[i] = 2.0*PI*i/frame_size + phase_dif[i]/hop_in; //Calcular la fase corregida

Page 76: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

76

cumulative_phase[i] = cumulative_phase[i] + (hop_out)*true_freq[i]; //Calcular parte real e imaginaria:

signal_R[i] = signal_mag[i] * cos(cumulative_phase[i]); signal_I[i] = signal_mag[i] * sin(cumulative_phase[i]);

} 5.2.3 Síntesis Llegados a este punto nuestros frames ya están listos para ser transformados de vuelta al dominio del tiempo y ser sumados de forma entrelazada (overlap/add), con suerte evitando los temidos clics si el procesado ha sido el correcto. Es importante tener en cuenta que durante la fase de síntesis se producirá una variación del régimen binario en el flujo DSP. Si la entrada del módulo de síntesis el régimen es 𝑅!, a la salida del mismo será 𝛼𝑅!. Esta variación instantánea del régimen binario será compensada durante el re-muestreo. El primer paso será devolver los frames al dominio del tiempo: para(i=0, hasta frame_size-1) { input_buf_windowed[i] = ifft(signal_R + I*signal_I)[i] } De vuelta al dominio del tiempo, enventanaremos la señal de nuevo: //Enventamamos de nuevo para(i=0, hasta frame_size-1) { x->input_buf_windowed[i] *= x->hann[i]; x->input_buf_windowed[i] *= amp_scalar; } Ha llegado el momento de entrelazar la señal. Para ello se ha creado el buffer

Page 77: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

77

overlpal_add_buffer, al que se irán sumando los frames entrantes, después de haber desplazado el contenido previo. Estos desplazamientos se harán en saltos de hop_out muestras. //Overlap/Add: //Desplazar hacia atrás el contenido previo del buffer para(i=0, hasta 2*frame_size - hop_out – 1) {

overlap_add_buffer[i] = overlap_add_buffer[i+hop_out];

} //Poner a cero el último bloque para(i= (2*frame_size - hop_out) hasta 2*frame_size - 1) overlap_add_buffer[i] = 0; //Sumar el frame actual para( i=0, hasta frame_size - 1) {

overlap_add_buffer[frame_size + i] = overlap_add_buffer[frame_size + i] + input_buf_windowed[i];

} //Sacar del buffer de salida un array de tamaño hop_out, para pasarlo al módulo de re-muestreo para( i=0, hasta hop_out -1 ) { vocoder_output[i] = overlap_add_buffer[frame_size - hop_out + i]; } Aquí termina el papel del Phase-Vocoder en nuestro algoritmo. Ya disponemos de un bloque de tamaño hop_out, que devolveremos a su tamaño inicial hop_in a través del proceso de re-muestreo.

Page 78: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

78

5.3 Re-muestreo El re-muestreo en este proyecto se entenderá como un cambio en el régimen binario al descartar muestras, o bien generar muestras nuevas en una determinada proporción. A la entrada del módulo de re-muestreo llega un bloque de tamaño hop_out y después del procesado se obtiene un bloque de tamaño hop_in, de forma que el factor de re-muestreo es alpha = hop_out/hop in. Esto implica que por cada muestra a la entrada se tendrán alpha muestras a la salida. Las muestras de salida se obtendrán interpolando linealmente la señal de entrada, según el algoritmo diseñado en capítulos anteriores. //RE-MUESTREO Enteros index_floor, index_ceil; // Índices de las

muestras previa y posterior a la que se quiere interpolar

para(i=0, hasta hop_in - 1) { index_floor = floor(alpha*i); index_ceil = index_floor + 1; final_output[i] = x->vocoder_output[ index_floor]; final_output[i] = final_output[i] +

(vocoder_output[index_ceil] – vocoder_output[index_floor])* (alpha*i - index_floor);

} Como se desprende del algoritmo, el proceso de re-muestreo equivale a reproducir la señal de entrada más rápido o más despacio dependiendo de que el factor alpha sea mayor o menor que uno respectivamente. Esto cumple un doble objetivo: Por un lado devuelve la señal, estirada o contraída, a su duración original. Por otro, produce una variación controlada en el tono de la señal. De cara a emplear nuestro programa en la modificación del tono de instrumentos musicales, resulta conveniente que las variaciones sean en pasos de semitono. Para ello definiremos la variable semitones, que se pasará como argumento al constructor del objeto pitchShifter, y se corresponderá con el número (con signo) de semitonos que deseamos aumentar o disminuir el tono de la señal.

Page 79: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

5. IMPLEMENTACIÓN DEL PITCH-SHIFTER

79

Por último se generará la salida del external. Esto deberá hacerse fuera de la condición si(x->dsp_tick>=x->buffer_limit), ya que debemos entregar la salida en bloques de n muestras, el tamaño del buffer de salida de Pd. Después de sacar un bloque es cuando debe incrementarse el contador dps_tick. //SALIDA para(i=0, hasta n) *out = final_output[dsp_tick*n + i]; x->dsp_tick++;

Page 80: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

80

6. RESULTADOS En este capítulo se presentan los resultados de las diferentes pruebas llevadas a cabo sobre el algoritmo de modificación de tono. Se mostrarán tanto aquellos obtenidos con el prototipo MatLab como los generados por el external de Pd. En ambos casos se emplearán tres señales de prueba: un tono puro de 1kHz, una nota de guitarra y una secuencia percusiva. La cantidad de variación de tono se limitará al rango de -4 a 4 semitonos, ya que el algoritmo clásico de phase-vocoder no logra mantener la naturalidad del sonido para valores fuera de este intervalo. En cada caso se representarán la señal de prueba entrante y la señal resultante después del procesado, tanto en el dominio del tiempo como en el de la frecuencia. Se compararán los espectros resultantes con los esperados teóricamente, comprobando que los picos se desplazan según el factor de modificación de tono 𝛼. La única excepción será la secuencia percusiva, en la que sólo se analizará la señal temporal resultante, con el fin de detectar posible emborronamiento de los transitorios.

Page 81: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

81

6.1 PROTOTIPO EN MATLAB 6.1.1 Señal sinusoidal Al aplicar el procesado sobre una señal sinusoidal de prueba x(t) de frecuencia f cabría esperar obtener a la salida una nueva señal y(t) de frecuencia 𝛼𝑓, (recordemos que 𝛼 = 2!"/!"#$%&'"!). En las figuras 6.1.1.1 a 6.1.1.4 se presentan los resultados obtenidos para una señal sinusoidal de 1 kHz, con variaciones de +4 y -4 semitonos respectivamente.

Figura 6.1.1.1: Señal de prueba sinusoidal de 1 kHz (azul) y señal resultante (rojo), al efectuar una variación de +4 semitonos

Page 82: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

82

Figura 6.1.1.2: Espectros de la señal de prueba sinusoidal de 1 kHz (azul) y señal resultante

(rojo), al efectuar una variación de +4 semitonos

Figura 6.1.1.3: Señal de prueba sinusoidal de 1 kHz (azul) y señal resultante (rojo), al efectuar una variación de -4 semitonos

Page 83: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

83

Figura 6.1.1.4: Espectros de la señal de prueba sinusoidal de 1 kHz (azul) y señal resultante

(rojo), al efectuar una variación de -4 semitonos

En la Tabla 6.1.1.1 se presentan las medidas de las frecuencias de las señales resultantes de procesar un tono de 1 kHz, junto a sus valores teóricos.

variación (semitonos)

frecuencia esperada 𝛼𝑓

(Hz)

frecuencia medida

(Hz)

Error relativo

(%)

+4 1259,9 1260,5 0,05

-4 793,7 794,0 0,04

Tabla 6.1.1.1: Frecuencias de la señal procesada, teóricas y experimentales, para un tono de 1 kHz a la entrada y variaciones de ±4 semitonos

Como puede comprobarse, los valores de frecuencia obtenidos son muy próximos a los esperados, con errores inferiores a 1 Hz, imperceptibles para el oyente.

Page 84: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

84

6.1.2 Señal de guitarra acústica La siguiente señal de prueba es una nota aislada de guitarra acústica. A diferencia del tono puro, esta señal presenta una serie de armónicos. Tras el procesado cabría esperar que las frecuencias de estos armónicos se desplazasen respecto al origen multiplicadas por un factor 𝛼. En las figuras 6.1.2.1 y 6.1.2.2 se presentan los resultados para una variación de -4 semitonos.

Figura 6.1.2.1: Señal de guitarra acústica entrante (azul) y señal resultante (rojo), al efectuar una variación de -4 semitonos

Page 85: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

85

Figura 6.1.2.2: Espectro de la señal de guitarra acústica entrante (azul) y de la señal resultante

(rojo), al efectuar una variación de -4 semitonos En la Tabla 6.1.2.1 se presentan las medidas de las frecuencias de los tres primeros armónicos de las señales resultantes de procesar una señal de guitarra acústica, junto a sus valores teóricos.

variación (semitonos)

Armónico

Frecuencia de entrada

(Hz)

Frecuencia resultante

esperada 𝛼𝑓 (Hz)

frecuencia resultante medida

(Hz)

Error relativo

(%)

+4 1 196,0 246,9 247,0 0,02 +4 2 295,0 371,7 372,0 0,09 +4 3 393,0 495,1 495,0 0,03 -4 1 196,0 155,6 156,0 0,28 -4 2 295,0 234,1 234,0 0,06 -4 3 393,0 311,9 312,0 0,02

Tabla 6.1.2.1: Frecuencias de los tres primeros armónicos de la señal procesada, obtenidas de

forma teórica y experimental, para una señal de guitarra acústica a la entrada y variaciones de ±4 semitonos

Page 86: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

86

6.1.3 Señal percusiva

Una de las contrapartidas del algoritmo clásico de phase-vocoder es la pérdida de definición de los transitorios por la introducción de emborronamiento, o semearing. Para comprobar la respuesta de nuestro prototipo frente a transitorios rápidos emplearemos una secuencia de percusión. En las figuras 6.1.3.1 y 6.1.3.2 se presentan los resultados para variaciones de +4 y -4 semitonos.

Figura 6.1.3.1: Señal de percusión de prueba (azul) y señal resultante (rojo), al efectuar una variación de +4 semitonos

Page 87: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

87

Figura 6.1.3.2: Señal de percusión de prueba (azul) y señal resultante (rojo), al efectuar una variación de -4 semitonos

En las figuras anteriores se comprueba que el prototipo apenas afecta a los transitorios y no introduce una cantidad de emborronamiento apreciable. 6.1.4 Prueba auditiva Las pruebas auditivas pusieron de manifiesto un correcto funcionamiento del prototipo entre el margen de -4 y 4 semitonos. La variación de tono se efectuó correctamente para todas las señales de prueba, obteniendo un sonido natural y fiel al original en cuanto a timbre y transitorios. Para valores más elevados empezó a hacerse patente un mayor emborronamiento, dando lugar a un sonido artificial.

Page 88: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

88

6.2 EXTERNAL DE PD Para realizar las pruebas sobre pitchShifter~ se creó un nuevo patch de Pd con los objetos necesarios para reproducir una señal pre-grabada, procesarla y registrar el resultado en un archivo de audio (Figura 6.2.1).

Figura 6.2.1: Patch de prueba en Pd

6.2.1 Señal Sinusoidal En las figuras 6.2.1.1 a 6.2.1.4 se presentan los resultados obtenidos para una señal sinusoidal de 1 kHz, con variaciones de +4 y -4 semitonos respectivamente.

Page 89: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

89

Figura 6.2.1.1: Señal de prueba sinusoidal de 1 kHz (azul) y señal resultante (rojo), al efectuar

una variación de +4 semitonos

Figura 6.2.1.2: Espectros de la señal de prueba sinusoidal de 1 kHz (azul) y señal resultante (rojo), al efectuar una variación de +4 semitono

Page 90: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

90

Figura 6.2.1.3: Señal de prueba sinusoidal de 1 kHz (azul) y señal resultante (rojo), al efectuar

una variación de -4 semitonos

Figura 6.2.1.4: Espectros de la señal de prueba sinusoidal de 1 kHz (azul) y señal resultante

(rojo), al efectuar una variación de -4 semitonos

Page 91: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

91

En la Tabla 6.2.1.1 se presentan las medidas de las frecuencias de las señales resultantes de procesar un tono de 1 kHz, junto a sus valores teóricos.

variación (semitonos)

frecuencia esperada 𝛼𝑓

(Hz)

frecuencia medida

(Hz)

Error relativo

(%)

+4 1259,9 1237,0 1,8

-4 793,7 876,0 10,4

Tabla 6.2.1.1: Frecuencias de la señal procesada, teóricas y experimentales, para un tono de 1 kHz a la entrada y variaciones de ±4 semitonos

Como se aprecia en la tabla anterior, los valores de frecuencia obtenidos sólo coinciden aproximadamente con los esperados. En particular, para una variación de -4 semitonos, se obtiene un error en torno al 10%, lo cual es inaceptable para usos musicales. Además se produce una atenuación excesiva de la señal. Esto hace pensar en un posible error de implementación en el código C del external. 6.2.2 Señal de guitarra acústica En las figuras 6.2.2.1 a 6.2.2.4 se presentan los resultados para variaciones de +4 y -4 semitonos sobre la señal de guitarra acústica.

Page 92: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

92

Figura 6.2.2.1: Señal de guitarra acústica entrante (azul) y señal resultante (rojo), al efectuar una variación de +4 semitonos

Figura 6.2.2.2: Espectro de la señal de guitarra acústica entrante (azul) y de la señal resultante

(rojo), al efectuar una variación de +4 semitonos

Page 93: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

93

Figura 6.2.2.3: Señal de guitarra acústica entrante (azul) y señal resultante (rojo), al efectuar

una variación de -4 semitonos

Page 94: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

94

Figura 6.2.2.4: Espectro de la señal de guitarra acústica entrante (azul) y de la señal resultante (rojo), al efectuar una variación de -4 semitonos Se observa que en ambos casos el procesado incorpora nuevas componentes espectrales inesperadas, sin poderse establecer una correspondencia evidente con los armónicos originales. Además, se produce una gran atenuación. En cuanto a la latencia, se mantiene en un nivel aceptable de 23 milisegundos.

Page 95: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

95

6.2.3 Señal percusiva En las figuras 6.2.3.1 y 6.2.3.2 se presentan los resultados para variaciones de +4 y -4 semitonos sobre la señal de percusión.

Figura 6.2.3.1: Señal de percusión entrante (azul) y señal resultante (rojo), al efectuar una variación de +4 semitonos

Page 96: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

6.RESULTADOS

96

Figura 6.2.3.2: Señal de percusión entrante (azul) y señal resultante (rojo), al efectuar una variación de -4 semitonos Vemos que para una variación de -4 tonos los transitorios se mantienenrelativamente inalterados, mientras que para +4 semitonos se produce unemborronamientodelosmismos. 6.2.4 Prueba auditiva Durante la prueba auditiva de pitchShifter~ se hizo evidente un error de programación en la implementación del algoritmo en C. Aunque el efecto ejecutó la modificación de tono en tiempo real, para ciertos valores de la variable semitones se produjeron resultados inesperados como una modificación de tono incorrecta, distorsión o atenuaciones excesivas. Esto se puso de manifiesto particularmente para señales sinusoidales.

Page 97: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

7. CONCLUSIONES

97

7. CONCLUSIONES A lo largo de este proyecto se ha demostrado la posibilidad de implementar un efecto de modificación de tono en tiempo real sobre la tarjeta Raspberry Pi codificado sobre un objeto de Pure Data. El empleo de la Raspberry y del interfaz de audio Scarlett permitió cumplir con nuestro propósito inicial de diseñar un sistema portable, de rápido montaje y asequible, que cumpliera con unos requisitos mínimos de rendimiento. Las latencias de salida obtenidas –inferiores a 30 ms- fueron lo bastante bajas para permitir su uso en aplicaciones musicales, lo cual satisface nuestro requisito de funcionamiento en tiempo real. En cuanto al objetivo de precisión, el prototipo en MatLab puso de manifiesto la eficacia del Phase Vocoder como algoritmo de modificación de tono para variaciones menores de 4 semitonos (para variaciones mayores se recomienda el uso de alguno de los algoritmos más sofisticados descritos en capítulos anteriores, cuya implementación se descartó por salirse del alcance del proyecto debido a su alta complejidad). Por el contrario, en la implementación del algoritmo sobre la Raspberry Pi como external de Pd, se evidenció un error de programación en el código C. Se llevaron a cabo varias pruebas sobre los módulos de código en la medida en que fue posible, pero el lento proceso de

Page 98: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

7. CONCLUSIONES

98

compilado y la dificultad para monitorizar resultados intermedios hicieron del depurado un proceso altamente complejo y tedioso. Estas pruebas descartaron errores en los módulos de procesado y re-muestreo, así como en la inicialización de la ventana Hanning, obteniéndose resultados idénticos a los proporcionados por el prototipo en MatLab. Los módulos de análisis y síntesis resultaron más complicados de testear ya que la función de FFT incorporada en Pd no puede ejecutarse fuera de un external. En definitiva, la implementación del algoritmo de modificación de tono en C fue un proceso arduo y dificultoso, pero supuso un apasionante reto de programación y dotó al autor de nuevos conocimientos y herramientas de un nivel impensable antes de emprender este proyecto. A pesar de los evidentes errores y limitaciones, se considera un éxito los logros alcanzados. Como posibles mejoras o extensiones del proyecto se proponen las siguientes líneas de actuación: -Detección y corrección de errores en el external de Pd: Se hace evidente la necesidad de un proceso ulterior de depurado y corrección de errores en el código C del external pitchShifter~. - Configuración de la Raspberry Pi para trabajar en modo autónomo, o stand-alone: Con el dispositivo actual, se requiere de un ordenador anfitrión para controlar la Raspberry Pi en modo escritorio y poder ejecutar el pitch-shifter y modificar sus parámetros. Esto contraviene en cierta medida nuestro objetivo de portabilidad y sencillez, al incorporar un elemento adicional al sistema. Podría evitarse esta situación programando la Raspberry Pi para ejecutar el programa al iniciarse e incorporando una botonera o una pantalla táctil en su puerto GPIO para controlar los parámetros de modificación de tono - Mejora en la precisión de la modificación del tono: Aunque el prototipo en MatLab dio buenos resultados en cuanto a precisión en la modificación del tono (con errores relativos inferiores al 0,3%) existe un error inherente al procesado. El factor de modificación de tono 𝛼 (relacionado con los saltos de análisis y síntesis a través de la expresión 𝛼 = !!"!

!!"!) está cuantizado, ya que

las variables de las que depende son números enteros, lo que provoca un error del orden de !

!!"!𝑓. Una posible solución sería el uso de un valor fraccionario para el

salto de síntesis, lo que supondría emplear interpolación para estimar el valor de cada muestra del frame que va a ser sumado. Esto permitiría establecer exactamente el factor de modificación de tono y eliminar el error.

Page 99: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

8. REFERENCIAS

99

8. REFERENCIAS [1] Johannes Grünwald – “Theory, Implementation and Evaluation of the Digital

Phase Vocoder in the Context of Audio Effects”. Bachelor Thesis, Telematics. Institute of Broadband Communication, Faculty of Electrical and Information Engineering. Graz University of Technology, 2010

[2] Flanagan J.L. and Golden, R. M. "Phase vocoder", Bell System Technical Journal, 1966

[3] Michael R. Portnoff – “Implementation of the Digital Phase Vocoder Using the Fast Fourier Transform”, IEE Transactions on Acoustics, Speech, and Signal Processing No. 3 Junio 1976

[4] Lawrence R. Rabiner, Ronald W. Schafer – “Digital Processing of Speech Signals”, Prentice-Hall 1978

[5] Charpentier, F., Stella, M. "Diphone synthesis using an overlap-add technique for speech waveforms concatenation". Acoustics, Speech, and Signal Processing, IEEE International Conference, 1986

Page 100: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

8. REFERENCIAS

100

[6] Miller Puckette – “Phase-locked Vocoder” IEEE ASSP Conference on Applications of Signal Processing to Audio and Acoustics, 1995

[7] “Time Stretching And Pitch Shifting of Audio Signals An Overview by Stephan M. Bernsee”, © 1995-2005 [Disponible online en: http://www.dspdimension.com]

[8] Orange Vocoder de Prosoniq [Disponible on-line en: http://www.zynaptiq.com/orangevocoder/]

[9] Fundación Raspberry Pi [Disponible on-line en: https://www.raspberrypi.org] [10] Pure Data [Disponible on-line en: https://puredata.info] [11] A brief history of MAX [Disponible on-line en :

http://web.archive.org/web/20090827105639/http://freesoftware.ircam.fr:80/article.php3?id_article=5]

[12] Web personal de William Brent [Disponible on-line en: http://williambrent.conflations.com/pages/research.html]

[13] XCode [Disponible on-line: https://developer.apple.com/xcode/ ] [14] Iohannes M. Zmölnig, “How to write an External for Pure Data”, Institute of

electronic music and acoustic, 2014 [15] Interfaces de audio compatibles con Raspbian [Disponible on-line en:

https://wiki.linuxaudio.org/wiki/hardware_support?redirect=1] [16] Focusrite Scarlett 2i2 [Disponible on-line en: https://us.focusrite.com/usb-

audio-interfaces/scarlett-2i2] [17] Magnus Erik Hvass Pedersen – “The Phase-Vocoder and its Realization”

Daimi, University of Aarhus, 2003 [18] Oppenheim & Schafer - Discrete Time Signal Processing-Prentice Hall, 1998 [19] Hermes Sampedro Llopis – “Implementación de efectos de audio en la tarjeta

Raspberry Pi B+”, PFG de Ingeniería de Sonido e Imagen, 2015 [20] [soundtouch~] for Pure Data [Disponible on-line en:

http://www.katjaas.nl/pitchshift/soundtouch~.html] [21] Pre-digital pitch-shifters [Disponible on-line en:

https://valhalladsp.com/2010/05/04/pitch-shifters-pre-digital/] [22] Web de Eventide [https://www.eventideaudio.com/] [23] Configuración VNC: http://frambuesa-pi.blogspot.com.es/2015/10/raspberry-

pi-primeros-pasos-con_21.html [24] Código fuente de Pd [Disponible on-line en: https://github.com/pure-

data/pure-data]

Page 101: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

101

9. APÉNDICES

9.1 APÉNDICE I: Función prototipo del pitch-shifter en código MatLab 9.1.1 Función createFrames.m % ************************************************************************* % CREATEFRAMES % ************************************************************************* % Autor: Carlos Nistal Hurlé, basado en el código de Laurier Demers, % Francois Grondin y Arash Vakili % % Fecha: 17/03/2017

Page 102: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

102

% ************************************************************************* % pitchsShifter es una función que toma un vector de muestras en el % dominio del tiempo y modifica su tono por una cantidad de semitonos % especificada. Se emplea un algoritmo de Phase-Vocoder para modificar % la duración de la señal e interpolación lineal para generar el cambio % de tono deseado, devolviendo la señal a su duración original % ************************************************************************* % Entradas: % x Vector * % hop hop de entrada % windowSize Tamaño de los frames * % ************************************************************************* % Salidas: vectorFrames Matriz resultante con todos los frames % numberSlices Number of frames in the matrix * % ************************************************************************* * % % createFrames divide una se?al en frames entrelazados y los almacena en % una matriz a % % * % * |------------------ Vector de entrada ---------------

Page 103: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

103

------| * % * * % * |------1------| * % * |------2------| * % * |------3------| * % * |------4------| * % * ... * % * * % * Índice Frame * % * 1 |------1------| * % * 2 |------2------| * % * 3 |------3------| * % * 4 |------4------| * % * ... ... * % * * function [vectorFrames,numberSlices] = createFrames(x,hop_in,frame_size) % Calcular el m?ximo n?mero de frames en que se puede dividir la se?al numberSlices = floor((length(x)-frame_size)/hop_in); % Recortar la se?al de forma que su duraci?n sea m?ltiplo de hop_in x = x(1:(numberSlices*hop_in+frame_size));

Page 104: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

104

% Inicializar una matriz para almacenar los frames vectorFrames = zeros(floor(length(x)/hop_in),frame_size); % Rellenar la matriz for index = 1:numberSlices indexTimeStart = (index-1)*hop_in + 1; indexTimeEnd = (index-1)*hop_in + frame_size; vectorFrames(index,:) = x(indexTimeStart: indexTimeEnd); end return 9.1.2 Función overlap_add.m %************************************************************************* % OVERLAP_ADD % ************************************************************************* % Autor: Carlos Nistal Hurl?, basado en el c?digo de Laurier Demers, % Francois Grondin y Arash Vakili [1] % % Fecha: 17/03/2017 % % ************************************************************************* % * Entradas: framesMatrix Matriz para contener todos los frames % * hop_out Tama?o del hop de salida, en muestras % *************************************************************************

Page 105: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

105

% * % * Salidas: vectorTime Resulting vector from overlapp add * % ************************************************************************* % * Description: * % * * % * Esta funci?n realiza la suma entrelazada de los frames de la matriz % * de entrada % * * % * ?ndice Frame * % * 1 |------1------| * % * 2 |------2------| * % * 3 |------3------| * % * 4 |------4------| * % * ... ... * % * * % * |------1------| * % * + |------2------| * % * + |------3------| * % * + |------4------| * % * + ... * % * *

Page 106: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

106

% * |------------------Vector de salida---------------------| * % * * % ************************************************************************* function vectorTime = overlap_add(framesMatrix, hop_out) sizeMatrix = size(framesMatrix); % Obtener el n?mero de frames numberFrames = sizeMatrix(1); % Obtener el tama?o de los frames sizeFrames = sizeMatrix(2); % Generar un vector donde almacenar el resultado vectorTime = zeros(numberFrames*hop_out-hop_out+sizeFrames,1); timeIndex = 1; % Realizar la suma entrelazada de todos los frames for index=1:numberFrames vectorTime(timeIndex:timeIndex+sizeFrames-1) = vectorTime(timeIndex:timeIndex+sizeFrames-1) + framesMatrix(index,:)'; timeIndex = timeIndex + hop_out; end return

Page 107: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

107

9.1.3 Función pichShifter.m % ************************************************************************* % PITCHSHIFTER % ************************************************************************* % Autor: Carlos Nistal Hurl?, basado en el c?digo de Laurier Demers, % Francois Grondin y Arash Vakili [1] % % Fecha: 17/03/2017 % ************************************************************************* % pitchsShifter es una función que toma un vector de muestras en el % dominio del tiempo y modifica su tono por una cantidad de semitonos % especificada. Se emplea un algoritmo de Phase-Vocoder para modificar % la duración de la señal e interpolación lineal para generar el cambio % de tono deseado, devolviendo la señal a su duración original % ************************************************************************* % Entradas: inputVector: vector con la señal en el dominio del tiempo % a procesar % % frame_size: Tamaño de los frames % % hop_in: Tamaño del hop de entrada (frame_size/4) para % un solapamiento del 75%) % % semitones: Número de semitonos que se

Page 108: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

108

modifica el tono de % la señal (Deber? estar comprendido entre % -4 y 4 para preservar la calidad) % ************************************************************************* % Salidas: outputVector: Vector con la se?al resultante % ************************************************************************* function [outputVector] = pitchShifter(inputVector, frameSize, hopIn, semitones) %% Variables % Tamaño de los frames frame_size = frameSize; % Hop de entrada hop_in = hopIn; % Factor de modificación del tono alpha = 2^(semitones/12); % Definir el tamaño del hop de salida hop_out = round(alpha*hop_in); % Inicializar la ventana Hanning hann_window = hann(frame_size*2+1); hann_window = hann_window(2:2:end); %% Se?al de entrada x = inputVector; % Rotate if needed if size(x,1) < size(x,2) x = transpose(x); end x = [zeros(hop_in*3,1) ; x];

Page 109: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

109

%% Inicialización % Crear una matriz de frames a partir de la señal de entrada [y,numberFramesInput] = createFrames(x,hop_in,frame_size); % Crear una matriz donde almacenar los frames procesados numberFramesOutput = numberFramesInput; outputy = zeros(numberFramesOutput,frame_size); % Inicializar la fase acumulada cumulative_phase = 0; % Inicializar la fase del frame anterior previous_phase = 0; for index=1:numberFramesInput %% ANALISIS % Seleccionar el siguiente frame a procesar currentFrame = y(index,:); % Enventar el frame currentFrameWindowed = currentFrame .* hann_window' / sqrt(((frame_size/hop_in)/2)); % Calcular su FFT currentFrameWindowedFFT = fft(currentFrameWindowed); % Calcular la magnitud magFrame = abs(currentFrameWindowedFFT); % Calcular la fase phaseFrame = angle(currentFrameWindowedFFT); %% PROCESADO % Calcular la diferencia de fase entre frames consecutivos

Page 110: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

110

deltaPhi = phaseFrame - previous_phase; previous_phase = phaseFrame; % Eliminar la diferencia de fase esperada deltaPhiPrime = deltaPhi - hop_in * 2*pi*(0:(frame_size-1))/frame_size; % Map to -pi/pi range deltaPhiPrimeMod = mod(deltaPhiPrime+pi, 2*pi) - pi; % Calcular la frecuencia verdadera trueFreq = 2*pi*(0:(frame_size-1))/frame_size + deltaPhiPrimeMod/hop_in; % Calcular la fase final cumulative_phase = cumulative_phase + hop_out * trueFreq; %% SINTEIS % Obtner la magnitud outputMag = magFrame; % Calcular la IFFT y generar el frame procesado outputFrame = real(ifft(outputMag .* exp(j*cumulative_phase))); % Almacenar el frame procesado outputy(index,:) = outputFrame .* hann_window' / sqrt(((frame_size/hop_out)/2)); end %% SUMA ENTRELAZADA % Realizar la suma entrelazada de los frames y almacenarla en un vector outputTimeStretched = overlap_add(outputy,hop_out); %% REMUESTREO % Re-muestreo con interpolación lineal outputTime = interp1((0:(length(outputTimeStretched)-

Page 111: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

111

1)),outputTimeStretched,(0:alpha:(length(outputTimeStretched)-1)),'linear'); % Devolver la secuencia de salida, con el tono modificado outputVector = outputTime; return

Page 112: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

112

9.2 APÉNDICE II: Código fuente, en lenguaje C, del pitch-shifter implementado como un external de Pure Data

#include "m_pd.h" #include <math.h> #include <complex.h> #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif int debug = 0; static t_class *pitchShifter_tilde_class; typedef struct _pitchShifter_tilde { t_object x_obj; //Objeto de Pd t_float sr; // t_float n; //Tamaño del Buffer de entrada de Pd int dsp_tick; // Contador para rellenar el buffer de

entrada del programa, de tamaño distinto del de Pd

int buffer_limit; //Límite del contador anterior int overlap_in; // window/hop_in int frame_size; // Tamaño del frame en muestras int frame_size_half; // Medio frame int hop_in; //Tamaño del hop de entrada en muestras int hop_out; //Tamaño del hop de salida en muestras

t_float amp_scalar; // Factor multiplicativo para el enventanado

t_float *hann; // Ventana Hanning

Page 113: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

113

t_sample *input_buf; // Array para almacenar el buffer

de entrada t_sample *input_buf_windowed; // Array para almacenar el

frame enventanado t_float *signal_R; //Array para almacenar la parte REAL

de la DFT t_float *signal_I; //Array para almacenar la parte

IMAGINARIA de la DFT t_float *signal_mag; // Array para almacenar la

magnitud de la DFT t_float *signal_phase; //Array para almacenar fase de la

DFT

t_float *prev_signal_mag; // Magnitud del frame anterior

t_float *prev_signal_phase; // Fase del frame

anterior t_float *phase_dif; // Diferencia de fase entre

frames consecutivos

t_float *true_freq; // Frecuencia verdadera t_float *cumulative_phase; // Fase acumulada int semitones; // Cantidad de semitonos (positiva o

negativa) que se va a modificar el tono

t_float alpha; // Relación entre los hops de entrada y

de salida: hop_out/hop_in t_sample *vocoder_output; // Señal de salida del Phase-

Page 114: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

114

Vocoder, estirada o contraída

t_sample *final_output; // Señal re-muestreada, de vuelta a su duración original

t_sample *overlap_add_buffer; t_inlet *semitones_in; // Entrada para controlar el

tono, en pasos de semitono t_outlet *x_out; // Buffer de salida de Pd t_float x_f; // Variable de control } t_pitchShifter_tilde; /* ---------------- pitchShifter~ ------------------------ */ static t_int *pitchShifter_tilde_perform(t_int *w) {

int i, j, n, frame_size, frame_size_half, overlap_in, overlap_chunk, hop_in, hop_out;

int semitones; t_float amp_scalar, alpha; t_pitchShifter_tilde *x = (t_pitchShifter_tilde *)(w[1]); t_sample *in = (t_float *)(w[2]); t_sample *out = (t_float *)(w[3]); n = w[4]; //Tamaño del buffer de entrada semitones = x->semitones; frame_size = x->frame_size; frame_size_half = x->frame_size_half; overlap_in = x->overlap_in; overlap_chunk = x->hop_in; hop_in = x->hop_in;

Page 115: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

115

alpha = pow(2.0,semitones/12.0);//x->alpha; hop_out = round(alpha*hop_in);//x->hop_out; amp_scalar = x->amp_scalar; //Desplaza el buffer de entrada (de tamaño window, 1024) 64 muestras a la izda 4 veces (buffer_limit) hasta un deplazamiento total de 256 muestras (window/4). Al ir actualizando el buffer de entrada cada window/4, conseguimos un solapamiento del 75% //Desplazar contenido previo for(i=0; i<(frame_size-n); i++) x->input_buf[i] = x->input_buf[n+i]; //Guardar el bloque más reciente en el buffer for(i=0; i<n; i++) x->input_buf[frame_size-n+i] = in[i]; //Una vez completado un bloque de tamaño window salta el contador dsp_tick. Ya disponemos de un nuevo frame y podemos procesarlo: if(x->dsp_tick>=x->buffer_limit) { x->dsp_tick = 0; //ANÁLISIS //Enventanar la señal for(i=0; i<frame_size; i++){ x->input_buf_windowed[i] = x->input_buf[i] * x->hann[i]; } //Realizar la FFT mayer_realfft(frame_size, x->input_buf_windowed); //Separar el resultado en parte real e imaginaria for(i=0; i<=frame_size_half; i++) {

Page 116: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

116

x->signal_R[i] = x->input_buf_windowed[i]; if(fabs(x->signal_R[i]) < 0.0001) x->signal_R[i] = 0.0; } x->signal_I[0]=0; // Eliminar componente continua

for(i=(frame_size-1), j=1; i>frame_size_half; i--, j++)

{ x->signal_I[j] = x->input_buf_windowed[i]; if(fabs(x->signal_I[j]) < 0.0001) x->signal_I[j] = 0.0; } x->signal_I[frame_size_half]=0; // Nyquist //PROCESADO for(i=0; i<=frame_size_half; i++) { //Calcular magnitud y fase x->signal_mag[i] = cabsf(x->signal_R[i]+I*x->signal_I[i]); x->signal_phase[i] = cargf(x->signal_R[i]+I*x->signal_I[i]); //Calcular la diferencia de fase entre frames

consecutivos x->phase_dif[i] = x->signal_phase[i] - x->prev_signal_phase[i]; //Almacenar la fase del frame actual x->prev_signal_phase[i] = x->signal_phase[i]; //Eliminar la diferencia de fase esperada x->phase_dif[i] -= hop_in*2.0*M_PI*i/frame_size;

Page 117: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

117

//Restringir al intervalo –PI-PI x->phase_dif[i] = x->phase_dif[i] + M_PI; x->phase_dif[i] = x->phase_dif[i] - floor(x->phase_dif[i]/(2.0*M_PI)) * 2.0*M_PI - M_PI; //Calcular la frecuencia verdadera x->true_freq[i] = 2.0*M_PI*i/frame_size + x->phase_dif[i]/hop_in; //W_bin + deltaW //Calcular la fase corregida x->cumulative_phase[i] += (hop_out)* x->true_freq[i]; //Guardar partes real e imaginaria x->signal_R[i] = x->signal_mag[i] * cos(x->cumulative_phase[i]); x->signal_I[i] = x->signal_mag[i] * sin(x->cumulative_phase[i]); } //SÍNTESIS //Almacenar partes real e imaginaria en la forma adecuada

para aplicar la IFFT for(i=0; i<=frame_size_half; i++) x->input_buf_windowed[i] = x->signal_R[i]; for(i=(frame_size_half+1), j=(frame_size_half-1); i<frame_size; i++, j--) x->input_buf_windowed[i] = x->signal_I[j]; //Calcular la IFFT mayer_realifft (frame_size, x->input_buf_windowed); //Enventanar for(i=0; i<frame_size; i++) { x->input_buf_windowed[i] *= x->hann[i];

Page 118: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

118

x->input_buf_windowed[i] *= amp_scalar; } //Overlap/Add: //Desplazar el contenido previo del buffer for(i=0; i<( 2*frame_size - hop_out); i++) x->overlap_add_buffer[i] = x->overlap_add_buffer[i+hop_out]; //Poner a cero el último trozo

for(i= (2*frame_size - hop_out); i< 2*frame_size; i++)

x->overlap_add_buffer[i] = 0; //Sumar el bloque más reciente for(i=0; i<frame_size; i++) x->overlap_add_buffer[frame_size + i] += x->input_buf_windowed[i]; //Llevar a la salida un bloque de tamaño hop_out for(i=0; i<hop_out; i++) x->vocoder_output[i] = x->overlap_add_buffer[frame_size – hop_out + i]; //RE-MUESTREO int index_floor, index_ceil; for(i=0; i<hop_in; i++) { index_floor = floor(alpha*i); index_ceil = index_floor + 1; x->final_output[i] = x->vocoder_output[ index_floor]; x->final_output[i] += ( x->vocoder_output[index_ceil] – x->vocoder_output[index_floor] )*

Page 119: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

119

(alpha*i - index_floor); } }; // fin if //SALIDA for(i=0; i<n; i++, out++) *out = x->final_output[(x->dsp_tick*n)+i]; x->dsp_tick++; return (w+5); } // FIN perform static void pitchShifter_tilde_dsp(t_pitchShifter_tilde *x, t_signal **sp) { dsp_add( pitchShifter_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n ); if( sp[0]->s_n != x->n || sp[0]->s_sr != x->sr ) { x->sr = sp[0]->s_sr; x->n = sp[0]->s_n; x->buffer_limit = x->frame_size/x->n/x->overlap_in; } } static void *pitchShifter_tilde_new(t_floatarg semitones) { t_pitchShifter_tilde *x = (t_pitchShifter_tilde *)pd_new(pitchShifter_tilde_class);

Page 120: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

120

int i, isPow2;

x->semitones_in = floatinlet_new (&x->x_obj, &x->semitones);

outlet_new(&x->x_obj, gensym("signal")); x->semitones = semitones; x->frame_size = 1024; x->overlap_in = 4; x->sr = 44100; x->n = 64; x->dsp_tick = 0; x->frame_size_half = x->frame_size/2.0; x->amp_scalar = (2.0/3.0)/x->frame_size; //Mis variables x->hop_in = x->frame_size/x->overlap_in; x->alpha = pow(2.0,x->semitones/12.0); x->hop_out = round(x->alpha*x->hop_in); x->buffer_limit = x->frame_size/x->n/x->overlap_in; //Reservar memoria para arrays x->hann = (t_float *)getbytes(x->frame_size * sizeof(t_float)); x->input_buf = (t_sample *)getbytes(x->frame_size * sizeof(t_sample)); x->input_buf_windowed = (t_sample *)getbytes(x->frame_size * sizeof(t_sample)); x->signal_R =

(t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float)); x->signal_I = (t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float));

x->vocoder_output = (t_sample *)getbytes((x->hop_out) * sizeof(t_sample)); x->final_output = (t_sample *)getbytes((x->hop_in) * sizeof(t_sample)); //Salida con tamaño hop_out x->overlap_add_buffer = (t_sample *)getbytes((2*x->frame_size) * sizeof(t_sample));

Page 121: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

121

x->signal_mag = (t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float)); x->signal_phase =

(t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float));

x->prev_signal_mag = (t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float));

x->prev_signal_phase = (t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float));

x->phase_dif = (t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float));

x->true_freq = (t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float));

x->cumulative_phase = (t_float *)getbytes((x->frame_size_half+1) * sizeof(t_float));

x->hann = (t_float *)getbytes((x->frame_size) * sizeof(t_float)); //Inicializar ventana Hanning for(i=0; i< x->frame_size; i++){ x->hann[i] = 0.5 * ( 1 - cos( 2.0*M_PI*(1*i)/ (1.0*x- >frame_size) ) ); } for(i=0; i<x->frame_size; i++) { x->input_buf[i] = 0.0; x->input_buf_windowed[i] = 0.0; }; //Init Overlap/addd buffer for(i=0; i<(2*x->frame_size); i++) x->overlap_add_buffer[i] = 0.0;

Page 122: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

122

//init vocoder output for(i=0; i<(x->hop_out); i++) x->vocoder_output[i] = 0.0; //init (window_half+1 size arrays) for(i=0; i<=x->frame_size_half; i++) { x->signal_R[i] = 0.0; x->signal_I[i] = 0.0; x->signal_mag[i] = 0.0; x->signal_phase[i] = 0.0; x->prev_signal_mag[i] = 0.0; x->prev_signal_phase[i] = 0.0; x->phase_dif[i] = 0.0; x->true_freq[i] = 0.0; x->cumulative_phase[i] = 0.0; }; //Inicializar salida final for(i=0; i<x->hop_in; i++) x->final_output[i] = 0.0;

post("pitchShifter~: frame size: %i, semitones: %i, alpha: %f, hop_out: %i", x->frame_size, x->semitones, x->alpha, x->hop_out );

return (void *)x; } static void pitchShifter_tilde_free(t_pitchShifter_tilde *x) { inlet_free(x->semitones_in); outlet_free(x->x_out); t_freebytes(x->hann, x->frame_size*sizeof(t_float)); t_freebytes(x->input_buf, x->frame_size*sizeof(t_sample));

t_freebytes(x->input_buf_windowed, x-

Page 123: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

123

>frame_size*sizeof(t_sample)); t_freebytes(x->signal_R, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->signal_I, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->vocoder_output, (x->hop_in)*sizeof(t_sample)); t_freebytes(x->final_output, (x->hop_in)*sizeof(t_sample)); t_freebytes(x->signal_mag, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->signal_phase, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->prev_signal_mag, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->prev_signal_phase, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->phase_dif, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->true_freq, (x->frame_size_half+1)*sizeof(t_float)); t_freebytes(x->cumulative_phase, (x->frame_size_half+1)*sizeof(t_float));

} void pitchShifter_tilde_setup(void) { pitchShifter_tilde_class = class_new( gensym("pitchShifter~"), (t_newmethod)pitchShifter_tilde_new, 0, sizeof(t_pitchShifter_tilde), CLASS_DEFAULT, A_DEFFLOAT, 0);

Page 124: PROYECTO FIN DE GRADO - Archivo Digital UPMoa.upm.es/52707/1/TFG_CARLOS_NISTAL_HURLE.pdfcomo la trompeta, con bombas de afinación (Figura 1.1 b). Para instrumentos de cuerda es común

9. APÉNDICES

124

CLASS_MAINSIGNALIN(pitchShifter_tilde_class, t_pitchShifter_tilde, x_f);

class_addmethod( pitchShifter_tilde_class, (t_method)pitchShifter_tilde_dsp, gensym("dsp"), 0 ); }