Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpin.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel Streaming Mixer 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: drivers/wdm/audio/filters/kmixer/kmixer.c 00005 * PURPOSE: Pin functions 00006 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) 00007 */ 00008 00009 #include "kmixer.h" 00010 00011 const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00012 00013 NTSTATUS 00014 PerformSampleRateConversion( 00015 PUCHAR Buffer, 00016 ULONG BufferLength, 00017 ULONG OldRate, 00018 ULONG NewRate, 00019 ULONG BytesPerSample, 00020 ULONG NumChannels, 00021 PVOID * Result, 00022 PULONG ResultLength) 00023 { 00024 KFLOATING_SAVE FloatSave; 00025 NTSTATUS Status; 00026 ULONG Index; 00027 SRC_STATE * State; 00028 SRC_DATA Data; 00029 PUCHAR ResultOut; 00030 int error; 00031 PFLOAT FloatIn, FloatOut; 00032 ULONG NumSamples; 00033 ULONG NewSamples; 00034 00035 DPRINT("PerformSampleRateConversion OldRate %u NewRate %u BytesPerSample %u NumChannels %u Irql %u\n", OldRate, NewRate, BytesPerSample, NumChannels, KeGetCurrentIrql()); 00036 00037 ASSERT(BytesPerSample == 1 || BytesPerSample == 2 || BytesPerSample == 4); 00038 00039 /* first acquire float save context */ 00040 Status = KeSaveFloatingPointState(&FloatSave); 00041 00042 if (!NT_SUCCESS(Status)) 00043 { 00044 DPRINT1("KeSaveFloatingPointState failed with %x\n", Status); 00045 return Status; 00046 } 00047 00048 NumSamples = BufferLength / (BytesPerSample * NumChannels); 00049 00050 FloatIn = ExAllocatePool(NonPagedPool, NumSamples * NumChannels * sizeof(FLOAT)); 00051 if (!FloatIn) 00052 { 00053 KeRestoreFloatingPointState(&FloatSave); 00054 return STATUS_INSUFFICIENT_RESOURCES; 00055 } 00056 00057 NewSamples = lrintf(((FLOAT)NumSamples * ((FLOAT)NewRate / (FLOAT)OldRate))) + 2; 00058 00059 FloatOut = ExAllocatePool(NonPagedPool, NewSamples * NumChannels * sizeof(FLOAT)); 00060 if (!FloatOut) 00061 { 00062 ExFreePool(FloatIn); 00063 KeRestoreFloatingPointState(&FloatSave); 00064 return STATUS_INSUFFICIENT_RESOURCES; 00065 } 00066 00067 ResultOut = ExAllocatePool(NonPagedPool, NewSamples * NumChannels * BytesPerSample); 00068 if (!ResultOut) 00069 { 00070 ExFreePool(FloatIn); 00071 ExFreePool(FloatOut); 00072 KeRestoreFloatingPointState(&FloatSave); 00073 return STATUS_INSUFFICIENT_RESOURCES; 00074 } 00075 00076 State = src_new(SRC_SINC_FASTEST, NumChannels, &error); 00077 if (!State) 00078 { 00079 DPRINT1("src_new failed with %x\n", error); 00080 KeRestoreFloatingPointState(&FloatSave); 00081 ExFreePool(FloatIn); 00082 ExFreePool(FloatOut); 00083 ExFreePool(ResultOut); 00084 return STATUS_UNSUCCESSFUL; 00085 } 00086 00087 /* fixme use asm */ 00088 if (BytesPerSample == 1) 00089 { 00090 for(Index = 0; Index < NumSamples * NumChannels; Index++) 00091 FloatIn[Index] = (float)(Buffer[Index] / (1.0 * 0x80)); 00092 } 00093 else if (BytesPerSample == 2) 00094 { 00095 src_short_to_float_array((short*)Buffer, FloatIn, NumSamples * NumChannels); 00096 } 00097 else if (BytesPerSample == 4) 00098 { 00099 src_int_to_float_array((int*)Buffer, FloatIn, NumSamples * NumChannels); 00100 } 00101 00102 Data.data_in = FloatIn; 00103 Data.data_out = FloatOut; 00104 Data.input_frames = NumSamples; 00105 Data.output_frames = NewSamples; 00106 Data.src_ratio = (double)NewRate / (double)OldRate; 00107 00108 error = src_process(State, &Data); 00109 if (error) 00110 { 00111 DPRINT1("src_process failed with %x\n", error); 00112 KeRestoreFloatingPointState(&FloatSave); 00113 ExFreePool(FloatIn); 00114 ExFreePool(FloatOut); 00115 ExFreePool(ResultOut); 00116 return STATUS_UNSUCCESSFUL; 00117 } 00118 00119 if (BytesPerSample == 1) 00120 { 00121 /* FIXME perform over/under clipping */ 00122 00123 for(Index = 0; Index < Data.output_frames_gen * NumChannels; Index++) 00124 ResultOut[Index] = (lrintf(FloatOut[Index]) >> 24); 00125 } 00126 else if (BytesPerSample == 2) 00127 { 00128 PUSHORT Res = (PUSHORT)ResultOut; 00129 00130 src_float_to_short_array(FloatOut, (short*)Res, Data.output_frames_gen * NumChannels); 00131 } 00132 else if (BytesPerSample == 4) 00133 { 00134 PULONG Res = (PULONG)ResultOut; 00135 00136 src_float_to_int_array(FloatOut, (int*)Res, Data.output_frames_gen * NumChannels); 00137 } 00138 00139 00140 *Result = ResultOut; 00141 *ResultLength = Data.output_frames_gen * BytesPerSample * NumChannels; 00142 ExFreePool(FloatIn); 00143 ExFreePool(FloatOut); 00144 src_delete(State); 00145 KeRestoreFloatingPointState(&FloatSave); 00146 return STATUS_SUCCESS; 00147 } 00148 00149 NTSTATUS 00150 PerformChannelConversion( 00151 PUCHAR Buffer, 00152 ULONG BufferLength, 00153 ULONG OldChannels, 00154 ULONG NewChannels, 00155 ULONG BitsPerSample, 00156 PVOID * Result, 00157 PULONG ResultLength) 00158 { 00159 ULONG Samples; 00160 ULONG NewIndex, OldIndex; 00161 00162 Samples = BufferLength / (BitsPerSample / 8) / OldChannels; 00163 00164 if (NewChannels > OldChannels) 00165 { 00166 if (BitsPerSample == 8) 00167 { 00168 PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); 00169 if (!BufferOut) 00170 return STATUS_INSUFFICIENT_RESOURCES; 00171 00172 for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) 00173 { 00174 ULONG SubIndex = 0; 00175 00176 RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(UCHAR)); 00177 00178 do 00179 { 00180 /* 2 channel stretched to 4 looks like LRLR */ 00181 BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)]; 00182 }while(SubIndex++ < NewChannels - OldChannels); 00183 } 00184 *Result = BufferOut; 00185 *ResultLength = Samples * NewChannels; 00186 } 00187 else if (BitsPerSample == 16) 00188 { 00189 PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); 00190 if (!BufferOut) 00191 return STATUS_INSUFFICIENT_RESOURCES; 00192 00193 for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) 00194 { 00195 ULONG SubIndex = 0; 00196 00197 RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(USHORT)); 00198 00199 do 00200 { 00201 BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)]; 00202 }while(SubIndex++ < NewChannels - OldChannels); 00203 } 00204 *Result = BufferOut; 00205 *ResultLength = Samples * NewChannels; 00206 } 00207 else if (BitsPerSample == 24) 00208 { 00209 PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); 00210 if (!BufferOut) 00211 return STATUS_INSUFFICIENT_RESOURCES; 00212 00213 for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) 00214 { 00215 ULONG SubIndex = 0; 00216 00217 RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * 3); 00218 00219 do 00220 { 00221 RtlMoveMemory(&BufferOut[(NewIndex+OldChannels + SubIndex) * 3], &Buffer[(OldIndex + (SubIndex % OldChannels)) * 3], 3); 00222 }while(SubIndex++ < NewChannels - OldChannels); 00223 } 00224 *Result = BufferOut; 00225 *ResultLength = Samples * NewChannels; 00226 } 00227 else if (BitsPerSample == 32) 00228 { 00229 PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); 00230 if (!BufferOut) 00231 return STATUS_INSUFFICIENT_RESOURCES; 00232 00233 for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) 00234 { 00235 ULONG SubIndex = 0; 00236 00237 RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(ULONG)); 00238 00239 do 00240 { 00241 BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)]; 00242 }while(SubIndex++ < NewChannels - OldChannels); 00243 } 00244 *Result = BufferOut; 00245 *ResultLength = Samples * NewChannels; 00246 } 00247 00248 } 00249 else 00250 { 00251 PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); 00252 if (!BufferOut) 00253 return STATUS_INSUFFICIENT_RESOURCES; 00254 00255 for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) 00256 { 00257 /* TODO 00258 * mix stream instead of just dumping part of it ;) 00259 */ 00260 RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], NewChannels * (BitsPerSample/8)); 00261 } 00262 00263 *Result = BufferOut; 00264 *ResultLength = Samples * NewChannels; 00265 } 00266 return STATUS_SUCCESS; 00267 } 00268 00269 00270 NTSTATUS 00271 PerformQualityConversion( 00272 PUCHAR Buffer, 00273 ULONG BufferLength, 00274 ULONG OldWidth, 00275 ULONG NewWidth, 00276 PVOID * Result, 00277 PULONG ResultLength) 00278 { 00279 ULONG Samples; 00280 ULONG Index; 00281 00282 ASSERT(OldWidth != NewWidth); 00283 00284 Samples = BufferLength / (OldWidth / 8); 00285 //DPRINT("Samples %u BufferLength %u\n", Samples, BufferLength); 00286 00287 if (OldWidth == 8 && NewWidth == 16) 00288 { 00289 USHORT Sample; 00290 PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(USHORT)); 00291 if (!BufferOut) 00292 return STATUS_INSUFFICIENT_RESOURCES; 00293 00294 for(Index = 0; Index < Samples; Index++) 00295 { 00296 Sample = Buffer[Index]; 00297 Sample *= 2; 00298 #ifdef _X86_ 00299 Sample = _byteswap_ushort(Sample); 00300 #endif 00301 BufferOut[Index] = Sample; 00302 } 00303 *Result = BufferOut; 00304 *ResultLength = Samples * sizeof(USHORT); 00305 } 00306 else if (OldWidth == 8 && NewWidth == 32) 00307 { 00308 ULONG Sample; 00309 PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(ULONG)); 00310 if (!BufferOut) 00311 return STATUS_INSUFFICIENT_RESOURCES; 00312 00313 for(Index = 0; Index < Samples; Index++) 00314 { 00315 Sample = Buffer[Index]; 00316 Sample *= 16777216; 00317 #ifdef _X86_ 00318 Sample = _byteswap_ulong(Sample); 00319 #endif 00320 BufferOut[Index] = Sample; 00321 } 00322 *Result = BufferOut; 00323 *ResultLength = Samples * sizeof(ULONG); 00324 } 00325 else if (OldWidth == 16 && NewWidth == 32) 00326 { 00327 ULONG Sample; 00328 PUSHORT BufferIn = (PUSHORT)Buffer; 00329 PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(ULONG)); 00330 if (!BufferOut) 00331 return STATUS_INSUFFICIENT_RESOURCES; 00332 00333 for(Index = 0; Index < Samples; Index++) 00334 { 00335 Sample = BufferIn[Index]; 00336 Sample *= 65536; 00337 #ifdef _X86_ 00338 Sample = _byteswap_ulong(Sample); 00339 #endif 00340 BufferOut[Index] = Sample; 00341 } 00342 *Result = BufferOut; 00343 *ResultLength = Samples * sizeof(ULONG); 00344 } 00345 00346 else if (OldWidth == 16 && NewWidth == 8) 00347 { 00348 USHORT Sample; 00349 PUSHORT BufferIn = (PUSHORT)Buffer; 00350 PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(UCHAR)); 00351 if (!BufferOut) 00352 return STATUS_INSUFFICIENT_RESOURCES; 00353 00354 for(Index = 0; Index < Samples; Index++) 00355 { 00356 Sample = BufferIn[Index]; 00357 #ifdef _X86_ 00358 Sample = _byteswap_ushort(Sample); 00359 #endif 00360 Sample /= 256; 00361 BufferOut[Index] = (Sample & 0xFF); 00362 } 00363 *Result = BufferOut; 00364 *ResultLength = Samples * sizeof(UCHAR); 00365 } 00366 else if (OldWidth == 32 && NewWidth == 8) 00367 { 00368 ULONG Sample; 00369 PULONG BufferIn = (PULONG)Buffer; 00370 PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(UCHAR)); 00371 if (!BufferOut) 00372 return STATUS_INSUFFICIENT_RESOURCES; 00373 00374 for(Index = 0; Index < Samples; Index++) 00375 { 00376 Sample = BufferIn[Index]; 00377 #ifdef _X86_ 00378 Sample = _byteswap_ulong(Sample); 00379 #endif 00380 Sample /= 16777216; 00381 BufferOut[Index] = (Sample & 0xFF); 00382 } 00383 *Result = BufferOut; 00384 *ResultLength = Samples * sizeof(UCHAR); 00385 } 00386 else if (OldWidth == 32 && NewWidth == 16) 00387 { 00388 USHORT Sample; 00389 PULONG BufferIn = (PULONG)Buffer; 00390 PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * sizeof(USHORT)); 00391 if (!BufferOut) 00392 return STATUS_INSUFFICIENT_RESOURCES; 00393 00394 for(Index = 0; Index < Samples; Index++) 00395 { 00396 Sample = BufferIn[Index]; 00397 #ifdef _X86_ 00398 Sample = _byteswap_ulong(Sample); 00399 #endif 00400 Sample /= 65536; 00401 BufferOut[Index] = (Sample & 0xFFFF); 00402 } 00403 *Result = BufferOut; 00404 *ResultLength = Samples * sizeof(USHORT); 00405 } 00406 else 00407 { 00408 DPRINT1("Not implemented conversion OldWidth %u NewWidth %u\n", OldWidth, NewWidth); 00409 return STATUS_NOT_IMPLEMENTED; 00410 } 00411 00412 return STATUS_SUCCESS; 00413 } 00414 00415 00416 NTSTATUS 00417 NTAPI 00418 Pin_fnDeviceIoControl( 00419 PDEVICE_OBJECT DeviceObject, 00420 PIRP Irp) 00421 { 00422 PIO_STACK_LOCATION IoStack; 00423 PKSP_PIN Property; 00424 //DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); 00425 00426 IoStack = IoGetCurrentIrpStackLocation(Irp); 00427 00428 if (IoStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(KSP_PIN) && IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSDATAFORMAT_WAVEFORMATEX)) 00429 { 00430 Property = (PKSP_PIN)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00431 00432 if (IsEqualGUIDAligned(&Property->Property.Set, &KSPROPSETID_Connection)) 00433 { 00434 if (Property->Property.Id == KSPROPERTY_CONNECTION_DATAFORMAT && Property->Property.Flags == KSPROPERTY_TYPE_SET) 00435 { 00436 PKSDATAFORMAT_WAVEFORMATEX Formats; 00437 PKSDATAFORMAT_WAVEFORMATEX WaveFormat; 00438 00439 Formats = (PKSDATAFORMAT_WAVEFORMATEX)IoStack->FileObject->FsContext2; 00440 WaveFormat = (PKSDATAFORMAT_WAVEFORMATEX)Irp->UserBuffer; 00441 00442 ASSERT(Property->PinId == 0 || Property->PinId == 1); 00443 ASSERT(Formats); 00444 ASSERT(WaveFormat); 00445 00446 Formats[Property->PinId].WaveFormatEx.nChannels = WaveFormat->WaveFormatEx.nChannels; 00447 Formats[Property->PinId].WaveFormatEx.wBitsPerSample = WaveFormat->WaveFormatEx.wBitsPerSample; 00448 Formats[Property->PinId].WaveFormatEx.nSamplesPerSec = WaveFormat->WaveFormatEx.nSamplesPerSec; 00449 00450 Irp->IoStatus.Information = 0; 00451 Irp->IoStatus.Status = STATUS_SUCCESS; 00452 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00453 return STATUS_SUCCESS; 00454 } 00455 } 00456 } 00457 DPRINT1("Size %u Expected %u\n",IoStack->Parameters.DeviceIoControl.OutputBufferLength, sizeof(KSDATAFORMAT_WAVEFORMATEX)); 00458 Irp->IoStatus.Information = 0; 00459 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00460 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00461 return STATUS_UNSUCCESSFUL; 00462 } 00463 00464 NTSTATUS 00465 NTAPI 00466 Pin_fnRead( 00467 PDEVICE_OBJECT DeviceObject, 00468 PIRP Irp) 00469 { 00470 UNIMPLEMENTED 00471 00472 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00473 Irp->IoStatus.Information = 0; 00474 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00475 return STATUS_UNSUCCESSFUL; 00476 } 00477 00478 NTSTATUS 00479 NTAPI 00480 Pin_fnWrite( 00481 PDEVICE_OBJECT DeviceObject, 00482 PIRP Irp) 00483 { 00484 UNIMPLEMENTED 00485 00486 Irp->IoStatus.Information = 0; 00487 Irp->IoStatus.Status = STATUS_SUCCESS; 00488 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00489 return STATUS_SUCCESS; 00490 } 00491 00492 NTSTATUS 00493 NTAPI 00494 Pin_fnFlush( 00495 PDEVICE_OBJECT DeviceObject, 00496 PIRP Irp) 00497 { 00498 UNIMPLEMENTED 00499 00500 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00501 Irp->IoStatus.Information = 0; 00502 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00503 return STATUS_UNSUCCESSFUL; 00504 } 00505 00506 NTSTATUS 00507 NTAPI 00508 Pin_fnClose( 00509 PDEVICE_OBJECT DeviceObject, 00510 PIRP Irp) 00511 { 00512 UNIMPLEMENTED 00513 00514 Irp->IoStatus.Status = STATUS_SUCCESS; 00515 Irp->IoStatus.Information = 0; 00516 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00517 return STATUS_SUCCESS; 00518 } 00519 00520 NTSTATUS 00521 NTAPI 00522 Pin_fnQuerySecurity( 00523 PDEVICE_OBJECT DeviceObject, 00524 PIRP Irp) 00525 { 00526 UNIMPLEMENTED 00527 00528 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00529 Irp->IoStatus.Information = 0; 00530 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00531 return STATUS_UNSUCCESSFUL; 00532 } 00533 00534 NTSTATUS 00535 NTAPI 00536 Pin_fnSetSecurity( 00537 PDEVICE_OBJECT DeviceObject, 00538 PIRP Irp) 00539 { 00540 00541 UNIMPLEMENTED 00542 00543 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00544 Irp->IoStatus.Information = 0; 00545 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00546 return STATUS_UNSUCCESSFUL; 00547 } 00548 00549 BOOLEAN 00550 NTAPI 00551 Pin_fnFastDeviceIoControl( 00552 PFILE_OBJECT FileObject, 00553 BOOLEAN Wait, 00554 PVOID InputBuffer, 00555 ULONG InputBufferLength, 00556 PVOID OutputBuffer, 00557 ULONG OutputBufferLength, 00558 ULONG IoControlCode, 00559 PIO_STATUS_BLOCK IoStatus, 00560 PDEVICE_OBJECT DeviceObject) 00561 { 00562 UNIMPLEMENTED 00563 00564 00565 return FALSE; 00566 } 00567 00568 00569 BOOLEAN 00570 NTAPI 00571 Pin_fnFastRead( 00572 PFILE_OBJECT FileObject, 00573 PLARGE_INTEGER FileOffset, 00574 ULONG Length, 00575 BOOLEAN Wait, 00576 ULONG LockKey, 00577 PVOID Buffer, 00578 PIO_STATUS_BLOCK IoStatus, 00579 PDEVICE_OBJECT DeviceObject) 00580 { 00581 UNIMPLEMENTED 00582 return FALSE; 00583 00584 } 00585 00586 BOOLEAN 00587 NTAPI 00588 Pin_fnFastWrite( 00589 PFILE_OBJECT FileObject, 00590 PLARGE_INTEGER FileOffset, 00591 ULONG Length, 00592 BOOLEAN Wait, 00593 ULONG LockKey, 00594 PVOID Buffer, 00595 PIO_STATUS_BLOCK IoStatus, 00596 PDEVICE_OBJECT DeviceObject) 00597 { 00598 PKSSTREAM_HEADER StreamHeader; 00599 PVOID BufferOut; 00600 ULONG BufferLength; 00601 NTSTATUS Status = STATUS_SUCCESS; 00602 PKSDATAFORMAT_WAVEFORMATEX Formats; 00603 PKSDATAFORMAT_WAVEFORMATEX InputFormat, OutputFormat; 00604 00605 DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject); 00606 00607 Formats = (PKSDATAFORMAT_WAVEFORMATEX)FileObject->FsContext2; 00608 00609 InputFormat = Formats; 00610 OutputFormat = (Formats + 1); 00611 StreamHeader = (PKSSTREAM_HEADER)Buffer; 00612 00613 00614 DPRINT("Num Channels %u Old Channels %u\n SampleRate %u Old SampleRate %u\n BitsPerSample %u Old BitsPerSample %u\n", 00615 InputFormat->WaveFormatEx.nChannels, OutputFormat->WaveFormatEx.nChannels, 00616 InputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.nSamplesPerSec, 00617 InputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.wBitsPerSample); 00618 00619 if (InputFormat->WaveFormatEx.wBitsPerSample != OutputFormat->WaveFormatEx.wBitsPerSample) 00620 { 00621 Status = PerformQualityConversion(StreamHeader->Data, 00622 StreamHeader->DataUsed, 00623 InputFormat->WaveFormatEx.wBitsPerSample, 00624 OutputFormat->WaveFormatEx.wBitsPerSample, 00625 &BufferOut, 00626 &BufferLength); 00627 if (NT_SUCCESS(Status)) 00628 { 00629 ExFreePool(StreamHeader->Data); 00630 StreamHeader->Data = BufferOut; 00631 StreamHeader->DataUsed = BufferLength; 00632 } 00633 } 00634 00635 if (InputFormat->WaveFormatEx.nChannels != OutputFormat->WaveFormatEx.nChannels) 00636 { 00637 Status = PerformChannelConversion(StreamHeader->Data, 00638 StreamHeader->DataUsed, 00639 InputFormat->WaveFormatEx.nChannels, 00640 OutputFormat->WaveFormatEx.nChannels, 00641 OutputFormat->WaveFormatEx.wBitsPerSample, 00642 &BufferOut, 00643 &BufferLength); 00644 00645 if (NT_SUCCESS(Status)) 00646 { 00647 ExFreePool(StreamHeader->Data); 00648 StreamHeader->Data = BufferOut; 00649 StreamHeader->DataUsed = BufferLength; 00650 } 00651 } 00652 00653 if (InputFormat->WaveFormatEx.nSamplesPerSec != OutputFormat->WaveFormatEx.nSamplesPerSec) 00654 { 00655 Status = PerformSampleRateConversion(StreamHeader->Data, 00656 StreamHeader->DataUsed, 00657 InputFormat->WaveFormatEx.nSamplesPerSec, 00658 OutputFormat->WaveFormatEx.nSamplesPerSec, 00659 OutputFormat->WaveFormatEx.wBitsPerSample / 8, 00660 OutputFormat->WaveFormatEx.nChannels, 00661 &BufferOut, 00662 &BufferLength); 00663 if (NT_SUCCESS(Status)) 00664 { 00665 ExFreePool(StreamHeader->Data); 00666 StreamHeader->Data = BufferOut; 00667 StreamHeader->DataUsed = BufferLength; 00668 } 00669 } 00670 00671 IoStatus->Status = Status; 00672 00673 if (NT_SUCCESS(Status)) 00674 return TRUE; 00675 else 00676 return TRUE; 00677 } 00678 00679 static KSDISPATCH_TABLE PinTable = 00680 { 00681 Pin_fnDeviceIoControl, 00682 Pin_fnRead, 00683 Pin_fnWrite, 00684 Pin_fnFlush, 00685 Pin_fnClose, 00686 Pin_fnQuerySecurity, 00687 Pin_fnSetSecurity, 00688 Pin_fnFastDeviceIoControl, 00689 Pin_fnFastRead, 00690 Pin_fnFastWrite, 00691 }; 00692 00693 NTSTATUS 00694 CreatePin( 00695 IN PIRP Irp) 00696 { 00697 NTSTATUS Status; 00698 KSOBJECT_HEADER ObjectHeader; 00699 PKSDATAFORMAT DataFormat; 00700 PIO_STACK_LOCATION IoStack; 00701 00702 00703 DataFormat = ExAllocatePool(NonPagedPool, sizeof(KSDATAFORMAT_WAVEFORMATEX) * 2); 00704 if (!DataFormat) 00705 return STATUS_INSUFFICIENT_RESOURCES; 00706 00707 RtlZeroMemory(DataFormat, sizeof(KSDATAFORMAT_WAVEFORMATEX) * 2); 00708 00709 IoStack = IoGetCurrentIrpStackLocation(Irp); 00710 IoStack->FileObject->FsContext2 = (PVOID)DataFormat; 00711 00712 /* allocate object header */ 00713 Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable); 00714 return Status; 00715 } 00716 00717 void * calloc(size_t Elements, size_t ElementSize) 00718 { 00719 ULONG Index; 00720 PUCHAR Block = ExAllocatePool(NonPagedPool, Elements * ElementSize); 00721 if (!Block) 00722 return NULL; 00723 00724 for(Index = 0; Index < Elements * ElementSize; Index++) 00725 Block[Index] = 0; 00726 00727 return Block; 00728 } 00729 00730 void free(PVOID Block) 00731 { 00732 ExFreePool(Block); 00733 } Generated on Sun May 27 2012 04:21:58 for ReactOS by
1.7.6.1
|