Thanks Matthew, that's fixed it! Jeff -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Matthew van Eerde Sent: Friday, 8 June 2012 2:18 AM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? For KSPROPERTY_AUDIO_PEAKMETER2 the ranges have to be LONG_MIN (0x80000000) and LONG_MAX (0x7fffffff) rather than 0x8000 and 0x7fff. Reported values should 0 for silence, LONG_MAX for a full-scale signal, and LONG_MAX/2 for a signal that ranges from (-0.5 to 0.5) * full scale. -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jeff Pages Sent: Wednesday, June 6, 2012 5:46 PM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? Hi Matthew, Good catch, I've now modified my basic support handler to set KSPROPERTY_MEMBERSHEADER.Flags field to KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL, set the MembersCount to 2 and included two KSPROPERTY_BOUNDS_LONG elements. Unfortunately, it hasn't solved the problem. I still see my property handler being called for each channel (left and right) with it returning STATUS_SUCCESS each time, but IAudioMeterInformation::GetPeakValue() and IAudioMeterInformation::GetChannelsPeakValues() both return E_INVALIDARG. IAudioMeterInformation::GetMeteringChannelCount succeeds and returns a channel count of 2. I noticed in the documentation for KSPROPERTY_AUDIO_PEAKMETER2 that it says, "This property retrieves the maximum audio signal level that occurred at a peakmeter node (KSNODETYPE_PEAKMETER)" but in the table immediately below that it says that the target is a pin. Is that an error, or should I now be trying to put the peak meter property handler on a pin (presumably the topology port's bridge pin) instead of using a KSNODETYPE_PEAKMETER node? Anyway, here's my entire property handler, in case anything else jumps out as being wrong: NTSTATUS CMiniportTopologyAur::PropertyHandler_Meter ( IN PPCPROPERTY_REQUEST PropertyRequest ) { PAGED_CODE (); ASSERT (PropertyRequest); DOUT (DBG_PROPERTY, ("[CMiniportTopologyAur::PropertyHandler_Meter]")); NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; TopoNodes NodeDef; LONG channel; // The major target is the object pointer to the topology miniport. CMiniportTopologyAur *that = (CMiniportTopologyAur *) PropertyRequest->MajorTarget; ASSERT (that); // validate node if (PropertyRequest->Node == (ULONG)-1) { DOUT (DBG_ERROR, ("PropertyRequest->Node == -1")); return ntStatus; } // do the appropriate action for the request. // we should do a get or a set? if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET)) { // validate parameters if ((PropertyRequest->InstanceSize < sizeof(LONG)) || (PropertyRequest->ValueSize < sizeof(LONG))) { DOUT (DBG_ERROR, ("PropertyValue->InstanceSize = %d PropertyRequest->ValueSize = %d", PropertyRequest->InstanceSize, PropertyRequest->ValueSize)); return ntStatus; } // get channel information channel = *((PLONG)PropertyRequest->Instance); // check channel types, return when unknown if ((channel != CHAN_LEFT) && (channel != CHAN_RIGHT)) { DOUT (DBG_ERROR, ("PropertyHandlerMeter unknown channel %d\n", channel)); return ntStatus; } // get the buffer PLONG Level = (PLONG)PropertyRequest->Value; // Switch on the node id. This is just for parameter checking. // If something goes wrong, we will immediately return with // ntStatus, which is STATUS_INVALID_PARAMETER. switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node)) { case NODE_MASTER_INPUT_METER: // check type if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_PEAKMETER2) { DOUT (DBG_ERROR, ("Input Meter: PropertyRequest->PropertyItem->Id == %d", PropertyRequest->PropertyItem->Id)); return ntStatus; } if (channel == CHAN_LEFT) { that->AdapterCommon->ReadLevel (Level, 0); DOUT (DBG_PRINT, ("GET input level left = 0x%x", *Level)); } else { // here goes mono or stereo-right that->AdapterCommon->ReadLevel (Level, 1); DOUT (DBG_PRINT, ("GET input level right = 0x%x", *Level)); } break; case NODE_MASTER_OUTPUT_METER: // check type if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_PEAKMETER2) { DOUT (DBG_ERROR, ("Output Meter: PropertyRequest->PropertyItem->Id == %d", PropertyRequest->PropertyItem->Id)); return ntStatus; } if (channel == CHAN_LEFT) { that->AdapterCommon->ReadLevel (Level, 8); DOUT (DBG_PRINT, ("GET output level left = 0x%x", *Level)); } else { // here goes mono or stereo-right that->AdapterCommon->ReadLevel (Level, 9); DOUT (DBG_PRINT, ("GET output level right = 0x%x", *Level)); } break; case NODE_INVALID: default: // Ooops DOUT (DBG_ERROR, ("PropertyHandler_Level: Invalid node %d requested.", NodeDef)); return ntStatus; } ntStatus = STATUS_SUCCESS; } else { if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) { // if there is enough space for a KSPROPERTY_DESCRIPTION information if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION))) { // we return a KSPROPERTY_DESCRIPTION structure. PKSPROPERTY_DESCRIPTION PropDesc = (PKSPROPERTY_DESCRIPTION)PropertyRequest->Value; PropDesc->AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET; PropDesc->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + 2 * sizeof(KSPROPERTY_BOUNDS_LONG); PropDesc->PropTypeSet.Set = KSPROPTYPESETID_General; PropDesc->PropTypeSet.Id = VT_I4; PropDesc->PropTypeSet.Flags = 0; PropDesc->MembersListCount = 1; PropDesc->Reserved = 0; // if return buffer can also hold a range description, return it too if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + 2 * sizeof(KSPROPERTY_BOUNDS_LONG))) { // fill in the members header PKSPROPERTY_MEMBERSHEADER Members = (PKSPROPERTY_MEMBERSHEADER)(PropDesc + 1); Members->MembersFlags = KSPROPERTY_MEMBER_RANGES; Members->MembersSize = sizeof(KSPROPERTY_BOUNDS_LONG); Members->MembersCount = 2; Members->Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL; // fill in the range PKSPROPERTY_BOUNDS_LONG Range = (PKSPROPERTY_BOUNDS_LONG)(Members + 1); for (ULONG i = 0; i < Members->MembersCount; i++) { Range[i].SignedMinimum = -32768; Range[i].SignedMaximum = 32767; } // set the return value size PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + 2 * sizeof(KSPROPERTY_BOUNDS_LONG); } else { // we hadn't enough space for the range information; // set the return value size PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION); } ntStatus = STATUS_SUCCESS; } else if (PropertyRequest->ValueSize >= sizeof(ULONG)) { // if return buffer can hold a ULONG, return the access flags PULONG AccessFlags = (PULONG)PropertyRequest->Value; *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET; // set the return value size PropertyRequest->ValueSize = sizeof(ULONG); ntStatus = STATUS_SUCCESS; } } } DOUT (DBG_PRINT, ("Returning %x", ntStatus)); return ntStatus; } Jeff -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Matthew van Eerde Sent: Thursday, 7 June 2012 2:34 AM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? One possible cause for a return of E_INVALIDARG could indicate that there is a mismatch between the number of channels supported by the peak meter property and the number of channels in the device format (WAVEFORMATEX.nChannels). It looks like from your description below that the number of channels supported by the peak meter is one. How many channels are in the device format? -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jeff Pages Sent: Tuesday, June 5, 2012 11:24 PM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? I've since discovered mention of KSPROPERTY_AUDIO_PEAKMETER2 which, according to its documentation: "The KSPROPERTY_AUDIO_PEAKMETER2 property is almost identical to the KSPROPERTY_AUDIO_PEAKMETER property. The KSPROPERTY_AUDIO_PEAKMETER2 property was introduced with Windows 8 and later operating systems to provide improved hardware metering of a pin topology. The legacy KSPROPERTY_AUDIO_PEAKMETER property has been retained for backward compatibility." I've tried implementing a property handler for this in my driver, and IAudioMeterInformation::QueryHardwareSupport() now shows the ENDPOINT_HARDWARE_SUPPORT_METER bit set. However, while in the debugger I can see it reading the left and right peaks and returning STATUS_SUCCESS, IAudioMeterInformation::GetPeakValue() and IAudioMeterInformation::GetChannelsPeakValues() both return an error value of 0x80000057 (invalid parameter). Curiously, when my property handler is first called, PropertyRequest->ValueSize is 16, then it calls it again with this set PropertyRequest->to 4 (sizeof(LONG) as expected). Is there some undocumented behaviour here? And what does "**almost** identical to the KSPROPERTY_AUDIO_PEAKMETER property" mean? What's the difference? For the record, in the KSPROPERTY_TYPE_BASICSUPPORT call, I return the following in the KSPROPERTY_DESCRIPTION field: PKSPROPERTY_DESCRIPTION PropDesc = (PKSPROPERTY_DESCRIPTION)PropertyRequest->Value; PropDesc->AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET; PropDesc->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_BOUNDS_LONG); PropDesc->PropTypeSet.Set = KSPROPTYPESETID_General; PropDesc->PropTypeSet.Id = VT_I4; PropDesc->PropTypeSet.Flags = 0; PropDesc->MembersListCount = 1; PropDesc->Reserved = 0; and for the KSPROPERTY_MEMBERSHEADER field, PKSPROPERTY_MEMBERSHEADER Members = (PKSPROPERTY_MEMBERSHEADER)(PropDesc + 1); Members->MembersFlags = KSPROPERTY_MEMBER_RANGES; Members->MembersSize = sizeof(KSPROPERTY_BOUNDS_LONG); Members->MembersCount = 1; Members->Flags = 0; and for the KSPROPERTY_BOUNDS_LONG field, PKSPROPERTY_BOUNDS_LONG Range = (PKSPROPERTY_BOUNDS_LONG)(Members + 1); Range->SignedMinimum = -32768; Range->SignedMaximum = 32767; Is there anything I'm doing wrong in this? I'm doing the same for KSPROPERTY_AUDIO_PEAKMETER2 in the Windows 8 driver as I do for KSPROPERTY_AUDIO_PEAKMETER in Windows 7, which works fine. Jeff -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jeff Pages Sent: Friday, 1 June 2012 2:02 PM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? I've just installed the latest Windows 8 Release Preview, but it looks like hardware peak meters are still not being recognised, with IAudioMeterInformation::QueryHardwareSupport not setting the ENDPOINT_HARDWARE_SUPPORT_METER bit, and the GetPeakValue and GetChannelsPeakValues functions using the software-based metering instead of our card's peak meter nodes. Jeff -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jeff Pages Sent: Monday, 5 March 2012 2:05 PM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? Thanks Matthew. Looking at it with the debugger, it appears my peak meter property handler isn't being called at all in Windows 8. Jeff -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Matthew van Eerde Sent: Saturday, 3 March 2012 9:52 AM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? Thank you. We will look into this further. -----Original Message----- From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jeff Pages Sent: Friday, March 02, 2012 11:41 AM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? Hi Matthew, The peak meter values are now coming from the OS. Jeff ----- Original Message ----- From: "Matthew van Eerde" <Matthew.van.Eerde@xxxxxxxxxxxxx> To: <wdmaudiodev@xxxxxxxxxxxxx> Sent: Saturday, March 03, 2012 4:46 AM Subject: [wdmaudiodev] Re: Are hardware peak meters supported on Windows 8? > Is the problem limited to QueryHardwareSupport? Or is your peak meter > handler no longer getting called, and the peak meter values are now > coming > from the OS? > > -----Original Message----- > From: wdmaudiodev-bounce@xxxxxxxxxxxxx > [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jeff Pages > Sent: Thursday, March 01, 2012 5:44 PM > To: wdmaudiodev@xxxxxxxxxxxxx > Subject: [wdmaudiodev] Re: Are hardware peak meters supported on > Windows 8? > > The devices are our own range of sound cards > (http://www.innescorp.com.au/categories/72_professional_pci_sound_card > s) > and > radio broadcast capture cards > (http://www.innescorp.com.au/categories/73_radio_capture_cards). The > peak meter nodes support the KSPROPERTY_AUDIO_PEAKMETER and > KSPROPERTY_AUDIO_CPU_RESOURCES requests as per the WDK documentation > and, as I said, work fine on the earlier versions of Windows. > > Jeff > > > -----Original Message----- > From: wdmaudiodev-bounce@xxxxxxxxxxxxx > [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Cheng-mean Liu > (SOCCER) > Sent: Friday, 2 March 2012 12:28 PM > To: wdmaudiodev@xxxxxxxxxxxxx > Subject: [wdmaudiodev] Re: Are hardware peak meters supported on > Windows 8? > > That sounds like a bug to me. > > What audio device are you using? > > -----Original Message----- > From: wdmaudiodev-bounce@xxxxxxxxxxxxx > [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jeff Pages > Sent: Thursday, March 01, 2012 4:21 PM > To: wdmaudiodev@xxxxxxxxxxxxx > Subject: [wdmaudiodev] Are hardware peak meters supported on Windows 8? > > Most of our cards have hardware peak meters in their topology, which > work fine on XP, Vista and Windows 7, but on the Windows 8 Consumer > Preview they are ignored, with > IAudioMeterInformation::QueryHardwareSupport not setting the > ENDPOINT_HARDWARE_SUPPORT_METER bit. Is this by design, a bug, or is > there some trick to making them work? > > Jeff > > ****************** > > WDMAUDIODEV addresses: > Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx > Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe > Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe > Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx > > URL to WDMAUDIODEV page: > http://www.wdmaudiodev.com/ > > > > ****************** > > WDMAUDIODEV addresses: > Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx > Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe > Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe > Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx > > URL to WDMAUDIODEV page: > http://www.wdmaudiodev.com/ > > > ****************** > > WDMAUDIODEV addresses: > Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx > Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe > Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe > Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx > > URL to WDMAUDIODEV page: > http://www.wdmaudiodev.com/ > > > > ****************** > > WDMAUDIODEV addresses: > Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx > Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe > Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe > Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx > > URL to WDMAUDIODEV page: > http://www.wdmaudiodev.com/ > ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/ ****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.com/