X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdrivers%2Fusb%2Fusbaudio%2Fpin.c;h=f0a50dad416c00321884cd16c534643d866382f9;hp=e9d5c05a76e827f6055c85433a76beca89c2338c;hb=ff46d90618147a15a0bc3bb66b9d28cdb5d4595a;hpb=d1faa1a99f81f8fa1c36d456e65936140c35a1e3 diff --git a/reactos/drivers/usb/usbaudio/pin.c b/reactos/drivers/usb/usbaudio/pin.c index e9d5c05a76e..f0a50dad416 100644 --- a/reactos/drivers/usb/usbaudio/pin.c +++ b/reactos/drivers/usb/usbaudio/pin.c @@ -9,6 +9,167 @@ #include "usbaudio.h" +NTSTATUS +UsbAudioSetFormat( + IN PKSPIN Pin) +{ + PURB Urb; + PUCHAR SampleRateBuffer; + PPIN_CONTEXT PinContext; + NTSTATUS Status; + PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx; + + /* allocate sample rate buffer */ + SampleRateBuffer = AllocFunction(sizeof(ULONG)); + if (!SampleRateBuffer) + { + /* no memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (IsEqualGUIDAligned(&Pin->ConnectionFormat->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) && + IsEqualGUIDAligned(&Pin->ConnectionFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) && + IsEqualGUIDAligned(&Pin->ConnectionFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) + { + WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat; + SampleRateBuffer[0] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 16) & 0xFF; + SampleRateBuffer[1] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 8) & 0xFF; + SampleRateBuffer[2] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 0) & 0xFF; + + /* TODO: verify connection format */ + } + else + { + /* not supported yet*/ + UNIMPLEMENTED; + FreeFunction(SampleRateBuffer); + return STATUS_INVALID_PARAMETER; + } + + /* allocate urb */ + Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); + if (!Urb) + { + /* no memory */ + FreeFunction(SampleRateBuffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* format urb */ + UsbBuildVendorRequest(Urb, + URB_FUNCTION_CLASS_ENDPOINT, + sizeof(URB), + USBD_TRANSFER_DIRECTION_OUT, + 0, + 0x01, + 0x100, + 0x81, //FIXME bEndpointAddress + SampleRateBuffer, + NULL, + 3, + NULL); + + /* get pin context */ + PinContext = Pin->Context; + DbgBreakPoint(); + /* submit urb */ + Status = SubmitUrbSync(PinContext->LowerDevice, Urb); + + DPRINT1("USBAudioPinSetDataFormat Pin %p Status %x\n", Pin, Status); + FreeFunction(Urb); + FreeFunction(SampleRateBuffer); + return Status; +} + +NTSTATUS +USBAudioSelectAudioStreamingInterface( + IN PDEVICE_EXTENSION DeviceExtension, + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor) +{ + PURB Urb; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + NTSTATUS Status; + + /* grab interface descriptor */ + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); + if (!InterfaceDescriptor) + { + /* no such interface */ + return STATUS_INVALID_PARAMETER; + } + + /* select the first interface with audio streaming and non zero num of endpoints */ + while (InterfaceDescriptor != NULL) + { + if (InterfaceDescriptor->bInterfaceSubClass == 0x02 /* AUDIO_STREAMING */ && InterfaceDescriptor->bNumEndpoints > 0) + { + break; + } + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1); + } + + if (!InterfaceDescriptor) + { + /* no such interface */ + return STATUS_INVALID_PARAMETER; + } + + Urb = AllocFunction(GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints)); + if (!Urb) + { + /* no memory */ + return USBD_STATUS_INSUFFICIENT_RESOURCES; + } + + /* now prepare interface urb */ + UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting); + + /* copy interface information */ + RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceInfo, DeviceExtension->InterfaceInfo->Length); + + /* set configuration handle */ + Urb->UrbSelectInterface.ConfigurationHandle = DeviceExtension->ConfigurationHandle; + + /* now select the interface */ + Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb); + + DPRINT1("USBAudioSelectAudioStreamingInterface Status %x UrbStatus %x\n", Status, Urb->UrbSelectInterface.Hdr.Status); + + /* did it succeeed */ + if (NT_SUCCESS(Status)) + { + /* update configuration info */ + ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceInfo->Length); + RtlCopyMemory(DeviceExtension->InterfaceInfo, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length); + } + + /* free urb */ + FreeFunction(Urb); + return Status; +} + +NTSTATUS +InitCapturePin( + IN PKSPIN Pin) +{ + NTSTATUS Status; + + /* set sample rate */ + Status = UsbAudioSetFormat(Pin); + + /* TODO: init pin */ + return Status; +} + +NTSTATUS +InitStreamPin( + IN PKSPIN Pin) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + + NTSTATUS NTAPI USBAudioPinCreate( @@ -18,6 +179,7 @@ USBAudioPinCreate( PKSFILTER Filter; PFILTER_CONTEXT FilterContext; PPIN_CONTEXT PinContext; + NTSTATUS Status; Filter = KsPinGetParentFilter(Pin); if (Filter == NULL) @@ -44,6 +206,25 @@ USBAudioPinCreate( /* store pin context*/ Pin->Context = PinContext; + /* select streaming interface */ + Status = USBAudioSelectAudioStreamingInterface(PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor); + if (!NT_SUCCESS(Status)) + { + /* failed */ + return Status; + } + + if (Pin->DataFlow == KSPIN_DATAFLOW_OUT) + { + /* init capture pin */ + Status = InitCapturePin(Pin); + } + else + { + /* audio streaming pin*/ + Status = InitStreamPin(Pin); + } + return STATUS_SUCCESS; } @@ -63,7 +244,6 @@ NTAPI USBAudioPinProcess( _In_ PKSPIN Pin) { - UNIMPLEMENTED return STATUS_SUCCESS; } @@ -85,70 +265,14 @@ USBAudioPinSetDataFormat( _In_ const KSDATARANGE* DataRange, _In_opt_ const KSATTRIBUTE_LIST* AttributeRange) { - PURB Urb; - PUCHAR SampleRateBuffer; - PPIN_CONTEXT PinContext; - NTSTATUS Status; - PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx; - - /* allocate sample rate buffer */ - SampleRateBuffer = AllocFunction(sizeof(ULONG)); - if (!SampleRateBuffer) + if (OldFormat == NULL) { - /* no memory */ - return STATUS_INSUFFICIENT_RESOURCES; - } - - if (IsEqualGUIDAligned(&Pin->ConnectionFormat->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) && - IsEqualGUIDAligned(&Pin->ConnectionFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) && - IsEqualGUIDAligned(&Pin->ConnectionFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) - { - WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat; - SampleRateBuffer[0] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 16) & 0xFF; - SampleRateBuffer[1] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 8) & 0xFF; - SampleRateBuffer[2] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 0) & 0xFF; - } - else - { - /* not supported yet*/ - UNIMPLEMENTED; - FreeFunction(SampleRateBuffer); - return STATUS_INVALID_PARAMETER; + /* TODO: verify connection format */ + UNIMPLEMENTED + return STATUS_SUCCESS; } - /* allocate urb */ - Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); - if (!Urb) - { - /* no memory */ - FreeFunction(SampleRateBuffer); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* format urb */ - UsbBuildVendorRequest(Urb, - URB_FUNCTION_CLASS_ENDPOINT, - sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), - USBD_TRANSFER_DIRECTION_OUT, - 0, - 0x01, - 0x100, - 0x81, //bEndpointAddress - SampleRateBuffer, - NULL, - 3, - NULL); - - /* get pin context */ - PinContext = Pin->Context; - DbgBreakPoint(); - /* submit urb */ - Status = SubmitUrbSync(PinContext->LowerDevice, Urb); - - DPRINT1("USBAudioPinSetDataFormat Pin %p Status %x\n", Pin, Status); - FreeFunction(Urb); - FreeFunction(SampleRateBuffer); - return Status; + return UsbAudioSetFormat(Pin); } NTSTATUS