You are on page 1of 153

INGENIERA DE TELECOMUNICACIN

rea de Teora de la Seal y Comunicaciones Departamento de Ingeniera Electrnica Escuela Superior de Ingenieros Universidad de Sevilla

PROYECTO FIN DE CARRERA


DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

AUTOR: Javier Ponce Surez DIRECTOR: Jos Ramn Cerquides Bueno

Sevilla, Julio 2004

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

NDICE
CAPTULO 1: INTRODUCCIN Y OBJETIVOS ...................................... 1 CAPTULO 2: HARDWARE Y SOFTWARE ............................................. 3 2.1. HARDWARE .............................................................................. 3 2.2. SOFTWARE ............................................................................... 5 2.3. PRUEBAS EN OTROS SISTEMAS ................................................ 9 2.4. ESTRUCTURA DEL PROGRAMA ................................................. 10 CAPTULO 3: DESARROLLO DE LA INTERFASE .................................. 14 3.1. USO DE DIRECTSHOW PARA EL CONTROL DE LA TARJETA......... 14 3.2. OTRAS CLASES PARA DECORACIN DE LA INTERFASE .............. 26 CAPTULO 4: ALGORITMO DE DETECCIN ....................................... 27 4.1. ALGORITMO DE CORRELACIN ................................................ 27 4.2. PARMETROS QUE INTERVIENEN EN EL PROCESO .................... 30 4.3. RUTINAS DESARROLLADAS ...................................................... 34 4.4. FASE DE PRUEBAS: RESULTADOS Y CONCLUSIONES ................. 38 4.5. DECISOR ................................................................................. 57 CAPTULO 5: MANUAL DE USUARIO .................................................. 61 5.1. INICIO DE LA APLICACIN ....................................................... 61 5.2. MENU ..................................................................................... 62 5.3. GRABACIN ............................................................................ 67 5.4. DETECCIN ............................................................................ 68 5.5. CONFIGURACIN DE PARMETROS .......................................... 70 CAPTULO 6: LNEAS FUTURAS DE INVESTIGACIN ........................ 73

-i-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

ANEXOS ANEXO 1: POSIBLES PROBLEMAS DE LA APLICACIN ..................... 74 ANEXO 2: FORMATO DE LOS FICHEROS WAV ................................... 78 ANEXO 3: CDIGO FUENTE ............................................................... 79 A3.1. Clase CRadioApp ................................................................... 79 A3.2. Clase CRadioDlg .................................................................... 82 A3.3. Clase CArchivos..................................................................... 120 A3.4. Clase CDialosint .................................................................... 125 A3.5. Clase Configuracin .............................................................. 128 A3.6. Clase CButtonST (Clase CMemDC est includa en ButtonST.h) ........................................................................ 132 BIBLIOGRAFA ................................................................................. 147

- ii -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Lista de ilustraciones
Ilustracin 1: Caractersticas sistema utilizado............................................... 4 Ilustracin 2: WINTV_USB........................................................................... 4 Ilustracin 3: S.O. Windows XP.................................................................... 6 Ilustracin 4: Visual Studio 6.0..................................................................... 6 Ilustracin 5: DirectX 9.0a............................................................................ 7 Ilustracin 6: Grafo 1 en la aplicacin GraphEdit............................................ 8 Ilustracin 7: Grafo 2 en la aplicacin GraphEdit............................................ 8 Ilustracin 8: Estructura de datos capstuff................................................ 12 Ilustracin 9: Estructura de datos archivo_wav......................................... 13 Ilustracin 10: Grafo 1............................................................................... 15 Ilustracin 11: Grafo 2............................................................................... 15 Ilustracin 12: Formacin Grafo DirectShow................................................ 24 Ilustracin 13: Formacin Grafo DirectShow (2)........................................... 25 Ilustracin 14: Formacin Grafo DirectShow (3).......................................... 25 Ilustracin 15: Formacin Grafo DirectShow (4)........................................... 26 Ilustracin 16: Colas de correlacin cruzada................................................ 28 Ilustracin 17: Nmero de muestras........................................................... 31 Ilustracin 18: Tiempo de conmutacin FM -> TV........................................ 41 Ilustracin 19: Tiempo de conmutacin FM -> FM....................................... 42 Ilustracin 20: Diagrama de flujo del decisor............................................... 59 Ilustracin 21: Dilogo principal.................................................................. 61 Ilustracin 22: Men Archivos..................................................................... 63 Ilustracin 23: Dilogo Archivos.................................................................. 64 Ilustracin 24: Men Configurar.................................................................. 64 Ilustracin 25: Dilogo Sintonizador............................................................ 65 Ilustracin 26: Dilogo Configuracin.......................................................... 66 Ilustracin 27: Dilogo Versin................................................................... 67 Ilustracin 28: Dilogo guardar archivo .wav............................................... 68 Ilustracin 29: Muestra archivo frecuencias.cfg............................................ 68 Ilustracin 30: Muestra anuncio detectado.................................................. 69

- iii -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 31: Muestra fichero resultados................................................... 70 Ilustracin 32: Configuracin sonido del sistema.......................................... 71 Ilustracin 33: Mensaje de registro correcto................................................ 76 Ilustracin 34: Mensaje de error anuncio piloto............................................ 77

- iv -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Lista de tablas
Tabla 1: Caractersticas tcnicas tarjeta WinTV............................................ 5 Tabla 2: Sistemas donde se ha comprobado el correcto funcionamiento de la aplicacin.................................................................................................. 9 Tabla 3: Ejemplo nmero de muestras-frecuencia de muestreo.................... 31 Tabla 4: Tiempo de computacin-Tiempo de captura.................................. 39 Tabla 5: Prueba FM 125 mseg................................................................... 44 Tabla 6: Prueba FM 100 mseg................................................................... 45 Tabla 7: Prueba FM 90 mseg..................................................................... 46 Tabla 8: Prueba FM 80 mseg..................................................................... 47 Tabla 9: Prueba FM 75 mseg..................................................................... 48 Tabla 10: Prueba TV 125 mseg.................................................................. 50 Tabla 11: Prueba TV 100 mseg.................................................................. 51 Tabla 12: Prueba TV 90 mseg.................................................................... 52 Tabla 13: Prueba TV 80 mseg.................................................................... 53 Tabla 14: Prueba TV 75 mseg.................................................................... 54 Tabla 15: Prueba TV 70 mseg.................................................................... 55 Tabla 16: Formato de los ficheros .WAV..................................................... 78

-v-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CAPTULO 1: INTRODUCCIN Y OBJETIVOS.


Es de sobra conocida la importancia de los anuncios publicitarios para las emisoras de radio o de televisin. Los contratos publicitarios son una fuente de ingreso muy importante y el tipo de contrato depende de la hora que se emita el anuncio ya que no es lo mismo la emisin en horario de mxima audiencia que en otro horario. Por lo tanto debido a las grandes sumas que se mueven en este mbito puede ser muy til una aplicacin que de algn modo certifique en tiempo real lo que se haba acordado anteriormente en el contrato. Este proyecto se basa en el desarrollo de una aplicacin que proporcione una solucin a la deteccin de anuncios de radio en FM y de televisin. Las herramientas necesarias para utilizar la aplicacin son un ordenador personal y una tarjeta capturadora TV/FM, se ha verificado tambin el correcto funcionamiento en un sistema con una tarjeta capturadora de TV exclusivamente. Para el desarrollo de la aplicacin se ha empleado como herramienta de programacin el Visual Studio y las libreras DirectX para controlar la tarjeta, ya que te permiten un control adecuado para la tarea que queremos desarrollar. Se ha empleado el Visual Studio para lograr una aplicacin que sea capaz de trabajar en tiempo real. Dentro del Visual Studio se ha empleado el lenguaje de programacin Visual C++, y se ha desarrollado una aplicacin basada en dilogo que facilite la utilizacin de la herramienta al usuario. La aplicacin desarrollada utiliza un algoritmo de correlacin para la comparacin de la seal de entrada de audio con los anuncios almacenados en ficheros de extensin .wav. Se ha utilizado el formato WAV porque es muy fcil y rpido acceder a las muestras de la seal de audio almacenadas. Este algoritmo genera un vector de valores que deben ser normalizados de manera conveniente para una posterior interpretacin de sus resultados. Cuando un valor del vector de correlacin normalizado sea mayor que un determinado umbral se habr producido una deteccin. Ambas seales son codificadas mediante PCM con los siguientes parmetros, frecuencia de muestreo de 8 Khz., 8 bits por muestra y adems a solo un canal (mono), estos parmetros han sido fijados a esos valores en

-1-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

cierto modo para disminuir en la medida de lo posible la excesiva carga computacional que implica el proceso. Est capacitada para trabajar con varios anuncios simultneamente y con varias sintonas de radio (o en su defecto canales de TV). Por lo tanto el objetivo es el desarrollo de una aplicacin que cumpla con los siguientes requisitos: Trabaje en tiempo real: Es el requisito principal y en torno a l gira el diseo de la aplicacin y las herramientas utilizadas para su desarrollo. Que sea eficiente computacionalmente: Cuanto ms eficiente sea la aplicacin se obtendrn mejores resultados y posibilitar el funcionamiento con un mayor nmero de anuncios y cadenas. Sencilla de cara al usuario final: Debe de ser sencilla de utilizar y con una interfaz amigable de cara al usuario. Flexible: Debe de ofrecer la posibilidad de cambiar los parmetros necesarios por parte del usuario final para un funcionamiento ms adecuado y preciso, orientado a una solucin particular. Portable: Debe de funcionar en todos los sistemas, y no debe de tener dependencia de la tarjeta capturadora. Para demostrar la portabilidad del sistema se ha comprobado el funcionamiento de la aplicacin en otros sistemas y los resultados son expuestos en el captulo 2.

-2-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CAPTULO 2: HARDWARE Y SOFWARE.


En este captulo se hace la descripcin del Hardware y el Software empleados para la realizacin del proyecto. Esto se expone en los dos primeros apartados del captulo. En el tercer apartado del captulo se dan los resultados de las pruebas realizadas para la comprobacin del funcionamiento de la aplicacin en otros sistemas. Para terminar el captulo se hace una descripcin de la estructura del programa, comentando brevemente las clases que lo componen y las estructuras de datos empleadas.

2.1. HARDWARE.
2.1.1. SISTEMA.
El PC utilizado es un porttil de procesador INTEL CENTRINO a 1.4 GHz., con 512 MB de RAM DDR como refleja en la ilustracin 1. Es el sistema con el que se han realizado las pruebas y medidas de tiempos como los de computacin o conmutacin que son descritos en los apartados 4.4.1 y 4.4.2, respectivamente. Es muy importante la velocidad del micro en una aplicacin de tan elevado coste computacional como esta.

-3-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 1: Caractersticas sistema utilizado.

Se han realizado comprobaciones en otros sistemas con diferentes configuraciones para comprobar el correcto funcionamiento de la aplicacin, los resultados de esas pruebas y las conclusiones se exponen en el apartado 2.3.

2.1.2. TARJETA CAPTURADORA.


La tarjeta empleada debido a que el ordenador era un ordenador porttil deba ser una tarjeta externa, es decir, que su conexin fuera por USB y adems que tambin tuviera posibilidad de FM lo cual no era tan comn entre los dispositivos capturadores. El modelo escogido fue la WINTV_USB de HAUPPAGE (ilustracin 2), o tambin conocida como el modelo 678.

Ilustracin 2: WINTV_USB.

-4-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

En la tabla 1 se hace un listado de las caractersticas tcnicas ms importantes de la tarjeta escogida:


Caractersticas tcnicas de la WinTV-USB-FM : PC con Windows 98, 2000, Millenium y XP con procesador Pentium 166 Mhz mnimo. Sintonizador : Sintonizador Philips 125 canales Formato sintona : Pal B/G Chip vdeo : USBVision Formato de puerto : PCI 2.1 Radio : Radio FM Entrada vdeo : Una entrada S/Video y un adaptador S-Video / Vdeo Compuesto (RCA) Audio : Entrada y salida de sonido Compatibilidad : Windows 98, 2000, Millennium Edition y XP. Sintona : Sintona automtica, vista previa de 16 canales, memorizacin de los canales, visualizacin en ventanas de Windows y pantalla completa Captura de imgenes : Captura de imgenes fijas y en movimiento en formato BMP, TIFF, GIF, JPEG, blanco y negro. Formato mximo: 800 x 600 pxeles. Captura de vdeos : Captura de vdeos AVI YUV 4:2:2 (320 x 240 con 25 imgenes por segundo en PAL) y compatible MPEG-4. Timer TV y Radio : Puede programar la visualizacin y grabacin de sus programas TV preferidos con la aplicacin TV Scheduler. Teletexto : Recepcin del Teletexto con el programa VTPlus. Memorizacin de sus pginas ms usuales. Creacin Vdeo CD : Posibilidad de grabar vdeos en Vdeo CDs. Tabla 1: Caractersticas tcnicas tarjeta WinTV. Configuracin mnima :

2.2. SOTWARE.
2.2.1. SISTEMA OPERATIVO.
El sistema operativo utilizado ha sido el Windows XP Profesional (ilustracin 3).

-5-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 3: S.O. Windows XP.

Un posible problema de usar otro sistema operativo puede ser conseguir los controladores de la tarjeta para ese sistema operativo. An teniendo la tarjeta correctamente instalada en otro sistema operativo puede que no sea correcto el funcionamiento del sistema ya que depende de configuraciones de DirectX que van directamente relacionadas con la versin de Windows. En el apartado de conclusiones (2.3.) se comenta los resultados de la prueba de la aplicacin en otros sistemas operativos. Debido a que el proyecto est ntimamente ligado al uso de DirectX, y este a su vez funciona en el entorno Windows (son unas libreras desarrolladas por Microsoft), la aplicacin en ningn caso funcionar con una plataforma diferente a Windows.

2.2.2. VISUAL STUDIO 6.

Ilustracin 4: Visual Studio 6.0.

-6-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Es el entorno de desarrollo empleado para la realizacin de la aplicacin (ilustracin 4). Concretamente la aplicacin est desarrollada con el lenguaje Visual C++, y se ha desarrollado una aplicacin MFC basada en un dilogo que permite un manejo sencillo de la misma.

2.2.3. DIRECTX 9.0a.

Ilustracin 5: DirectX 9.0a.

Es un conjunto de libreras desarrolladas por Microsoft que permiten el desarrollo de utilidades de diferente ndole como pueden ser grficos, sonidos, y entre otras cosas, el control de los dispositivos Hardware del sistema, con lo que se ha empleado para el control del dispositivo capturador. Hemos utilizado concretamente entre todos los paquetes de libreras el denominado DirectShow que es el que se encarga de esta labor. Es necesario tener instaladas las libreras DirectX 9.0a (como mnimo) para la utilizacin de la aplicacin. Tiene un entorno de desarrollo (SDK) que contiene toda la documentacin, tutoriales, ejemplos y aplicaciones de inters, como por ejemplo GraphEdit, que es una aplicacin que hemos utilizado para verificar el correcto funcionamiento de la parte de la aplicacin relacionada con DirectShow. Concretamente se han desarrollado dos grafos DirectShow (explicacin ms detallada en captulo 3), uno para la grabacin de anuncios (grafo 2), y otro que va capturando de forma peridica la entrada de audio para despus ser comparada con los anuncios que tenemos almacenados (grafo 1).

-7-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Estos dos grafos antes de la programacin en el entorno del Visual Studio se han formado en la aplicacin GraphEdit que viene incorporada en el SDK de DirectX. Esta aplicacin te informa si la conexin entre dos filtros es posible, te da informacin sobre los filtros y tambin sobre los pines de cada filtro. En las ilustraciones 6 y 7 respectivamente se refleja el grafo 1 y 2 en la aplicacin GraphEdit.

Ilustracin 6: Grafo 1 en la aplicacin GraphEdit.

Ilustracin 7: Grafo 2 en la aplicacin GraphEdit.

-8-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

2.3. PRUEBAS EN OTROS SISTEMAS.


En este apartado se dan los resultados de las pruebas en otras plataformas reflejados en una tabla, en funcin a estos resultados se aportarn las conclusiones pertinentes donde se indicar en qu situaciones y configuraciones no es correcto el funcionamiento de la aplicacin. En todos los sistemas donde se han hecho pruebas tenan las libreras DirectX necesarias instaladas.

2.3.1. RESULTADO PRUEBAS.


En la siguiente tabla se refleja los distintos sistemas donde se ha probado la aplicacin y sus respectivas configuraciones de inters.

CASO

CPU
Intel Centrino 1.4 GHz Intel P4 2.4 GHz Intel P4 2.6 GHz Intel P3 864 Mhz AMD K6-2 400 Mhz

MEM.
512 MB

S.O.
WIN. XP

TARJETA TV
Hauppauge WinTV USB

FM
SI

O.K. SI

1 2 3 4 5

256 MB

WIN. XP

Hauppauge WinTV USB Best Buy Easy TV Pinnacle PCTV PRO Hauppauge WinTV USB

SI

SI SI
SI

512 MB

WIN. XP

NO

256 MB

WIN. XP

NO

256 MB

WIN. 98

SI

SI

Tabla 2: Sistemas donde se ha comprobado el correcto funcionamiento de la aplicacin.

2.3.2. CONCLUSIONES.
Las pruebas van encaminadas a ver si se encontraba algn tipo de tarjeta en la que no funcionara la aplicacin. Se ha comprobado en los sistemas anteriores que teniendo las libreras de DirectX 9.0a (o superior) ha funcionado correctamente la aplicacin incluso

-9-

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

en Windows 98, pero el funcionamiento en este no era igual que en Windows XP. El funcionamiento ms adecuado se obtiene en el sistema operativo Windows XP, y se recomienda el uso de la aplicacin en este sistema operativo.

2.4. ESTRUCTURA DEL PROGRAMA.


El cdigo est desarrollado en el lenguaje Visual C++, que es un lenguaje de programacin de alto nivel orientado a objeto (ms informacin en referencias [3], [8] y [7]). Debido al uso de la programacin orientada a objeto, el cdigo se divide en clases, donde cada una de ellas tiene sus propios mtodos y variables. En este captulo se hace una descripcin de las clases que componen el cdigo y adems de las estructuras de datos definidas para una mejor compresin del mismo.

2.4.1. DIAGRAMA DE CLASES.


En este apartado se describen las clases que forman parte del cdigo, haciendo un breve comentario sobre cada una de ellas. El desarrollo de la aplicacin se ha hecho en el entorno del Visual Studio y se ha generado un proyecto que es un MFC AppWizard, dentro de este hemos empleado una aplicacin basada en dilogo y hemos dejado la posibilidad de crear el dilogo Acerca de. Por lo tanto la inicializacin del proyecto a travs de los Wizards de inicializacin del entorno te da de entrada (en este caso) 3 clases, que son CRadioApp, CRadioDlg y CAboutDlg. Las restantes clases que componen el programa han sido desarrolladas y tiene una funcionalidad propia que ser descrita en su apartado correspondiente. CRadioApp.

Clase incorporada al crear el proyecto de aplicacin MFC. No se ha modificado nada dentro de ella. En ella nace la aplicacin al ejecutarse y es esta clase la que abre el dilogo principal de la aplicacin, y la que devuelve el control al sistema cuando se cierra.

- 10 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CRadioDlg.

Clase incorporada al crear el proyecto de aplicacin MFC. Es la clase principal del programa ya que es una aplicacin basada en dilogo. Es esta clase la que utiliza las dems clases que le sirven de apoyo para la labor a realizar. CAboutDlg.

Clase incorporada al crear el proyecto de aplicacin MFC. Es una clase derivada de la clase CDialog, y la utilidad que tiene es mostrarnos un dilogo sobre la versin del producto. CButtonST.

Clase utilizada para decoracin de la interfase. Tanto para poner iconos en los botones del dilogo, como para cambiar la forma del cursor cuando est encima de un botn. CMemDC.

Clase utilizada por la clase CButtonST y que implementa un contexto de dispositivo de memoria. CDialosint.

Clase que tiene como utilidad mostrarnos un dilogo para la sintonizacin del dispositivo. CConfiguracin.

Clase que tiene como utilidad mostrarnos un dilogo para la configuracin del dispositivo. Se pueden configurar algunos parmetros como son el tiempo de captura, el umbral y el formato de dato de entrada (TV o FM). CArchivos.

Clase que tiene como utilidad mostrarnos un dilogo para la eleccin de los anuncios que van a formar parte del proceso de deteccin.

2.4.2. ESTRUCTURAS DE DATOS.


Se han creado dos estructuras de datos, una con la informacin precisa de los interfaces que se usan para el correcto control del dispositivo capturador, la otra est ms relacionada con el algoritmo de deteccin y tiene informacin sobre cada anuncio a detectar.

- 11 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

_capstuff

Esta es la estructura de datos dedicada a almacenar las referencias a las interfaces utilizadas para el control de la tarjeta de TV/FM. Solo tendremos una estructura de datos de este tipo. Las interfaces que utiliza son explicadas en el apartado 3.1.2. de la memoria. En el cuadro de texto que contiene la ilustracin 8 se muestra la declaracin de esta estructura de datos.

struct _capstuff { ICaptureGraphBuilder2 *pBuilder; IAMCrossbar *pBar; IGraphBuilder *pFg; IMoniker *pMoniker; IAMTVTuner * pradio; IBaseFilter * pSrc, *pGrabberf, *pnull, *pWAVDest, *pWriter; ISampleGrabber * pGrabber; IMediaControl *pControl; IFileSinkFilter2 *pFileSink; }gcap;
Ilustracin 8: Estructura de datos capstuff.

archivo_wav

Estructura que contiene informacin sobre cada anuncio a detectar. Tendremos una tabla de estructuras de este tipo, donde el nmero de elementos de la tabla ser el de anuncios a detectar. El cuadro de texto que contiene la ilustracin 9 se muestra la declaracin de la estructura de datos.

- 12 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

struct archivo_wav { float *archivo; double *energia; int detectado; int fallo; int N1; long frecuencia; CString anuncio; int posibles_detecciones; };
Ilustracin 9: Estructura de datos archivo_wav.

Donde: archivo: apunta a las muestras del anuncio. energia: apunta al vector de energas del anuncio (explicado en apartado), sirve para una correcta normalizacin del proceso de correlacin. detectado: enumera las veces que se ha detectado, es informacin para el decisor. fallo: enumera las veces que ha fallado, es informacin para el decisor. N1: nmero de muestras del anuncio. frecuencia: frecuencia donde se grab el anuncio. anuncio: nombre del anuncio. posibles_detecciones: entero que refleja segn las condiciones de la deteccin (nmero de anuncios...) cuantas veces se puede detectar el anuncio en cuestin.

- 13 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CAPTULO 3: DESARROLLO DE LA INTERFASE.


Como ya se coment anteriormente uno de los componentes software utilizados han sido las libreras de DirectX. Dentro de estas he utilizado ms concretamente las libreras de DirectShow, que proporciona las herramientas necesarias para el control de dispositivos Hardware instalados en el sistema y ms concretamente de los dispositivos capturadotes que es lo que nos interesa en este caso, como una tarjeta capturadora de video/FM. Para el desarrollo de este apartado se han consultado las referencias [13], [4], [6] y [5]. Donde la ms utilizada ha sido la documentacin que viene con el SDK [13], debido a que era ms completa y adems contena algunos ejemplos desarrollados en C++ que sirven de mucha ayuda para comprender el funcionamiento de las libreras. En este captulo se hace una descripcin exhaustiva de cmo utilizando las libreras de DirectShow se puede controlar un dispositivo Hardware sin utilizar la herramienta software que suele acompaarle. Nuestro inters se centra en el desarrollo de una interfase de comunicacin entre PC y tarjeta a travs de DirectShow que nos proporcione el grado de control suficiente sobre la tarjeta como para no tener que emplear ningn tipo de software adicional.

3.1. USO DE DIRECTSHOW PARA EL CONTROL DE LA TARJETA.


El funcionamiento de DirectShow se basa en la correcta conexin de filtros DirectShow, controlando adecuadamente sus propiedades y haciendo las conexiones con los pines adecuados de cada filtro. Un filtro representa un dispositivo instalado en el sistema de forma Hardware o Software teniendo una funcionalidad propia. Al conjunto de varios filtros conectados se le denomina grafo y el propio SDK te proporciona la herramienta GraphEdit para hacer diseo de grafos y comprobar su funcionamiento antes de la etapa de programacin. En el apartado 2.2.3. de la memoria se muestra unos ejemplos del uso de la herramienta GraphEdit. Se han formado dos grafos. El grafo 1 que es el principal y que lleva el funcionamiento de deteccin de tramas de audio, y el grafo 2 que es secundario pero tambin importante ya que a partir de l proporcionamos una herramienta al usuario para grabar las tramas de audio que posteriormente - 14 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

desee comparar. Se puede hacer la grabacin con cualquier otro programa con la restriccin de que tiene que ser en formato .wav.

3.1.1. GRAFOS Y FILTROS.


Grafo 1: Es el grafo principal de la aplicacin. Su funcionamiento se basa en el almacenamiento de las muestras de audio en un buffer y la realizacin del algoritmo de deteccin con el contenido del buffer.

Audio Capture

SampleGrabber

Null Renderer

Ilustracin 10: Grafo 1.

A continuacin se hace una descripcin de los filtros que componen el grafo y que se ven representados en la ilustracin 10. Filtros: Audio Capture: filtro que representa la tarjeta capturadora. SampleGrabber: filtro DirectShow que almacena las muestras que van pasando por l en un buffer. Null Renderer: Necesario para que este grafo funcione. Hace las funciones de sumidero en este grafo.

Grafo 2: Grafo que sirve como herramienta de grabacin para obtener as las tramas de audio que van a ser comparadas con posterioridad.

Audio Capture

WavDest

File Writer

Ilustracin 11: Grafo 2.

- 15 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Filtros: Audio Capture: filtro que representa la tarjeta capturadora. WavDest: filtro DirectShow que sirve para poder grabar las muestras que vienen de la tarjeta a disco en formato WAV. File Writer: filtro DirectShow que representa el fichero de destino de las muestras.

3.1.2. INTERFACES Y MTODOS


DirectShow dispone de una amplia coleccin de interfaces y mtodos, en este apartado se comenta las ms importantes interfaces y dentro de ellas los mtodos ms relevantes que se han usado en el desarrollo de la aplicacin para una mejor compresin del cdigo. Una documentacin ms detallada se puede encontrar en el SDK de DirectX [13].

Interfaces: 3.1.2.1. IGraphBuilder.


Es una interfaz necesaria para construir un grafo de filtros. Esta interfaz est implementada por el filtro que controla todo el grafo y que se denomina: Filter Graph Manager. Mtodos: AddFilter: aade un filtro al grafo. Necesita de un parmetro que sea un puntero a IBaseFilter que es otra interfaz que se comentar posteriormente. Connect: mtodo que sirve para conectar dos pines.

- 16 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

3.1.2.2. ICaptureGraphBuilder2.
Interfaz usada para construir un grafo concretamente de tipo captura, es decir, donde intervenga un dispositivo de captura. Mtodos: SetFiltergraph: especifica un grafo en concreto. Sirve para relacionarlo con el Filter Graph Manager. FindInterface: busca en el grafo si alguno de los filtros implementan una determinada interfaz.

3.1.2.3. IBaseFilter.
Sirve para controlar los filtros. Todos los filtros DirectShow implementan esta interfaz. Lo primero es instanciar el filtro mediante el mtodo CoCreateInstance como se muestra de ejemplo a continuacin:
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&gcap.pnull);

El caso que se refleja es el del filtro Null Renderer. Y despus de esto con el mtodo AddFilter se une el filtro al grafo. Este es el proceso para unir al grafo un filtro DirectShow, es decir, en nuestro caso de los 5 filtros diferentes que usamos, son todos menos el filtro de captura de audio que representa la tarjeta capturadora externa y como unirlo al grafo se explicar en el apartado 3.1.2.11..

3.1.2.4. IMediaControl:
Interfaz que proporciona mtodos para controlar el flujo de datos a travs del grafo. Mtodos: Run: para que empiecen a funcionar todos los filtros en el grafo. Stop: detiene el funcionamiento del grafo.

- 17 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

3.1.2.5. IAMCrossbar.
Es una interfaz que la implementa el filtro Analog Video Crossbar Filter, y que sirve para dirigir las seales de una fuente (tanto analgica como digital) hacia un dispositivo de captura. Se usa para conectar el dispositivo de captura con la tarjeta de audio del sistema y as poder controlar con la tarjeta de audio del sistema el proceso (las tarjetas de TV se unen directamente con la tarjeta de audio del sistema tanto en el caso de que sean tarjetas externas como internas). Lo que hacemos es activar el dispositivo capturador para que empiece a funcionar pero trabajamos con la tarjeta de audio interna del sistema ya que suele tener mejores propiedades de audio y trabaja con numerosos formatos. Mtodos: Route: conecta dos pines que se le pasa como parmetro.

3.1.2.6. IFileSinkFilter2.
Interfaz que es implementada por el filtro que representa el fichero donde se almacenan las muestras en el proceso de grabacin. Mtodos: SetMode: se le pasa como parmetro la etiqueta AM_FILE_OVERWRITE , e indica que el fichero se sobrescribir si antes exista uno de mismo nombre. SetFileName: para indicar el nombre del fichero de destino.

3.1.2.7. ISampleGrabber.
Interfaz que es implementada por el filtro SampleGrabber, que era el filtro encargado de almacenar las muestras capturadas en un buffer interno. Mtodos: SetBufferSamples: si se le pasa TRUE como parmetro comienza a almacenar en un buffer interno las muestras que van pasando por l. El tamao de dicho buffer se determina mediante la interfaz IAMBufferNegotiation (se comentar posteriormente).

- 18 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

GetCurrentBuffer: te da una copia de las muestras ms recientes que el filtro recibi, en un buffer de datos que le pasas como parmetro al mtodo.

3.1.2.8. IAMTVTuner.
Interfaz que proporciona mtodos para la sintonizacin del dispositivo. Mtodos: Put_Mode: para determinar que sintonizacin vamos a realizar, en el caso de FM se pasa como parmetro AMTUNER_MODE_FM_RADIO y en el caso de TV AMTUNER_MODE_TV. put_InputType: para determinar si la entrada de informacin viene por el cable o la antena. Put_Channel: para sintonizar a la frecuencia que queramos. Tiene tres parmetros. El que vamos a utilizar va a ser el primero (los otros dos sern siempre cero) y este en el caso de FM tiene que corresponderse con el valor de la frecuencia (Hz.) de la emisora deseada, y en el caso de TV con el canal correspondiente.

3.1.2.9. IAMStreamConfig.
Interfaz usada para conseguir el formato deseado de los datos , con ella se consigue capturar a 8 Khz., 8 bits por muestra, y un solo canal (mono). Al menos en el caso de la tarjeta de TV/FM empleada no funcionaba a ese formato, es decir, no tenamos el control suficiente para trabajar en ese formato y por eso trabajamos con la tarjeta interna de sonido del sistema. Mtodos: GetFormat: devuelve el formato de datos preferido o establecido de un determinado pin de salida. SetFormat: Establece un determinado formato para el pin de salida del dispositivo de captura usado.

- 19 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

3.1.2.10. IAMBufferNegotiation.
Interfaz usada para el control del buffer interno que almacena las muestras de la captura. Mtodos: SuggestAllocatorProperties: sugiere al pin determinado las propiedades preferidas para el buffer interno.

3.1.2.11. ICreateDevEnum, IEnumMoniker e IMoniker.


Usadas conjuntamente para conseguir enumerar los dispositivos hardware del sistema y as poder encontrar el dispositivo de captura adecuado a nuestras necesidades. A continuacin se hace una breve descripcin del proceso sin profundizar en exceso en cada uno de los pasos. El primer paso sera la instanciacin del filtro que sirve para la enumeracin de los dispositivos que se encuentran instalados en el sistema. La interfaz que es implementada por este filtro es ICreateDevEnume. Despus se emplea el mtodo de esta interfaz CreateClassEnumerator donde se le pasa como parmetro que tipo de dispositivo se quiere enumerar y un puntero a una interfaz IEnumMoniker que es una interfaz donde se almacena informacin de los dispositivos enumerados y que les permite al sistema distinguir uno de otro. Tras esto solo falta quedarnos con el dispositivo deseado con el mtodo Next de la interfaz IEnumMoniker. Cada vez que se llama a este mtodo se avanza un dispositivo en la lista y se asocia este dispositivo seleccionado en una interfaz IMoniker que se le pasa como parmetro al mtodo. Por ltimo para unir al grafo el dispositivo deseado se usa el mtodo BindToObject de la interfaz IMoniker y as conseguimos asociar el dispositivo a una interfaz IBaseFilter, y tras esto se emplea el ya conocido mtodo AddFilter para aadir el filtro al grafo.

3.1.2.12. IPin.
Se usa para identificar los pines de los filtros y realizar una conexin entre ellos.

- 20 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Mtodos: QueryDirection: devuelve la direccin del pin, es decir, si es un pin de salida o de entrada.

3.1.2.13. Otros mtodos de inters.


CocreateInstance: para instanciar un filtro.

QueryInterface: mtodo que usa un elemento de IBaseFilter para adaptarse a una interfaz especfica.

3.1.3. MTODOS DESARROLLADOS.


El lenguaje de programacin usado ha sido el Visual C++ en el entorno de desarrollo de Visual Studio. A continuacin se hace una descripcin sobre algunas rutinas desarrolladas para el control de la interfase. SetAudioProperties: rutina para el control del formato de audio capturado. Controla la frecuencia de muestreo, los bytes por muestra, y el nmero de canales de entrada (mono o estreo). Tambin controla el tamao del buffer interno de datos ya que se le pasa como parmetro el tiempo de captura y el tamao del buffer de datos es el resultado del producto entre el tiempo de captura y la frecuencia de muestreo.

HRESULT SetAudioProperties(int nChannels,int nBytesPerSample,int nFrequency,float tiempo_captura);


Iniciacaptura: rutina que inicia el desarrollo del grafo DirectShow y llama al mtodo EnumFiltersWithMonikerToList que es el que se encarga de enumerar los dispositivos capturadores instalados en el sistema en la lista que aparece en el dilogo principal de la aplicacin.

void iniciacaptura();
Iniciasintonizacion: Rutina para configurar y encontrar correctamente la interfaz de sintonizacin IAMTVTuner. Tambin llama a las rutinas de lectura de frecuencias (o canales dependiendo del caso) que lee las frecuencias donde se desea hacer el proceso de deteccin del archivo frecuencias.cfg.

void iniciasintonizacion();

- 21 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

GetPin: rutina que sirve para obtener un pin de un determinado filtro. Hay que pasarle como parmetro adems del filtro correspondiente, en que direccin queremos buscar el pin, es decir, si es de salida o de entrada y un puntero a una referencia IPin donde te la rutina te devuelve el resultado.

HRESULT GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);


Conecta: rutina que conecta dos filtros a partir de sus respectivos interfaces IBaseFilter. La conexin se hace de modo que el pin de salida del filtro 1 se conecta al de entrada del filtro 2.

void conecta(IBaseFilter * filtro1,IBaseFilter * filtro2);


OnGrabaradio: rutina que se ejecuta tras pulsar el botn GRABAR del dilogo principal. Se encarga de preparar e inicializar todo el grafo de grabacin.

void OnGrabaradio();
OnDeteccion: rutina que se ejecuta tras pulsar el botn DETECCIN del dilogo principal. Se encarga de preparar e inicializar el grafo de deteccin y adems la fase de establecimiento del proceso de deteccin. Este proceso est descrito ms detenidamente en el captulo 4.

void OnDeteccion();
OnSalir: rutina que se ejecuta tras pulsar el botn SALIR del dilogo principal. Se encarga de liberar todos los punteros de forma adecuada, detiene el grafo mediante el mtodo Stop de la interfaz IMediaControl y cierra la aplicacin.

void OnSalir();
OnSeldisp: rutina que se ejecuta tras pulsar el botn SELECCIONAR DISPOSITIVO del dilogo principal. Se encarga de seleccionar el dispositivo de captura que vamos a utilizar de la lista de dispositivos de captura que aparece en el dilogo principal de la aplicacin y que representa los dispositivos encontrados en el sistema, y lo aade al grafo, una vez hecho esto llama a la rutina iniciasintonizacion.

void OnSeldisp();

- 22 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

EnumFiltersWithMonikerToList: rutina que utiliza otras dos rutinas (EnumFiltersAndMonikersToList y AddFilterToListWithMoniker) para rellenar una lista con los dispositivos encontrados en el sistema. Se puede utilizar con muchos tipos de dispositivos, tiene tres parmetros, el primero es para pasarle un elemento de la interfaz ICreateEnum, el segundo es para indicarle qu tipos de dispositivos se quiere listar, y el tercero la lista de destino.

HRESULT EnumFiltersWithMonikerToList(ICreateDevEnum *pSysDevEnum,const GUID *clsid, CListBox& List);


OnArchivosAnuncios: rutina que se ejecuta al pulsar el elemento ANUNCIOS del men ARCHIVOS. Te muestra un dilogo para seleccionar los anuncios que van a formar parte del proceso de deteccin.

void OnArchivosAnuncios();
OnArchivosSalir: rutina que se ejecuta al pulsar el elemento SALIR del men ARCHIVOS. La accin que realiza es cerrar la aplicacin del mismo modo que lo hace el botn SALIR del dilogo principal.

void OnSalir();
OnConfigurarSintonizador: rutina que se ejecuta al pulsar el elemento SINTONIZADOR del men CONFIGURAR. Te muestra un dilogo donde puedes sintonizar el dispositivo capturador al canal deseado.

void OnConfigurarSintonizador();
OnConfiguracion: rutina que se ejecuta al pulsar el elemento CONFIGURACIN del men CONFIGURAR. Te muestra un dilogo donde puedes configurar ciertos aspectos como son el tipo de entrada (TV o FM), el tiempo de captura y el umbral.

void OnConfiguracion();
OnHelpVersin: rutina que se ejecuta al pulsar el elemento VERSION del men ACERCA DE. Te muestra un dilogo donde te da informacin acerca de la aplicacin.

void OnHelpVersin();

- 23 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

3.1.4. BREVE DESCRIPCIN DEL PROCESO.


En este apartado se hace una descripcin de los pasos a seguir para realizar estos grafos en Visual C++. 1. Libreras: para utilizar DirectShow en tu aplicacin hace falta incluir las libreras y archivos de cabecera correspondientes. Para realizar esto hay que incluir los archivos de cabecera DShow.h y Qedit.h y adems linkarle la librera Strmiids.lib. 2. Filter Graph Manager: tras las libreras ya se puede hacer uso de todas las interfaces de DirectShow y por ello lo primero es crear (o instanciar) el filtro principal para crear el grafo. 3. Se asocia este filtro principal al filtro especfico de captura indicndole de esta forma al sistema que el grafo que vamos a desarrollar tiene un elemento de captura de datos. Los puntos 2 y 3 se ven reflejados en el cuadro de texto que aparece en la ilustracin 12:
CoInitialize(NULL); // Se crea el "Filter Graph Manager". hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&gcap.pFg); // Y ahora se crea "Capture Graph Builder". hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2, (void **)&gcap.pBuilder); // Se asocia el grafo con el constructor. gcap.pBuilder->SetFiltergraph(gcap.pFg);

Ilustracin 12: Formacin Grafo DirectShow.

Ilustracin 10

4. Se van incorporando los filtros al grafo con el mtodo AddFilter. Incorporar un filtro a un grafo no significa que este conectado, es decir, todava no tiene ninguna funcionalidad, despus se tiene que conectar con otro filtro con el mtodo conecta en el orden deseado. Lo primero que se hace es unir el filtro al grafo con AddFilter, despus se configurara el filtro de manera conveniente a nuestras necesidades y por ltimo se conecta para que forme parte del camino del flujo de datos. Un ejemplo de este proceso se observa en

- 24 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

el cuadro de texto que contiene la ilustracin 13, donde se encuentra el proceso de conexin del grafo de deteccin (grafo 1).

// Primero se instancia el filtro hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&gcap.pGrabberf); hr = gcap.pFg->AddFilter(gcap.pGrabberf, L"Sample Grabber"); //Ahora a compartir el interfaz gcap.pGrabberf->QueryInterface(IID_ISampleGrabber, (void**)&gcap.pGrabber); //Configuramos adecuadamente el tipo de dato que va a llegar //para asegurarnos de que no haya problemas gcap.pGrabber->SetMediaType(pmt); //para activar el modo buffer se llama a SetBufferSamples hr = gcap.pGrabber->SetOneShot(FALSE); hr = gcap.pGrabber->SetBufferSamples(TRUE); //Falta el filtro Null Renderer //Primero creo el filtro hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&gcap.pnull); hr = gcap.pFg->AddFilter(gcap.pnull, L"Null Renderer"); //los conectamos conecta(gcap.pSrc,gcap.pGrabberf); conecta(gcap.pGrabberf,gcap.pnull); Ilustracin 13: Formacin Grafo DirectShow (2).

5. Hay ocasiones en las que queremos que algn filtro del grafo soporte algn tipo de interfaz particular y esto se hace con el mtodo QueryInterface. Se muestra en la ilustracin 14 un uso de este mtodo para hacer que el grafo contenga la funcionalidad de la interfaz IMediaControl.

hr = gcap.pFg->QueryInterface(IID_IMediaControl, (void **)&gcap.pControl);

Ilustracin 14: Formacin Grafo DirectShow (3).

6. Una vez que tengamos todo configurado y conectado solo queda indicarle al grafo que comience a funcionar y para ello se utiliza el mtodo Run de la interfaz IMediaControl, tal y como refleja la ilustracin 15. - 25 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

hr = gcap.pControl->Run();

Ilustracin 15: Formacin Grafo DirectShow (4).

3.2. OTRAS CLASES PARA DECORACIN DE LA INTERFASE.


Se ha usado una clase denominada CButtonST para poner iconos a los botones del dilogo y adems para que el cursor del ratn cambie cuando este situado encima de un botn. En las libreras del Visual C++ ya exista una clase para controlar los botones del dilogo llamada CButton. Los cambios que queramos realizar en el aspecto de los botones no te permita hacerlo la clase CButton por si sola y por ello hay que usar una clase que derive de ella y sobrecargar sus mtodos virtuales, en especial el mtodo DrawItem. Para realizar estas acciones hay que hacer los siguientes pasos: 1. Definir una variable miembro al botn de tipo CButtonST. 2. Para poner un icono se usa el mtodo SetIcon de la siguiente forma:

Nombre_variable.SetIcon(ID_ICON);
3. Para cambiar el cursor cuando se este situado sobre algn botn se usa el mtodo SetBtnCursor de la siguiente forma.

Nombre_variable.SetBtnCursor(ID_CURSOR);
Nota: evidentemente para poder realizarlo tienes que tener importado en tu lista de recursos tanto el icono preciso como el cursor, y es su respectivo identificador el que se pasa como parmetro a los respectivos mtodos.

- 26 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CAPTULO 4: ALGORITMO DE DETECCIN.


En este apartado se desarrolla el algoritmo usado para la deteccin de las tramas de audio. Como algoritmo hemos usado la correlacin cruzada normalizada, ver [1]. Aunque no es el ms eficiente computacionalmente, es un algoritmo muy robusto que nos ha dado muy buenos resultados. Tambin se comentan en este apartado las rutinas desarrolladas para la deteccin con el objetivo de facilitarle la labor al lector del cdigo fuente. Adems se aportan los resultados ms relevantes de cientos de pruebas realizadas y en funcin a estas se elaboran unas conclusiones muy importantes para el usuario final de la aplicacin. Para terminar el captulo se desarrolla el proceso de decisin que se ha empleado para determinar si es el anuncio o por el contrario lo que se ha detectado es una falsa alarma.

4.1. ALGORITMO DE CORRELACIN.


Es un algoritmo utilizado frecuentemente en procesos de comparacin de seales de muy diversa ndole. Se aplica a dos seales y nos ofrece un vector de resultado donde aquellos elementos que tengan un valor lo suficientemente grande significar que las seales se parecen entre s. La correlacin que hemos usado ha sido la correlacin discreta debido a que las seales con las que trabajamos son seales discretas. La definicin de la correlacin es la que aparece en la siguiente expresin:

rxy (l ) = x ( n ) * y ( n l )
n

Tal y como se coment anteriormente la correlacin cruzada es un algoritmo que se le aplica a dos seales (x(n), y(n)). En la implementacin del algoritmo una de esas seales se va desplazando con respecto a la otra para generar los valores de la correlacin cruzada para cada valor del parmetro l, y en cada desplazamiento se calcula la suma de los productos entre las muestras de las dos seales que coinciden en ese momento. - 27 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Para la implementacin de este algoritmo en nuestra aplicacin hemos adoptado por desplazar la ms pequea sobre la grande, donde la pequea es lo que se va capturando de forma peridica y la grande es el anuncio a comparar. Si la longitud de X(n) es N1, y la longitud de Y(n) es N2 (en nuestro caso N2<N1), el resultado de este proceso es otra seal de N2 + N1 -1 puntos. Este sera el resultado terico del proceso de correlacin cruzada, pero a la hora de la implementacin y por razones de eficiencia computacional el proceso no comprende las colas resultando solamente una seal de N2N1+1 puntos. Las colas son aquellas zonas donde no entran en la operacin todos los trminos de la seal ms pequea. Esto se ve reflejado en la ilustracin 8.

x(n)

y(n)

Solo solapa una parte

Ilustracin 16: Colas de correlacin cruzada.

La ilustracin 16 refleja uno de los dos casos de colas, donde las primeras muestras de y(n) se multiplicaran por cero. Y el otro sera igual pero situada la seal y(n) al final de x(n). Ese vector de correlacin representa el resultado de la comparacin entre ambas seales, pero para hacer una interpretacin del mismo ms correcta es necesario una correcta normalizacin. Para conseguir esa normalizacin se divide cada uno de los coeficientes de correlacin por la raz cuadrada de las energas tal como refleja la siguiente

- 28 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

expresin, donde para calcular las energas solo se toman en cuenta los puntos que han intervenido en la suma de productos de las seales.

rxy ( l ) =

x(n) * y (n l ) Ex ( l ) * Ey

l = 0,1,..., N1 N 2

En nuestro proceso el valor de Ey corresponde con la suma del cuadrado de las muestras de la seal y(n) que es la seal que estamos capturando. Esta energa se mantiene constante para el clculo de la correlacin cruzada ya que los puntos de la seal y(n) siempre sern los mismos los que intervengan en el clculo. En el caso de Ex es un poco ms complejo ya que corresponde con la suma del cuadrado de las muestras de la seal x(n) que intervienen en el clculo, es decir, es la suma del cuadrado de N2 muestras dependiendo del desplazamiento de la seal y(n). Por lo tanto no es un valor constante y va a depender del desplazamiento de y(n) con lo que nos dar lugar a un vector de energas. Las expresiones de ambas energas se muestran a continuacin:

Ey =

N 2 1 n =0

y ( n) * y ( n)
N 2 1 n =0

Ex(l ) =

x(n + l ) * x(n + l )

l = 0,1,..., N1 N 2

Tras realizar esto hemos conseguido acotar el vector correlacin normalizado entre -1 y 1, con lo que ya estamos a disposicin de interpretar los resultados. Es evidente que cuanto ms cercanos estemos a 1 significar que las seales que han formado parte del proceso de correlacin se parecen ms. En la implementacin de este algoritmo se busca el mximo de los coeficientes del vector correlacin cruzada normalizada. Es este valor mximo el que vamos a comparar con un cierto valor que le denominamos umbral de la deteccin y es el que va a decidir si la deteccin ha sido correcta o no. En el caso de que haya sido correcto se puntualizar en el archivo de resultados y en una lista de anuncios detectados situada en el dilogo principal

- 29 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

de la aplicacin. Por lo tanto la lista mostrar todos los mximos de correlacin que superen el umbral.

4.2. PARMETROS QUE INTERVIENEN EN EL PROCESO.


Los parmetros ms importantes son los que se describen a continuacin:

4.2.1. FRECUENCIA DE MUESTREO:


Estamos realizando comparaciones entre el anuncio grabado previamente y la seal de audio que vamos capturando de forma progresiva. Ambas seales para poder tratarlas con un computador tenemos que digitalizarlas. En ese proceso de digitalizacin el primer paso es el muestreo de la seal analgica. Es importante darse cuenta que debido al algoritmo empleado para la deteccin tanto el anuncio como el trozo de audio capturado deben de estar muestreados a la misma frecuencia de muestreo. La eleccin de la frecuencia de muestreo correcta es determinante para las posibilidades de este proyecto. Segn el teorema de Nyquist se debe de elegir como mnimo una frecuencia de muestreo que sea el doble del ancho de banda de la seal a muestrear. En el caso de que la seal analgica sea de voz con una frecuencia de muestreo de 8 Khz. sera suficiente pero en el caso de msica hara falta una frecuencia de muestreo mayor para una posterior recuperacin de la seal analgica. Por ejemplo si reproducimos una cancin que grabemos a 8 Khz. no la escucharemos de modo correcto, se est produciendo Aliasing ya que la msica tiene frecuencias superiores a 4 Khz. Debido a la explicacin anterior se podra pensar en que una buena frecuencia de muestreo es 44,1 Khz. (que es calidad de CD) y as te aseguras de que todas las seales se muestrean de modo correcto siguiendo en todos los casos el teorema de Nyquist. Pero no hay que olvidar que esta es una aplicacin que debe de trabajar en tiempo real y que la frecuencia de muestreo est ntimamente ligada al nmero de muestras de las seales en un mismo tiempo de captura tal como refleja la siguiente expresin enmarcada en la ilustracin 17.

- 30 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Num. Muestras = (F. Muestreo) * (Tiempo de captura)

Ilustracin 17: Nmero de muestras.

Segn se ve en la expresin anterior el nmero de muestras que luego van a formar parte del algoritmo de correlacin es directamente proporcional a la frecuencia de muestreo. Un ejemplo de ese resultado se puede ver en la tabla 3 donde se encuentran los valores del nmero de muestras en funcin al tiempo de muestreo en el caso de un anuncio de 20 segundos.

FRECUENCIA MUESTREO 8000 16000 22050 44100

NUMERO DE MUESTRAS 160000 320000 441000 882000

Tabla 3: Ejemplo nmero de muestras-frecuencia de muestreo.

Teniendo en cuenta que con el proceso utilizado para la deteccin el nmero de operaciones aumenta al cuadrado con el nmero de muestras es evidente que nos interesa la frecuencia de muestreo ms baja posible para conseguir nuestros objetivos. Con todo lo anterior la frecuencia de muestreo utilizada ha sido de 8 Khz. ya que aunque no permita una correcta reconstruccin de la seal en algunos casos, hemos comprobado mediante numerosas pruebas que es lo suficientemente buena como para que mediante la correlacin seamos capaces de detectar cuando se est emitiendo un determinado anuncio. Es evidente que sera mucho mejor poder trabajar con una frecuencia de muestreo mayor ya que as reduciramos la probabilidad de error del proceso pero debido a la cantidad de muestras que tiene tendra que ser un proceso que no trabajara en tiempo real.

- 31 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.2.2. NMERO DE BITS POR MUESTRA:


Tras el muestreo de la seal analgica el siguiente paso para la digitalizacin es la cuantizacin que en este caso es una cuantizacin uniforme. Tras esto viene la codificacin que hemos elegido quedarnos con 8 bits por muestra, ya que nos da una calidad lo suficientemente buena para nuestro proceso.

4.2.3. NMERO DE CANALES:


En este caso las posibles elecciones son 1 o 2, o lo que es lo mismo Mono o Estreo, pero para una mejor eficiencia computacional hemos elegido Mono (se tienen la mitad de muestras).

4.2.4. TIEMPO DE CAPTURA:


Es el tiempo que se captura la seal de entrada analgica para poder compararse posteriormente con los anuncios almacenados. Este es un parmetro que est ligado de forma directa a la frecuencia de muestreo dando lugar al nmero de muestras totales a comparar. Este parmetro interesa que sea pequeo en nuestro objetivo de una aplicacin en tiempo real para que as el nmero de muestras sea menor y el tiempo empleado en la comparacin sea razonable para los objetivos que pretendemos. La probabilidad de error depende mucho de la eleccin de este parmetro. Como probabilidad de error distinguimos dos sucesos:

Probabilidad de no deteccin: probabilidad de que no detecte nada cuando se este emitiendo un anuncio. Probabilidad de falsa alarma: probabilidad de que detecte un anuncio cuando no se este emitiendo.

Para tener valores aceptables de la probabilidad de error se debe tener un mnimo en el nmero de muestras, que implica un mnimo en el tiempo de captura. Segn se consult en la referencia [9], donde se hace un estudio estadstico de este caso, utilizando la funcin de distribucin Beta, llegando a la conclusin que para una correcta deteccin se necesitan

- 32 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

como mnimo 1000 muestras, con lo que el tiempo de captura era 125 mseg ( a una frecuencia de muestreo de 8 Khz. ). Este es un mnimo terico que procede de un estudio estadstico, se han realizado multitud de pruebas con otros tiempos de captura menores con el fin de poder mejorar en eficiencia computacional. El resultado de esas pruebas se encuentran en el apartado 4.4 de la memoria. Conforme se baja el tiempo de captura se tiene una mayor probabilidad de error pero se gana en eficiencia computacional. Es un parmetro que se queda de configuracin en la aplicacin (a diferencia de los tres anteriores que son fijos). Aunque el valor ms adecuado es el mnimo terico, en ocasiones el usuario puede optar por disminuir ese mnimo en busca de una optimizacin computacional, aunque esto no siempre ser conveniente (depender de los anuncios). En el apartado 4.4 se describe y analiza la eleccin de los tiempos de captura, describindose las numerosas pruebas realizadas y evaluando las conclusiones derivadas de las mismas.

4.2.5. UMBRAL DE DETECCIN:


Es el nmero con el que se va a comparar el mximo de la correlacin normalizada para determinar si se ha detectado algn anuncio. Este nmero est comprendido entre -1 y 1 ya que el resultado de la correlacin normalizada est comprendido en ese intervalo tal y como se explic en el apartado 4.1. Este parmetro al igual que el anterior es un parmetro que se puede cambiar en la aplicacin. Como valor predeterminado tiene 0,5, pero tal vez pueda interesar cambiarlo. En el caso de bajarlo la probabilidad de falsa alarma ser mayor, en cambio la probabilidad de no deteccin ser menor. Si por el contrario se pone como un umbral un valor mayor de 0,5 ocurre exactamente lo contrario. El fichero de resultados resultado.txt mostrar los valores del mximo del vector de correlacin en caso de deteccin positiva, con lo que el usuario tras observar los resultados puede optar por cambiar el umbral. En el caso de que observe que hay demasiadas falsas alarmas se optara por subir el umbral (comprobando siempre con los valores

- 33 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

detectados que esta subida no enmascara tambin las detecciones correctas). En el caso de que la deteccin no sea correcta con un umbral de 0,5 no se recomienda disminuirlo, ya que el nmero de falsas alarmas aumentar considerablemente. En este caso se recomienda usar un tiempo de captura mayor, y si ya estamos con 125 mseg. es recomendable volver a realizar la grabacin del anuncio. Debido a todo esto se decidi que fuera un parmetro que se pudiera modificar por parte del usuario final.

4.3. RUTINAS DESARROLLADAS.


Este apartado pretende servir de ayuda a los lectores interesados en estudiar el cdigo fuente del programa. En el proceso de deteccin, despus de la correcta configuracin del grafo DirectShow, se pueden distinguir dos fases:

4.3.1. FASE DE ESTABLECIMIENTO.


Es una fase que solo se ejecuta una vez en el proceso de deteccin. En esta fase lo que se hace es preparar los anuncios que van a ser detectados y las frecuencias que van a ser examinadas. Los anuncios se leen de un archivo .wav que se encuentra en el directorio ARCHIVOS dentro de la carpeta base de la aplicacin. Estos se leen y se almacenan en memoria para una mayor eficiencia del proceso. Adems hay que calcular el vector de energas correspondiente a cada anuncio. Para almacenar cada anuncio se ha utilizado la estructura de datos denominada archivo_wav ya comentada en el apartado 2.4.2. Las rutinas relacionadas con esta fase de establecimiento se describen a continuacin:

Lectura_anuncios: Rutina que realiza todo lo referente a la lectura de los anuncios seleccionados para la deteccin, y para ello se basa en las rutinas Leewav, calcula_vector_energia y

- 34 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

calcula_posibles_detecciones. Los almacena de modo adecuado dentro de la estructura de datos archivo_wav. Tambin se asegura si hay algn anuncio seleccionado y de no ser as te muestra el dilogo correspondiente para su seleccin.

void lectura_anuncios();

Leewav: Rutina que se le pasa como entrada el nombre del archivo a leer (solamente el nombre, pero se tiene que encontrar en el directorio ARCHIVOS), y te devuelve las muestras de ese archivo en un vector de float. Tambin se obtiene el nmero de muestras mediante un parmetro que se le pasa por referencia. Esta rutina controla la correcta lectura de archivos .wav sea cual sea su procedencia, ya que la cabecera de los mismos es diferente dependiendo de con que aplicacin se haya grabado el anuncio (en el anexo se aporta ms informacin sobre el formato WAV).

float *leewav(int *N1,CString nombre);

Calcula_vector_energia: Rutina que calcula el vector de energa correspondiente a cada anuncio.

double *calcula_vector_energia(float *data1,int N1);

Calcula_posibles_detecciones: Rutina que calcula las posibles detecciones de un anuncio dependiendo de con qu parmetros se haga la prueba. Una mejor explicacin de lo que significa el nmero posible de detecciones de un anuncio se encuentra en el apartado 4.5. de la memoria.

int calcula_posibles_detecciones(int N1);

Lectura_frecuencias: Rutina que hace todo lo necesario para la lectura de las frecuencias donde queremos realizar el proceso de deteccin. El usuario puede introducir las frecuencias deseadas mediante un fichero denominado frecuencias.cfg y que se encuentra en el directorio base de la aplicacin. Los detalles de cmo introducir esas frecuencias de modo correcto se encuentran en el apartado 5.4. de la memoria.

void lectura_frecuencias();

Lectura_cadenas_tv: Rutina que hace todo lo necesario para la lectura de las cadenas de TV (en el caso de que la aplicacin este configurada en modo TV). El usuario debe de introducir las cadenas deseadas en el fichero de configuracin frecuencias.cfg y que se encuentra en el directorio base de la aplicacin. Los detalles de cmo introducir la lista de canales en el fichero de

- 35 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

configuracin de modo correcto se encuentran en el apartado 5.4. de la memoria.

void lectura_canales_tv();

prueba_piloto: rutina que se encarga de realizar una correlacin con un anuncio de referencia (anuncio_piloto.wav) y as se calcula el tiempo de computacin para dicho anuncio. Ese tiempo se emplear posteriormente para el clculo del nmero de detecciones posibles por anuncio. Para medir estos tiempos se ha hecho uso de la librera time.h.

void prueba_piloto();

calcula_frecuencias_correlacion: rutina que se encarga de rellenar una tabla de long con las frecuencias (o cadenas) donde se debe de hacer el proceso de deteccin. Mediante el fichero frecuencias.cfg se introducen las frecuencias posibles, estas despus aparecen en el dilogo de seleccin de anuncios, y dependiendo de la seleccin se formar la tabla de frecuencias.

void calcula_frecuencias_correlacion();

4.3.2. FASE DE APLICACIN DEL ALGORITMO.


El algoritmo se aplicar de forma peridica hasta que el usuario lo detenga. Los mtodos desarrollados para esta fase se describen a continuacin:

OnTimer: Rutina que representa la periodicidad del proceso de deteccin. Esta rutina se ejecuta cada vez que vence el temporizador de la aplicacin. Como el temporizador se reinicia al final de la rutina se garantiza la periodicidad de la aplicacin sin llegar a ser un bucle infinito (que absorbera todos los recursos del sistema).

void OnTimer(UINT nIDEvent);

Cambiacanal: Rutina que sintoniza a la cadena de radio de FM o la cadena de TV (dependiendo del caso) que se le pasa como parmetro. En el caso de FM la frecuencia que se le pasa como parmetro debe de estar en Hz.

void cambia_canal(long canal);


- 36 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Correlacin: Rutina que calcula el valor mximo de la correlacin cruzada normalizada de dos seales que se le pasa como parmetro. Con el mximo calculado llama a la rutina decisor.

void correlacion(archivo_wav *anuncio,float *data2,int N2,double energia2);


Calcula_energia: Rutina que se encarga de calcular la energa de las tramas capturadas de forma peridica en el proceso de deteccin.

double calculo_energia(float *muestras,int longitud);

Decisor: Rutina que se encarga de comparar el valor mximo que se le pasa como parmetro con el umbral de deteccin, si es mayor llama a la rutina anota_resultado. Adems tiene un criterio de decisin basado en el nmero de detecciones posibles de cada anuncio que determinar si es el anuncio detectado o no. El algoritmo que sigue el proceso de decisin se describe en profundidad en el apartado 4.5. de la memoria.

void decisor(archivo_wav *anuncio,double maximo);

Anota_resultado: Rutina que se encarga de reflejar en la lista del dilogo principal y en el fichero de resultado los anuncios detectados.

void anota_resultado(archivo_wav *anuncio,double maximo);


El fichero de resultado se denomina resultado.txt y en el fichero se van almacenando los resultados de la aplicacin en sus diferentes ejecuciones. Cuando se ejecuta la aplicacin se escribe en l un mensaje donde aparece tambin la fecha actual, y despus van apareciendo las detecciones junto con las cadenas donde se detectaron, la hora y adems ( y solo en el fichero ) se escribe tambin el valor que provoc la deteccin, de este modo se puede hacer una mejor interpretacin del resultado ya que no es lo mismo una deteccin de 0,8 o 0,9 a una de 0,55 por ejemplo, y esto va a ayudar a la mejora de la deteccin de los anuncios por parte del usuario.

- 37 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4. FASE DE PRUEBAS: RESULTADOS Y CONCLUSIONES.


La fase de pruebas de este proyecto ha sido muy costosa tanto en tiempo como en esfuerzo. Se ha tenido que probar el funcionamiento de la aplicacin cambiando sus parmetros para determinar cules son los valores ptimos de los mismos. Las pruebas se han basado en la comprobacin del correcto funcionamiento de la aplicacin para diferentes casos, variando tanto los anuncios como los parmetros, ms concretamente el tiempo de captura y la fuente de entrada TV o FM. Han estado encaminadas al intento de verificacin del uso de un tiempo de muestreo menor que el mnimo terico (125 mseg.) que nos aportara una mayor eficiencia computacional. Se ha ido reduciendo progresivamente el tiempo de captura hasta que los resultados han sido muy desfavorables, mostrando en cada paso los resultados ms relevantes en unas tablas que se pueden observar en el apartado 4.4.3. Por ltimo se establecen conclusiones sobre las pruebas realizadas que pueden ser de gran ayuda a la hora de configurar los parmetros de la aplicacin.

4.4.1. TIEMPO DE COMPUTACIN.


En este apartado se examina el tiempo de computacin del algoritmo que vamos a utilizar. Para ello se ha medido el tiempo que tarda la fase de aplicacin del algoritmo (no la de establecimiento) para un anuncio concreto con N1=225000 (unos 28 seg.) y variando los tiempos de captura progresivamente. Los resultados de este proceso se reflejan en la tabla 4.

- 38 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

TIEMPO CAPTURA (SEG.) 0.125 0.100 0.09 0.08 0.075 0.07 0.06 0.05 0.04 0.03 0.025 0.02 0.01

TIEMPO COMPUTACIN (MSEG.) 2804 2244 2094 1802 1712 1582 1362 1141 931 701 590 481 251

Tabla 4: Tiempo de computacin-Tiempo de captura.

El tiempo de captura mayor escogido es el ptimo segn el proceso estadstico que ya cit en el apartado 4.2.4. En el caso de que el usuario quiera conocer el tiempo de computacin en un determinado caso puede obtener una aproximacin eligiendo el tiempo de captura deseado y haciendo una simple regla de tres entre la suma de los tiempos de los anuncios seleccionados, el tiempo de computacin para el tiempo de captura seleccionado (de la tabla anterior) y los 28 segundos que es la duracin aproximada del anuncio de referencia. Es importante saber el tiempo que tarda el proceso de forma peridica para un correcto uso del detector de anuncios. Si por ejemplo tenemos el anuncio de referencia y nos ponemos a detectarlo en una sola cadena con 0,125 segundos sabemos por la tabla anterior que el proceso tarda en dar una pasada casi 3 segundos. El sistema est diseado para que refleje los resultados tanto en la lista como en el archivo cada vez que lo detecte. Como estamos en una sola cadena y el anuncio dura unos 28 segundos el sistema deber de detectarlo unas 9 (o 10) veces de media. Con lo que si el usuario maneja este tipo de informacin implcita en el proceso tendr un mejor criterio de comprobacin para la deteccin. Si en el caso del ejemplo anterior solo aparece un detectado en pantalla, es muy probable que solo sea una falsa alarma, en cambio si aparecen ms pues se puede certificar que es una deteccin correcta. Adems es importante conocer el tiempo del proceso en cada caso particular para verificar si es factible o no la herramienta desarrollada. Para ello se calcula el tiempo de computacin tal y como se ha explicado anteriormente (teniendo en cuenta todos los anuncios que formen parte del proceso). Para que sea factible el proceso el resultado debe ser menor que la duracin del

- 39 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

anuncio ms corto que forme parte del proceso. El clculo se refleja en la siguiente expresin.

T .C .T .( seg ) = (T .T . Anuncios _( seg )) * (T .C .( seg )) * 8000 / 225000

Donde: T.C.T.(seg.) : El tiempo de computacin total del proceso. T.T.Anuncios(seg.) : El tiempo total de los anuncios seleccionados en el proceso. T.C.(seg.): El tiempo de computacin escogido de la tabla de la ilustracin 11 dependiendo del tiempo de captura seleccionado y dividido por 1000 para expresarlo en segundos.

El tiempo de computacin (T.C.) depende del ordenador en el que se est trabajando. Este tiempo es necesario para calcular el nmero posible de detecciones de un determinado anuncio (ver apartado 4.5) que es un parmetro que utiliza el decisor en su algoritmo. Debido a esto se calcula ese tiempo en la fase de establecimiento del algoritmo de deteccin.

4.4.2. TIEMPOS DE CONMUTACIN ENTRE SINTONAS.


En este apartado se comenta los tiempos que transcurren en la sintonizacin de cadenas de radio o TV. La aplicacin no permite hacer una deteccin de radio y TV en la misma ejecucin debido a que el tiempo de conmutacin es excesivo al pasar de un formato al otro, y en nuestro objetivo de llegar a la eficiencia no hemos permitido que se realice en una misma deteccin sintonas de radio y cadenas de TV. Este tiempo de conmutacin se puede reflejar en la ilustracin 18.

- 40 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 18: Tiempo de conmutacin FM -> TV.

Esta ilustracin es reflejo de la prueba realizada para calcular los tiempos de conmutacin. Dicha prueba consiste en hacer una grabacin donde intervenga la conmutacin de cadenas, para despus observar los resultados en MATLAB. En este caso la prueba ha consistido en sintonizar una emisora de FM y despus pasar a un canal de TV. Basndonos en la grfica el nmero de muestras que dura el periodo de conmutacin son 54000 45000 = 9000, que con una frecuencia de muestreo de 8 Khz. que es con la que trabajamos nos da como resultado un tiempo de conmutacin de ms de un segundo. Esta prueba se ha secundado con la medicin del tiempo en la aplicacin resultando un tiempo de 1,3 segundos. Son tiempos de conmutacin excesivos y por eso la aplicacin no est diseada para trabajar conmutando emisoras de FM y TV, en una misma ejecucin. En el caso de la conmutacin en un mismo tipo de entrada cadena de radio o TV (segn sea el caso) la representacin de MATLAB se ilustra en la ilustracin 19. El experimento es el mismo con los mismos tiempos y solo cambiando la sintonizacin dependiendo del caso, as que debera de apreciarse el periodo de conmutacin en las mismas muestras aproximadamente, y la figura refleja que esa zona es casi imperceptible.

- 41 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 19: Tiempo de conmutacin FM -> FM.

Y mediante la medicin de tiempos en la aplicacin da como resultado el tiempo de 0,1 segundos que son 800 muestras y por eso es casi imperceptible. La diferencia entre los dos experimentos realizados es notable y por ello se ha optado por la solucin de desarrollar la aplicacin para que solo permita la deteccin de un grupo de canales de radio, o de canales de TV pero no entremezclados entre s.

4.4.3. PRUEBAS REALIZADAS.


Este apartado pretende ser una sntesis de las innumerables pruebas realizadas para la verificacin del correcto funcionamiento de la aplicacin. Se reflejar en diferentes tablas los resultados de las pruebas ms interesantes, con las que se reflejarn el correcto comportamiento del sistema ante unas ciertas condiciones y tambin los casos en los que el sistema no funciona tan correctamente. Con este apartado se pretende mostrar que aunque el correcto funcionamiento de la aplicacin es con un tiempo de captura de 125 mseg., debido a sus limitaciones computacionales se ha ido probando el sistema progresivamente disminuyendo dicho tiempo, y en cada una de esas pruebas evaluando si bajo esas condiciones el sistema tena una probabilidad de error considerable.

- 42 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Es evidente que la eleccin de un tiempo de captura menor va a aumentar la probabilidad de error, pero el tiempo de computacin va a disminuir considerablemente y va a permitir una mayor seleccin de anuncios y de cadenas. En cada prueba se especifica la duracin del anuncio que se utiliza y la duracin de la prueba. El parmetro que va a ir variando a lo largo de las pruebas es el tiempo de captura. El umbral de deteccin permanecer fijo a lo largo de las pruebas y su valor es 0,5. Las pruebas pretenden ser una orientacin de cara al usuario para un ajuste posterior del umbral de deteccin. Adems se reflejar en una tabla los resultados ms importantes de la prueba que son:

Duracin del anuncio: representa la duracin del anuncio utilizado para la prueba. Duracin de la prueba: el tiempo que ha estado la aplicacin detectando. Deteccin: se anotar en las tablas los valores del mximo de la correlacin cuando se detecte. Tambin se reflejar el nmero de detecciones. Nmero de correlaciones: representa el nmero de correlaciones que se han realizado a lo largo de la duracin de la prueba. No deteccin: se anotar el valor del mximo de la correlacin cuando no lo detecte. En el caso de detectarlo siempre se anotar el valor ms pequeo de ellos como reflejo de lo ms cercano al fallo en la deteccin. Falsa alarma: se anotarn el nmero de falsas alarmas ocurridas a lo largo del proceso. Adems se anotar el mayor de todos esos valores.

Se van a clasificar las pruebas como pruebas de FM y de TV, y dentro de estas se dividirn en pruebas correspondientes a anuncios grabados y detectados en la misma cadena y en las que la cadena es diferente.

4.4.3.1. PRUEBAS EN FM.


Apartado que contiene las tablas que reflejan los resultados de las pruebas realizadas en FM. Aunque se han realizado pruebas con anuncios

- 43 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

diferentes los resultados que se exponen corresponden a pruebas siempre con el mismo anuncio.

4.4.3.1.1. PRUEBAS EN MISMA CADENA. 4.4.3.1.1.1. 125 MSEG:

TABLA RESULTADO PRUEBAS (125 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 1272 DETECCIN: 0.719474 VALORES DETECTADOS 0.745797 0.838725 0.735068 0.644228 0.695858 0.785313 0.629237 0.555057 0.579072 NO DETECCIN: VALORES NO DETECTADOS FALSA ALARMA: TOTAL 0 VALOR MAYOR 0.418618 COMENTARIOS: Son unos resultados muy buenos. En una hora de grabacin no se ha obtenido ninguna falsa alarma. Esto no significa que no haya nunca falsas alarmas con estos parmetros, pero s es un reflejo de la baja probabilidad de error que tiene el proceso en este caso y que si aparece una falsa alarma esta se presentar con toda seguridad de forma aislada y con valores cercanos a 0,5.
Tabla 5: Prueba FM 125 mseg.

- 44 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.1.1.2. 100 MSEG:

TABLA RESULTADO PRUEBAS (100 MSEG) DURACIN PRUEBA (SEG.) 4800 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 2090 DETECCIN: 0.675718 VALORES DETECTADOS 0.50237 0.735822 0.541747 0.583228 0.611289 0.796734 0.678963 NO DETECCIN: 0.44814 VALORES NO DETECTADOS FALSA ALARMA: TOTAL 6 VALOR MAYOR 0.544701 COMENTARIOS: El nmero de falsas alarmas no es elevado. Hay que tener en cuenta que se han presentado de forma aislada y espordica en los 80 minutos de deteccin. Aunque los resultados no son tan buenos como los anteriores, pero el proceso sigue siendo factible con el umbral de 0,5.

Tabla 6: Prueba FM 100 mseg.

- 45 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.1.1.3. 90 MSEG:

TABLA RESULTADO PRUEBAS (90 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 27 segundos NMERO CORRELACIONES 1670 DETECCIN: 0.541926 VALORES DETECTADOS 0.694484 0.680579 0.617272 0.563161 0.794023 0.580843 0.657791 NO DETECCIN: 0.34585 VALORES NO DETECTADOS 0.30279 0.402349 0.487067 0.435318 FALSA ALARMA: TOTAL 1 VALOR MAYOR 0.545953 COMENTARIOS: Demasiados valores no detectados. Esto empieza a ser un comportamiento no deseado. Las falsas alarmas se quedan en una buena proporcin.

Tabla 7: Prueba FM 90 mseg.

- 46 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.1.1.4. 80 MSEG:

TABLA RESULTADO PRUEBAS (80 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 1832 DETECCIN: 0.79075 VALORES DETECTADOS 0.779303 0.730766 0.773051 0.574557 0.55876 0.514566 0.503984 NO DETECCIN: Todos los dems son no detectados. VALORES NO DETECTADOS En torno a 7 veces. FALSA ALARMA: TOTAL 10 VALOR MAYOR 0.554896 COMENTARIOS: Los resultados han empeorado considerablemente con respecto a los anteriores. Se tienen demasiadas falsas alarmas. Lo que es ms preocupante es la gran probabilidad de no deteccin.

Tabla 8: Prueba FM 80 mseg.

- 47 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.1.1.5. 75 MSEG:

TABLA RESULTADO PRUEBAS (75 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 1895 segundos NMERO CORRELACIONES 1956 DETECCIN: 0.546275 VALORES DETECTADOS 0.559874 NO DETECCIN: Todos los dems son no detectados. VALORES NO DETECTADOS En torno a 14 veces. FALSA ALARMA: TOTAL 2 VALOR MAYOR 0.566606 COMENTARIOS: Habra fallado en la deteccin alrededor de 14 veces, lo cual es demasiado. Debido a estos resultados se concluyen en este tiempo de muestreo las pruebas de FM en misma cadena.

Tabla 9: Prueba FM 75 mseg.

- 48 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.1.2. PRUEBAS CON DISTINTAS CADENAS.


Esta prueba consiste en hacer la grabacin del anuncio en una cadena y realizar el proceso de deteccin en una cadena diferente a la anterior con dicho anuncio. Se han realizado numerosas pruebas con diferentes anuncios, y en diferentes emisoras. En algunos casos las pruebas han sido ms satisfactorias que en otros, pero con un denominador comn y es el hecho de que la deteccin no es correcta en estos casos. Hay algunas veces que hace detecciones pero el decisor lo interpreta como falsas alarmas. Y adems las detecciones que realiza son en la mayora de las ocasiones cercanas a 0,5. Hay casos en los que ni lo detecta y si lo detecta se asemeja a una falsa alarma luego no nos valdra como deteccin correcta porque no seramos capaces de discernir entre una deteccin correcta y una falsa alarma. Debido a los resultados de estas pruebas se ha cambiado el diseo del proyecto ya que el funcionamiento en distintas cadenas era errneo. Lo que se ha hecho es asociar a cada anuncio una cadena de radio o TV (donde se grab) y el sistema se encarga de detectarlo en esa cadena. Entonces cuando se quiera detectar un anuncio en una cadena determinada simplemente hay que hacer una grabacin de la emisin del anuncio en esa cadena y emplearlo en la deteccin. Con ms de una cadena consistira en tener una grabacin del anuncio en cada una de las cadenas. Este problema es debido a ecualizaciones realizadas en las emisiones de FM que implica que la seal cambie lo suficiente como para que trabajando con tan pocas muestras sea irreconocible para el detector.

4.4.3.2. CASO TV.


Apartado que contiene las tablas con los resultados de las pruebas realizadas en TV.

- 49 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.2.1. PRUEBAS MISMAS CADENAS. 4.4.3.2.1.1. 125 MSEG.

TABLA RESULTADO PRUEBAS (125 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 27 segundos NMERO CORRELACIONES 1384 DETECCIN: 0.798555 VALORES DETECTADOS 0.751583 0.841755 0.776946 0.872686 0.794023 0.870426 0.809763 0.824234 0.859476 NO DETECCIN: VALORES NO DETECTADOS FALSA ALARMA: TOTAL 1 VALOR MAYOR 0.561273 COMENTARIOS: Se refleja un mejor comportamiento que en la prueba de FM, esto puede ser debido a que la calidad de la seal que llega por la antena de TV es mejor que la de FM. Viendo los resultados de las detecciones se observa que se podra subir un poco ms el umbral (tal vez a 0.55 o 0.6) y as disminuiramos la probabilidad de error sin que afecte demasiado a la probabilidad de deteccin.

Tabla 10: Prueba TV 125 mseg.

- 50 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.2.1.2. 100 MSEG.

TABLA RESULTADO PRUEBAS (100 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 1567 DETECCIN: 0.734606 VALORES DETECTADOS 0.878421 0.815686 0.855235 0.749646 0.863439 0.733144 0.850438 0.753155 0.813936 0.797073 0.85384 NO DETECCIN: VALORES NO DETECTADOS FALSA ALARMA: TOTAL 26 VALOR MAYOR 0.641732 COMENTARIOS: El nmero de falsas alarmas es ms elevado que en el caso de la radio. Se ha cambiado de anuncio con respecto a la prueba de 125 porque se ha dejado de emitir el anterior. Nos ha dado muchas falsas alarmas pero por el contrario nos da muy buenas propiedades de deteccin. Las falsas alarmas han aparecido de forma espordica y con valores cercanos a 0,5 con lo que son fcilmente descubiertas. Viendo los resultados de los valores detectados tal vez sea interesante subir un poco el umbral de deteccin para corregir as las falsas alarmas, ya que los valores detectados estn muy por encima del umbral (0,5).
Tabla 11: Prueba TV 100 mseg.

- 51 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.2.1.3. 90 MSEG.

TABLA RESULTADO PRUEBAS (90 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 1680 DETECCIN: 0.563848 VALORES DETECTADOS 0.797944 0.707956 0.813583 0.687222 0.777917 0.816483 0.631247 0.82167 0.711654 0.794637 0.769021 0.708772 0.763509 NO DETECCIN: VALORES NO DETECTADOS FALSA ALARMA: TOTAL 22 VALOR MAYOR 0.694682 COMENTARIOS: Sigue habiendo muchas falsas alarmas. Se refleja un comportamiento ms desfavorable que la prueba anterior debido a que los valores detectados son menores que en 100 mseg. y el mayor valor de falsa alarma encontrado es mayor que el de 100 mseg. En comparacin con su anlogo en FM ofrece mejores resultados ya que aunque tiene ms falsas alarmas pero la deteccin aporta resultados mucho ms favorables (no tiene ningn valor no detectado).
Tabla 12: Prueba TV 90 mseg.

- 52 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.2.1.4. 80 MSEG.

TABLA RESULTADO PRUEBAS (80 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 1832 DETECCIN: 0.789809 VALORES DETECTADOS 0.850341 0.745543 0.660441 0.711634 0.793488 0.75766 0.632259 0.732108 0.742045 0.557095 0.513547 0.669168 0.786232 0.701513 0.61781 NO DETECCIN: 0.470368 VALORES NO DETECTADOS FALSA ALARMA: TOTAL Alrededor de 50 VALOR MAYOR 0.670315 COMENTARIOS: Se tienen muchas falsas alarmas aunque se presentan de manera espordica. La deteccin sigue siendo buena aunque con valores muy pequeos y cercanos a los valores de las falsas alarmas.

Tabla 13: Prueba TV 80 mseg.

- 53 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.2.1.5. 75 MSEG.

TABLA RESULTADO PRUEBAS (75 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 1956 DETECCIN: 0.889612 VALORES DETECTADOS 0.894542 0.859036 0.891163 0.889624 0.938044 0.927093 0.890967 0.868901 0.827815 0.817964 0.926623 0.886618 0.898926 0.823316 NO DETECCIN: VALORES NO DETECTADOS FALSA ALARMA: TOTAL Alrededor de 100 VALOR MAYOR 0.739362 COMENTARIOS: El nmero de falsas alarmas es preocupante. An as el decisor las interpreta como falsas alarmas. Pero si se trabajara con ms anuncios habra problemas. Como los resultados de deteccin son muy altos hay que ir pensando en subir el umbral de deteccin.

Tabla 14: Prueba TV 75 mseg.

- 54 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.2.1.6. 70 MSEG.

TABLA RESULTADO PRUEBAS (70 MSEG) DURACIN PRUEBA (SEG.) 3600 segundos DURACIN ANUNCIO (SEG.) 28 segundos NMERO CORRELACIONES 2183 DETECCIN: 0.775853 VALORES DETECTADOS 0.873107 0.848691 0.68619 0.750697 0.586971 0.787503 0.729053 0.776796 0.694129 0.764154 0.682163 0.771405 0.765666 0.74415 0.645923 0.727603 NO DETECCIN: VALORES NO DETECTADOS FALSA ALARMA: TOTAL Alrededor de 150 VALOR MAYOR 0.739362 COMENTARIOS: Aunque la deteccin sigue siendo correcta, el nmero de falsas alarmas es muy grande, adems ha fallado incluso una vez con el decisor, lo que quiere decir que se han presentado una vez de forma contigua. Adems los valores de deteccin no son muy altos, con lo que no se solucionara el problema subiendo el umbral de deteccin. Debido a todas estas razones se finalizan aqu las pruebas realizadas con la TV.
Tabla 15: Prueba TV 70 mseg.

- 55 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

4.4.3.2.2. PRUEBAS DISTINTAS CADENAS.


Los resultados de estas pruebas son similares a los obtenidos en las pruebas de FM, siendo aplicable a este caso todo lo comentado en ese apartado (4.4.3.1.2.). La modulacin del audio en la televisin analgica es mediante FM, y por ello los resultados de estas pruebas eran esperados de antemano.

4.4.4. ELABORACIN DE CONCLUSIONES.


De las pruebas realizadas y cuyos resultados ms importantes se han expuesto en el apartado anterior se pueden obtener las siguientes conclusiones:

El comportamiento de la radio FM y de la TV son diferentes tal y como reflejan los resultados. En la radio se pararon las pruebas porque no se producan de correlacin cuando se emita el anuncio, en cambio en la TV debido al enorme nmero de falsas alarmas. Esto puede ser debido a la calidad de seal de cada una de las fuentes que llega a la tarjeta. Se han hecho pruebas con otros anuncios en FM para ver si la tendencia era la misma en cuanto a probabilidad de no deteccin, y se ha comprobado que se asemeja bastante a los resultados obtenidos en la TV donde se detectaban con grandes valores y tena ms falsas alarmas. Con lo que se concluye que si la seal de entrada es correcta (tanto FM como TV) y las grabaciones tambin, el patrn de resultados se asemeja mucho a los resultados aportados en las pruebas de TV. En las pruebas donde se reflejen valores muy altos (por ejemplo en TV con el anuncio de las pruebas anteriores) es recomendable subir el nivel del umbral por ejemplo a 0,6 ya que esto reducira considerablemente el nmero de falsas alarmas sin enmascarar las detecciones. Mientras sea posible siempre se recomienda usar la aplicacin con tiempo de captura 125 mseg. En ambos casos la deteccin en cadenas con anuncios obtenidos de otra diferente ha sido errnea. La grabacin del anuncio que forme parte del proceso de deteccin debe ser correcta, por ejemplo no debe incluir los silencios de detrs ni de delante. Es importante esto ya que esos silencios son una fuente de falsas alarmas. La forma del anuncio, si tiene o no muchos silencios, o por ejemplo una meloda de fondo, hace que tenga ms falsas alarmas o menos y de ah que la configuracin de los parmetros de la aplicacin

- 56 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

est pensada para hacerla cada usuario de modo particular a sus necesidades.

El anuncio usado en las pruebas de FM aportaba muy buenos resultados de falsas alarmas, ya que se han comprobado con otros anuncios que el nmero de falsas alarmas aumenta con respecto a lo que reflejan las pruebas, asemejndose bastante a las pruebas de TV. Con todo lo anterior se conluye que debido a que el patrn general es el que reflejan los resultados presentados en las pruebas de TV, la causa principal de no disminuir an ms el tiempo de captura es debido a las falsas alarmas y a que los valores obtenidos de falsas alarmas conforme vamos reduciendo los tiempos de captura se van asemejando a los valores de deteccin.

4.5. DECISOR.
La aplicacin muestra tanto en el dilogo principal como en el archivo todos los resultados que tengan un valor mximo mayor que el umbral de deteccin. A priori se desconoce si los resultados pertenecen a una falsa alarma o es una deteccin correcta. Ya se ha comentado que para discernir una falsa alarma de una deteccin correcta hay que utilizar ms informacin como puede ser el valor mximo del proceso de correlacin (no es lo mismo una deteccin por 0,55 que por 0,8), o el nmero de detecciones correlativas ya que las falsas alarmas se suelen presentar de forma aislada. Para entender como trabaja el decisor y cules son sus lmites hay que introducir algunos conceptos:

Nmero de detecciones posibles por anuncio: Es el nmero de pasadas que le da tiempo a hacer a la aplicacin en la duracin de un determinado anuncio. Para ello se calcula el tiempo de computacin del proceso total (apartado 4.4.1.) y dividimos por este la duracin de cada uno de los anuncios. El cociente nos da el nmero de detecciones posibles para cada anuncio.

Aplicacin trabajando al lmite de sus posibilidades:

- 57 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Es cuando el nmero de detecciones posibles para algn anuncio que forme parte del proceso de deteccin sea 1.

Ya se ha comentado y se ha reflejado en los resultados de las pruebas que las falsas alarmas aparecen normalmente de forma espordica, separadas entre s y con valores cercanos al umbral. Se va a emplear la informacin de que las falsas alarmas aparecen separadas entre s como criterio para diferenciar de algn modo una deteccin correcta de una falsa alarma. En esto se basa el decisor, y por eso no es recomendable tener la aplicacin funcionando al lmite de sus posibilidades ya que en ese determinado anuncio donde el nmero de detecciones posibles sea 1, no se puede usar la informacin de dos detecciones consecutivas porque solo se da una posible deteccin de ese determinado anuncio. En estos casos, cuando la aplicacin trabaje al lmite de sus posibilidades en algn anuncio, aquel anuncio no pasar por el algoritmo de decisin, solamente si el valor sale mayor que el umbral se apuntar en la lista y el archivo, pero ser tarea del usuario el comprobar el valor mximo de la correlacin en el fichero para determinar si ha sido una deteccin correcta o por el contrario una falsa alarma. Por esta razn se recomienda no usar la aplicacin al lmite de sus posibilidades ya que pierde mucha fiabilidad en la deteccin. El algoritmo del decisor se basa en la aparicin de forma aislada de las falsas alarmas para distinguir estas de las detecciones correctas. Hay que calcular para cada anuncio el nmero de detecciones posibles segn el caso. Si para algn anuncio este nmero de detecciones sale uno, entonces estaremos trabajando al lmite con ese anuncio y no se ejecutar sobre l el proceso de deteccin. La idea consiste en que al menos se pueda detectar el anuncio dos veces, as si tenemos dos consecutivas ser considerado una deteccin. La condicin que sigue es menos restrictiva y consiste en que se detecte la mitad de las veces posibles pero lo que pasa es que si las veces posibles son dos entonces estaramos en un caso similar al lmite y por eso en ese caso la condicin es mucho ms restrictiva. En el caso de que el decisor finalice el proceso con el resultado de deteccin correcta se escribir ANUNCIO DETECTADO, tanto en el dilogo principal como en el archivo de resultados.

- 58 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Una mejor descripcin del algoritmo de decisin se encuentra en el diagrama de flujo de la ilustracin 20:

DECISOR
SI

>umbral?
NO

Fallo=0 Detectado++ Anota_resultado

Fallo++ Condicion? Fallo=2?


SI SI

Fallo=0 Detectado=0

Fallo=0 Detectado=0 Anuncio Detectado

FIN

Ilustracin 20: Diagrama de flujo del decisor.

Parmetros del diagrama:

Umbral: valor con el que se compara el mximo del vector de correlacin. Fallo: variable que tiene cada anuncio (en la estructura archivo_wav) y que enumera el nmero de veces que el mximo del vector de correlacin es menor que el umbral. Detectado: variable que tiene cada anuncio y que enumera el nmero de veces que ha sido detectado (mximo mayor que el umbral). Condicin: se elabora una condicin que consiste en comprobar si el nmero de detecciones ha sido mayor que el nmero de detecciones

- 59 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

posibles de ese anuncio dividido entre dos (en el caso de que no salga entero se toma el entero superior ms cercano). Excepto en el caso en que el nmero de detecciones posible sea dos donde se compara con el nmero de detecciones posibles (2).

- 60 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CAPTULO 5: MANUAL DE USUARIO.


El desarrollo de la aplicacin tena como objetivo la rapidez y la eficacia computacional, pero en un segundo plano se ha diseado pensando en la facilidad de manejo por parte del usuario final. En este captulo vamos a hacer un manual para la utilizacin de la aplicacin, pero de antemano hago la observacin que para un control ms exhaustivo debera de ser un usuario capaz de desenvolverse en el Visual Studio ya que hay parmetros fijos que puede ser que en algn caso sea interesante cambiar. Como ya se ha descrito en numerosas ocasiones en el documento la aplicacin realiza dos tareas independientes que son la de deteccin y la de grabacin de tramas de audio.

5.1. INICIO DE LA APLICACIN.


Despus de la ejecucin aparecer una pantalla como la siguiente:

Ilustracin 21: Dilogo principal.

Esta es la pantalla principal de la aplicacin. Tal como se refleja en la ilustracin 21 tiene 4 botones, dos listas de datos, y un men. Comentaremos el men ms adelante en el apartado 5.2.

- 61 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

En la lista DISPOSITIVOS DE CAPTURA aparecen listados los dispositivos capturadores que estn presentes en el sistema. En el caso de que no aparezca aqu ninguno la causa podra ser de que la tarjeta capturadora no este instalada correctamente. En el caso de la ilustracin se ve en la lista dos elementos, el primero corresponde a la tarjeta interna de audio del PC y el segundo a la externa ya descrita en el captulo 2. Como se explic anteriormente la frecuencia de muestreo para los dos procesos era de 8 Khz., por lo tanto el dispositivo que se seleccione debe ser capaz de trabajar a dicha frecuencia. Como regla se recomienda seleccionar la tarjeta interna del PC ya que se ha comprobado que se tiene un mejor funcionamiento de la aplicacin porque se tiene ms control sobre ella. En el caso de la tarjeta usada para el desarrollo del proyecto no funcionaba correctamente a una frecuencia de muestreo de 8 Khz. En el caso de tener una tarjeta de TV (sin FM) debera de aparecer en la lista solamente la tarjeta interna de audio del PC aunque se han comprobado en otros sistemas que a veces aparece tambin el mdem (u otros dispositivos desconocidos), y se seleccionara la tarjeta de sonido. Una vez que se selecciona se pulsa el botn SELECCIONAR DISPOSITIVO y entonces de momento se debera de escuchar algo (aunque sea solo ruido) de no ser as pulsa el botn SALIR de la aplicacin. Entonces ejecuta el programa que viene incorporado con la tarjeta capturadora, en el caso de no encontrarlo comprueba si hay que instalarlo y tras esto lo ejecutas. Despus de ejecutarlo y comprobar que funciona correctamente cierra el programa y vuelve a ejecutar la aplicacin de deteccin.

5.2. MENU.
En este apartado se hace una descripcin del men incorporado al dilogo. Los elementos que lo conforman estarn disponibles segn convenga, es decir, que estarn habilitados los submens en funcin al estado en que se encuentre la aplicacin. Este tiene tres elementos como se ve en la ilustracin 20 que son: 5.2.1. Archivos.

- 62 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 22: Men Archivos.

Que consta de dos elementos a su vez tal como se refleja en la ilustracin 22: 5.2.1.1. Anuncios. Al seleccionar este elemento sale un dilogo donde se seleccionan los anuncios que queremos detectar (ilustracin 23). Cada anuncio va asociado a una frecuencia que es la frecuencia en la que se grab el anuncio y es en esta frecuencia donde se debe de usar para la deteccin en caso de que queramos un funcionamiento correcto de la aplicacin (tal y como se comprob en las pruebas realizadas en el apartado de la memoria 4.4.). Para ello se crea previamente una carpeta llamada ARCHIVOS dentro del directorio base donde est el ejecutable y ah tenemos que almacenar los archivos .wav que queremos como referencia para la deteccin. Se selecciona un archivo y se asocia a una frecuencia. Las frecuencias salen en un desplegable y se corresponden con las frecuencias introducidas en el fichero frecuencias.cfg. Tras seleccionarlo se pulsa en AADIR que provoca que el sistema almacene la informacin y adems borra de la lista de anuncios el anuncio escogido. Para terminar de elegir las frecuencias se pulsa en el botn SALIR.

- 63 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 23: Dilogo Archivos.

5.2.1.2. Salir. Cierra la aplicacin. Tiene el mismo efecto que el botn SALIR del dilogo principal. 5.2.2. Configurar. Este men tiene dos elementos tal como se refleja en la ilustracin 24. A continuacin se hace una descripcin ms detallada de ambos elementos.

Ilustracin 24: Men Configurar.

- 64 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

5.2.2.1. Sintonizador. Al seleccionar este elemento sale un cuadro de dilogo como el que refleja la ilustracin 25 y que sirve para sintonizar la cadena de radio o TV.

Ilustracin 25: Dilogo Sintonizador.

Su uso es para la tarea de grabacin debido a que en el caso de la deteccin la introduccin de las frecuencias con las que se trabajara ser a partir de un fichero como se explicar ms adelante. En este caso y al igual del dilogo explicado anteriormente se pulsa en ACEPTAR en el caso de que se quiera que se sintonice adecuadamente y en CANCELAR en caso contrario. Hay que introducir las frecuencias en Hz. en el caso de FM o el canal de TV en su defecto. El caso de introducir una cantidad no vlida est controlado por el sistema. Es un submen que estar disponible despus de seleccionar el dispositivo de captura. 5.2.2.2. Configuracin. Al seleccionar este elemento aparece un dilogo secundario como el que se muestra en la ilustracin 26.

- 65 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 26: Dilogo Configuracin.

Tal como refleja la ilustracin este dilogo sirve para cambiar el tipo de entrada FM/TV y adems los parmetros tiempo de captura y umbral. Tiene por defecto que se seleccione FM, 0.125 seg. para el tiempo de captura y 0.5 para el umbral de deteccin. El funcionamiento es semejante a los dilogos anteriores en cuanto al funcionamiento de los botones. Hay que tener en cuenta que si se quiere cambiar el tipo de entrada o el tiempo de captura hay que hacerlo antes de seleccionar el dispositivo. 5.2.3. Acerca De. Solo tiene un elemento que es VERSION y al seleccionarlo nos muestra el dilogo de informacin acerca del producto mostrado en la ilustracin 27.

- 66 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 27: Dilogo Versin.

5.3. GRABACIN.
Una vez seleccionado el dispositivo de captura tal y como se explic en el punto 5.1. se debe de sintonizar el sistema adecuadamente tal y como se explico en el men CONFIGURACIN. Tras esto se pulsa en el botn GRABAR y te sale un dilogo estndar de salvar un archivo en el entorno Windows (ilustracin 28). El directorio debe de ser ARCHIVOS en el directorio base de la aplicacin y no hay ninguna restriccin en cuanto al nombre del archivo. Una vez aceptado esto y si el dispositivo de captura que hemos seleccionado es adecuado, empezar la grabacin y para terminarla solo hay que pulsar el botn SALIR. Es muy probable que aparezca un error cuando se va a emplear la aplicacin para realizar una grabacin. Este error es debido a que se est usando el filtro WavDest en el grafo de grabacin y este filtro no est registrado en el sistema. La explicacin de cmo solucionar este problema se encuentra en el apartado 5 del anexo 1.

- 67 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 28: Dilogo guardar archivo .wav.

5.4. DETECCIN.
Al igual que en el proceso de grabacin hay que seleccionar el dispositivo de captura tal y como se ha descrito en el punto 5.1. La aplicacin utiliza un archivo llamado configuracin.cfg para conocer las cadenas a las que se quiere hacer el proceso de deteccin. Con lo que antes de hacer ninguna deteccin hay que rellenar ese archivo convenientemente. Para ello se abre el bloc de notas (o cualquier otro editor) y se escriben las cadenas deseadas una en cada lnea tal y como refleja la ilustracin 29. En el caso de ser cadenas de TV es del mismo modo.

Ilustracin 29: Muestra archivo frecuencias.cfg.

- 68 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Tras esto se guarda el archivo con nombre configuracin.cfg en el directorio base de la aplicacin. El sistema controla que las cadenas introducidas sean vlidas (en ambos casos tanto en FM como en TV). La ilustracin 29 refleja el caso de FM, pero el caso de TV es semejante pero utilizando los canales de TV. Ahora se seleccionan los anuncios que van a detectarse mediante el men ANUNCIOS dentro de ARCHIVO. Por ltimo se pulsa el botn DETECTAR. En el caso de pulsar el botn DETECTAR sin haber seleccionado ningn anuncio aparece el dilogo de seleccionar anuncios automticamente. Para parar la aplicacin se pulsa en SALIR. Los resultados de la deteccin se observan en la lista ANUNCIOS DETECTADOS donde aparece primero la hora, despus el anuncio y por ltimo la frecuencia a la que fue detectado (ilustracin 30). Es importante destacar que esto no tiene porque ser detecciones correctas, tambin pueden corresponderse a falsas alarmas, es el decisor (apartado 4.5 de la memoria) el que decidir si es una deteccin correcta y si es as apuntar tanto en la lista como en el fichero que el anuncio ha sido detectado, en la ilustracin 31 se refleja como resultara en el fichero de resultados (en la lista sera semejante).

Ilustracin 30: Muestra anuncio detectado.

- 69 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Ilustracin 31: Muestra fichero resultados.

Es posible de que aparezcan dos veces seguidas indicndonos ANUNCIO DETECTADO, pero es debido al algoritmo del decisor. Con que salga una es suficiente para interpretarlo como una deteccin correcta. Aunque no aparece la hora de la deteccin es la misma que la anterior entrada, que sera la de arriba en el caso del archivo y la de debajo en el caso de la lista en el dilogo principal. El fichero generado se llama resultado.txt y es donde se escriben los resultados. Este fichero no borra los resultados anteriores y en el caso de que la aplicacin no lo encuentre genera uno nuevo, por lo que una opcin para tener los resultados almacenados por das es al final del da quitar el fichero del directorio base de la aplicacin.

5.5. CONFIGURACIN DE PARMETROS.


En este apartado se resumen los conceptos desarrollados en toda la memoria, siendo imprescindible su lectura para conseguir un funcionamiento a medida de la aplicacin. Es conveniente haber ledo antes el captulo 4 de la memoria, en el que se fundamenta todo el proceso y te introduce en lo que sera la configuracin de los parmetros en la aplicacin. A continuacin se hace una descripcin sobre los pasos a seguir para la configuracin del sistema en el proceso de deteccin en cada caso particular. 1. AJUSTE CONFIGURACIN SONIDO: hay que configurar el sonido del ordenador personal de manera conveniente, hay que activar la

- 70 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

lnea de entrada pero no ajustarla al mximo ya que se distorsionara la captura de sonido. Adems es conveniente quitar el micrfono ya que puede ser que aumente el ruido de las grabaciones. Esto se refleja en la ilustracin 32:

Ilustracin 32: Configuracin sonido del sistema. 2. ELECCIN TIEMPO CAPTURA: como ya se ha comentado a lo largo de la memoria el tiempo de captura es un parmetro ntimamente ligado al tiempo de computacin y a la probabilidad de error del sistema. Lo ideal es que el tiempo de captura sea de 125 mseg. (que es el valor predeterminado), pero hay ocasiones en los que ese tiempo de captura no es factible debido a su gran tiempo de computacin. En estos casos habr que reducirlo hasta donde sea conveniente pero recordando siempre que esto afectar al correcto funcionamiento del sistema (tendr una probabilidad de error mayor). La comprobacin de que un tiempo de captura es factible para un determinado proceso se encuentra en el apartado tiempo de computacin (4.4.1.). 3. ELECCIN UMBRAL DE DETECCIN: despus de elegir el tiempo de captura se elige el umbral de deteccin que de manera predeterminada tiene el valor 0,5 y se puede optar por cambiarlo en caso que se crea necesario. Para cambiarlo de manera razonada se pueden observar las pruebas hechas en el apartado 4.4.3., tambin el usuario se puede guiar de su propia experiencia con la aplicacin. 4. INICIAR APLICACIN: ejecutar la aplicacin. Antes de empezar el proceso de deteccin hay que rellenar de manera adecuada (descrito en 5.4.) el fichero frecuencias.cfg.

- 71 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

5. COMENZAR DETECCIN: primero se configura el sistema con los parmetros adecuados segn el punto 2 y 3. Despus se selecciona el dispositivo de captura. Posteriormente se seleccionan los anuncios que van a formar parte del proceso y para terminar se pulsa en el botn DETECCIN. 6. ESTUDIO DE LOS RESULTADOS: Tras la ejecucin de la aplicacin llega lo ms importante que es la interpretacin de los resultados. Ya se ha comentado que hay una deteccin correcta cuando se apunta ANUNCIO DETECTADO tanto en la lista del dilogo como en el fichero. En el caso de trabajar en el lmite de las posibilidades de la aplicacin (concepto explicado en el apartado de decisor 4.5.) no se ejecutar el algoritmo de decisin con lo que para determinar si el pico de correlacin es una falsa alarma o es un valor detectado la nica informacin de la que disponemos es el resultado que ha dado la deteccin (solo aparece en el fichero) ya que si se acerca mucho al umbral no ser del todo fiable. Normalmente las falsas alarmas se presentan de forma aislada y con un resultado cercano al umbral. Con toda esta informacin el usuario podr interpretar de una forma ms correcta los resultados obtenidos por la aplicacin y adems podr aprender de ellos para una mejor configuracin del sistema para utilizaciones posteriores.

- 72 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CAPTULO 6: LNEAS FUTURAS DE INVESTIGACIN.


En este ltimo captulo de la memoria se exponen algunas de las posibles lneas de investigacin que pueden ampliar y mejorar el proyecto.

MEJORA EFICIENCIA COMPUTACIONAL:


La mejora en la eficiencia computacional es necesaria si se quiere que este proyecto aspire a cotas mayores. Esta mejora computacional consiste en el desarrollo de un algoritmo que desempee la misma labor que el presente pero que este menos cargado de operaciones, como puede ser la correlacin rpida basada en la FFT, ver [1]. De conseguir una mejora sustancial en el proceso permitira el uso de la aplicacin con un mayor nmero de cadenas y anuncios simultneamente con un tiempo de captura adecuado lo que resultar en un mejor comportamiento del sistema y una mejora sustancial de los resultados.

DESARROLLO COMPLETO DETECTOR ANUNCIOS TV.:

Desarrollar una aplicacin destinada a la deteccin de los anuncios de TV teniendo en cuenta tanto el audio como el video. Al tener en cuenta ambos factores se tiene mayor informacin de la seal capturada y esto conlleva una menor probabilidad de error en la deteccin.

- 73 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

ANEXO 1: POSIBLES PROBLEMAS DE LA APLICACIN.


Anexo que argumenta los posibles problemas que pueden surgir al utilizar la aplicacin y aporta soluciones a los mismos.

A1.1. INSTALACIN DE LIBRERAS:


Hay que tener instalada en el sistema las libreras DirectX 9.0a (o alguna superior). Las libreras se pueden conseguir de muchas formas. El software que viene con la tarjeta capturadora suele tenerlas. De no ser as se pueden descargar gratuitamente de Microsoft.

A1.2. LISTA DE ANUNCIOS CAPTURADOS VACA:


Si la lista de anuncios aparece vaca, y se tiene la constancia de tener almacenado algn anuncio, hay que comprobar que el directorio donde se almacenan los anuncios se llama ARCHIVOS, y se encuentra en el directorio base de la aplicacin (donde se encuentra el ejecutable). Adems los anuncios almacenados en este directorio deben ser de extensin .wav.

A1.3. PROBLEMAS CUANDO SE PULSA DETECTAR:


El problema ms frecuente est relacionado con el fichero frecuencias.cfg. Hay que asegurarse que existe en la aplicacin un fichero frecuencias.cfg y que se encuentre situado en el directorio base de la aplicacin (donde se encuentra el ejecutable de la aplicacin). Adems hay que introducir la informacin de los canales de manera adecuada tal y como se ha explicado en el apartado 5.4. de la memoria.

A1.4. NO SE ESCUCHA CUANDO SE SELECCIONA EL DISPOSITIVO:


Si la tarjeta capturadora est instalada convenientemente (con los controladores actualizados) y no se escucha nada en la aplicacin al ejecutarse, hay que instalar tambin el software que viene acompaando a la tarjeta. Tras la instalacin de ese software se vuelve a ejecutar la aplicacin, si se escucha

- 74 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

algo (aunque sea solo ruido) ya est solucionado, en el caso de que no se escuche nada se cierra la aplicacin y se ejecuta la aplicacin de radio que venga en dicho software. Si al ejecutarla no funcionara el fallo est en la instalacin o tal vez en la tarjeta capturadora. Si se comprueba que funciona se cierra y se vuelve a ejecutar la aplicacin de deteccin.

A1.5. PROBLEMAS CUANDO SE PULSA GRABAR:


La primera vez que se ejecuta la aplicacin y que su funcionamiento sea correcto si intentas grabar algo es muy probable que salga un error que no permita continuar. Este error es debido a que el grafo DirectShow utilizado para la grabacin contiene el filtro WAVDEST, y este filtro con las versiones DirectX actuales no se instala ni se registra en el sistema. La solucin est en registrar este filtro en el sistema (archivo WavDest.ax). Vamos a aportar 2 soluciones al problema:

1 SOLUCIN:

Una posible forma de realizar esto es con el entorno del Visual Studio. En el SDK viene el filtro WavDest como ejemplo, y para registrarlo tenemos que seguir los siguientes pasos: 1. Evidentemente tener instalado el SDK de DirectX y el Visual Studio. 2. Abrir el proyecto de Visual Studio correspondiente al ejemplo del filtro WavDest. En el caso de que la instalacin del SDK se haya dejado los directorios por defecto este se encuentra en:

C:\DX90SDK\Samples\C++\DirectShow\Filters\WavDest
En caso contrario la ruta ser la misma solo que aadiendo los directorios correspondientes despus de C:. (en el caso de no tener instalado el SDK, el proyecto de WavDest se encuentra ubicado dentro del CD del proyecto). 3. Hay que construir el fichero WavDest.ax y para ello se selecciona Rebuild All del men Build, dar un error porque no se ha construido todava la librera strembasd.lib. Para generar esta librera hay que abrir el proyecto de Visual Studio que se encuentra en el directorio:

- 75 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

C:\DX90SDK\Samples\C++\DirectShow\BaseClasses
Se selecciona Rebuild All, y as se genera la librera strembasd.lib, y una vez hecho esto ya se puede generar el fichero WavDest.ax. 4. Hay que registrarlo y para ello se selecciona Register Control del men Tools.

2 SOLUCIN: Registrar el filtro mediante la aplicacin Regsvr32. Pasos:

1. Abrir el men ejecutar de la barra de inicio. 2. Ejecutar la aplicacin Regsvr32 seguida de la ruta completa del archivo wavdest.ax, en el caso de que se copie la carpeta WavDest directamente en el directorio raiz la ejecucin sera semejante a: Regsvr32 C:\WavDest\Debug_Unicode\wavdest.ax 3. En el caso de que el registro del filtro sea correcto aparecer una pantalla semejante a la de la ilustracin 33 :

Ilustracin 33: Mensaje de registro correcto.

NOTA: En las dos opciones es necesario tener instalado el Visual Studio. Adems se ha comprobado que el correcto funcionamiento del filtro es mientras el Visual Studio permanece instalado en el sistema.

- 76 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

A1.6. NO SE ENCUENTRA EL ANUNCIO PILOTO.


La aplicacin al hacer el algoritmo de deteccin, concretamente al implementar el decisor necesita de una medida del tiempo de computacin del ordenador en el que se est ejecutando. Para ello se realiza un proceso de correlacin con un anuncio de referencia. Este anuncio se denomina anuncio_piloto.wav y tiene 225000 muestras (cada muestra un byte). Este debe de encontrarse dentro de la carpeta ARCHIVOS que se encuentra ubicada en el directorio base de la aplicacin. De no encontrar el archivo se muestra el mensaje de error que muestra la ilustracin 34.

Ilustracin 34: Mensaje de error anuncio piloto.

- 77 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

ANEXO 2: FORMATO DE LOS FICHEROS WAV.


El formato WAV es uno de los formatos de fichero ms utilizados para almacenar sonidos. Se trata de almacenar las muestras una tras otra (a continuacin de la cabecera del fichero, que entre otras cosas indica la frecuencia de muestreo), sin ningn tipo de compresin de datos, con cuantificacin uniforme. La sencillez de este formato lo hace ideal para el tratamiento digital del sonido. La cabecera puede discernir segn que aplicacin se escoja para la formacin del fichero .WAV, pero lo importante al menos en nuestro caso es que los datos van siempre detrs de data y Nmero de bytes muestreados, y en esto se basa la rutina leewav desarrollada, en buscar en el fichero la palabra data. Formato de los ficheros .WAV
Bytes 00-03 04-07 08-11 12-15 16-19 20-21 22-23 24-27 28-31 32-33 34-35 36-39 40-43 resto Contenido Usual "RIFF" ??? "WAVE" "fmt " 16, 0, 0, 0 1, 0 1, 0 ??? ??? 1, 0 8, 0 "data" ??? ??? Propsito/Descripcin Bloque de identificacin (sin comillas). Entero largo. Tamao del fichero en bytes, incluyendo cabecera. Otro identificador. Otro identificador Tamao de la cabecera hasta este punto. Etiqueta de formato. (Algo as como la versin del tipo de formato utilizado). Nmero de canales (2 si es estreo). Frecuencia de muestreo (muestras/segundo). Nmero medio de bytes/segundo. Alineamiento de bloque. Nmero de Bits por muestra (normalmente 8, 16 32). Marcador que indica el comienzo de los datos de las muestras. Nmero de bytes muestreados. Muestras (cuantificacin uniforme) Tabla 16: Formato de los ficheros .WAV.

Los datos numricos que ocupan ms de un byte se representan de la siguiente forma: Primero estn los bytes menos significativos, y a continuacin los ms significativos.

- 78 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

ANEXO 3: CDIGO FUENTE.


A3.1. Clase CRadioApp
Radio.h
// Radio.h : main header file for the RADIO application // #if !defined(AFX_RADIO_H__8975FB44_119A_45F1_8728_697743F5B053__INCLUDED_) #define AFX_RADIO_H__8975FB44_119A_45F1_8728_697743F5B053__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif #include "resource.h" // main symbols

///////////////////////////////////////////////////////////////////////////// // CRadioApp: // See Radio.cpp for the implementation of this class // class CRadioApp : public CWinApp { public: CRadioApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CRadioApp) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL // Implementation //{{AFX_MSG(CRadioApp) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_RADIO_H__8975FB44_119A_45F1_8728_697743F5B053__INCLUDED_)

- 79 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Radio.cpp
// Radio.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "Radio.h" #include "RadioDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CRadioApp BEGIN_MESSAGE_MAP(CRadioApp, CWinApp) //{{AFX_MSG_MAP(CRadioApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRadioApp construction CRadioApp::CRadioApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CRadioApp object CRadioApp theApp; ///////////////////////////////////////////////////////////////////////////// // CRadioApp initialization BOOL CRadioApp::InitInstance() { AfxEnableControlContainer(); // // // // Standard initialization If you are not using these features and wish to reduce the size of your final executable, you should remove from the following the specific initialization routines you do not need. // Call this when using MFC in a shared DLL // Call this when linking to MFC statically

#ifdef _AFXDLL Enable3dControls(); #else Enable3dControlsStatic(); #endif

- 80 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CRadioDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE;

- 81 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

A3.2. Clase CRadioDlg


RadioDlg.h
// RadioDlg.h : header file // #if !defined(AFX_RADIODLG_H__3B0CEA02_43B6_4949_9DD7_0909CF92726C__INCLUDED_) #define AFX_RADIODLG_H__3B0CEA02_43B6_4949_9DD7_0909CF92726C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000

#include #include #include #include #include #include #include

"Dshow.h" "Dialosint.h" "Archivos.h" "Configuracion.h" "Qedit.h" <fstream.h> "ButtonST.h"

static const GUID CLSID_WavDest = { 0x3c78b8e2, 0x6c4d, 0x11d1, { 0xad, 0xe2, 0x0, 0x0, 0xf8, 0x75, 0x4b, 0x99 } }; ///////////////////////////////////////////////////////////////////////////// // CRadioDlg dialog struct archivo_wav { float *archivo; double *energia; int detectado; int fallo; int N1; long frecuencia; CString anuncio; int posibles_detecciones; }; class CRadioDlg : public CDialog { // Construction public: CRadioDlg(CWnd* pParent = NULL); // Dialog Data //{{AFX_DATA(CRadioDlg) enum { IDD = IDD_RADIO_DIALOG }; CListBox m_anuncio; CButtonST m_grabar; CButtonST m_deteccion; CButtonST m_salir;

// standard constructor

- 82 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL CListBox m_ListaCaptura; CString m_status; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CRadioDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CRadioDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnSalir(); afx_msg void OnHelpVersin(); afx_msg void OnSeldisp(); afx_msg void OnDeteccion(); afx_msg void OnGrabaradio(); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnConfigurarSintonizador(); afx_msg void OnArchivosAnuncios(); afx_msg void OnArchivosSalir(); afx_msg void OnConfiguracion(); //}}AFX_MSG DECLARE_MESSAGE_MAP() protected: void UtilDeleteMediaType(AM_MEDIA_TYPE *pmt); HRESULT SetAudioProperties(int nChannels,int nBytesPerSample,int nFrequency, float tiempo_captura); void iniciacaptura(); void iniciasintonizacion(); void AddFilterToListWithMoniker(const TCHAR *szFilterName,IMoniker *pMoniker, CListBox& ListFilters); HRESULT EnumFiltersAndMonikersToList(IEnumMoniker *pEnumCat, CListBox& ListFilters); HRESULT EnumFiltersWithMonikerToList(ICreateDevEnum *pSysDevEnum, const GUID *clsid, CListBox& List); HRESULT GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin); void conecta(IBaseFilter * filtro1,IBaseFilter * filtro2); float *leewav(int *N1,CString nombre); void lectura_anuncios(); void lectura_frecuencias(); void lectura_canales_tv(); double calculo_energia(float *muestras,int longitud); void correlacion(archivo_wav *anuncio,float *data2,int N2,double energia2); void decisor(archivo_wav *anuncio,double maximo); double *calcula_vector_energia(float *data1,int N1); void anota_resultado(archivo_wav *anuncio,double maximo);

// DDX/DDV support

- 83 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL int calcula_posibles_detecciones(int N1); void calcula_frecuencias_correlacion(); void prueba_piloto(); public: void cambia_canal(long canal); CConfiguracion configuracion; CDialosint dialogo2; CArchivos dialogo_archivo; long *frecuencias; long *frecuencias_correlacion; private:

}; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_RADIODLG_H__3B0CEA02_43B6_4949_9DD7_0909CF92726C__INCLUDED_)

- 84 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

CRadioDlg.cpp
// RadioDlg.cpp : implementation file // #include #include #include #include #include #include #include "Dshow.h" "stdafx.h" "Radio.h" "RadioDlg.h" <math.h> "time.h" <atlbase.h>

#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define SAFE_RELEASE(i) {if (i) {i->Release(); i = NULL;}} ///////////////////////////////////////////////////////////////////////////// // ESTRUCTURA DE DATOS struct _capstuff { ICaptureGraphBuilder2 *pBuilder; IAMCrossbar *pBar; IGraphBuilder *pFg; IMoniker *pMoniker; IAMTVTuner * pradio; IBaseFilter * pSrc, *pGrabberf, *pnull, *pWAVDest, *pWriter; ISampleGrabber * pGrabber; IMediaControl *pControl; IFileSinkFilter2 *pFileSink; }gcap;

///////////////////////////////////////////////////////////////////////////// // VARIABLES HRESULT hr; AM_MEDIA_TYPE *pmt; char *pBuffer; int N1; long N2; clock_t time1,time2; archivo_wav *tabla_anuncios; int freq; long frecuencia_anterior;

- 85 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL double tiempo_procesado_total; CMenu *Menu; CTime actual; fstream fichero_resultado;

///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP()

// DDX/DDV support

/////////////////////////////////////////////////////////////////////////////

- 86 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL // CRadioDlg dialog CRadioDlg::CRadioDlg(CWnd* pParent /*=NULL*/) : CDialog(CRadioDlg::IDD, pParent) { //{{AFX_DATA_INIT(CRadioDlg) m_status = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CRadioDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CRadioDlg) DDX_Control(pDX, IDC_LIST2, m_anuncio); DDX_Control(pDX, IDC_GRABARADIO, m_grabar); DDX_Control(pDX, IDC_DETECCION, m_deteccion); DDX_Control(pDX, IDC_SALIR, m_salir); DDX_Control(pDX, IDC_LISTACAPTURA, m_ListaCaptura); DDX_Text(pDX, IDC_STATUS, m_status); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CRadioDlg, CDialog) //{{AFX_MSG_MAP(CRadioDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_SALIR, OnSalir) ON_COMMAND(ID_HELP_VERSIN, OnHelpVersin) ON_BN_CLICKED(IDC_SELDISP, OnSeldisp) ON_BN_CLICKED(IDC_DETECCION, OnDeteccion) ON_BN_CLICKED(IDC_GRABARADIO, OnGrabaradio) ON_WM_TIMER() ON_COMMAND(ID_CONFIGURAR_SINTONIZADOR, OnConfigurarSintonizador) ON_COMMAND(ID_ARCHIVOS_ANUNCIOS, OnArchivosAnuncios) ON_COMMAND(ID_ARCHIVOS_SALIR, OnArchivosSalir) ON_COMMAND(ID_CONFIGURACION, OnConfiguracion) //}}AFX_MSG_MAP END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////// // CRadioDlg message handlers BOOL CRadioDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu.

- 87 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here Menu=GetMenu(); // Pongo los iconos pertinentes m_salir.SetIcon(IDI_EXIT); m_deteccion.SetIcon(IDI_ICON1); m_grabar.SetIcon(IDI_ICON2); m_salir.SetBtnCursor(IDC_CURSOR1); m_deteccion.SetBtnCursor(IDC_CURSOR1); m_grabar.SetBtnCursor(IDC_CURSOR1); // Habilito y deshabilito los botones correspondientes GetDlgItem(IDC_SELDISP)->EnableWindow(TRUE); GetDlgItem(IDC_DETECCION)->EnableWindow(FALSE); GetDlgItem(IDC_GRABARADIO)->EnableWindow(FALSE); // Deshabilito los menus adecuados EnableMenuItem(*Menu,ID_CONFIGURAR_SINTONIZADOR,MF_DISABLED||MF_GRAYED); EnableMenuItem(*Menu,ID_ARCHIVOS_ANUNCIOS,MF_DISABLED||MF_GRAYED); // Relleno la lista de captura e inicio el grafo iniciacaptura();

- 88 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL // Inicializo algunas variables freq=0; dialogo_archivo.seleccion=0; m_status=""; //doy valor por defecto al tiempo decaptura y al umbral configuracion.m_tiempo_captura=0.125; configuracion.m_umbral=0.5; //pongo por defecto la deteccin en FM. configuracion.m_fm=0;

//inicializo archivo de resultados CString auxiliar; actual=CTime::GetCurrentTime(); auxiliar="Inicializando aplicacion .... "+actual.Format( "%d-%m-%Y" )+"\n"; fichero_resultado.open("resultado.txt",ios::out | ios::app ); fichero_resultado << auxiliar; return TRUE; // return TRUE unless you set the focus to a control } void CRadioDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.

- 89 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL void CRadioDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon);

} else { } }

CDialog::OnPaint();

// The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CRadioDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } ////////////////////////////////////////////////////////////////////// void CRadioDlg::OnSalir() { // TODO: Add your control notification handler code here fichero_resultado.close(); gcap.pControl->Stop(); //liberamos la memoria reservada SAFE_RELEASE(gcap.pBuilder); SAFE_RELEASE(gcap.pFg); SAFE_RELEASE(gcap.pMoniker); SAFE_RELEASE(gcap.pSrc); SAFE_RELEASE(gcap.pradio); SAFE_RELEASE(gcap.pControl); SAFE_RELEASE(gcap.pWAVDest); SAFE_RELEASE(gcap.pWriter);

- 90 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL SAFE_RELEASE(gcap.pFileSink); SAFE_RELEASE(gcap.pGrabber); SAFE_RELEASE(gcap.pGrabberf); SAFE_RELEASE(gcap.pnull); SAFE_RELEASE(gcap.pBar); UtilDeleteMediaType(pmt); m_ListaCaptura.ResetContent(); // delete [] dialogo.frecuencias; Menu->DestroyMenu(); CoUninitialize(); delete [] tabla_anuncios; OnOK(); }

////////////////////////////////////////////////////////////////////// HRESULT CRadioDlg::EnumFiltersWithMonikerToList(ICreateDevEnum *pSysDevEnum, const GUID *clsid, CListBox& List) { HRESULT hr; IEnumMoniker *pEnumCat = NULL; // Se instancia el enumerador de dispositivos de sistema si este no existe if (pSysDevEnum == NULL) { hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&pSysDevEnum); if FAILED(hr) return hr; } // Se enumeran todos los filtros de la categora seleccionada hr = pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); if (SUCCEEDED(hr)) { hr = EnumFiltersAndMonikersToList(pEnumCat, List); pEnumCat->Release(); } pSysDevEnum->Release(); return hr;

- 91 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

////////////////////////////////////////////////////////////////////// HRESULT CRadioDlg::EnumFiltersAndMonikersToList(IEnumMoniker *pEnumCat, CListBox& ListFilters) { HRESULT hr=S_OK; IMoniker *pMoniker=0; ULONG cFetched=0; VARIANT varName={0}; int nFilters=0; // En el caso de que no haya filtros de ese tipo se muestra <<No entries>> if (!pEnumCat) { ListFilters.AddString(TEXT("<< No entries >>\0")); return S_FALSE; } // Enumerate all items associated with the moniker while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) { IPropertyBag *pPropBag; ASSERT(pMoniker); hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); ASSERT(SUCCEEDED(hr)); ASSERT(pPropBag); if (FAILED(hr)) continue; // Se lee el nombre del filtro del property bag varName.vt = VT_BSTR; hr = pPropBag->Read(L"FriendlyName", &varName, 0); if (FAILED(hr)) continue; // Se convierte de BSTR name a CString CString str(varName.bstrVal); SysFreeString(varName.bstrVal); nFilters++; // Se aaden el nombre del filtro al ListBox AddFilterToListWithMoniker(str, pMoniker, ListFilters); pPropBag->Release(); // No se libera el IMoniker para poder usarlo despues } } return hr;

- 92 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL ////////////////////////////////////////////////////////////////////// void CRadioDlg::AddFilterToListWithMoniker(const TCHAR *szFilterName, IMoniker *pMoniker, CListBox& ListFilters) { if (!szFilterName) return; int nSuccess = ListFilters.AddString(szFilterName); int nIndexNew = ListFilters.FindStringExact(-1, szFilterName); } nSuccess = ListFilters.SetItemDataPtr(nIndexNew, pMoniker);

////////////////////////////////////////////////////////////////////// void CRadioDlg::iniciacaptura() { // pongo el cdigo necesario para empezar CoInitialize(NULL);

// Create the Filter Graph Manager. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&gcap.pFg); // Create the Capture Graph Builder. hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2, (void **)&gcap.pBuilder); // Associate the graph with the builder. gcap.pBuilder->SetFiltergraph(gcap.pFg);

hr = gcap.pFg->QueryInterface(IID_IMediaControl, (void **)&gcap.pControl); EnumFiltersWithMonikerToList(NULL,&CLSID_AudioInputDeviceCategory,m_ListaCaptura); }

////////////////////////////////////////////////////////////////////// HRESULT CRadioDlg::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)

- 93 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL {

IEnumPins *pEnum = NULL; IPin *pPin = NULL; HRESULT hr; hr = pFilter->EnumPins(&pEnum); if (FAILED(hr)) { return hr; } while(pEnum->Next(1, &pPin, 0) == S_OK) { PIN_DIRECTION PinDirThis; hr = pPin->QueryDirection(&PinDirThis); if (FAILED(hr)) { pPin->Release(); pEnum->Release(); return hr; } if (PinDir == PinDirThis) { // Devuelve un puntero a IPin por referencia. *ppPin = pPin; pEnum->Release(); return S_OK; } pPin->Release(); } // Si no encontramos ningn pin. pEnum->Release(); return E_FAIL;

} ////////////////////////////////////////////////////////////////////// void CRadioDlg::conecta(IBaseFilter * filtro1,IBaseFilter * filtro2) { //para conectar con la funcion connect de IGraphBuilder necesito //los pins a conectar IPin * pinprueba1, * pinprueba2; GetPin(filtro1,PINDIR_OUTPUT,&pinprueba1); GetPin(filtro2,PINDIR_INPUT,&pinprueba2); gcap.pFg->Connect(pinprueba1,pinprueba2); (pinprueba1)->Release(); (pinprueba2)->Release(); }

- 94 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

////////////////////////////////////////////////////////////////////// //funcin que prepara toda la caracterstica del audio. HRESULT CRadioDlg::SetAudioProperties(int nChannels,int nBytesPerSample,int nFrequency,float Tiempo_captura) { HRESULT hr=0; IPin *pPin=0; IAMBufferNegotiation *pNeg=0; IAMStreamConfig *pCfg=0; // Calcula el nmero de bytes por segundo. long lBytesPerSecond = (long) (nBytesPerSample * nFrequency * nChannels); // Pone el tamao del buffer de trabajo long lBufferSize = (long) ((float) lBytesPerSecond * Tiempo_captura); // Obtengo el pin de salida del dispoditivo de captura hr = GetPin(gcap.pSrc, PINDIR_OUTPUT, &pPin); if (SUCCEEDED(hr)) { // Intento de encontrar el interface IAMBufferNegotiation hr = pPin->QueryInterface(IID_IAMBufferNegotiation, (void **)&pNeg); if (FAILED(hr)) { pPin->Release(); } else { // Pongo las propiedades adecuadas ALLOCATOR_PROPERTIES prop={0}; prop.cbBuffer = lBufferSize; prop.cBuffers = 6; prop.cbAlign = nBytesPerSample * nChannels; hr = pNeg->SuggestAllocatorProperties(&prop); pNeg->Release(); } // Configuracin de audio deseada if (FAILED(hr)) { hr = pPin->QueryInterface(IID_IAMStreamConfig, (void **)&pCfg);

pPin->Release();

- 95 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

else {

hr = pCfg->GetFormat(&pmt); if (SUCCEEDED(hr)) { //Rellenamos con los valores deseados WAVEFORMATEX *pWF = (WAVEFORMATEX *) pmt->pbFormat; pWF->nChannels = (WORD) nChannels; pWF->nSamplesPerSec = nFrequency; pWF->nAvgBytesPerSec = lBytesPerSecond; pWF->wBitsPerSample = (WORD) (nBytesPerSample * 8); pWF->nBlockAlign = (WORD) (nBytesPerSample * nChannels); hr = pCfg->SetFormat(pmt); } // liberamos interfaces pCfg->Release(); pPin->Release();

} } return hr; }

////////////////////////////////////////////////////////////////////// void CRadioDlg::OnHelpVersin() { // TODO: Add your command handler code here CAboutDlg version; version.DoModal(); } //////////////////////////////////////////////////////////////////////

void CRadioDlg::OnSeldisp() {

- 96 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

// TODO: Add your control notification handler code here int nItem=m_ListaCaptura.GetCurSel(); if (nItem== LB_ERR) { MessageBox("Seleccionar dispositivo"); } else { gcap.pMoniker= (IMoniker *) m_ListaCaptura.GetItemDataPtr(nItem); ((gcap.pMoniker))->BindToObject(0,0, IID_IBaseFilter, (void**)&gcap.pSrc); // pSrc es el filtro de captura gcap.pFg->AddFilter(gcap.pSrc, L"Audio Capture"); // Configuramos las propiedades de audio deseadas SetAudioProperties(1,1,8000,configuracion.m_tiempo_captura); // Encontrar la sintonizacin iniciasintonizacion();

// Habilito y deshabilito los botones adecuados GetDlgItem(IDC_LISTACAPTURA)->EnableWindow(FALSE); GetDlgItem(IDC_SELDISP)->EnableWindow(FALSE); GetDlgItem(IDC_DETECCION)->EnableWindow(TRUE); GetDlgItem(IDC_GRABARADIO)->EnableWindow(TRUE); // Habilito los menus adecuados EnableMenuItem(*Menu,ID_ARCHIVOS_ANUNCIOS,MF_ENABLED); EnableMenuItem(*Menu,ID_CONFIGURAR_SINTONIZADOR,MF_ENABLED); EnableMenuItem(*Menu,ID_CONFIGURACION,MF_DISABLED||MF_GRAYED); gcap.pControl->Run(); } }

- 97 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL ////////////////////////////////////////////////////////////////////// void CRadioDlg::iniciasintonizacion() { //me parece que para encontrar el filtro voy //a necesitar crear momentaneamente un filtro //de captura de video ICreateDevEnum * pDevEnum; IEnumMoniker * pClassEnum; IMoniker * pmVideo; IBaseFilter * pSrc; CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&pDevEnum);

pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0); ULONG cFetched;

if (pClassEnum->Next(1, &pmVideo, &cFetched) == S_OK) {

((pmVideo))->BindToObject(0,0, IID_IBaseFilter, (void**)&pSrc); gcap.pFg->AddFilter(pSrc, L"Video Capture"); hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, pSrc, IID_IAMTVTuner, (void **)&gcap.pradio); if(hr != S_OK) { hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSrc, IID_IAMTVTuner, (void **)&gcap.pradio); } // Con la interfaz IAMCrossbar nos aseguramos el funcionamiento correcto. hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video, pSrc,IID_IAMCrossbar, (void**)&gcap.pBar); if (SUCCEEDED(hr))

- 98 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL { IBaseFilter *pFilter = NULL; hr = gcap.pBar->QueryInterface(IID_IBaseFilter, (void**)&pFilter); if (SUCCEEDED(hr)) { gcap.pBar->Route (1,3); } } } else { //si no lo intento con el filtro de captura de audio. hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, gcap.pSrc, IID_IAMTVTuner, (void **)&gcap.pradio); if(hr != S_OK) { hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, gcap.pSrc, IID_IAMTVTuner, (void **)&gcap.pradio); } hr = gcap.pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video, gcap.pSrc,IID_IAMCrossbar, (void**)&gcap.pBar); if (SUCCEEDED(hr)) { IBaseFilter *pFilter = NULL; hr = gcap.pBar->QueryInterface(IID_IBaseFilter, (void**)&pFilter); if (SUCCEEDED(hr)) { gcap.pBar->Route (1,3); } } } if(hr==S_OK) { // COMPRUEBO SI EST EN MODO RADIO O MODO T.V. if(configuracion.m_fm==0) { gcap.pradio->put_Mode(AMTUNER_MODE_FM_RADIO );

- 99 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

hr = gcap.pradio->put_InputType(0,TunerInputAntenna); // hago la lectura de las frecuencias que vienen en el // fichero frecuencias.cfg lectura_frecuencias(); // sintonizo la primera de las escritas gcap.pradio->put_Channel(frecuencias[0],0,0); dialogo_archivo.freq=frecuencias; } else { gcap.pradio->put_Mode(AMTUNER_MODE_TV ); hr = gcap.pradio->put_InputType(0,TunerInputAntenna); // hago la lectura de los canales de TV que vienen en el // fichero frecuencias.cfg lectura_canales_tv(); gcap.pradio->put_Channel(frecuencias[0],0,0); dialogo_archivo.freq=frecuencias; } } else { } //libero aqui pero no se si me va a dar problemas //porque gcap.pradio esta asociado a pSrc SAFE_RELEASE(pDevEnum); SAFE_RELEASE(pClassEnum); SAFE_RELEASE(pmVideo); SAFE_RELEASE(pSrc); MessageBox("No se encontr el dispositivo sintonizador en el sistema"); GetDlgItem(IDC_DETECCION)->EnableWindow(FALSE);

////////////////////////////////////////////////////////////////////// // Para liberar correctamente las estructuras de tipo AM_MEDIA_TYPE

- 100 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL void CRadioDlg::UtilDeleteMediaType(AM_MEDIA_TYPE *pmt) { if (pmt == NULL) { return; } if (pmt->cbFormat != 0) { CoTaskMemFree((PVOID)pmt->pbFormat); pmt->cbFormat = 0; pmt->pbFormat = NULL;

if (pmt->pUnk != NULL) { pmt->pUnk->Release(); pmt->pUnk = NULL; } } CoTaskMemFree((PVOID)pmt);

////////////////////////////////////////////////////////////////////// void CRadioDlg::OnDeteccion() { // TODO: Add your control notification handler code here // Deshabilito los botones correspondientes GetDlgItem(IDC_DETECCION)->EnableWindow(FALSE); GetDlgItem(IDC_GRABARADIO)->EnableWindow(FALSE); // Deshabilito los menus adecuados EnableMenuItem(*Menu,ID_CONFIGURAR_SINTONIZADOR,MF_DISABLED||MF_GRAYED); EnableMenuItem(*Menu,ID_ARCHIVOS_ANUNCIOS,MF_DISABLED||MF_GRAYED); gcap.pControl->Stop(); hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&gcap.pGrabberf); hr = gcap.pFg->AddFilter(gcap.pGrabberf, L"Sample Grabber");

- 101 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL //Ahora a compartir el interfaz gcap.pGrabberf->QueryInterface(IID_ISampleGrabber, (void**)&gcap.pGrabber); //Configuramos adecuadamente el tipo de dato que va a llegar //para asegurarnos de que no haya problemas gcap.pGrabber->SetMediaType(pmt);

//para activar el modo buffer se llama a SetBufferSamples hr = gcap.pGrabber->SetOneShot(FALSE); hr = gcap.pGrabber->SetBufferSamples(TRUE); //Falta el filtro Null Renderer //Primero creo el filtro hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&gcap.pnull); hr = gcap.pFg->AddFilter(gcap.pnull, L"Null Renderer"); //los conectamos conecta(gcap.pSrc,gcap.pGrabberf); conecta(gcap.pGrabberf,gcap.pnull); //Empieza a funcionar el grafo hr = gcap.pControl->Run();

m_status="detectando ..."; UpdateData(FALSE); Sleep(300); gcap.pGrabber->GetCurrentBuffer(&N2,NULL); // Se hace una prueba piloto para ver cuanto tarda en // hacer el proceso de correlacin prueba_piloto(); // Se pone la primera de las frecuencias y se inicializa

- 102 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL // la variable frecuencia_anterior. gcap.pControl->Stop(); //leemos los anuncios y calculamos sus energias lectura_anuncios(); calcula_frecuencias_correlacion(); cambia_canal(frecuencias_correlacion[freq]); frecuencia_anterior=frecuencias_correlacion[freq]; freq++; gcap.pControl->Run(); SetTimer(ID_TIMER,300,NULL); } ////////////////////////////////////////////////////////////////////// void CRadioDlg::OnGrabaradio() { // TODO: Add your control notification handler code here // Para poner el nombre del archivo // Abro un dilogo para poner el nombre requerido CFileDialog dialogo_archivo(FALSE,"wav"); if (dialogo_archivo.DoModal()==IDOK) { // Primero hay que parar el grafo gcap.pControl->Stop(); // Deshabilito los botones adecuados GetDlgItem(IDC_DETECCION)->EnableWindow(FALSE); GetDlgItem(IDC_GRABARADIO)->EnableWindow(FALSE); // Deshabilito los mens adecuados EnableMenuItem(*Menu,ID_CONFIGURAR_SINTONIZADOR,MF_DISABLED||MF_GRAYED); EnableMenuItem(*Menu,ID_ARCHIVOS_ANUNCIOS,MF_DISABLED||MF_GRAYED);

- 103 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

// Creo el filtro WAVDest // Nota el filtro WAVDest tiene que esta registrado en el sistema // Instrucciones de como hacerlo en la memoria hr = CoCreateInstance(CLSID_WavDest, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&gcap.pWAVDest); // Aado el filtro WAVDest al grafo hr = gcap.pFg->AddFilter(gcap.pWAVDest, L"WAV Dest"); // Creo el filtro que representa la escritura hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void **)&gcap.pWriter); gcap.pWriter->QueryInterface(IID_IFileSinkFilter2, (void**)&gcap.pFileSink); gcap.pFileSink->SetMode(AM_FILE_OVERWRITE);

// Las lneas siguientes son para cambiar el tipo de CString a lo que // me piden en SetFileName que es unsigned short *. USES_CONVERSION; WCHAR wszFileName[MAX_PATH]; wcsncpy(wszFileName, T2W(dialogo_archivo.GetPathName()), NUMELMS(wszFileName)-1); wszFileName[MAX_PATH-1] = 0; // Se pone nombre del archivo gcap.pFileSink->SetFileName(wszFileName,NULL); hr = gcap.pFg->AddFilter((IBaseFilter *)gcap.pWriter, L"File Writer"); // para conectar los filtros conecta(gcap.pSrc,gcap.pWAVDest); conecta(gcap.pWAVDest,gcap.pWriter); //y a grabar gcap.pControl->Run(); m_status="grabando ...";

- 104 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL UpdateData(FALSE); } } ////////////////////////////////////////////////////////////////////// void CRadioDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default KillTimer(ID_TIMER); int j; long cbBuffer=0; // Esta primera llamada es para obtener el tamao del buffer necesitado hr = gcap.pGrabber->GetCurrentBuffer(&cbBuffer, NULL); // Reservamos memoria para el buffer pBuffer = new char[cbBuffer]; if (!pBuffer) { MessageBox("fuera de memoria"); // Se recogen las muestras en el buffer hr = gcap.pGrabber->GetCurrentBuffer(&cbBuffer,(long *)pBuffer); // Se normalizan entre -1 y 1 float *norma=new float[cbBuffer]; for(j=0;j<cbBuffer;j++) { norma[j]=(float)pBuffer[j]/128; }

// Se cambia de canal if(frecuencias_correlacion[1]!=0) {

- 105 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

cambia_canal(frecuencias_correlacion[freq]); frecuencia_anterior=frecuencias_correlacion[freq]; freq++; if (frecuencias_correlacion[freq]==0) freq=0;

// Se calcula la energa del trozo de audio capturado double energia2=0; energia2=calculo_energia(norma,cbBuffer);

// Bucle para los distintos anuncios for(j=0;j<dialogo_archivo.seleccion;j++) { if(frecuencia_anterior==tabla_anuncios[j].frecuencia) correlacion(&tabla_anuncios[j],norma,cbBuffer,energia2); }

delete [] pBuffer; delete [] norma; SetTimer(ID_TIMER,1,NULL); CDialog::OnTimer(nIDEvent); }

//////////////////////////////////////////////////////////////////////

float *CRadioDlg::leewav(int *N1,CString nombre) {

- 106 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

nombre="ARCHIVOS\\"+nombre; CFile wav(nombre,CFile::modeRead);

//Busqueda de la palabra Data char auxiliar[80]; wav.Read(auxiliar,80); int j; for(j=0;j<76;j++) { if(auxiliar[j]=='d') if(auxiliar[j+1]=='a') if(auxiliar[j+2]=='t') if(auxiliar[j+3]=='a') break; } // Despus tengo que posicionar el puntero long posicion; //con esto determino la longitud del archivo y los bytes de las muestras son //dicha longitud menos 46 bytes que son los de la cabecera WAV posicion=wav.Seek(j+4,CFile::begin); unsigned long tama[1]; wav.Read(tama,4); char *muestras=new char[tama[0]]; wav.Read(muestras,tama[0]); *N1=tama[0]; float *normalizado=new float[tama[0]]; for(j=0;j<*N1;j++) normalizado[j]=(float)muestras[j]/128; delete [] muestras; return normalizado;

- 107 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

////////////////////////////////////////////////////////////////////// void CRadioDlg::OnConfigurarSintonizador() { // TODO: Add your command handler code here } dialogo2.DoModal();

////////////////////////////////////////////////////////////////////// void CRadioDlg::cambia_canal(long canal) { gcap.pradio->put_Channel(canal,0,0); }

////////////////////////////////////////////////////////////////////// void CRadioDlg::OnArchivosAnuncios() { // TODO: Add your command handler code here dialogo_archivo.DoModal(); } ////////////////////////////////////////////////////////////////////// void CRadioDlg::lectura_anuncios() { // Comprobacion de que antes se ha seleccionado algn anuncio while(dialogo_archivo.seleccion==0) { MessageBox("NO HAY ANUNCIOS SELECCIONADOS"); dialogo_archivo.DoModal(); } tabla_anuncios=new archivo_wav[dialogo_archivo.seleccion]; int j;

- 108 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

for(j=0;j<dialogo_archivo.seleccion;j++) { tabla_anuncios[j].archivo=leewav(&tabla_anuncios[j].N1,dialogo_archivo.temporal[j]); tabla_anuncios[j].energia=calcula_vector_energia(tabla_anuncios[j].archivo, tabla_anuncios[j].N1); tabla_anuncios[j].detectado=0; tabla_anuncios[j].fallo=0; tabla_anuncios[j].frecuencia=dialogo_archivo.frecuencias[j]; tabla_anuncios[j].anuncio=dialogo_archivo.temporal[j]; } // SE CALCULA EL TIEMPO DE PROCESADO TOTAL tiempo_procesado_total=0; for(j=0;j<dialogo_archivo.seleccion;j++) tiempo_procesado_total+=tabla_anuncios[j].N1; tiempo_procesado_total*=(((float)(time2time1)/1000)*configuracion.m_tiempo_captura)/(225000*0.125); for(j=0;j<dialogo_archivo.seleccion;j++) { tabla_anuncios[j].posibles_detecciones=calcula_posibles_detecciones(tabla_anuncios[j].N1); if(tabla_anuncios[j].posibles_detecciones<1) { //NO SE PUEDE DETECTAR MessageBox("SATURACIN DE APLICACIN, TERMINE LA APLICACIN Y SELECCIONE UN MENOR NMERO DE ANUNCIOS"); } if(tabla_anuncios[j].posibles_detecciones==1) { //NO SE PUEDE DETECTAR MessageBox("SE ESTA TRABAJANDO AL LIMITE DE LA APLICACIN"); } } }

//////////////////////////////////////////////////////////////////////

- 109 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

double CRadioDlg::calculo_energia(float *muestras,int longitud) { double energia=0; int j; for(j=0;j<longitud;j++) { energia+=(muestras[j]*muestras[j]); } return energia; }

////////////////////////////////////////////////////////////////////// void CRadioDlg::correlacion(archivo_wav *anuncio,float *data2,int N2,double energia2) { double maximo=0; float *data1=(*anuncio).archivo; int N1=(*anuncio).N1; double *energia1=(*anuncio).energia; int size=N1-N2+1; int j,i; ///// INICIALIZO A CERO double *correlacion=new double [size]; for(j=0;j<size;j++) { correlacion[j]=0; }

for(i=0;i<N1-N2+1;i++) { for(j=0;j<N2;j++)

- 110 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL { }

correlacion[i]+=data1[j+i]*data2[j];

correlacion[i]*=1/sqrt((energia2)*(energia1[i])); if(correlacion[i]>maximo) { maximo=correlacion[i]; } } decisor(anuncio,maximo); delete [] correlacion; }

////////////////////////////////////////////////////////////////////// void CRadioDlg::decisor(archivo_wav { *anuncio,double maximo)

double umbral=configuracion.m_umbral; if (maximo>umbral) { (*anuncio).detectado++; (*anuncio).fallo=0; anota_resultado(anuncio,maximo); // ANOTAR EN FICHERO RESULTADO // ANOTAR EN EL DIALOGO PRINCIPAL if((*anuncio).detectado>=((int)ceil((float)anuncio->posibles_detecciones/2))) { //MENSAJE DE DETECTADO if ((int)ceil((float)anuncio->posibles_detecciones/2)==1) { if(anuncio->posibles_detecciones==2) { if(anuncio->detectado>=anuncio->posibles_detecciones) { m_anuncio.InsertString(0,"< ANUNCIO DETECTADO > "+anuncio->anuncio);

- 111 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL fichero_resultado << "< ANUNCIO DETECTADO > " << anuncio->anuncio << "\n"; (*anuncio).fallo=0; (*anuncio).detectado=0; } } else { // SE ESTA TRABAJANDO AL LIMITE CON ESE ANUNCIO (*anuncio).fallo=0; (*anuncio).detectado=0; }

} else { m_anuncio.InsertString(0,"< ANUNCIO DETECTADO > "+anuncio->anuncio); fichero_resultado << "< ANUNCIO DETECTADO > " << anuncio->anuncio << "\n"; (*anuncio).fallo=0; (*anuncio).detectado=0; } } } else {

(*anuncio).fallo++; if ((*anuncio).fallo==2) { (*anuncio).fallo=0; (*anuncio).detectado=0; }

} } //////////////////////////////////////////////////////////////////////

- 112 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL double *CRadioDlg::calcula_vector_energia(float *data1,int N1) { double *resultado=new double[N1-N2+1]; int j,i; for(i=0;i<N1-N2+1;i++) resultado[i]=0; for(i=0;i<N1-N2+1;i++) { for(j=0;j<N2;j++) { resultado[i]+=data1[j+i]*data1[j+i]; } }

return resultado;

////////////////////////////////////////////////////////////////////// void CRadioDlg::lectura_frecuencias() { frecuencias=new long[10]; char temporal[10]; int i,j; for(i=0;i<10;i++) frecuencias[i]=0; CFile archivo_frecuencias; archivo_frecuencias.Open("frecuencias.cfg",CFile::modeRead); for(i=0;i<10;i++) { archivo_frecuencias.Read(temporal,10); frecuencias[i]= strtol(temporal,NULL,10); } //PARA VERIFICAR QUE LAS FRECUENCIAS SON FRECUENCIAS CORRECTAS

- 113 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

for(i=0;i<10;i++) { /*if(i!=0) if(frecuencias[i]==frecuencias[i-1]) frecuencias[i]=0;*/ while (((frecuencias[i]>108000000)||(frecuencias[i]<87500000))) {

for(j=i;j<9;j++) { frecuencias[j]=frecuencias[j+1]; } frecuencias[9]=0;

if (frecuencias[i]==0) break; } }

//BUCLE PARA VER SI ESTAN REPETIDAS for(j=1;j<10;j++) for(i=1;i<j+1;i++) if(frecuencias[j]==frecuencias[j-i]) frecuencias[j]=0;

} ////////////////////////////////////////////////////////////////////// void CRadioDlg::lectura_canales_tv() { frecuencias=new long[10]; char temporal[4]; int i,j; for(i=0;i<10;i++)

- 114 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL frecuencias[i]=0; CFile archivo_frecuencias; archivo_frecuencias.Open("frecuencias.cfg",CFile::modeRead); for(i=0;i<10;i++) { archivo_frecuencias.Read(temporal,4); frecuencias[i]= strtol(temporal,NULL,10); } //PARA VERIFICAR QUE LOS CANALES DE T.V. ESTN EN EL RANGO CORRECTO for(i=0;i<10;i++) { while (frecuencias[i]>100) { for(j=i;j<9;j++) { frecuencias[j]=frecuencias[j+1]; } frecuencias[9]=0;

if (frecuencias[i]==0) break; } }

//BUCLE PARA VER SI ESTAN LOS CANALES REPETIDOS for(j=1;j<10;j++) for(i=1;i<j+1;i++) if(frecuencias[j]==frecuencias[j-i]) frecuencias[j]=0;

//////////////////////////////////////////////////////////////////////

- 115 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL void CRadioDlg::OnArchivosSalir() { // TODO: Add your command handler code here OnSalir(); } ////////////////////////////////////////////////////////////////////// void CRadioDlg::anota_resultado(archivo_wav *anuncio,double maximo) { CString resultado; actual=CTime::GetCurrentTime(); resultado = actual.Format( "%H:%M:%S " ); resultado+=(*anuncio).anuncio; resultado+=" EN "; char temporal[10]; _ltoa(anuncio->frecuencia,temporal,10); resultado+=temporal; m_anuncio.InsertString(0,resultado); resultado+=" CON VALOR: "; //Y tambin lo almaceno en el fichero fichero_resultado << resultado << maximo << "\n"; } ////////////////////////////////////////////////////////////////////// void CRadioDlg::OnConfiguracion() { // TODO: Add your command handler code here } configuracion.DoModal();

- 116 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL /////////////////////////////////////////////////////////////////////// int CRadioDlg::calcula_posibles_detecciones(int N1) { int resultado; resultado=(int)(((float)N1/8000)/tiempo_procesado_total); return resultado; }

////////////////////////////////////////////////////////////////////// void CRadioDlg::calcula_frecuencias_correlacion() { int i; int j; int k=0; BOOL repetido; frecuencias_correlacion=new long[dialogo_archivo.seleccion+1]; for(j=0;j<=dialogo_archivo.seleccion;j++) frecuencias_correlacion[j]=0; frecuencias_correlacion[0]=tabla_anuncios[0].frecuencia; k++; for (j=1;j<dialogo_archivo.seleccion;j++) { for(i=0;i<k;i++) { if(tabla_anuncios[j].frecuencia==frecuencias_correlacion[i]) { repetido=TRUE; break; } else } repetido=FALSE;

- 117 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL if(!repetido) { frecuencias_correlacion[k]=tabla_anuncios[j].frecuencia; k++; } } } /////////////////////////////////////////////////////////////

void CRadioDlg::prueba_piloto() { int j; archivo_wav anuncio_piloto; // Se lee el anuncio piloto anuncio_piloto.archivo=leewav(&anuncio_piloto.N1,"anuncio_piloto.wav"); anuncio_piloto.energia=calcula_vector_energia(anuncio_piloto.archivo,anuncio_piloto.N1); anuncio_piloto.detectado=0; anuncio_piloto.fallo=0; anuncio_piloto.frecuencia=0; anuncio_piloto.anuncio="anuncio_piloto.wav"; anuncio_piloto.posibles_detecciones=1; // Reservamos memoria para el buffer time1=clock(); pBuffer = new char[N2]; if (!pBuffer) { MessageBox("fuera de memoria"); } // Se recogen las muestras en el buffer hr = gcap.pGrabber->GetCurrentBuffer(&N2,(long *)pBuffer); // Se normalizan entre -1 y 1 float *norma=new float[N2]; for(j=0;j<N2;j++) { norma[j]=(float)pBuffer[j]/128;

- 118 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL } // Se calcula la energa del trozo de audio capturado double energia2=0; energia2=calculo_energia(norma,N2); // se realiza el proceso de correlacin correlacion(&anuncio_piloto,norma,N2,energia2); delete [] pBuffer; delete [] norma; time2=clock(); }

- 119 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

A3.3. Clase CArchivos


Archivos.h
#if !defined(AFX_ARCHIVOS_H__A6E8C0DA_F3A0_4774_A2BE_39566E1A7B6E__INCLUDED_) #define AFX_ARCHIVOS_H__A6E8C0DA_F3A0_4774_A2BE_39566E1A7B6E__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Archivos.h : header file // ///////////////////////////////////////////////////////////////////////////// // CArchivos dialog class CArchivos : public CDialog { // Construction public: CArchivos(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CArchivos) enum { IDD = IDD_DIALOG3 }; CComboBox m_freq; CListBox m_lista; //}}AFX_DATA long *freq; CString temporal[30]; long frecuencias[30]; int seleccion; // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CArchivos) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CArchivos) afx_msg void OnLista(); afx_msg void Onexit(); //}}AFX_MSG DECLARE_MESSAGE_MAP()

// DDX/DDV support

};

//{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

- 120 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL #endif // !defined(AFX_ARCHIVOS_H__A6E8C0DA_F3A0_4774_A2BE_39566E1A7B6E__INCLUDED_)

- 121 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Archivos.cpp
// Archivos.cpp : implementation file // #include #include #include #include "stdafx.h" "Radio.h" "Archivos.h" "RadioDlg.h"

#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CArchivos dialog

CArchivos::CArchivos(CWnd* pParent /*=NULL*/) : CDialog(CArchivos::IDD, pParent) { //{{AFX_DATA_INIT(CArchivos) //}}AFX_DATA_INIT }

void CArchivos::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CArchivos) DDX_Control(pDX, IDC_DESPLEGAFREQ, m_freq); DDX_Control(pDX, IDC_LISTARCHIVO, m_lista); //}}AFX_DATA_MAP //Pongo esta lnea para poner los archivos en la List Box m_lista.Dir(0x0000,"ARCHIVOS\\*.wav"); //Rellenamos la lista de frecuencias con las frecuencias introducidas //anteriormente por el usuario. int j=0; char auxiliar[10]; while(freq[j]!=0) {

- 122 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

_ltoa(freq[j],auxiliar,10); m_freq.AddString(auxiliar); j++; } } BEGIN_MESSAGE_MAP(CArchivos, CDialog) //{{AFX_MSG_MAP(CArchivos) ON_BN_CLICKED(IDC_BUTTON1, OnLista) ON_BN_CLICKED(IDC_BUTTON2, Onexit) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CArchivos message handlers void CArchivos::OnLista() { // TODO: Add your control notification handler code here CString auxiliar; if (m_lista.GetCurSel()!=LB_ERR) { m_lista.GetText(m_lista.GetCurSel(),temporal[seleccion]); if(m_freq.GetCurSel()!=CB_ERR) { m_freq.GetLBText(m_freq.GetCurSel(),auxiliar); frecuencias[seleccion]=strtol(auxiliar,NULL,10); seleccion++; //ME ASEGURO QUE NO SE PUEDA VOLVER A SELECCIONAR //BORRNDOLO DE LA LISTA m_lista.DeleteString(m_lista.GetCurSel()); } else { } else }

MessageBox("SELECCIONA UNA FRECUENCIA");

- 123 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL { }

MessageBox("SELECCIONA UN ANUNCIO");

////////////////////////////////////////////////////////////////////// void CArchivos::Onexit() { // TODO: Add your control notification handler code here OnOK(); }

- 124 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

A3.4. Clase CDialosint


Dialosint.h
#if !defined(AFX_DIALOSINT_H__28645B3F_7033_44AB_96A3_3897F5A8A910__INCLUDED_) #define AFX_DIALOSINT_H__28645B3F_7033_44AB_96A3_3897F5A8A910__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Dialosint.h : header file // ///////////////////////////////////////////////////////////////////////////// // CDialosint dialog class CDialosint : public CDialog { // Construction public: CDialosint(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDialosint) enum { IDD = IDD_DIALOG2 }; long m_sintoniza; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDialosint) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CDialosint) afx_msg void OnSalir2(); afx_msg void OnOk(); //}}AFX_MSG DECLARE_MESSAGE_MAP()

// DDX/DDV support

};

//{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_DIALOSINT_H__28645B3F_7033_44AB_96A3_3897F5A8A910__INCLUDED_)

- 125 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Dialosint.cpp
// Dialosint.cpp : implementation file // #include #include #include #include "stdafx.h" "Radio.h" "RadioDlg.h" "Dialosint.h"

#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDialosint dialog CDialosint::CDialosint(CWnd* pParent /*=NULL*/) : CDialog(CDialosint::IDD, pParent) { //{{AFX_DATA_INIT(CDialosint) m_sintoniza = 0; //}}AFX_DATA_INIT } void CDialosint::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDialosint) DDX_Text(pDX, IDC_SINTFREC, m_sintoniza); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDialosint, CDialog) //{{AFX_MSG_MAP(CDialosint) ON_BN_CLICKED(IDC_SALIR2, OnSalir2) ON_BN_CLICKED(IDC_OK, OnOk) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDialosint message handlers void CDialosint::OnSalir2() { // TODO: Add your control notification handler code here

- 126 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL OnOK(); }

////////////////////////////////////////////////////////////////////// // En esta rutina se sintoniza el canal deseado. void CDialosint::OnOk() { // TODO: Add your control notification handler code here UpdateData(TRUE); CRadioDlg dialogo; dialogo.cambia_canal(m_sintoniza); OnOK(); }

- 127 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

A3.5. Clase CConfiguracion


Configuracion.h
#if !defined(AFX_CONFIGURACION_H__0C1C2B59_0A7A_499E_A58F_560C063F4832__INCLUDED _) #define AFX_CONFIGURACION_H__0C1C2B59_0A7A_499E_A58F_560C063F4832__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Configuracion.h : header file // ///////////////////////////////////////////////////////////////////////////// // CConfiguracion dialog class CConfiguracion : public CDialog { // Construction public: CConfiguracion(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CConfiguracion) enum { IDD = IDD_DIALOG6 }; float m_umbral; float m_tiempo_captura; int m_fm; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CConfiguracion) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CConfiguracion) afx_msg void OnAceptar(); afx_msg void OnCancelar(); //}}AFX_MSG DECLARE_MESSAGE_MAP()

// DDX/DDV support

};

//{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

- 128 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL #endif // !defined(AFX_CONFIGURACION_H__0C1C2B59_0A7A_499E_A58F_560C063F4832__INCLUDED _)

- 129 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

Configuracion.cpp
// Configuracion.cpp : implementation file // #include "stdafx.h" #include "Radio.h" #include "Configuracion.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CConfiguracion dialog CConfiguracion::CConfiguracion(CWnd* pParent /*=NULL*/) : CDialog(CConfiguracion::IDD, pParent) { //{{AFX_DATA_INIT(CConfiguracion) m_umbral = 0.0f; m_tiempo_captura = 0.0f; m_fm = -1; //}}AFX_DATA_INIT } void CConfiguracion::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CConfiguracion) DDX_Text(pDX, IDC_UMBRAL, m_umbral); DDV_MinMaxFloat(pDX, m_umbral, 0.f, 1.f); DDX_Text(pDX, IDC_TIEMPO_CAPTURA, m_tiempo_captura); DDX_Radio(pDX, IDC_FM, m_fm); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CConfiguracion, CDialog) //{{AFX_MSG_MAP(CConfiguracion) ON_BN_CLICKED(IDC_ACEPTAR, OnAceptar) ON_BN_CLICKED(IDC_CANCELAR, OnCancelar) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CConfiguracion message handlers void CConfiguracion::OnAceptar() { // TODO: Add your control notification handler code here

- 130 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL UpdateData(TRUE); OnOK(); } ////////////////////////////////////////////////////////////////////// void CConfiguracion::OnCancelar() { // TODO: Add your control notification handler code here OnOK(); }

- 131 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

A3.6. Clase CButtonST (Clase CMemDC est includa en ButtonST.h)


ButtonST.h
#if !defined(AFX_BUTTONST_H__B07118FE_52A5_4B67_B2B4_351291562378__INCLUDED_) #define AFX_BUTTONST_H__B07118FE_52A5_4B67_B2B4_351291562378__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // ButtonST.h : header file //

// Comment this if you don't want that CButtonST hilights itself // also when the window is inactive (like happens in Internet Explorer) #define ST_LIKEIE // Comment this if you don't want to use CMemDC class #define ST_USE_MEMDC ///////////////////////////////////////////////////////////////////////////// // CButtonST window class CButtonST : public CButton { // Construction public: CButtonST(); ~CButtonST(); enum {ST_ALIGN_HORIZ, ST_ALIGN_VERT}; // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CButtonST) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected: virtual void PreSubclassWindow(); //}}AFX_VIRTUAL // Implementation public: BOOL SetBtnCursor(int nCursorId = -1); void SetFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint = FALSE);

- 132 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL BOOL GetFlatFocus(); void SetDefaultActiveFgColor(BOOL bRepaint = FALSE); void SetActiveFgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetActiveFgColor(); void SetDefaultActiveBgColor(BOOL bRepaint = FALSE); void SetActiveBgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetActiveBgColor(); void SetDefaultInactiveFgColor(BOOL bRepaint = FALSE); void SetInactiveFgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetInactiveFgColor(); void SetDefaultInactiveBgColor(BOOL bRepaint = FALSE); void SetInactiveBgColor(COLORREF crNew, BOOL bRepaint = FALSE); const COLORREF GetInactiveBgColor(); void SetShowText(BOOL bShow = TRUE); BOOL GetShowText(); void SetAlign(int nAlign); int GetAlign(); void SetFlat(BOOL bState = TRUE); BOOL GetFlat(); void DrawBorder(BOOL bEnable = TRUE); void SetIcon(int nIconInId, int nIconOutId = NULL, BYTE cx = 32, BYTE cy = 32); static const short GetVersionI(); static const char* GetVersionC(); protected: //{{AFX_MSG(CButtonST) afx_msg void OnCaptureChanged(CWnd *pWnd); afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnMouseMove(UINT nFlags, CPoint point); //}}AFX_MSG private: DECLARE_MESSAGE_MAP() void DrawTheIcon(CDC* pDC, CString* title, RECT* rcItem, CRect* captionRect, BOOL IsPressed, BOOL IsDisabled); int m_nAlign; BOOL m_bShowText; BOOL m_bDrawBorder; BOOL m_bIsFlat; BOOL m_MouseOnButton; BOOL m_bDrawFlatFocus; HCURSOR m_hCursor; HICON m_hIconIn; HICON m_hIconOut; BYTE m_cyIcon;

- 133 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL BYTE m_cxIcon; COLORREF m_crInactiveBg; COLORREF m_crInactiveFg; COLORREF m_crActiveBg; COLORREF m_crActiveFg;

};

#ifdef ST_USE_MEMDC ////////////////////////////////////////////////// // CMemDC - memory DC // // Author: Keith Rule // Email: keithr@europa.com // Copyright 1996-1997, Keith Rule // // You may freely use or modify this code provided this // Copyright is included in all derived versions. // // History - 10/3/97 Fixed scrolling bug. // Added print support. // 25 feb 98 - fixed minor assertion bug // // This class implements a memory Device Context class CMemDC : public CDC { public: // constructor sets up the memory DC CMemDC(CDC* pDC) : CDC() { ASSERT(pDC != NULL); m_pDC = pDC; m_pOldBitmap = NULL; m_bMemDC = !pDC->IsPrinting(); if (m_bMemDC) // Create a Memory DC { pDC->GetClipBox(&m_rect); CreateCompatibleDC(pDC); m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height()); m_pOldBitmap = SelectObject(&m_bitmap); SetWindowOrg(m_rect.left, m_rect.top); } else // Make a copy of the relevent parts of the current DC for printing { m_bPrinting = pDC->m_bPrinting; m_hDC = pDC->m_hDC; m_hAttribDC = pDC->m_hAttribDC; }

// Destructor copies the contents of the mem DC to the original DC ~CMemDC() {

- 134 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL if (m_bMemDC) { // Copy the offscreen bitmap onto the screen. m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), this, m_rect.left, m_rect.top, SRCCOPY); //Swap back the original bitmap. SelectObject(m_pOldBitmap); } else { // All we need to do is replace the DC with an illegal value, // this keeps us from accidently deleting the handles associated with // the CDC that was passed to the constructor. m_hDC = m_hAttribDC = NULL; }

// Allow usage as a pointer CMemDC* operator->() {return this;} // Allow usage as a pointer operator CMemDC*() {return this;} private: CBitmap m_bitmap; // Offscreen bitmap CBitmap* m_pOldBitmap; // bitmap originally found in CMemDC CDC* m_pDC; // Saves CDC passed in constructor CRect m_rect; // Rectangle of drawing area. BOOL m_bMemDC; // TRUE if CDC really is a Memory DC. }; #endif ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif

- 135 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

ButtonST.cpp
// ButtonST.cpp : implementation file // #include "stdafx.h" #include "Radio.h" #include "ButtonST.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif

///////////////////////////////////////////////////////////////////////////// // CButtonST CButtonST::CButtonST() { m_MouseOnButton = FALSE; m_hIconIn = NULL; m_hIconOut = NULL; m_cxIcon = 0; m_cyIcon = 0; m_hCursor = NULL; // Default type is "flat" button m_bIsFlat = TRUE; // By default draw border in "flat" button m_bDrawBorder = TRUE; // By default icon is aligned horizontally m_nAlign = ST_ALIGN_HORIZ; // By default show the text button m_bShowText = TRUE; // By default, for "flat" button, don't draw the focus rect m_bDrawFlatFocus = FALSE; SetDefaultInactiveBgColor(); SetDefaultInactiveFgColor(); SetDefaultActiveBgColor(); SetDefaultActiveFgColor(); } // End of CButtonST CButtonST::~CButtonST() { // Destroy the icons (if any) if (m_hIconIn != NULL) ::DeleteObject(m_hIconIn);

- 136 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL if (m_hIconOut != NULL) ::DeleteObject(m_hIconOut); // Destroy the cursor (if any) if (m_hCursor != NULL) ::DestroyCursor(m_hCursor); } // End of ~CButtonST

BEGIN_MESSAGE_MAP(CButtonST, CButton) //{{AFX_MSG_MAP(CButtonST) ON_WM_CAPTURECHANGED() ON_WM_SETCURSOR() ON_WM_KILLFOCUS() ON_WM_MOUSEMOVE() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CButtonST::SetIcon(int nIconInId, int nIconOutId, BYTE cx, BYTE cy) { HINSTANCE hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconInId), RT_GROUP_ICON); // Set icon when the mouse is IN the button m_hIconIn = (HICON)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nIconInId), IMAGE_ICON, 0, 0, 0); // Set icon when the mouse is OUT the button m_hIconOut = (nIconOutId == NULL) ? m_hIconIn : (HICON)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nIconOutId), IMAGE_ICON, 0, 0, 0); m_cxIcon = cx; m_cyIcon = cy; RedrawWindow(); } // End of SetIcon BOOL CButtonST::SetBtnCursor(int nCursorId) { HINSTANCE hInstResource; // Destroy any previous cursor if (m_hCursor != NULL) ::DestroyCursor(m_hCursor); m_hCursor = NULL; // If we want a cursor if (nCursorId != -1) { hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId), RT_GROUP_CURSOR); // Load icon resource m_hCursor = (HCURSOR)::LoadImage(hInstResource/*AfxGetApp()>m_hInstance*/, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0); // If something wrong then return FALSE if (m_hCursor == NULL) return FALSE; }

- 137 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL return TRUE; } // End of SetBtnCursor void CButtonST::SetFlat(BOOL bState) { m_bIsFlat = bState; Invalidate(); } // End of SetFlat BOOL CButtonST::GetFlat() { return m_bIsFlat; } // End of GetFlat void CButtonST::SetAlign(int nAlign) { switch (nAlign) { case ST_ALIGN_HORIZ: m_nAlign = ST_ALIGN_HORIZ; break; case ST_ALIGN_VERT: m_nAlign = ST_ALIGN_VERT; break; } Invalidate(); } // End of SetAlign int CButtonST::GetAlign() { return m_nAlign; } // End of GetAlign void CButtonST::DrawBorder(BOOL bEnable) { m_bDrawBorder = bEnable; } // End of DrawBorder const char* CButtonST::GetVersionC() { return "2.3"; } // End of GetVersionC const short CButtonST::GetVersionI() { return 23; // Divide by 10 to get actual version } // End of GetVersionI void CButtonST::SetShowText(BOOL bShow) {

- 138 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL m_bShowText = bShow; Invalidate(); } // End of SetShowText BOOL CButtonST::GetShowText() { return m_bShowText; } // End of GetShowText void CButtonST::OnMouseMove(UINT nFlags, CPoint point) { CWnd* pWnd; // Finestra attiva CWnd* pParent; // Finestra che contiene il bottone CButton::OnMouseMove(nFlags, point); // If the mouse enter the button with the left button pressed // then do nothing if (nFlags & MK_LBUTTON && m_MouseOnButton == FALSE) return; // If our button is not flat then do nothing if (m_bIsFlat == FALSE) return; pWnd = GetActiveWindow(); pParent = GetOwner(); if ((GetCapture() != this) && ( #ifndef ST_LIKEIE pWnd != NULL && #endif pParent != NULL)) { m_MouseOnButton = TRUE; //SetFocus(); // Thanks Ralph! SetCapture(); Invalidate(); } else { CRect rc; GetClientRect(&rc); if (!rc.PtInRect(point)) { // Redraw only if mouse goes out if (m_MouseOnButton == TRUE) { m_MouseOnButton = FALSE; Invalidate(); } // If user is NOT pressing left button then release capture! if (!(nFlags & MK_LBUTTON)) ReleaseCapture(); } } } // End of OnMouseMove

- 139 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

void CButtonST::OnKillFocus(CWnd * pNewWnd) { CButton::OnKillFocus(pNewWnd); // If our button is not flat then do nothing if (m_bIsFlat == FALSE) return; if (m_MouseOnButton == TRUE) { m_MouseOnButton = FALSE; Invalidate(); } } // End of OnKillFocus void CButtonST::OnCaptureChanged(CWnd *pWnd) { if (m_MouseOnButton == TRUE) { ReleaseCapture(); Invalidate(); } // Call base message handler CButton::OnCaptureChanged(pWnd); } // End of OnCaptureChanged void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDIS) { #ifdef ST_USE_MEMDC CDC *pdrawDC = CDC::FromHandle(lpDIS->hDC); CMemDC memDC(pdrawDC); CDC *pDC = &memDC; #else CDC* pDC = CDC::FromHandle(lpDIS->hDC); #endif CPen *pOldPen; BOOL bIsPressed = (lpDIS->itemState & ODS_SELECTED); BOOL bIsFocused = (lpDIS->itemState & ODS_FOCUS); BOOL bIsDisabled = (lpDIS->itemState & ODS_DISABLED); CRect itemRect = lpDIS->rcItem; if (m_bIsFlat == FALSE) { if (bIsFocused) { CBrush br(RGB(0,0,0)); pDC->FrameRect(&itemRect, &br); itemRect.DeflateRect(1, 1); } } // Prepare draw... paint button's area with background color COLORREF bgColor;

- 140 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL if ((m_MouseOnButton == TRUE) || (bIsPressed)) bgColor = GetActiveBgColor(); else bgColor = GetInactiveBgColor(); CBrush br(bgColor); pDC->FillRect(&itemRect, &br); // Disegno lo sfondo del bottone //CBrush br(GetSysColor(COLOR_BTNFACE)); //pDC->FillRect(&itemRect, &br); // Draw pressed button if (bIsPressed) { if (m_bIsFlat == TRUE) { if (m_bDrawBorder == TRUE) { CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // Bianco CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); // Grigio scuro // Disegno i bordi a sinistra e in alto // Dark gray line pOldPen = pDC->SelectObject(&penBtnShadow); pDC->MoveTo(itemRect.left, itemRect.bottom-1); pDC->LineTo(itemRect.left, itemRect.top); pDC->LineTo(itemRect.right, itemRect.top); // Disegno i bordi a destra e in basso // White line pDC->SelectObject(penBtnHiLight); pDC->MoveTo(itemRect.left, itemRect.bottom-1); pDC->LineTo(itemRect.right-1, itemRect.bottom-1); pDC->LineTo(itemRect.right-1, itemRect.top-1); // pDC->SelectObject(pOldPen);

} else // ...else draw non pressed button { CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // White CPen pen3DLight(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT)); // Light gray CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); // Dark gray CPen pen3DDKShadow(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW)); // Black if (m_bIsFlat == TRUE) { if (m_MouseOnButton == TRUE && m_bDrawBorder == TRUE) { // Disegno i bordi a sinistra e in alto // White line pOldPen = pDC->SelectObject(&penBtnHiLight);

} } else { CBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW)); pDC->FrameRect(&itemRect, &brBtnShadow); }

- 141 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL pDC->MoveTo(itemRect.left, itemRect.bottom-1); pDC->LineTo(itemRect.left, itemRect.top); pDC->LineTo(itemRect.right, itemRect.top); // Disegno i bordi a destra e in basso // Dark gray line pDC->SelectObject(penBtnShadow); pDC->MoveTo(itemRect.left, itemRect.bottom-1); pDC->LineTo(itemRect.right-1, itemRect.bottom-1); pDC->LineTo(itemRect.right-1, itemRect.top-1); // pDC->SelectObject(pOldPen); } } else { // Disegno i bordi a sinistra e in alto // White line pOldPen = pDC->SelectObject(&penBtnHiLight); pDC->MoveTo(itemRect.left, itemRect.bottom-1); pDC->LineTo(itemRect.left, itemRect.top); pDC->LineTo(itemRect.right, itemRect.top); // Light gray line pDC->SelectObject(pen3DLight); pDC->MoveTo(itemRect.left+1, itemRect.bottom-1); pDC->LineTo(itemRect.left+1, itemRect.top+1); pDC->LineTo(itemRect.right, itemRect.top+1); // Disegno i bordi a destra e in basso // Black line pDC->SelectObject(pen3DDKShadow); pDC->MoveTo(itemRect.left, itemRect.bottom-1); pDC->LineTo(itemRect.right-1, itemRect.bottom-1); pDC->LineTo(itemRect.right-1, itemRect.top-1); // Dark gray line pDC->SelectObject(penBtnShadow); pDC->MoveTo(itemRect.left+1, itemRect.bottom-2); pDC->LineTo(itemRect.right-2, itemRect.bottom-2); pDC->LineTo(itemRect.right-2, itemRect.top); // pDC->SelectObject(pOldPen); } } // Read the button title CString sTitle; GetWindowText(sTitle); // If we don't want the title displayed if (m_bShowText == FALSE) sTitle.Empty(); CRect captionRect = lpDIS->rcItem; // Draw the icon if (m_hIconIn != NULL) { DrawTheIcon(pDC, &sTitle, &lpDIS->rcItem, &captionRect, bIsPressed, bIsDisabled); } // Write the button title (if any)

- 142 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL if (sTitle.IsEmpty() == FALSE) { // Disegno la caption del bottone // Se il bottone e' premuto muovo la captionRect di conseguenza if (bIsPressed) captionRect.OffsetRect(1, 1); // ONLY FOR DEBUG // Evidenzia il rettangolo in cui verra' centrata la caption //CBrush brBtnShadow(RGB(255, 0, 0)); //pDC->FrameRect(&captionRect, &brBtnShadow); #ifdef ST_USE_MEMDC // Get dialog's font CFont *pCurrentFont = GetFont(); CFont *pOldFont = pDC->SelectObject(pCurrentFont); #endif if ((m_MouseOnButton == TRUE) || (bIsPressed)) { pDC->SetTextColor(GetActiveFgColor()); pDC->SetBkColor(GetActiveBgColor()); } else { pDC->SetTextColor(GetInactiveFgColor()); pDC->SetBkColor(GetInactiveBgColor()); } // Center text CRect centerRect = captionRect; pDC->DrawText(sTitle, -1, captionRect, DT_SINGLELINE|DT_CALCRECT); captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() captionRect.Height())/2); /* RFU captionRect.OffsetRect(0, (centerRect.Height() - captionRect.Height())/2); captionRect.OffsetRect((centerRect.Width() - captionRect.Width())-4, (centerRect.Height() captionRect.Height())/2); */ pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), TRUE, 0, (CBrush*)NULL); #ifdef ST_USE_MEMDC pDC->SelectObject(pOldFont); #endif } if (m_bIsFlat == FALSE || (m_bIsFlat == TRUE && m_bDrawFlatFocus == TRUE)) { // Draw the focus rect if (bIsFocused) { CRect focusRect = itemRect; focusRect.DeflateRect(3, 3); pDC->DrawFocusRect(&focusRect); } } } // End of DrawItem

- 143 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

void CButtonST::DrawTheIcon(CDC* pDC, CString* title, RECT* rcItem, CRect* captionRect, BOOL IsPressed, BOOL IsDisabled) { CRect iconRect = rcItem; switch (m_nAlign) { case ST_ALIGN_HORIZ: if (title->IsEmpty()) { // Center the icon horizontally iconRect.left += ((iconRect.Width() - m_cxIcon)/2); } else { // L'icona deve vedersi subito dentro il focus rect iconRect.left += 3; captionRect->left += m_cxIcon + 3; } // Center the icon vertically iconRect.top += ((iconRect.Height() - m_cyIcon)/2); break; case ST_ALIGN_VERT: // Center the icon horizontally iconRect.left += ((iconRect.Width() - m_cxIcon)/2); if (title->IsEmpty()) { // Center the icon vertically iconRect.top += ((iconRect.Height() - m_cyIcon)/2); } else { captionRect->top += m_cyIcon; } break; } // If button is pressed then press the icon also if (IsPressed) iconRect.OffsetRect(1, 1); // Ole'! pDC->DrawState(iconRect.TopLeft(),iconRect.Size(), (m_MouseOnButton == TRUE || IsPressed) ? m_hIconIn : m_hIconOut, (IsDisabled ? DSS_DISABLED : DSS_NORMAL),(CBrush*)NULL); } // End of DrawTheIcon void CButtonST::PreSubclassWindow() { // Add BS_OWNERDRAW style SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW); CButton::PreSubclassWindow(); } // End of PreSubclassWindow void CButtonST::SetDefaultInactiveBgColor(BOOL bRepaint) { m_crInactiveBg = ::GetSysColor(COLOR_BTNFACE);

- 144 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL if (bRepaint == TRUE) Invalidate(); } // End of SetDefaultInactiveBgColor void CButtonST::SetInactiveBgColor(COLORREF crNew, BOOL bRepaint) { m_crInactiveBg = crNew; if (bRepaint == TRUE) Invalidate(); } // End of SetInactiveBgColor const COLORREF CButtonST::GetInactiveBgColor() { return m_crInactiveBg; } // End of GetInactiveBgColor void CButtonST::SetDefaultInactiveFgColor(BOOL bRepaint) { m_crInactiveFg = ::GetSysColor(COLOR_BTNTEXT); if (bRepaint == TRUE) Invalidate(); } // End of SetDefaultInactiveFgColor void CButtonST::SetInactiveFgColor(COLORREF crNew, BOOL bRepaint) { m_crInactiveFg = crNew; if (bRepaint == TRUE) Invalidate(); } // End of SetInactiveFgColor const COLORREF CButtonST::GetInactiveFgColor() { return m_crInactiveFg; } // End of GetInactiveFgColor void CButtonST::SetDefaultActiveBgColor(BOOL bRepaint) { m_crActiveBg = ::GetSysColor(COLOR_BTNFACE); if (bRepaint == TRUE) Invalidate(); } // End of SetDefaultActiveBgColor void CButtonST::SetActiveBgColor(COLORREF crNew, BOOL bRepaint) { m_crActiveBg = crNew; if (bRepaint == TRUE) Invalidate(); } // End of SetActiveBgColor const COLORREF CButtonST::GetActiveBgColor() { return m_crActiveBg; } // End of GetActiveBgColor void CButtonST::SetDefaultActiveFgColor(BOOL bRepaint)

- 145 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL {

m_crActiveFg = ::GetSysColor(COLOR_BTNTEXT); if (bRepaint == TRUE) Invalidate(); } // End of SetDefaultActiveFgColor void CButtonST::SetActiveFgColor(COLORREF crNew, BOOL bRepaint) { m_crActiveFg = crNew; if (bRepaint == TRUE) Invalidate(); } // End of SetActiveFgColor const COLORREF CButtonST::GetActiveFgColor() { return m_crActiveFg; } // End of GetActiveFgColor void CButtonST::SetFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint) { m_bDrawFlatFocus = bDrawFlatFocus; // Repaint the button if (bRepaint == TRUE) Invalidate(); } // End of SetFlatFocus BOOL CButtonST::GetFlatFocus() { return m_bDrawFlatFocus; } // End of GetFlatFocus

BOOL CButtonST::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // If a cursor was specified then use it! if (m_hCursor != NULL) { ::SetCursor(m_hCursor); return TRUE; } return CButton::OnSetCursor(pWnd, nHitTest, message); } // End of OnSetCursor

#undef ST_USE_MEMDC #undef ST_LIKE

- 146 -

DETECCIN AUTOMTICA DE ANUNCIOS EN RADIO EN TIEMPO REAL

BIBLIOGRAFA:
[1] Ifeachor, E. C., Y Jervis, B. W. Digital signal processing : a practical Prentice-Hall. [2] Stremler, F. G. Introduccin a los Sistemas de Comunicacin. Addison-Wesley. [3] Chapman, D. Teach Yourself Visual C++ 6 in 21 days. Sams. [4] Dunlop, R. Teach Yourself DirectX 7 in 24. Sams. [5] Ceballos Sierra, F. J. Visual C++ : Programacin Avanzada en Win32. Ra-Ma. [6] Bargen, B., Y Donnelly, P. Inside DirectX. Microsoft Press. [7] STEVENS, Al. Y WALNUM, Clayton. Programacin con C++. Anaya Multimedia. [8] Zaratian, B. Microsoft Visual C++ 6.0 : Manual del Programador. McGraw-Hill. [9] Vallejo Prez, R. J. Deteccin de Tramas de Audio con Sound Blaster. Proyecto fin de carrera.

approach.

Tiempo Real.

[10] Cadenas Martn, I. E. Deteccin Automtica de Anuncios en Televisin en Proyecto fin de carrera. [11] Aprenda C++ como si estuviera en primero. Manual obtenido en internet. URL: http://mat21.etsii.upm.es/ayudainf/aprendainf/Cpp/manualcpp.pdf [12] MSDN. Ayuda del Visual Studio. [13] Microsoft DirectX 9.0 SDK. Documentation for C++. [14] Press, W. H. Numerical recipes in C : the art of scientific computing. Cambridge University Press. [15] http://www.lawebdelprogramador.com/

- 147 -

You might also like