Ticket #7351: SystemMixer.diff
File SystemMixer.diff, 8.7 KB (added by , 13 years ago) |
---|
-
GameSoundDevice.cpp
85 85 fIsConnected(false), 86 86 fSoundCount(kInitSoundCount) 87 87 { 88 fConnection = new Connection;89 88 memset(&fFormat, 0, sizeof(gs_audio_format)); 90 89 91 fInitError = Connect();90 fInitError = B_OK; 92 91 93 92 fSounds = new GameSoundBuffer*[kInitSoundCount]; 94 93 for (int32 i = 0; i < kInitSoundCount; i++) … … 98 97 99 98 BGameSoundDevice::~BGameSoundDevice() 100 99 { 101 BMediaRoster* roster = BMediaRoster::Roster();102 103 100 // We need to stop all the sounds before we stop the mixer 104 101 for (int32 i = 0; i < fSoundCount; i++) { 105 102 if (fSounds[i]) … … 109 106 110 107 if (fIsConnected) { 111 108 // stop the nodes if they are running 112 roster->StopNode(fConnection->producer, 0, true);113 // synchronous stop114 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 the117 // Mixer is a Bad Idea (tm). So, we just disconnect from it, and118 // 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);125 109 } 126 110 127 111 delete[] fSounds; 128 delete fConnection;129 112 } 130 113 131 114 … … 168 151 int32 position = AllocateSound(); 169 152 170 153 if (position >= 0) { 154 media_node systemMixer; 155 BMediaRoster::Roster()->GetAudioMixer(&systemMixer); 171 156 fSounds[position] = new SimpleSoundBuffer(format, data, frames); 172 err = fSounds[position]->Connect(& fConnection->producer);157 err = fSounds[position]->Connect(&systemMixer); 173 158 } 174 159 175 160 if (err == B_OK) … … 189 174 int32 position = AllocateSound(); 190 175 191 176 if (position >= 0) { 177 media_node systemMixer; 178 BMediaRoster::Roster()->GetAudioMixer(&systemMixer); 192 179 fSounds[position] = new StreamingSoundBuffer(format, object); 193 err = fSounds[position]->Connect(& fConnection->producer);180 err = fSounds[position]->Connect(&systemMixer); 194 181 } 195 182 196 183 if (err == B_OK) … … 296 283 } 297 284 298 285 299 status_t300 BGameSoundDevice::Connect()301 {302 BMediaRoster* roster = BMediaRoster::Roster();303 304 // create your own audio mixer305 // TODO: Don't do this!!! See bug #575306 // 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 mixer323 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, which348 // 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 to354 // 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 mixer370 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 the377 // nodes' negotiation of the Connect(). That's why we wait until378 // 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 producer384 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 393 286 int32 394 287 BGameSoundDevice::AllocateSound() 395 288 { -
GameSoundDevice.h
38 38 39 39 class BGameSoundDevice { 40 40 public: 41 BGameSoundDevice();41 BGameSoundDevice(); 42 42 virtual ~BGameSoundDevice(); 43 43 44 status_tInitCheck() const;44 status_t InitCheck() const; 45 45 virtual const gs_audio_format & Format() const; 46 46 virtual const gs_audio_format & Format(gs_id sound) const; 47 47 48 48 virtual status_t CreateBuffer(gs_id * sound, 49 50 51 49 const gs_audio_format * format, 50 const void * data, 51 int64 frames); 52 52 virtual status_t CreateBuffer(gs_id * sound, 53 54 53 const void * object, 54 const gs_audio_format * format); 55 55 virtual void ReleaseBuffer(gs_id sound); 56 56 57 57 virtual status_t Buffer(gs_id sound, 58 59 58 gs_audio_format * format, 59 void *& data); 60 60 61 61 virtual bool IsPlaying(gs_id sound); 62 62 virtual status_t StartPlaying(gs_id sound); 63 63 virtual status_t StopPlaying(gs_id sound); 64 64 65 65 virtual status_t GetAttributes(gs_id sound, 66 67 66 gs_attribute * attributes, 67 size_t attributeCount); 68 68 virtual status_t SetAttributes(gs_id sound, 69 70 69 gs_attribute * attributes, 70 size_t attributeCount); 71 71 72 72 protected: 73 73 void SetInitError(status_t error); 74 74 75 75 gs_audio_format fFormat; 76 76 private: 77 status_t Connect();78 77 int32 AllocateSound(); 79 78 80 79 status_t fInitError; 81 80 82 Connection * fConnection;83 81 bool fIsConnected; 84 82 85 83 int32 fSoundCount; -
GameSoundBuffer.cpp
101 101 BMediaRoster* roster = BMediaRoster::Roster(); 102 102 103 103 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. 108 109 roster->Disconnect(fConnection->producer.node, fConnection->source, 109 110 fConnection->consumer.node, fConnection->destination); 110 111 111 112 roster->ReleaseNode(fConnection->producer); 112 113 roster->ReleaseNode(fConnection->consumer); … … 390 391 if (err != B_OK) 391 392 return err; 392 393 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; 396 398 // got the nodes; now we find the endpoints of the connection 397 399 media_input mixerInput; 398 400 media_output soundOutput;