Una clase para un reproductor de CD. versión: 0.9
Por: Demian Panello.
En la librería multimedia de Windows, (winmm.dll), se encuentran las funciones para manipular video, CD de audio, midi, archivos de sonido, etc. En particular una sola función es necesaria para realizar un simple reproductor de CD, mciSendString(). Todas las acciones, (reproducir, detener, averiguar si hay un cd, cantidad de canciones, duración de cada una de ellas, etc.), se encuentran disponibles por medio de cadenas de comandos. Por ejemplo para reproducir un CD, hay que abrir el medio, (cadena "Open ..."), y luego reproducir, (cadena "Play...").
|
MCIERROR errMci;
errMci=mciSendString("Open cdaudio alias micd", NULL, 0, NULL); if (errMci!=0) ...error. errMci=mciSendString("Play micd", NULL,0,NULL); ... |
Como estas hay muchas otras cadenas que están compartidas por los diferentes medios y otras son exclusivas. En este ejemplo la reproducción comienza del primer tema y no se detiene hasta terminar el disco, pero hay variantes de "Play", por ejemplo indicándole que reproduzca entre dos posiciones, (tiempos comprendidos dentro del tiempo total del CD), e incluso se puede especificar el handle de una ventana, (último parámetro de mciSendString()), que será la que reciba alguno de los mensajes multimedia, (por ejemplo MM_MCINOTIFY).
La clase CAudioCD.
Para facilitar el uso de la lectora de cd's como reproductora de cd's de audio, he escrito una clase que precisamente "envuelve" algunas de estas acciones con las cadenas MCI.
En principio, esta clase que llamé CAudioCD, ofrece la funcionalidad más común de un reproductor de CD's, (reproducir, pasar al siguiente tema, pasar al tema anterior, detener, pausar, eject, obtener información de capacidades del dispositivo, reproducción aleatoria y algunos pocos más). Todavía le falta algo de depuración y agregarle mayor funcionalidad, pero para el simple hecho de aprender como construir objetos que faciliten la programación y de practicar con C++ es más que suficiente.
La clase está mayormente en inglés; porque, que se le va a hacer, uno está más acostumbrado a ver Play que Reproducir, o Next que siguiente, etc.
Definición de la clase CAudioCD:
Esta es la definición de la clase. La implementación, (junto con esta definición), la pueden descargar pulsando un link al final del artículo:
Descripción de la clase CAudioCD:
Funciones públicas:
Este es el constructor. Se encarga de abrir el dispositivo de CDAudio.
Puede declarar una variable miembro en un diálogo como sigue:
CAudioCD m_cd;
Este es el destructor. Se encarga de enviar la cadena "close" que permite cerrar el dispositivo, (obviamente lo contrario que hace el constructor).
Esta función se encarga de verificar si hay un CD en la lectora y, en caso de haberlo, inicializa la variable miembro protegida m_currentPosition y m_currentStart. Puede usar esta función antes de mostrar el diálogo, (o ventana), así ya está posicionado en el primer corte del disco.
Simplemente comienza la reproducción. Se detiene unicamente con un llamado a CAudioCD::StopCD() o CAudioCD::PauseCD(). Ejemplo:
| if
(!m_cd.isPlaying()) m_cd.PlayCD (); |
Reproduce entre dos posiciones. Los dos parámetros son cadenas cuyo contenido puede ser, por ejemplo: mm:ss y mm:ss, dependiendo del formato del tiempo especificado con CAudioCD::SetTimeFormat(int TimeFormat=STF_MSF). Envía el mensaje MM_MCINOTIFY.
Reproduce el número de tema nTrack pasado como parámetro. Envía el mensaje MM_MCINOTIFY.
Abre o cierra la lectora.
Detiene la reproducción.
Detiene la reproducción. Pero "recuerda" la posición para continuar.
Pasar al siguiente tema y al anterior. Si se llega al último y se vuelve a llamar a NextTrack() pasa al primero, si se está en el primer corte y se llama a PreviousTrack() se pasa al último.
Reproduce una canción de forma aleatoria. Envía el mensaje MM_MCINOTIFY.
Devuelven 1 en caso que se esté reproduciendo, ó esté detenido, ó en pausa, ó hay un cd en la lectora. Cero en caso que no, y otro valor es error.
Devuelve 1 en caso que el dispositivo esté listo para recibir una orden. Cero en caso que no y otro valor es error.
Coloca en nTracks la cantidad de temas del CD.
Coloca en curTrack el número de tema actual, (se esté reproducciendo o no).
Coloca en curPos la posición actual. Ejemplo si el CD dura 50:00 y se encuentra en reproducción, (o no), por la mitad, esta función almacenaría "25:00" en curPos. Esta función es útil, por ejemplo, en combinación con GetCurrentTrack(int* curTrack).
Coloca en curStart la posición de inicio del CD. La función InitialStartTrack() llama a esta función.
Coloca en cd_length la longitud, (en el formato de tiempo especificado por SetTimeFormat()), de todo el CD de audio.
Coloca en track_length la longitud, (duración), del tema actual, (en reproducción o no).
Coloca en track_length la longitud del corte especificado en nTrack.
Coloca en time_format el formato del tiempo actual: "msf", "ms" ó "tmsf".
Establece el formato del tiempo de acuerdo a la constante pasada como parámetro. Estas constantes pueden ser:
STF_MS: Para establecer el formato a milésimas de
segundos.
STF_MSF: Para establecer el formato a minutos/segundos/frames. Este es el valor por
defecto que toma la función.
STF_TMSF: Para establecer el formato a track/minutos/segundos/frame.
Carga una estructura de tipo CD_INFO con información del dispositivo. Ver CD_INFO.
Carga una estructura de tipo CD_CAPABILITY con las capacidades de la lectora. Ver CD_CAPABILITY.
Carga StartPos con la posición de inicio del número de tema especificado en nTrack.
Muestra un mensaje descriptivo sobre el error pasado como parámetro.
Funciones privadas:
Esta función, por el hecho de ser privada, (sólo está disponible para las funciones de la clase), no puede ser accedida por el programa. Es utilizada por la función CAudioCD::PlayCD(int nTrack).
Las función CAudioCD::PlayCD(char* posIni, char* posEnd) usa la función mciSendString() de la siguiente forma:
| //Reproduce entre dos posiciones. MCIERROR CAudioCD::PlayCD (char* posIni, char* posEnd) { char mciCad[80]; wsprintf(mciCad, "Play micd from %s to %s notify", posIni, posEnd); m_mciError=mciSendString(mciCad, NULL, 0, Parent); if (m_mciError!=0) return m_mciError; return 0; } |
Indica que reproduzca entre dos posiciones y que notifique cuando el comando se complete, (notify). Esto da lugar a que se "dispare" un mensaje a una ventana, que es precisamente el handle almacenado en HWND Parent.
Lo primero que hay que hacer cuando se carga una ventana, (por ejemplo en OnInitDialog()), es especificarle al objeto CAudioCD(), (dato miembro del diálogo), cuál es el handle del diálogo por medio de una sentencia como la siguiente, (supongamos que el objeto CAudioCD es m_cd):
| m_cd.AttachHandle(m_hWnd); //o this->m_hWnd |
Y además agregar el mensaje MM_MCINOTIFY al diálogo.
Desde ya esto es optativo, si no se especifica el handle de la ventana al dato miembro de la clase y no se agrega el mensaje, la función CAudioCD::PlayCD(char* posIni, char* posEnd) igual funcionará, aunque obviamente no existirá ninguna notificación de terminación.
Cómo usar la clase:
Si quiere hacer un reproductor de CD usando esta clase, (al pié de la página puede descargar un demo de ejemplo), es muy fácil, (supongo un proyecto Dialog Based ya creado, aunque la puede usar también en proyectos SDI):
1) Agregue al proyecto los archivos de CAudioCD.h y CAudioCD.cpp, (Recuerde: Project -> Add to project -> files).
2) Escriba en el archivo StdAfx.h la siguiente sentencia: #include "mmsystem.h".
3) Agregue la librería winmm.lib al proyecto.
4) Verifique que en el archivo de cabecera del diálogo se encuentre la sentencia: #include "AudioCD.h", (debería estar puesto que la coloca automáticamente el Class Wizard), si no está, escríbala.
5) Agregue una variable de tipo CAudioCD al diálogo, (ejemplo CAudioCD m_cd). Puede editar directamente la clase del diálogo.
6) Luego, en OnInitDialog(), llame a la función CAudioCD::InitialStartTrack(), de la siguiente forma:
err=m_cd.InitialStartTrack();
7) Optativamente, puede especificarle al objeto CAudioCD cuál es el handle del diálogo para poder recibir el mensaje MM_MCINOTIFY, (si hace esto debe además agregar este mensaje).
8) Codifique los controles del diálogo, (ejemplo: botones, ListBox, ComboBox, etc.), con las funciones del objeto m_cd, (PlayCD(), StopCD(), PauseCD(), etc.).
Programa de ejemplo:
El programa de ejemplo que pueden descargar más abajo es un reproductor de CD,s simple. Utiliza la mayoría de las funciones de la clase y además muestra como colocar ToolTips en controles e implementa una clase para manipular el volumen escrita por Alex Chmut, la cual agiliza bastante la tarea.
Descargar archivo fuente de CAudioCD, (archivos caudiocd.h y caudiocd.cpp).