Changeset 112


Ignore:
Timestamp:
Aug 3, 2006, 5:22:52 PM (19 years ago)
Author:
dmik
Message:

Kernel: QSound: Fixed sound playback on single-streamed audio devices:

  • Preloaded sounds (allocated QSound instances) could not be played;
  • Playing too many sounds simultaneously created too many threads that could screw up the MMPM audio driver (uniaud);
  • Sound playback suspended due to the lack of the resources produced orphan sounds upon resumption (reasoned but not nice).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel/qsound_pm.cpp

    r47 r112  
    129129typedef MMAUDIOHEADER *PMMAUDIOHEADER;
    130130
    131 #define MCI_OPEN_TYPE_ID                    0x00001000L
    132 #define MCI_OPEN_SHAREABLE                  0x00002000L
    133 #define MCI_OPEN_MMIO                       0x00004000L
    134 
    135131typedef struct _MCI_OPEN_PARMS 
    136132{
     
    167163#define MCI_FROM                            0x00000004L
    168164
     165#define MCI_OPEN_TYPE_ID                    0x00001000L
     166#define MCI_OPEN_SHAREABLE                  0x00002000L
     167#define MCI_OPEN_MMIO                       0x00004000L
     168#define MCI_READONLY                        0x00008000L
     169
     170#define MCI_RETURN_RESOURCE                 0x00000100L
     171
     172#define MCI_CLOSE_EXIT                 0x10000000L
     173
    169174#define MCI_OPEN                        1
    170175#define MCI_CLOSE                       2
    171176#define MCI_PLAY                        4
    172177#define MCI_STOP                        6
     178#define MCI_ACQUIREDEVICE               23
     179#define MCI_RELEASEDEVICE               24
     180
     181#define MM_MCINOTIFY                        0x0500
     182#define MM_MCIPASSDEVICE                    0x0501
    173183
    174184#define MCI_NOTIFY_SUCCESSFUL               0x0000
    175 
    176 #define MM_MCINOTIFY                        0x0500
    177 
     185#define MCI_NOTIFY_SUPERSEDED               0x0001
     186
     187#define MCI_LOSING_USE                      0x00000001L
     188#define MCI_GAINING_USE                     0x00000002L
     189
     190#define MCIERR_BASE                      5000
    178191#define MCIERR_SUCCESS                   0
     192#define MCIERR_INSTANCE_INACTIVE         (MCIERR_BASE + 34)
     193#define MCIERR_DEVICE_LOCKED             (MCIERR_BASE + 32)
    179194
    180195// functions resolved by mmio.dll
     
    232247private slots:
    233248
    234     void aboutToQuit() { isAboutToQuit = TRUE; }
     249    void serverUninit();
    235250   
    236251private:   
     
    238253    HWND hwnd;
    239254    bool isOk;
    240     bool isAboutToQuit;
    241255   
    242256    QLibrary mdmLib;
    243257    QLibrary mmioLib;
    244258   
    245     QIntDict< QAuBucketMMPM > buckets;
     259    QIntDict< QAuBucketMMPM > bucketMap;
     260    QPtrList< QAuBucketMMPM > bucketList;
    246261   
    247262    static const char *ClassName;
     
    258273public:
    259274
     275    enum State { Stopped, Playing, Waiting };
     276
    260277    QAuBucketMMPM( QAuServerMMPM *server, QSound *sound );
    261278    QAuBucketMMPM( QAuServerMMPM *server, const QString &soundFile );
    262279    ~QAuBucketMMPM();
    263280
    264     void play();
     281    void open();
     282    void close( bool atExit = FALSE );
     283    bool play();
    265284    void stop();
    266     bool okay() { return fileHandle != NULLHANDLE && deviceId != 0; }
     285    bool okay() { return fileHandle != NULLHANDLE; }
    267286   
    268287    QSound *sound() { return snd; }
    269    
    270     static const char *ClassName;
     288    State state() { return st; }
     289   
     290    void onDeviceGained( bool gained );
     291   
     292#if defined(QT_DEBUG)
     293    QCString fileName() { return fName; };
     294#endif
    271295   
    272296private:
     
    278302   
    279303#if defined(QT_DEBUG)
    280     QCString fileName;
     304    QCString fName;
    281305#endif
    282306
    283307    HMMIO fileHandle;
    284308    USHORT deviceId;
     309   
     310    State st;
    285311};
    286312
     
    288314
    289315QAuBucketMMPM::QAuBucketMMPM( QAuServerMMPM *server, QSound *sound ) :
    290     srv( server ), snd( sound ), fileHandle( NULLHANDLE ), deviceId( 0 )
     316    srv( server ), snd( sound ), fileHandle( NULLHANDLE ), deviceId( 0 ),
     317    st( Stopped )
    291318{
    292319    Q_ASSERT( srv );
    293320    Q_ASSERT( snd );
     321    if ( !srv || !snd )
     322        return;
    294323   
    295324    init( snd->fileName() );
    296     if ( okay() )
    297         srv->buckets.insert( deviceId, this );
    298325}
    299326
    300327QAuBucketMMPM::QAuBucketMMPM( QAuServerMMPM *server, const QString &fileName ) :
    301     srv( server ), snd( NULL ), fileHandle( NULLHANDLE ), deviceId( 0 )
     328    srv( server ), snd( NULL ), fileHandle( NULLHANDLE ), deviceId( 0 ),
     329    st( Stopped )
    302330{
    303331    Q_ASSERT( srv );
     332    if ( !srv )
     333        return;
    304334   
    305335    init( fileName );
    306     if ( okay() )
    307         srv->buckets.insert( deviceId, this );
    308336}
    309337
    310338void QAuBucketMMPM::init( const QString &soundFile )
    311339{
     340    Q_ASSERT( fileHandle == NULLHANDLE );
     341    if ( fileHandle != NULLHANDLE )
     342        return;
     343   
    312344#if !defined(QT_DEBUG)
    313345    QCString
    314346#endif   
    315     fileName = QFile::encodeName( soundFile );
    316    
     347    fName = QFile::encodeName( soundFile );
     348
    317349    MMIOINFO mmioinfo = { 0 };
    318350    mmioinfo.ulTranslate = MMIO_TRANSLATEDATA | MMIO_TRANSLATEHEADER;
    319     fileHandle = mmioOpen( fileName.data(), &mmioinfo, MMIO_READ );
     351    fileHandle = mmioOpen( fName.data(), &mmioinfo, MMIO_READ );
    320352    if ( fileHandle == NULLHANDLE ) {
    321353#if defined(QT_DEBUG)
    322         qDebug( "QAuBucketMMPM: falied to open sound file [%s]",
    323                 fileName.data() );
     354        qDebug( "QAuBucketMMPM: falied to open sound file [%s]", fName.data() );
    324355#endif
    325356        return;
     
    332363#if defined(QT_DEBUG)
    333364        qDebug( "QAuBucketMMPM: [%s] is not a sound file or "
    334                 "has an unsupported format (rc=%04ld)", fileName.data(), rc );
    335 #endif
    336         return;
    337     }
     365                "has an unsupported format (rc=%04hu:%04hu)",
     366                fName.data(), HIUSHORT( rc ), LOUSHORT( rc ) );
     367#endif
     368        mmioClose( fileHandle, 0 );
     369        fileHandle = NULLHANDLE;           
     370        return;
     371    }
     372   
     373    srv->bucketList.append( this );
     374   
     375#if defined(QT_QSOUND_DEBUG)   
     376    qDebug( "QAuBucketMMPM::init(): {%p} [%s]", this, fName.data() );
     377#endif
     378}
     379
     380QAuBucketMMPM::~QAuBucketMMPM()
     381{
     382#if defined(QT_QSOUND_DEBUG)   
     383    qDebug( "~QAuBucketMMPM(): {%p} [%s]", this, fName.data() );
     384#endif   
     385
     386    if ( deviceId )
     387        close( srv->hwnd == NULLHANDLE );
     388
     389    if ( fileHandle != NULLHANDLE ) {           
     390        srv->bucketList.removeRef( this );
     391        mmioClose( fileHandle, 0 );
     392    }
     393}
     394
     395void QAuBucketMMPM::open()
     396{
     397    Q_ASSERT( !deviceId );
     398    if ( deviceId )
     399        return;
    338400   
    339401    MCI_OPEN_PARMS openParams = { 0 };
     402    openParams.hwndCallback = srv->hwnd;
    340403    openParams.pszDeviceType = (PSZ) MAKEULONG( MCI_DEVTYPE_WAVEFORM_AUDIO, 0 );
    341404    openParams.pszElementName = (PSZ) fileHandle;
    342     rc = mciSendCommand( 0, MCI_OPEN, MCI_WAIT | MCI_OPEN_MMIO |
    343                                       MCI_OPEN_SHAREABLE | MCI_OPEN_TYPE_ID,
    344                          &openParams, 0 );               
     405    ULONG rc = mciSendCommand( 0, MCI_OPEN, MCI_WAIT | MCI_OPEN_MMIO | MCI_READONLY |
     406                                  MCI_OPEN_SHAREABLE | MCI_OPEN_TYPE_ID,
     407                               &openParams, 0 );               
    345408    if ( rc != MCIERR_SUCCESS ) {
    346409#if defined(QT_DEBUG)
    347410        qDebug( "QAuBucketMMPM: failed to open a device for sound file [%s] "
    348                 "(rc=%04ld)", fileName.data(), rc );
     411                "(rc=%04hu:%04hu)", fName.data(), HIUSHORT( rc ), LOUSHORT( rc ) );
    349412#endif
    350413        return;
     
    352415   
    353416    deviceId = openParams.usDeviceID;
    354 }
    355 
    356 QAuBucketMMPM::~QAuBucketMMPM()
    357 {
     417   
     418    srv->bucketMap.insert( deviceId, this );
     419
    358420#if defined(QT_QSOUND_DEBUG)   
    359     qDebug( "~QAuBucketMMPM(): this=%p", this );
     421    qDebug( "QAuBucketMMPM::open(): {%p} [%s] deviceId=%08hu",
     422            this, fName.data(), deviceId );
     423#endif
     424}
     425
     426void QAuBucketMMPM::close( bool atExit /* = FALSE */)
     427{
     428    Q_ASSERT( deviceId );
     429    if ( !deviceId )
     430        return;
     431   
     432#if defined(QT_QSOUND_DEBUG)   
     433    qDebug( "QAuBucketMMPM()::close(): {%p} [%s]", this, fName.data() );
    360434#endif   
    361435
    362     if ( okay() )
    363         srv->buckets.remove( deviceId );
    364 
    365     if ( okay() && snd && !srv->isAboutToQuit ) {
    366         // in order to guarantee that the device is closed only after all
    367         // messages for the particular device ID are delivered to WindowProc()
    368         // and that no other device is assigned the same ID until then, we post
    369         // a special message containing fileHandle and deviceId to be closed
    370         WinPostMsg( srv->hwnd, WM_USER,
    371                     MPFROMLONG( fileHandle ), MPFROMSHORT( deviceId ) );
    372     } else {
    373         if ( deviceId != 0 )
    374             mciSendCommand( deviceId, MCI_CLOSE, MCI_WAIT, NULL, 0 );               
    375         if ( fileHandle != NULLHANDLE )           
    376             mmioClose( fileHandle, 0 );
    377     }
    378 }
    379 
    380 void QAuBucketMMPM::play()
    381 {
     436    // remove from the map anyway -- we don't plan to retry
     437    srv->bucketMap.remove( deviceId );
     438
     439    // Use MCI_CLOSE_EXIT to tell the media control driver it should
     440    // close immediately, w/o doing for any notifications, etc.
     441    ULONG param = atExit ? MCI_CLOSE_EXIT : 0;
     442   
     443    ULONG rc = mciSendCommand( deviceId, MCI_CLOSE, param, NULL, 0 );
     444#if defined(QT_DEBUG)
     445    if ( rc != MCIERR_SUCCESS )
     446        qDebug( "QAuBucketMMPM: failed to close the device for sound file [%s] "
     447                "(rc=%04hu:%04hu)",
     448                fName.data(), HIUSHORT( rc ), LOUSHORT( rc ) );
     449#endif
     450    Q_UNUSED( rc );
     451   
     452    st = Stopped;
     453    deviceId = 0;
     454}
     455
     456bool QAuBucketMMPM::play()
     457{
     458#if defined(QT_QSOUND_DEBUG)   
     459    qDebug( "QAuBucketMMPM()::play(): {%p} [%s]", this, fName.data() );
     460#endif   
     461   
     462    if ( !deviceId ) {
     463        open();
     464        if ( !deviceId )
     465            return FALSE;
     466    }
     467   
    382468    MCI_PLAY_PARMS playParams = { 0 };
    383469    playParams.hwndCallback = srv->hwnd;
    384470    playParams.ulFrom = 0; // always play from the beginning
    385    
     471
    386472    ULONG rc = mciSendCommand( deviceId, MCI_PLAY, MCI_NOTIFY | MCI_FROM,
    387                                &playParams, 0 );               
    388 
    389     if ( rc != MCIERR_SUCCESS ) {
    390 #if defined(QT_DEBUG)
    391         qDebug( "QAuBucketMMPM: failed to play sound file [%s] (rc=%04ld)",
    392                 fileName.data(), rc );
    393 #endif
    394     }
     473                               &playParams, 0 );
     474   
     475    if ( LOUSHORT( rc ) == MCIERR_INSTANCE_INACTIVE ) {
     476        // There are not enough simultaneous audio streams. Try to acquire the
     477        // resources and play again. Note that if the device is already acquired
     478        // for exclusive use, this command will not wait but return immediately.
     479        rc = mciSendCommand( deviceId, MCI_ACQUIREDEVICE, MCI_WAIT, NULL, 0 );
     480        if ( rc == MCIERR_SUCCESS ) {
     481            rc = mciSendCommand( deviceId, MCI_PLAY, MCI_NOTIFY | MCI_FROM,
     482                                 &playParams, 0 );               
     483        } else if ( LOUSHORT( rc ) == MCIERR_DEVICE_LOCKED &&
     484                    snd && snd->loops() < 0 ) {
     485            // Enter the special state to let this infinitive sound start
     486            // playing when the resource becomes available.
     487            st = Waiting;
     488            return FALSE;
     489        }
     490    }
     491
     492    if ( rc == MCIERR_SUCCESS ) {
     493        st = Playing;
     494    } else {
     495        st = Stopped;
     496#if defined(QT_DEBUG)
     497        qDebug( "QAuBucketMMPM: failed to play sound file [%s] (rc=%04hu:%04hu)",
     498                fName.data(), HIUSHORT( rc ), LOUSHORT( rc ) );
     499#endif
     500    }
     501   
     502    return st == Playing;
    395503}
    396504
    397505void QAuBucketMMPM::stop()
    398506{
     507    if ( st == Stopped )
     508        return;
     509
     510    // always go to Stopped -- we won't retry
     511    // (this is also used in MM_MCINOTIFY processing)
     512    st = Stopped;
     513   
    399514    ULONG rc = mciSendCommand( deviceId, MCI_STOP, MCI_WAIT, NULL, 0 );               
    400515
    401     if ( rc != MCIERR_SUCCESS ) {
    402 #if defined(QT_DEBUG)
    403         qDebug( "QAuBucketMMPM: failed to stop sound file [%s] (rc=%04ld)",
    404                 fileName.data(), rc );
    405 #endif
     516    if ( rc == MCIERR_SUCCESS ) {
     517        // nothing
     518    } else if ( LOUSHORT( rc ) == MCIERR_INSTANCE_INACTIVE ) {
     519        // The infinite QSound-full bucket is now suspended (some other instance
     520        // has gained the resource). Close this instance to prevent it from
     521        // being automatically resumed later.
     522        close();
     523    } else {
     524#if defined(QT_DEBUG)
     525        qDebug( "QAuBucketMMPM: failed to stop sound file [%s] (rc=%04hu:%04hu)",
     526                fName.data(), HIUSHORT( rc ), LOUSHORT( rc ) );
     527#endif
     528        // last chance to stop
     529        close();
     530    }
     531}
     532
     533void QAuBucketMMPM::onDeviceGained( bool gained )
     534{
     535    if ( gained ) {
     536        // We gained the device resource.
     537        if ( st == Waiting ) {
     538            /// @todo (dmik) For some reason, starting playback from here
     539            //  (i.e. when we've been given the deivce resource back after
     540            //  some other application finished using it exclusively), we can
     541            //  get error 5053 (MCIERR_NO_CONNECTION) or even undocumented 5659.
     542            //  When it happens, subsequent attempts to play something will
     543            //  result into an unkillable hang... Experimemtal for now. 
     544#if 1           
     545            // A QSound-full bucket attempted to play eventually regained
     546            // the resource. Start playing.
     547            play();
     548#else
     549            st = Stopped;
     550#endif
     551        }
     552    } else {
     553        // We lost the device resource.
     554        if ( st == Playing ) {
     555            // Close the instance to prevent the playback from being resumed
     556            // when the device is auto-gained again (by another instance that
     557            // uses MCI_RETURN_RESOURCE in MCI_RELEASEDEVICE). The exception is
     558            // a QSound-full bucket with an infinitive loop (that will continue
     559            // playing when the resuorce is back).
     560            if ( snd ) {
     561                // infinitive loop?
     562                if ( snd->loops() < 0 )
     563                    return;
     564                // decrease loops to zero
     565                while ( srv->decLoop( snd ) > 0 ) ;
     566            }
     567            close();
     568            if ( !snd ) {
     569                // delete QSound-less bucket
     570                delete this;
     571            }
     572        }
    406573    }
    407574}
     
    413580QAuServerMMPM::QAuServerMMPM( QObject* parent ) :
    414581    QAuServer( parent, "OS/2 MMPM Audio Server" ),
    415     isOk( FALSE ), isAboutToQuit( FALSE ),
     582    hwnd( NULLHANDLE ), isOk( FALSE ),
    416583    mdmLib( "mdm.dll" ), mmioLib( "mmio.dll" )
    417584{
     
    450617#if defined(QT_DEBUG)
    451618        qDebug( "QAuServerMMPM: failed to open the default waveaudio device "
    452                 "(rc=%04ld)", rc );
     619                "(rc=%04hu:%04hu)", HIUSHORT( rc ), LOUSHORT( rc ) );
    453620#endif
    454621        return;
     
    458625    mciSendCommand( openParams.usDeviceID, MCI_CLOSE, MCI_WAIT, NULL, 0 );               
    459626   
    460     connect( qApp, SIGNAL( aboutToQuit() ), SLOT( aboutToQuit() ) );
     627    connect( qApp, SIGNAL( aboutToQuit() ), SLOT( serverUninit() ) );
    461628   
    462629    isOk = TRUE;
     
    465632QAuServerMMPM::~QAuServerMMPM()
    466633{
     634    // still alive?
     635    if ( hwnd )
     636        serverUninit();
     637}   
     638
     639void QAuServerMMPM::serverUninit()
     640{
    467641#if defined(QT_QSOUND_DEBUG)   
    468     qDebug( "~QAuServerMMPM(): buckets left: %d", buckets.count() );
    469 #endif
    470 
    471     // deassociate all remaining buckets from QSound objects and delete them
    472     // (note that deleting a bucket will remove it from the dictionary, which
    473     // in turn will update all dictionary iterators to point to the next item,
    474     // so there is no iterator increment statement below)
    475     QIntDictIterator< QAuBucketMMPM > it( buckets );
    476     while ( it.current() ) {
    477         QSound *s = it.current()->sound();
     642    qDebug( "QAuServerMMPM::serverUninit(): buckets left: %d",
     643            bucketList.count() );
     644#endif
     645
     646    Q_ASSERT( hwnd );
     647    if ( hwnd == NULLHANDLE )
     648        return;
     649
     650    WinDestroyWindow( hwnd );
     651    hwnd = NULLHANDLE;
     652
     653    // Deassociate all remaining buckets from QSound objects and delete them
     654    // (note that deleting a bucket will remove it from the list, which
     655    // in turn will advance the current item to the next one, so current() is
     656    // is used instead of next() in the loop).
     657    for ( QAuBucketMMPM *b = bucketList.first(); b; b = bucketList.current() ) {
     658        QSound *s = b->sound();
    478659        if ( s ) {
    479660            // the below call will delete the associated bucket
    480661            setBucket ( s, 0 );
    481662        } else {
    482             delete it.current();
     663            delete b;
    483664        }
    484665    }
    485666   
    486     Q_ASSERT( buckets.count() == 0 );
    487    
     667    Q_ASSERT( bucketList.count() == 0 );
     668    Q_ASSERT( bucketMap.count() == 0 );
     669
    488670    mmioClose = 0;
    489671    mmioOpen = 0;
     
    503685        setBucket( s, b );
    504686#if defined(QT_QSOUND_DEBUG)   
    505         qDebug( "init(): bucket=%p sound=[%s]", b, s->fileName().latin1() );
     687        qDebug( "QAuServerMMPM::init(): bucket=%p [%s]",
     688                b, b->fileName().data() );
    506689#endif       
    507690    } else {
     
    519702    if ( b->okay() ) {
    520703#if defined(QT_QSOUND_DEBUG)   
    521         qDebug( "play(QString): bucket=%p sound=[%s]", b, filename.latin1() );
     704        qDebug( "play(QString): bucket=%p [%s]", b, b->fileName().data() );
    522705#endif       
    523         b->play();
    524         // b will be deleted in WindowProc()
     706        if ( b->play() ) {
     707            // b will be deleted in WindowProc() or in onDeviceGained()
     708        } else {
     709            delete b;
     710        }
    525711    } else {
    526712        delete b;
     
    541727    if ( b ) {
    542728#if defined(QT_QSOUND_DEBUG)   
    543         qDebug( "play(QSound): bucket=%p sound=[%s]", b, s->fileName().latin1() );
     729        qDebug( "play(QSound): bucket=%p [%s]", b, b->fileName().data() );
    544730#endif       
    545731        b->play();
     
    590776            USHORT code = SHORT1FROMMP( mp1 );
    591777            USHORT deviceId = SHORT1FROMMP( mp2 );
     778            USHORT mcimsg = SHORT2FROMMP( mp2 );
    592779#if defined(QT_QSOUND_DEBUG)           
    593             qDebug( "MM_MCINOTIFY: code=%04hX deviceId=%04hX", code, deviceId );
     780            qDebug( "MM_MCINOTIFY: code=0x%04hX, deviceId=%04hu, mcimsg=%04hu",
     781                    code, deviceId, mcimsg );
    594782#endif           
    595 
    596             QAuBucketMMPM *b = that->buckets.find( deviceId );
     783            Q_ASSERT( mcimsg == MCI_PLAY );
     784            if ( mcimsg != MCI_PLAY )
     785                return 0;
     786
     787            QAuBucketMMPM *b = that->bucketMap.find( deviceId );
     788            // There will be a late notification if the sound is
     789            // playing when close() happens. Just return silently.
    597790            if ( !b )
    598791                return 0;
     792
    599793#if defined(QT_QSOUND_DEBUG)           
    600             qDebug( "MM_MCINOTIFY: bucket=%p", b );
     794            qDebug( "MM_MCINOTIFY: bucket=%p [%s]", b, b->fileName().data() );
    601795#endif           
    602796           
    603797            QSound *sound = b->sound();
    604798            if ( sound ) {
    605                 if ( code == MCI_NOTIFY_SUCCESSFUL ) {
     799                bool returnResource = FALSE;
     800                if ( b->state() == QAuBucketMMPM::Stopped ) {
     801                    // It's possible that MCI_STOP is issued right after MCI_PLAY
     802                    // has successfilly finished and sent MM_MCINOTIFY but before
     803                    // we start it again here. Obey the STOP request.
     804                    returnResource = TRUE;
     805                } else if ( code == MCI_NOTIFY_SUCCESSFUL ) {
    606806                    // play the sound until there are no loops left
    607807                    int loopsLeft = that->decLoop( sound );
    608808                    if ( loopsLeft != 0 )
    609809                        b->play();
     810                    else
     811                        returnResource = TRUE;
     812                } else if ( code != MCI_NOTIFY_SUPERSEDED ) {
     813                    returnResource = TRUE;
     814                }
     815                if ( returnResource ) {
     816                    // let infinitive sounds continue playing
     817                    mciSendCommand( deviceId, MCI_RELEASEDEVICE,
     818                                    MCI_RETURN_RESOURCE, NULL, 0 );
    610819                }
    611820            } else {
    612                 // delete QSound'less bucket when finished or stopped playing
     821                // delete QSound-less bucket when finished or stopped playing
     822                // (closing the instance will return the resource)
    613823                delete b;
    614824            }
     
    616826            return 0;
    617827        }
    618         case WM_USER: {
    619             HMMIO fileHandle = LONGFROMMP( mp1 );
    620             USHORT deviceId = SHORT1FROMMP( mp2 );
     828        case MM_MCIPASSDEVICE: {
     829            if ( !that )
     830                return 0;
     831           
     832            USHORT deviceId = SHORT1FROMMP( mp1 );
     833            USHORT event = SHORT1FROMMP( mp2 );
    621834#if defined(QT_QSOUND_DEBUG)           
    622             qDebug( "WM_USER: deviceId=%04hX", deviceId );
     835            qDebug( "MM_MCIPASSDEVICE: deviceId=%04hu, event=0x%04hX",
     836                    deviceId, event );
    623837#endif           
    624             // there should be no buckets with the given ID at this point
    625             Q_ASSERT( that->buckets.find( deviceId ) == 0 );
    626             mciSendCommand( deviceId, MCI_CLOSE, MCI_WAIT, NULL, 0 );               
    627             mmioClose( fileHandle, 0 );
     838            QAuBucketMMPM *b = that->bucketMap.find( deviceId );
     839            if ( !b )
     840                return 0;
     841
     842#if defined(QT_QSOUND_DEBUG)           
     843            qDebug( "MM_MCIPASSDEVICE: bucket=%p [%s]", b, b->fileName().data() );
     844#endif
     845            // Note: this call may delete b
     846            b->onDeviceGained( event == MCI_GAINING_USE );
     847           
     848            return 0;
    628849        }
    629850    }
Note: See TracChangeset for help on using the changeset viewer.