Newsgroup: it.comp.lang.visual-basic
Titolo: Gestire l'audio con le API Multimedia

Ciao,
faccio riferimento ad un mio post:
"Gestire l'audio con la winmm in una DLL ActiveX"
Sto cercando di capire perchè non funge!! Dunque...
Ho una classe in una DLL Ax che crea una finestra invisibile per
ricevere imessaggi:
------------------------------------------------------------------------
Private Sub Class_Initialize()
    'Creo la finestra per la ricezione dei messaggi
    hWnd = CreateWindowEx(WS_EX_TRANSPARENT, _
                          "STATIC", _
                          "NULL", _
                          (Not WS_VISIBLE), _
                          0&, 0&, 100&, 100&, 0&, 0&, 0&, ByVal 0&)
    'Subclasso la finestra
    MHookMe.HookWindow hWnd, Me
End Sub
------------------------------------------------------------------------
Utilizzando questo metodo per il subclassing:
http://vb.mvps.org/samples/project.asp?id=hookme
Ora, nella WindowProc ho il seguente codice:
------------------------------------------------------------------------
Private Function IHookSink_WindowProc(hWnd As Long, msg As Long, wp As
Long, lp As Long) As Long
    Dim wavhdr As WAVEHDR
    Static DataRemaining As Long
    Dim i As Integer
    If (msg = MM_WOM_DONE) Then
        CopyMemory wavhdr, lp, 4
        If (mStatus = STATE_PLAYING) Then
            'Sto ancora suonando
            DataRemaining = (dataOffset + _
                            WaveLenght - mmioSeek(hmmioIn, 0, SEEK_CUR))
            If (WaveBufferSize < DataRemaining) Then
                RetVal = mmioRead(hmmioIn, _
                                  wavhdr.lpData, _
                                  WaveBufferSize)
            Else
                'Invio l'ultima parte di dati
                RetVal = mmioRead(hmmioIn, wavhdr.lpData, DataRemaining)
                mStatus = STATE_STOPPED
            End If
            wavhdr.dwBufferLength = RetVal
            RetVal = waveOutWrite(hWaveOut, wavhdr, Len(wavhdr))
        Else
            For i = 0 To NUM_BUFFERS - 1
                waveOutUnprepareHeader hWaveOut, _
                                       WaveHeader(i), _
                                       Len(WaveHeader(i))
                'Libero la memoria
                GlobalFree hmem(i)
            Next
            waveOutClose hWaveOut
            hWaveOut = 0
        End If
    End If
    IHookSink_WindowProc = MHookMe.InvokeWindowProc(hWnd, msg, wp, lp)
End Function
------------------------------------------------------------------------
Il problema è che la funzione mmioRead ritorna -1 (a causa di un errore)
e alla finestra non vengono inviati più messaggi.
Nella mia funzione Play ho :
------------------------------------------------------------------------
    For i = 0 To NUM_BUFFERS - 1
        GlobalFree hmem(i)
        hmem(i) = GlobalAlloc(0, WaveBufferSize)
        WaveHeader(i).lpData = GlobalLock(hmem(i))
        If WaveHeader(i).lpData = 0 Then
            'Impossibile allocare la memoria
            Play = GetLastError
            GoTo Play_Error
        End If
        WaveHeader(i).dwBufferLength = WaveBufferSize
        WaveHeader(i).dwFlags = 0
        WaveHeader(i).dwLoops = 0
        'Preparo gli header
        Play = waveOutPrepareHeader(hWaveOut, _
                                    WaveHeader(i), _
                                    Len(WaveHeader(i)))
        If (Play <> MMSYSERR_NOERROR) Then GoTo Play_Error
    Next
    startPos = mmioSeek(hmmioIn, 0, SEEK_CUR) - dataOffset
    mStatus = STATE_PLAYING
    For i = 0 To NUM_BUFFERS - 1
        PostWavMessage hWnd, MM_WOM_DONE, 0, WaveHeader(i)
    Next
------------------------------------------------------------------------
Avete qualche idea?
PS per Rafunk.
Raf, hai detto che hai fatto una cosa simile per i MIDI....mi puoi dare
qualche consiglio in merito?
Tnx!
Daniele.
-- 
*******************
Free As In Freedom
-= 
www.fsf.org
 =-

qualche consiglio in merito?
Anche io sarei interessato....

 Daniele.
Prima di tutto, hai guardato l'esempio classico di utilizzo delle multimedia API
con VB?
http://support.microsoft.com/?scid=%2Fsupport%2Fkb%2Farticles%2Fq182%2F9%2F83.asp
Il mio progetto MIDI era assai più semplice, non avendo a che fare con uno
"stream" audio: in pratica si limitava ad inviare note e altri messaggi in
maniera estemporanea, e non continuativa leggendo da un file.
Nel Class_Initialize la finestra invisibile l'ho creata chiamando una funzione
che esegui:
    hwndCallback = CreateWindowEx(WS_EX_TRANSPARENT, "static", "MIDI Callback
Window", _
                        WS_OVERLAPPED, 0&, 0&, 0&, 0&, 0&, 0&,
CLng(App.hInstance), 0&)
In ogni caso per il subclassing non ho usato codice di terze parti, ma l'ho
scritto io stesso.
Un apposito modulo BAS contiene una funzione, chiamata nel Class_Initialize, che
attiva il subclassing in questo modo:
    pcbOldWindowProc = SetWindowLong(hwndCallback, GWL_WNDPROC, AddressOf
WindowProc)
Ed un'altra, chiamata nel Class_Terminate lo disattiva così:
    SetWindowLong hwndCallback, GWL_WNDPROC, pcbOldWindowProc
pcbOldWindowProc è una variabile di modulo, mentre WindowProc è una funzione
privata:
Private Function WindowProc(ByVal hWnd As Long, ByVal lMsg As Long, ByVal wParam
As Long, ByVal lParam As Long) As Long
        Select Case lMsg
        Case MM_MIM_OPEN To MM_MIM_LONGERROR, MM_MIM_MOREDATA
        ...
        Case MM_MOM_OPEN To MM_MOM_DONE
        ...
        End Select
        WindowProc = CallWindowProc(pcbOldWindowProc, hWnd, lMsg, wParam,
lParam)
End Function
Questa a grandi linee era l'infrastruttura. Non so se possa esserti utile...
Ciao

 scritto io stesso.
Bè, il codice che uso è molto comodo perchè ti permette di gestire i
messaggi in arrivo direttamente all'interno della classe anzichè gestire
tutto nel modulo BAS.
Adesso faccio un po' di prove e ti faccio sapere!
Grazie!
Ciao...
-- 
Free As In Freedom
www.fsf.org