ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pin.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.