21 [[nodiscard]] ULONG pin_count()
const noexcept;
22 [[nodiscard]]
std::string pin_name(ULONG pin_nr)
const noexcept;
24 [[nodiscard]]
generator<ULONG> find_streaming_pins(audio_direction direction)
const noexcept;
26 [[nodiscard]] GUID pin_category(ULONG pin_nr)
const noexcept;
28 [[nodiscard]] KSPIN_COMMUNICATION pin_communication(ULONG pin_nr)
const noexcept;
42 [[nodiscard]]
generator<T const *> get_pin_properties(ULONG pin_id, KSPROPERTY_PIN property)
const
44 auto r = get_pin_property_data(pin_id, property);
47 auto *header = std::launder(
reinterpret_cast<KSMULTIPLE_ITEM
const *
>(ptr));
49 hilet expected_size = header->Count *
sizeof(T) +
sizeof(KSMULTIPLE_ITEM);
50 if (header->Size != expected_size) {
51 throw io_error(
"KSMULTIPLE_ITEM header corrupt");
54 ptr +=
sizeof(KSMULTIPLE_ITEM);
55 for (
auto i = 0_uz; i != header->Count; ++i) {
56 co_yield std::launder(
reinterpret_cast<T
const *
>(ptr));
68 auto r = get_pin_property_data(pin_id, property);
71 auto *header = std::launder(
reinterpret_cast<KSMULTIPLE_ITEM
const *
>(ptr));
73 ptr +=
sizeof(KSMULTIPLE_ITEM);
74 for (
auto i = 0_uz; i != header->Count; ++i) {
75 auto *item = std::launder(
reinterpret_cast<KSDATARANGE
const *
>(ptr));
78 ptr += item->FormatSize;
86 [[nodiscard]]
std::string get_pin_property_string(ULONG pin_id, KSPROPERTY_PIN property)
const;
89 [[nodiscard]] T get_pin_property(ULONG pin_id, KSPROPERTY_PIN property)
const
91 auto property_info = KSP_PIN{};
92 property_info.Property.Set = KSPROPSETID_Pin;
93 property_info.Property.Id = property;
94 property_info.Property.Flags = KSPROPERTY_TYPE_GET;
95 property_info.PinId = pin_id;
96 property_info.Reserved = 0;
100 if (not DeviceIoControl(_handle, IOCTL_KS_PROPERTY, &property_info,
sizeof(KSP_PIN), &r,
sizeof(T), &r_size, NULL)) {
101 throw io_error(get_last_error_message());
104 if (r_size !=
sizeof(T)) {
105 throw io_error(
"Unexpected return size");
113 auto property_info = KSP_PIN{};
114 property_info.Property.Set = KSPROPSETID_Pin;
115 property_info.Property.Id = property;
116 property_info.Property.Flags = KSPROPERTY_TYPE_GET;
117 property_info.PinId = pin_id;
118 property_info.Reserved = 0;
121 if (DeviceIoControl(_handle, IOCTL_KS_PROPERTY, &property_info,
sizeof(KSP_PIN), NULL, 0, &r_size, NULL)) {
122 throw io_error(
"Unexpected return size 0");
124 if (GetLastError() != ERROR_MORE_DATA) {
128 if (r_size <
sizeof(KSMULTIPLE_ITEM)) {
129 throw io_error(
"Unexpected return size");
132 auto r = std::make_unique<char[]>(r_size);
133 if (not DeviceIoControl(_handle, IOCTL_KS_PROPERTY, &property_info,
sizeof(KSP_PIN), r.get(), r_size, &r_size, NULL)) {
137 if (r_size <
sizeof(KSMULTIPLE_ITEM)) {
138 throw io_error(
"Incomplete header read");
141 auto *header = std::launder(
reinterpret_cast<KSMULTIPLE_ITEM *
>(r.get()));
142 if (r_size < header->Size) {
143 throw io_error(
"Incomplete read");
150 [[nodiscard]]
std::string get_pin_property<std::string>(ULONG pin_id, KSPROPERTY_PIN property)
const
152 auto property_info = KSP_PIN{};
153 property_info.Property.Set = KSPROPSETID_Pin;
154 property_info.Property.Id = property;
155 property_info.Property.Flags = KSPROPERTY_TYPE_GET;
156 property_info.PinId = pin_id;
157 property_info.Reserved = 0;
160 if (DeviceIoControl(_handle, IOCTL_KS_PROPERTY, &property_info,
sizeof(KSP_PIN), NULL, 0, &r_size, NULL)) {
164 if (GetLastError() != ERROR_MORE_DATA) {
168 if (r_size % 2 != 0) {
169 throw io_error(
"Expected even number of bytes in return value.");
172 auto r =
std::wstring(r_size /
sizeof(
wchar_t{}) - 1,
wchar_t{});
173 hi_assert(r_size == (r.size() + 1) *
sizeof(
wchar_t{}));
175 if (not DeviceIoControl(_handle, IOCTL_KS_PROPERTY, &property_info,
sizeof(KSP_PIN), r.data(), r_size, &r_size, NULL)) {
182 [[nodiscard]]
bool is_streaming_interface(ULONG pin_nr)
const noexcept;
184 [[nodiscard]]
bool is_standerdio_medium(ULONG pin_nr)
const noexcept;
186 [[nodiscard]]
bool is_streaming_pin(ULONG pin_nr, audio_direction direction)
const noexcept;