mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[USBAUDIO]
- implement USBAudioSelectAudioStreamingInterface svn path=/trunk/; revision=72843
This commit is contained in:
parent
d1faa1a99f
commit
ff46d90618
3 changed files with 187 additions and 70 deletions
|
@ -136,6 +136,7 @@ USBAudioFilterCreate(
|
|||
FilterContext->LowerDevice = Device->NextDeviceObject;
|
||||
Filter->Context = FilterContext;
|
||||
|
||||
DPRINT("USBAudioFilterCreate FilterContext %p LowerDevice %p DeviceExtension %p\n", FilterContext, FilterContext->LowerDevice, FilterContext->DeviceExtension);
|
||||
KsAddItemToObjectBag(Filter->Bag, FilterContext, ExFreePool);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
/* TODO: verify connection format */
|
||||
UNIMPLEMENTED
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
|
|
@ -79,14 +79,6 @@ SubmitUrbSync(
|
|||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
}
|
||||
|
||||
// complete request
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
// get final status
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue