Ticket #7351: SystemMixer.diff

File SystemMixer.diff, 8.7 KB (added by pulkomandy, 13 years ago)

Attempt at patching it

  • GameSoundDevice.cpp

     
    8585    fIsConnected(false),
    8686    fSoundCount(kInitSoundCount)
    8787{
    88     fConnection = new Connection;
    8988    memset(&fFormat, 0, sizeof(gs_audio_format));
    9089
    91     fInitError = Connect();
     90    fInitError = B_OK;
    9291
    9392    fSounds = new GameSoundBuffer*[kInitSoundCount];
    9493    for (int32 i = 0; i < kInitSoundCount; i++)
     
    9897
    9998BGameSoundDevice::~BGameSoundDevice()
    10099{
    101     BMediaRoster* roster = BMediaRoster::Roster();
    102 
    103100    // We need to stop all the sounds before we stop the mixer
    104101    for (int32 i = 0; i < fSoundCount; i++) {
    105102        if (fSounds[i])
     
    109106
    110107    if (fIsConnected) {
    111108        // stop the nodes if they are running
    112         roster->StopNode(fConnection->producer, 0, true);
    113             // synchronous stop
    114 
    115         // Ordinarily we'd stop *all* of the nodes in the chain at this point.
    116         // However, one of the nodes is the System Mixer, and stopping the
    117         // Mixer is a Bad Idea (tm). So, we just disconnect from it, and
    118         // release our references to the nodes that we're using.  We *are*
    119         // supposed to do that even for global nodes like the Mixer.
    120         roster->Disconnect(fConnection->producer.node, fConnection->source,
    121             fConnection->consumer.node, fConnection->destination);
    122 
    123         roster->ReleaseNode(fConnection->producer);
    124         roster->ReleaseNode(fConnection->consumer);
    125109    }
    126110
    127111    delete[] fSounds;
    128     delete fConnection;
    129112}
    130113
    131114
     
    168151    int32 position = AllocateSound();
    169152
    170153    if (position >= 0) {
     154        media_node systemMixer;
     155        BMediaRoster::Roster()->GetAudioMixer(&systemMixer);
    171156        fSounds[position] = new SimpleSoundBuffer(format, data, frames);
    172         err = fSounds[position]->Connect(&fConnection->producer);
     157        err = fSounds[position]->Connect(&systemMixer);
    173158    }
    174159
    175160    if (err == B_OK)
     
    189174    int32 position = AllocateSound();
    190175
    191176    if (position >= 0) {
     177        media_node systemMixer;
     178        BMediaRoster::Roster()->GetAudioMixer(&systemMixer);
    192179        fSounds[position] = new StreamingSoundBuffer(format, object);
    193         err = fSounds[position]->Connect(&fConnection->producer);
     180        err = fSounds[position]->Connect(&systemMixer);
    194181    }
    195182
    196183    if (err == B_OK)
     
    296283}
    297284
    298285
    299 status_t
    300 BGameSoundDevice::Connect()
    301 {
    302     BMediaRoster* roster = BMediaRoster::Roster();
    303 
    304     // create your own audio mixer
    305     // TODO: Don't do this!!! See bug #575
    306     // from #575.
    307     // marcusoverhagen : tries to instantiate a new audio mixer, which is bad.
    308     // It should use the system mixer.
    309     dormant_node_info mixer_dormant_info;
    310     int32 mixer_count = 1; // for now, we only care about the first  we find.
    311     status_t err = roster->GetDormantNodes(&mixer_dormant_info,
    312         &mixer_count, 0, 0, 0, B_SYSTEM_MIXER, 0);
    313     if (err != B_OK)
    314         return err;
    315 
    316     //fMixer = new media_node;
    317     err = roster->InstantiateDormantNode(mixer_dormant_info,
    318         &fConnection->producer);
    319     if (err != B_OK)
    320         return err;
    321 
    322     // retieve the system's audio mixer
    323     err = roster->GetAudioMixer(&fConnection->consumer);
    324     if (err != B_OK)
    325         return err;
    326 
    327     int32 count = 1;
    328     media_input mixerInput;
    329     err = roster->GetFreeInputsFor(fConnection->consumer, &mixerInput, 1,
    330         &count);
    331     if (err != B_OK)
    332         return err;
    333 
    334     count = 1;
    335     media_output mixerOutput;
    336     err = roster->GetFreeOutputsFor(fConnection->producer, &mixerOutput, 1,
    337         &count);
    338     if (err != B_OK)
    339         return err;
    340 
    341     media_format format(mixerOutput.format);
    342     err = roster->Connect(mixerOutput.source, mixerInput.destination,
    343         &format, &mixerOutput, &mixerInput);
    344     if (err != B_OK)
    345         return err;
    346 
    347     // set the producer's time source to be the "default" time source, which
    348     // the Mixer uses too.
    349     roster->GetTimeSource(&fConnection->timeSource);
    350     roster->SetTimeSourceFor(fConnection->producer.node,
    351         fConnection->timeSource.node);
    352 
    353     // Start our mixer's time source if need be. Chances are, it won't need to
    354     // be, but if we forget to do this, our mixer might not do anything at all.
    355     BTimeSource* mixerTimeSource = roster->MakeTimeSourceFor(
    356         fConnection->producer);
    357     if (!mixerTimeSource)
    358         return B_ERROR;
    359 
    360     if (!mixerTimeSource->IsRunning()) {
    361         status_t err = roster->StartNode(mixerTimeSource->Node(),
    362             BTimeSource::RealTime());
    363         if (err != B_OK) {
    364             mixerTimeSource->Release();
    365             return err;
    366         }
    367     }
    368 
    369     // Start up our mixer
    370     bigtime_t tpNow = mixerTimeSource->Now();
    371     err = roster->StartNode(fConnection->producer, tpNow + 10000);
    372     mixerTimeSource->Release();
    373     if (err != B_OK)
    374         return err;
    375 
    376     // the inputs and outputs might have been reassigned during the
    377     // nodes' negotiation of the Connect().  That's why we wait until
    378     // after Connect() finishes to save their contents.
    379     fConnection->format = format;
    380     fConnection->source = mixerOutput.source;
    381     fConnection->destination = mixerInput.destination;
    382 
    383     // Set an appropriate run mode for the producer
    384     roster->SetRunModeNode(fConnection->producer,
    385         BMediaNode::B_INCREASE_LATENCY);
    386 
    387     media_to_gs_format(&fFormat, &format.u.raw_audio);
    388     fIsConnected = true;
    389     return B_OK;
    390 }
    391 
    392 
    393286int32
    394287BGameSoundDevice::AllocateSound()
    395288{
  • GameSoundDevice.h

     
    3838
    3939class BGameSoundDevice {
    4040public:
    41                                 BGameSoundDevice();
     41                                    BGameSoundDevice();
    4242    virtual                         ~BGameSoundDevice();
    4343
    44             status_t                InitCheck() const;
     44    status_t                        InitCheck() const;
    4545    virtual const gs_audio_format & Format() const;     
    4646    virtual const gs_audio_format & Format(gs_id sound) const;
    4747       
    4848    virtual status_t                CreateBuffer(gs_id * sound,
    49                                                  const gs_audio_format * format,
    50                                                  const void * data,
    51                                                  int64 frames);
     49                                        const gs_audio_format * format,
     50                                        const void * data,
     51                                        int64 frames);
    5252    virtual status_t                CreateBuffer(gs_id * sound,
    53                                                  const void * object,
    54                                                  const gs_audio_format * format);
     53                                        const void * object,
     54                                        const gs_audio_format * format);
    5555    virtual void                    ReleaseBuffer(gs_id sound);
    5656   
    5757    virtual status_t                Buffer(gs_id sound,
    58                                             gs_audio_format * format,
    59                                             void *& data);
     58                                        gs_audio_format * format,
     59                                        void *& data);
    6060           
    6161    virtual bool                    IsPlaying(gs_id sound);
    6262    virtual status_t                StartPlaying(gs_id sound);
    6363    virtual status_t                StopPlaying(gs_id sound);
    6464           
    6565    virtual status_t                GetAttributes(gs_id sound,
    66                                                 gs_attribute * attributes,
    67                                                 size_t attributeCount);
     66                                        gs_attribute * attributes,
     67                                        size_t attributeCount);
    6868    virtual status_t                SetAttributes(gs_id sound,
    69                                                 gs_attribute * attributes,
    70                                                 size_t attributeCount);
     69                                        gs_attribute * attributes,
     70                                        size_t attributeCount);
    7171                                               
    7272protected:
    7373            void                    SetInitError(status_t error);
    7474               
    7575            gs_audio_format         fFormat;                                           
    7676private:
    77             status_t                Connect();
    7877            int32                   AllocateSound();
    7978           
    8079            status_t                fInitError;
    8180       
    82             Connection *            fConnection;
    8381            bool                    fIsConnected;
    8482           
    8583            int32                   fSoundCount;
  • GameSoundBuffer.cpp

     
    101101    BMediaRoster* roster = BMediaRoster::Roster();
    102102   
    103103    if (fIsConnected) {
    104         // Ordinarily we'd stop *all* of the nodes in the chain at this point.  However,
    105         // one of the nodes is the System Mixer, and stopping the Mixer is a Bad Idea (tm).
    106         // So, we just disconnect from it, and release our references to the nodes that
    107         // we're using.  We *are* supposed to do that even for global nodes like the Mixer.
     104        // Ordinarily we'd stop *all* of the nodes in the chain at this point.
     105        // However, one of the nodes is the System Mixer, and stopping the Mixer
     106        // is a Bad Idea (tm). So, we just disconnect from it, and release our
     107        // references to the nodes that we're using.  We *are* supposed to do
     108        // that even for global nodes like the Mixer.
    108109        roster->Disconnect(fConnection->producer.node, fConnection->source,
    109                             fConnection->consumer.node, fConnection->destination);
     110            fConnection->consumer.node, fConnection->destination);
    110111       
    111112        roster->ReleaseNode(fConnection->producer);
    112113        roster->ReleaseNode(fConnection->consumer);
     
    390391    if (err != B_OK)
    391392                return err;
    392393
    393     err = roster->SetTimeSourceFor(fConnection->producer.node, fConnection->timeSource.node);
    394         if (err != B_OK)
    395                 return err;
     394    err = roster->SetTimeSourceFor(fConnection->producer.node,
     395        fConnection->timeSource.node);
     396    if (err != B_OK)
     397        return err;
    396398    // got the nodes; now we find the endpoints of the connection
    397399    media_input mixerInput;
    398400    media_output soundOutput;