Aunque ya he puesto un tip en la sección del API, aunque sólo para WAVs, te muestro aquí cómo hacer que también ser repita un fichero de sonido del tipo MIDI, de camino, en el ejemplo también se incluye ese ejemplo, para que puedas probarlo, ya que entre otras cosas, lo que si se puede hacer es tocar un fichero WAV y un MIDI al mismo tiempo... lo mismo ocurriría con una pista de un CD de audio... Aunque este tema es más laborioso por aquello de que hay que controlar la pista que se quiere tocar y esas cosas... así que en este ejemplo sólo se contemplan los WAVs y MIDIs.
El ejemplo:
Este ejemplo permite seleccionar dos ficheros de sonido, relamente no permite seleccionar, sino que debes especificar los que quieres usar.
Tiene dos botones para poder tocar cada uno de ellos, siempre que sean de diferentes tipos, ya que no se permite tocar dos WAVs al mismo tiempo...
Sólo habrá un botón de detener, para parar cualquier fichero que se esté tocando y para que se puedan especificar los nombres de esos ficheros a usar, se usan dos TEXTBOXES.
Veamos una "instantánea" del form en tiempo de diseño:
Para los ficheros de tipo WAVs, no hay conplicación, ya que usando sndPlaySound con los parámetros: SND_ASYNC + SND_LOOP, se consigue lo deseado.
Sin embargo para los MIDIs, hay que saber cuando termina para volver a tocarlo de nuevo, esto se soluciona añadiendo un control timer al form y comprobar si se ha terminado de tocar el fichero, en caso de que sea así, empezar de nuevo... y así hasta que lo detengamos.
Este sería el código del Timer1_Timer:
Private Sub Timer1_Timer() Dim mciStatusParms As MCI_STATUS_PARMS 'Sólo para el MIDI: If IdMIDI Then 'Obtenemos el estado del dispositivo mciStatusParms.dwItem = MCI_STATUS_MODE Call mciSendCommand(IdMIDI, MCI_STATUS, MCI_STATUS_ITEM, _ mciStatusParms) 'Si no se está reproduciendo If mciStatusParms.dwReturn = MCI_MODE_STOP Then 'Empezar de nuevo 'Posicionar el puntero al principio Call mciSendCommand(IdMIDI, MCI_SEEK, _ MCI_SEEK_TO_START, 0) 'Empezar de nuevo Call mciSendCommand(IdMIDI, MCI_PLAY, 0, 0) End If End If End SubEs decir, se comprueba el estado del dispositivo, si el modo que devuelve es que está parado, se posiciona el "puntero" de la canción al principio y se le indica que vuelva a empezar a tocarlo.
Cuando nos hartemos de que toque... lo paramos y ya está. Esto mismo hay que hacerlo al cerrar el FORM...
Veamos el código para detener el MIDI:'Detener el MIDI Call mciSendCommand(IdMIDI, MCI_STOP, 0, 0) Call mciSendCommand(IdMIDI, MCI_CLOSE, 0, 0) IdMIDI = 0 Timer1.Enabled = FalsePara detenerlo, le mandamos un comando STOP y de camino cerramos el dispositivo.
Esto lo podemos tener en un procedimiento, para que lo podamos usar de forma genérica, lo mismo desde un botón que detenga la música como desde el evento UNLOAD del form.
Lo único que necesitaríamos es usar un SUB que haga lo mismo, es decir: PARE y CIERRE.Veamos ahora el código para que la canción empiece a tocar:
' Private Sub TocarMIDI(ByVal sMID As String) 'Tocar un Mid usando mciSendCommand ' Dim mciOpenParms As MCI_OPEN_PARMS If IdMIDI <> 0 Then Call mciSendCommand(IdMIDI, MCI_CLOSE, 0, 0) IdMIDI = 0 End If With mciOpenParms .lpstrElementName = sMID End With Call mciSendCommand(0, MCI_OPEN, _ MCI_OPEN_ELEMENT, _ mciOpenParms) IdMIDI = mciOpenParms.wDeviceID Call mciSendCommand(IdMIDI, MCI_PLAY, 0, 0) Timer1.Enabled = True End SubAquí se comprueba si ya se está usando otro MIDI, en caso de que sea así, se detiene la anterior y se empieza con la nueva.
Ahora bien... ¿cómo sabemos si es un fichero MID o uno WAV?
Pues con una simple comparación... si la extensión es MID, se tocará como MIDI, si es WAV, como WAV...
Vamos a ver el código completo del botón tocar:
Private Sub cmdTocar_Click(Index As Integer) Dim Archivo As String On Local Error Resume Next Archivo = Text1(Index) 'Para tocar un fichero se la llamas así: If InStr(Archivo, ".wav") Then Call sndPlaySound(Archivo, SND_ASYNC + SND_LOOP) ElseIf InStr(Archivo, ".mid") Then TocarMIDI Archivo End If Err = 0 End SubAquí lo único que se hace es saber que fichero queremos tocar, comprobar si la extensión es WAV, en cuyo caso se llama a la función sndPlaySound con los susodichos parámetros ASYNC y LOOP.
El SND_LOOP es el que se encarga de que siempre esté haciendo "bucles", por otra parte SND_ASYNC lo que hace es que no se espere a que el fichero termine de tocar para que se pueda hacer algo después de empezar a tocarlo. Es decir: tocar de forma asíncrona, osease que no haya que esperar a que termine... ¿'ta claro?En caso de ser un MIDI, se llama al procedimiento que hemos visto anteriormente.
Este es el código completo del botón parar:
Private Sub cmdParar_Click() 'Para detener lo que se esté tocando Call sndPlaySound(ByVal "", 0) 'Detener el MIDI Call mciSendCommand(IdMIDI, MCI_STOP, 0, 0) Call mciSendCommand(IdMIDI, MCI_CLOSE, 0, 0) IdMIDI = 0 Timer1.Enabled = False End SubPara detener un fichero WAV, se llama a la función SndPlaySound con una cadena vacía y se para la música.
Para detener un MIDI, también se podría usar la función: mciSendString con el comando "close all" y se pararía el MIDI que estuviese sonando:Call mciSendString("close all", 0, 0, 0)En los listados de ejemplo están todas las declaraciones del API, así cómo las constantes usadas.
Espero que te de pie a investigar un poco más sobre el tema, si es que te interesa... y si "encuentras" los comandos para que se haga de forma "simple" esto de que se toque de forma repetida un MIDI, pues me lo dices, para que el personal se entere de cómo hacerlo... porque haber debe haberlo... pero ¿dónde?
Nos vemos.
Guillermo
Pulsa en este link, si quieres bajarte el listado de ejemplo, se incluyen dos ficheros de prueba (sndAPI_rep.zip 67.8 KB)