[RESOLVED] PDK Sound Service Instance -> Play() Function

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

[RESOLVED] PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Wed Dec 12, 2018 3:24 pm

I'm getting valid HRESULT saying that the SoundServiceInstance Play() function executed normally but no sound. I checked and set the volume and cockpit attenuation and nothing. I even called IsPlaying() and it said the sound was playing?

Any ideas as to what to try next?

User avatar
Brady Butler
Lockheed Martin
Posts: 917
Joined: Tue May 09, 2017 5:31 pm

Re: PDK Sound Service Instance -> Play() Function

Postby Brady Butler » Wed Dec 12, 2018 3:30 pm

Hello,

Is it related to what was reported here? https://www.prepar3d.com/forum/viewtopi ... 2&t=131937

Regards,
Brady
Brady Butler
Prepar3D® Software Engineer

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

Re: PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Wed Dec 12, 2018 5:03 pm

I don't think so, my setup is different, everything is set up for my headset. P3D is set to use the Default device.

User avatar
Rob McCarthy
Lockheed Martin
Posts: 2297
Joined: Wed Aug 24, 2011 1:37 pm

Re: PDK Sound Service Instance -> Play() Function

Postby Rob McCarthy » Thu Dec 13, 2018 12:38 pm

Are you doing any position sets on the sound? Is it potentially too far away to hear?

Regards,
Rob McCarthy
Rob McCarthy
Prepar3D® Core Lead

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

Re: PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Thu Dec 13, 2018 2:30 pm

No, I'm only declaring the pointers in the .h file as private:

Code: Select all

P3D::IPdk* pIPdk = nullptr; CComPtr<P3D::ISoundServiceV440> pPdkSoundService; CComPtr<P3D::ISoundInstanceV440> pPdkGearWarningSoundInstance; LPCWSTR pszSoundFileName = L"..\\SimObjects\\Airplanes\\Aircraft\\Panel\\AircraftSound\\sound.wav";

The only functions I'm calling are the following (in order) all in the .cpp/constructor at this point:

Code: Select all

query_pdk(P3D::IID_IPdkV01, (void **)&pIPdk); pPdkSoundService->CreateSoundInstance(pszSoundFileName, P3D::SOUND_GROUP::SOUND_GROUP_COCKPIT, P3D::VIEW_POINT::VIEW_POINT_INTERIOR, TRUE, FALSE, FALSE, (void **)&pPdkGearWarningSoundInstance);
Then to test functionality calls:

Code: Select all

pPdkGearWarningSoundInstance->GetVolume(); pPdkGearWarningSoundInstance->GetCockpitAttenuation(); pPdkGearWarningSoundInstance->SetVolume(500.0); pPdkGearWarningSoundInstance->SetCockpitAttenuation(1.0); pPdkGearWarningSoundInstance->GetVolume(); pPdkGearWarningSoundInstance->GetCockpitAttenuation();
After that, I call the Play() function:

Code: Select all

pPdkGearWarningSoundInstance->Play();

Then I check if the sound is playing and looping:

Code: Select all

pPdkGearWarningSoundInstance->IsLooping(); pPdkGearWarningSoundInstance->IsPlaying();
I hooked up my logger and between it and the debugger, I verified all the HRESULTs are valid and OK. In fact, I get results for the above that show the sound is playing/looping.

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

Re: PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Thu Dec 13, 2018 4:04 pm

Apologies, this line had a typo,

pPdkGearWarningSoundInstance->SetVolume(500.0);

...it should be:

pPdkGearWarningSoundInstance->SetVolume(9500.0);

and I verified that the sound plays.

Thank you guys for your help in getting this far.

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

Re: PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Sat Dec 15, 2018 4:15 pm

I noticed in the PDK documentation that QueryInterface is supposed to be called on the newly created SoundInstance object. Or at least that is what I inferred. The line below is the call to create the sound instance (All error and exception handling removed for simplicity):

Code: Select all

pPdkSoundService->CreateSoundInstance(pszSoundFileName, P3D::SOUND_GROUP::SOUND_GROUP_COCKPIT, P3D::VIEW_POINT::VIEW_POINT_INTERIOR, TRUE, FALSE, FALSE, (void **)&pPdkGearWarningSoundInstance);
Then I call the QueryInterface that generates the exception,

Code: Select all

pPdkSoundService->QueryInterface(P3D::IID_ISoundInstanceV440, (void**)&pPdkGearWarningSoundInstance);
This is the text of the dialog,

Debug Assertion Failed!
Program: <Path on my machine>\my.dll
File: <Path on my machine>\atlcomcli.h
Line: 199
Expression: p==0

I'm obviously missing something, I can get the sound to play in the constructor without calling QueryInterface, but when I try to play from another function besides the constructor, the call to play returns garbage in the HRESULT. I understood that may be a reference count problem that could be alleviated by doing an AddRef, then I noticed that QueryInterface does an AddRef, and since the doc's said I should do it (but not for the stated reason in the PDK docs), I wanted to try it to see if I could get the calls to play and stop playing in class functions (not the constructor). Any ideas how to solve this?

BenBaron
Posts: 72
Joined: Fri Jan 16, 2015 7:51 am

Re: PDK Sound Service Instance -> Play() Function

Postby BenBaron » Sun Dec 16, 2018 11:18 am

Hi,

I haven't fiddeled around with the SoundService, yet, but the QueryInterface does something different from my understanding and doesn't have something to do with what you're trying to achieve. It is used to query for a different version of an existing interface. So you could directly query the pPdkGearWarningSoundInstance for another version of the IID_ISoundInstance, if available (but there is no different one as of now, as it was only introduced in 4.4). But you cannot query the pPdkSoundService for a SoundInstance, so an exception is expected.

As far as my understanding of what is written in the SDK goes, you should be able to do the pPdkSoundService->CreateSoundInstance call and then work directly on the returned pPdkGearWarningSoundInstance with Play(), Stop() etc.

Greets, Benny

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

Re: PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Sun Dec 16, 2018 12:33 pm

Thanks Benny,

Then the only other question I have is why once the CComPtr which is a class variable (private) is initialized in the constructor becomes useless (the value it returns in the HRESULT looks like a hexidecimal value) when I call the Play() in a class function. I can call play in the constructor and it works. My guess (around 2000 was when I wrote my last COM project) is that I need to do an AddRef but it won't compile. I had earlier or in another thread asked about a canonical or idomatic order of calls to setup the CComPtr for use in a class as a member variable. I've gone over every use of a CComPtr in the PDK samples...I even broke out Don Box's book Essential COM (published a long time ago) and looked through it again. So any help to solve this would be greatly appreciated.

Very Respectfully,

Jim

BenBaron
Posts: 72
Joined: Fri Jan 16, 2015 7:51 am

Re: PDK Sound Service Instance -> Play() Function

Postby BenBaron » Sun Dec 16, 2018 8:46 pm

Hi Jim,

I "might" be fiddeling around with the SoundService and with its instances over the next week for a project of ours, so everything I discover or every problem I'm gonna stumble over, I'm gonna relay here.

But I'd say that you shouldn't need to AddRef manually on the CComPtr in order for it to work, as I'd expect the RefCount to become 2 on the SoundInstance, which should work just fine. One reference that is kept by P3Ds SoundService on creation of the SoundInstance and one reference that is kept by the CComPtr in your code.

Of course, I am just guessing here and I might experience something different, next week :).

But maybe someone else is able to shed a light on your issue, beforehand.

All the best,

Benny

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

Re: PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Sun Dec 16, 2018 11:13 pm

Benny,

Sounds like a plan to me! And thank you for helping.

I had some time to dig a little deeper on this today, I ran down the error when I check if IsPlaying() is true or not, the HRESULT comes back as 0x887800aa. That error code is, I'm pretty sure for the LM sound.dll which I assume is using DirectMusic? I deduce this since the only code I could find for an HRESULT is the one for FACILITY_DIRECTMUSIC, Error 0x887800AA - DSERR_UNINITIALIZED. "This object has not been initialized" is how the documentation reads. Here's the sequence of PDK calls contained in a single class function, PlayGearWarningSound():

Code: Select all

query_pdk(P3D::IID_IPdkV01, (void **)&pIPdk); pIPdk->QueryService(P3D::SID_SoundService, P3D::IID_ISoundServiceV440, (void**)&pPdkSoundService); pPdkSoundService->CreateSoundInstance(pszSoundFileName, P3D::SOUND_GROUP::SOUND_GROUP_COCKPIT, P3D::VIEW_POINT::VIEW_POINT_INTERIOR, TRUE, FALSE, FALSE, (void **)&pPdkGearWarningSoundInstance); pPdkGearWarningSoundInstance->SetVolume(9500.0); pPdkGearWarningSoundInstance->IsPlaying();
I never make it to the call Play() on pPdkGearWarningSoundInstance. That last line doesn't return the S_OK HRESULT, it returns 0x887800aa. So the mystery is how did pPdkGearWarningSoundInstance become uninitialized when all that is between the function calls to that point are reading the HRESULT from each return and logging the result???

V/R
Jim

BenBaron
Posts: 72
Joined: Fri Jan 16, 2015 7:51 am

Re: PDK Sound Service Instance -> Play() Function

Postby BenBaron » Mon Dec 17, 2018 7:09 pm

Jim,

I started implementing the SoundService and I am also seeing the HRESULT 0x887800aa on the first call to IsPlaying(). Nevertheless, I can call Play() on the SoundInstance which also becomes audible and all subsequent calls to IsPlaying() return either S_OK or S_FALSE, as expected. So not much of an issue, I guess.

Now, I am trying to get the sound to play as Environment in 3D and there I am stuck, right now.

All the best,

Benny

Clifton Crane
Lockheed Martin
Posts: 988
Joined: Tue Sep 25, 2012 2:34 pm

Re: PDK Sound Service Instance -> Play() Function

Postby Clifton Crane » Mon Dec 17, 2018 8:01 pm

Hello,

The CreateSoundInstance function will give back a SoundInstance with a ref-count of one. One can then manually call Release() or it can be stored within a CComPtr for automatic release. You should not need to add a reference. Calling CreateSoundInstance essentially hands over ownership to your plugin.

The idea behind the subsequent QueryInterface on the SoundInstance is so that your plugin can verify that version you expected was actually returned. For right now, there is only the ISoundInstanceV440 interface, but that could potentially change with subsequent releases just as other PDK services/interfaces.

I can confirm that IsPlaying() will return S_OK or S_FALSE only after the sound has been played once using the Play() function. I would recommend explicitly checking for S_OK, S_FALSE, and using the FAILED() macro to determine if you should Play() your sound.

As far as playing your sound as Environment in 3D, be sure that you have correctly set the position of the sound as it will default to 0,0,0.

Hope this helps!
Clifton Crane
Prepar3D® Software Engineer

flyboy7798
Posts: 31
Joined: Thu Jul 20, 2017 7:15 pm

Re: PDK Sound Service Instance -> Play() Function

Postby flyboy7798 » Mon Dec 17, 2018 8:12 pm

Benny, thanks for your reply. Thanks, Clifton for the information. Both your responses make sense as to why I'm getting the results in the debugger. I do have a followup question, I declare the both CComPtrs for the sound service and the sound instance as private. I initialize both smart pointers, in the constructor of the class, and set the sound volume on the SoundInstance. After the class is constructed I have a function that checks in a loop if a certain set of conditions is met and then calls a function which has the actual Play() call or another function that has the Stop() call. Are there any problems with the reference count doing this?
Last edited by flyboy7798 on Mon Dec 17, 2018 8:30 pm, edited 2 times in total.

BenBaron
Posts: 72
Joined: Fri Jan 16, 2015 7:51 am

Re: PDK Sound Service Instance -> Play() Function

Postby BenBaron » Mon Dec 17, 2018 8:27 pm

As far as playing your sound as Environment in 3D, be sure that you have correctly set the position of the sound as it will default to 0,0,0.
Thanks Clifton...I noticed I did a stupid mistake there and used SetOrientation instead of SetPosition on the SoundInstance.
Now, it all works like a charm.

All the best, Benny


Return to “Software Development Kit (SDK) Questions”

Who is online

Users browsing this forum: No registered users and 7 guests