ReactOS  0.4.14-dev-556-g4c5b21f
mixer.c File Reference
#include "wdmaud.h"
#include <samplerate.h>
#include <float_cast.h>
#include <debug.h>
#include <mmebuddy_debug.h>
Include dependency graph for mixer.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

DWORD PerformSampleRateConversion (PUCHAR Buffer, ULONG BufferLength, ULONG OldRate, ULONG NewRate, ULONG BytesPerSample, ULONG NumChannels, PVOID *Result, PULONG ResultLength)
 
DWORD PerformChannelConversion (PUCHAR Buffer, ULONG BufferLength, ULONG OldChannels, ULONG NewChannels, ULONG BitsPerSample, PVOID *Result, PULONG ResultLength)
 
DWORD PerformQualityConversion (PUCHAR Buffer, ULONG BufferLength, ULONG OldWidth, ULONG NewWidth, PVOID *Result, PULONG ResultLength)
 
VOID CALLBACK MixerCompletionRoutine (IN DWORD dwErrorCode, IN DWORD dwNumberOfBytesTransferred, IN LPOVERLAPPED lpOverlapped)
 
MMRESULT WriteFileEx_Remixer (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID OffsetPtr, IN DWORD Length, IN PSOUND_OVERLAPPED Overlap, IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
 

Variables

HANDLE KernelHandle
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file mixer.c.

Function Documentation

◆ MixerCompletionRoutine()

VOID CALLBACK MixerCompletionRoutine ( IN DWORD  dwErrorCode,
IN DWORD  dwNumberOfBytesTransferred,
IN LPOVERLAPPED  lpOverlapped 
)

Definition at line 411 of file mixer.c.

415 {
417 
418  /* Call mmebuddy overlap routine */
419  Overlap->OriginalCompletionRoutine(dwErrorCode, PtrToUlong(Overlap->CompletionContext), lpOverlapped);
420 }
PVOID CompletionContext
Definition: mmebuddy.h:126
#define PtrToUlong(u)
Definition: config.h:107
struct _SOUND_OVERLAPPED * PSOUND_OVERLAPPED
LPOVERLAPPED_COMPLETION_ROUTINE OriginalCompletionRoutine
Definition: mmebuddy.h:125
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90

Referenced by WriteFileEx_Remixer().

◆ PerformChannelConversion()

DWORD PerformChannelConversion ( PUCHAR  Buffer,
ULONG  BufferLength,
ULONG  OldChannels,
ULONG  NewChannels,
ULONG  BitsPerSample,
PVOID Result,
PULONG  ResultLength 
)

Definition at line 140 of file mixer.c.

148 {
149  ULONG Samples;
150  ULONG NewIndex, OldIndex;
151 
152  Samples = BufferLength / (BitsPerSample / 8) / OldChannels;
153 
154  SND_TRACE(L"PerformChannelConversion OldChannels %u NewChannels %u\n", OldChannels, NewChannels);
155 
156  if (NewChannels > OldChannels)
157  {
158  if (BitsPerSample == 8)
159  {
160  PUCHAR BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * NewChannels);
161  if (!BufferOut)
163 
164  for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
165  {
166  ULONG SubIndex = 0;
167 
168  RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(UCHAR));
169 
170  do
171  {
172  /* 2 channel stretched to 4 looks like LRLR */
173  BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)];
174  }while(SubIndex++ < NewChannels - OldChannels);
175  }
176  *Result = BufferOut;
177  *ResultLength = Samples * NewChannels;
178  }
179  else if (BitsPerSample == 16)
180  {
181  PUSHORT BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * NewChannels);
182  if (!BufferOut)
184 
185  for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
186  {
187  ULONG SubIndex = 0;
188 
189  RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(USHORT));
190 
191  do
192  {
193  BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)];
194  }while(SubIndex++ < NewChannels - OldChannels);
195  }
196  *Result = BufferOut;
197  *ResultLength = Samples * NewChannels;
198  }
199  else if (BitsPerSample == 24)
200  {
201  PUCHAR BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * NewChannels);
202  if (!BufferOut)
204 
205  for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
206  {
207  ULONG SubIndex = 0;
208 
209  RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * 3);
210 
211  do
212  {
213  RtlMoveMemory(&BufferOut[(NewIndex+OldChannels + SubIndex) * 3], &Buffer[(OldIndex + (SubIndex % OldChannels)) * 3], 3);
214  }while(SubIndex++ < NewChannels - OldChannels);
215  }
216  *Result = BufferOut;
217  *ResultLength = Samples * NewChannels;
218  }
219  else if (BitsPerSample == 32)
220  {
221  PULONG BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * NewChannels);
222  if (!BufferOut)
224 
225  for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
226  {
227  ULONG SubIndex = 0;
228 
229  RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(ULONG));
230 
231  do
232  {
233  BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)];
234  }while(SubIndex++ < NewChannels - OldChannels);
235  }
236  *Result = BufferOut;
237  *ResultLength = Samples * NewChannels;
238  }
239 
240  }
241  else
242  {
243  PUSHORT BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * NewChannels);
244  if (!BufferOut)
246 
247  for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels)
248  {
249  /* TODO
250  * mix stream instead of just dumping part of it ;)
251  */
252  RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], NewChannels * (BitsPerSample/8));
253  }
254 
255  *Result = BufferOut;
256  *ResultLength = Samples * NewChannels;
257  }
258  return ERROR_SUCCESS;
259 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define ERROR_SUCCESS
Definition: deptool.c:10
unsigned char * PUCHAR
Definition: retypes.h:3
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ ULONG BufferLength
Definition: usbdlib.h:225
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
Definition: bufpool.h:45
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
unsigned short * PUSHORT
Definition: retypes.h:2
#define SND_TRACE(...)

Referenced by WriteFileEx_Remixer().

◆ PerformQualityConversion()

DWORD PerformQualityConversion ( PUCHAR  Buffer,
ULONG  BufferLength,
ULONG  OldWidth,
ULONG  NewWidth,
PVOID Result,
PULONG  ResultLength 
)

Definition at line 263 of file mixer.c.

270 {
271  ULONG Samples;
272  ULONG Index;
273 
274  ASSERT(OldWidth != NewWidth);
275 
276  Samples = BufferLength / (OldWidth / 8);
277  //DPRINT("Samples %u BufferLength %u\n", Samples, BufferLength);
278 
279  //SND_TRACE(L"PerformQualityConversion OldWidth %u NewWidth %u\n", OldWidth, NewWidth);
280 
281  if (OldWidth == 8 && NewWidth == 16)
282  {
283  USHORT Sample;
284  PUSHORT BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * sizeof(USHORT));
285  if (!BufferOut)
287 
288  for(Index = 0; Index < Samples; Index++)
289  {
290  Sample = Buffer[Index];// & 0xFF);
291  Sample *= 2;
292 #ifdef _X86_
293  Sample = _byteswap_ushort(Sample);
294 #endif
295  BufferOut[Index] = Sample;
296  }
297  *Result = BufferOut;
298  *ResultLength = Samples * sizeof(USHORT);
299  }
300  else if (OldWidth == 8 && NewWidth == 32)
301  {
302  ULONG Sample;
303  PULONG BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * sizeof(ULONG));
304  if (!BufferOut)
306 
307  for(Index = 0; Index < Samples; Index++)
308  {
309  Sample = Buffer[Index];
310  Sample *= 16777216;
311 #ifdef _X86_
312  Sample = _byteswap_ulong(Sample);
313 #endif
314  BufferOut[Index] = Sample;
315  }
316  *Result = BufferOut;
317  *ResultLength = Samples * sizeof(ULONG);
318  }
319  else if (OldWidth == 16 && NewWidth == 32)
320  {
321  ULONG Sample;
322  PUSHORT BufferIn = (PUSHORT)Buffer;
323  PULONG BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * sizeof(ULONG));
324  if (!BufferOut)
326 
327  for(Index = 0; Index < Samples; Index++)
328  {
329  Sample = BufferIn[Index];
330  Sample *= 65536;
331 #ifdef _X86_
332  Sample = _byteswap_ulong(Sample);
333 #endif
334  BufferOut[Index] = Sample;
335  }
336  *Result = BufferOut;
337  *ResultLength = Samples * sizeof(ULONG);
338  }
339 
340  else if (OldWidth == 16 && NewWidth == 8)
341  {
342  USHORT Sample;
343  PUSHORT BufferIn = (PUSHORT)Buffer;
344  PUCHAR BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * sizeof(UCHAR));
345  if (!BufferOut)
347 
348  for(Index = 0; Index < Samples; Index++)
349  {
350  Sample = BufferIn[Index];
351 #ifdef _X86_
352  Sample = _byteswap_ushort(Sample);
353 #endif
354  Sample /= 256;
355  BufferOut[Index] = (Sample & 0xFF);
356  }
357  *Result = BufferOut;
358  *ResultLength = Samples * sizeof(UCHAR);
359  }
360  else if (OldWidth == 32 && NewWidth == 8)
361  {
362  ULONG Sample;
363  PULONG BufferIn = (PULONG)Buffer;
364  PUCHAR BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * sizeof(UCHAR));
365  if (!BufferOut)
367 
368  for(Index = 0; Index < Samples; Index++)
369  {
370  Sample = BufferIn[Index];
371 #ifdef _X86_
372  Sample = _byteswap_ulong(Sample);
373 #endif
374  Sample /= 16777216;
375  BufferOut[Index] = (Sample & 0xFF);
376  }
377  *Result = BufferOut;
378  *ResultLength = Samples * sizeof(UCHAR);
379  }
380  else if (OldWidth == 32 && NewWidth == 16)
381  {
382  USHORT Sample;
383  PULONG BufferIn = (PULONG)Buffer;
384  PUSHORT BufferOut = HeapAlloc(GetProcessHeap(), 0, Samples * sizeof(USHORT));
385  if (!BufferOut)
387 
388  for(Index = 0; Index < Samples; Index++)
389  {
390  Sample = BufferIn[Index];
391 #ifdef _X86_
392  Sample = _byteswap_ulong(Sample);
393 #endif
394  Sample /= 65536;
395  BufferOut[Index] = (Sample & 0xFFFF);
396  }
397  *Result = BufferOut;
398  *ResultLength = Samples * sizeof(USHORT);
399  }
400  else
401  {
402  DPRINT1("Not implemented conversion OldWidth %u NewWidth %u\n", OldWidth, NewWidth);
403  return ERROR_NOT_SUPPORTED;
404  }
405 
406  return ERROR_SUCCESS;
407 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define ERROR_SUCCESS
Definition: deptool.c:10
unsigned char * PUCHAR
Definition: retypes.h:3
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
_Check_return_ unsigned short __cdecl _byteswap_ushort(_In_ unsigned short)
_In_ ULONG BufferLength
Definition: usbdlib.h:225
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
Definition: bufpool.h:45
_Check_return_ unsigned long __cdecl _byteswap_ulong(_In_ unsigned long)
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static const UCHAR Index[8]
Definition: usbohci.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
unsigned int ULONG
Definition: retypes.h:1
unsigned short * PUSHORT
Definition: retypes.h:2

Referenced by WriteFileEx_Remixer().

◆ PerformSampleRateConversion()

DWORD PerformSampleRateConversion ( PUCHAR  Buffer,
ULONG  BufferLength,
ULONG  OldRate,
ULONG  NewRate,
ULONG  BytesPerSample,
ULONG  NumChannels,
PVOID Result,
PULONG  ResultLength 
)

Definition at line 22 of file mixer.c.

31 {
32  ULONG Index;
33  SRC_STATE * State;
34  SRC_DATA Data;
35  PUCHAR ResultOut;
36  int error;
37  PFLOAT FloatIn, FloatOut;
38  ULONG NumSamples;
39  ULONG NewSamples;
40 
41  //SND_TRACE(L"PerformSampleRateConversion OldRate %u NewRate %u BytesPerSample %u NumChannels %u\n", OldRate, NewRate, BytesPerSample, NumChannels);
42 
43  ASSERT(BytesPerSample == 1 || BytesPerSample == 2 || BytesPerSample == 4);
44 
45  NumSamples = BufferLength / (BytesPerSample * NumChannels);
46 
47  FloatIn = HeapAlloc(GetProcessHeap(), 0, NumSamples * NumChannels * sizeof(FLOAT));
48  if (!FloatIn)
49  {
51  }
52 
53  NewSamples = ((((ULONG64)NumSamples * NewRate) + (OldRate / 2)) / OldRate) + 2;
54 
55  FloatOut = HeapAlloc(GetProcessHeap(), 0, NewSamples * NumChannels * sizeof(FLOAT));
56  if (!FloatOut)
57  {
58  HeapFree(GetProcessHeap(), 0,FloatIn);
60  }
61 
62  ResultOut = HeapAlloc(GetProcessHeap(), 0, NewSamples * NumChannels * BytesPerSample);
63  if (!ResultOut)
64  {
65  HeapFree(GetProcessHeap(), 0,FloatIn);
66  HeapFree(GetProcessHeap(), 0,FloatOut);
68  }
69 
70  State = src_new(SRC_SINC_FASTEST, NumChannels, &error);
71  if (!State)
72  {
73  HeapFree(GetProcessHeap(), 0,FloatIn);
74  HeapFree(GetProcessHeap(), 0,FloatOut);
75  HeapFree(GetProcessHeap(), 0,ResultOut);
77  }
78 
79  /* fixme use asm */
80  if (BytesPerSample == 1)
81  {
82  for(Index = 0; Index < NumSamples * NumChannels; Index++)
83  FloatIn[Index] = (float)(Buffer[Index] / (1.0 * 0x80));
84  }
85  else if (BytesPerSample == 2)
86  {
87  src_short_to_float_array((short*)Buffer, FloatIn, NumSamples * NumChannels);
88  }
89  else if (BytesPerSample == 4)
90  {
91  src_int_to_float_array((int*)Buffer, FloatIn, NumSamples * NumChannels);
92  }
93 
94  Data.data_in = FloatIn;
95  Data.data_out = FloatOut;
96  Data.input_frames = NumSamples;
97  Data.output_frames = NewSamples;
98  Data.src_ratio = (double)NewRate / (double)OldRate;
99 
101  if (error)
102  {
103  DPRINT1("src_process failed with %x\n", error);
104  HeapFree(GetProcessHeap(), 0,FloatIn);
105  HeapFree(GetProcessHeap(), 0,FloatOut);
106  HeapFree(GetProcessHeap(), 0,ResultOut);
107  return ERROR_INVALID_DATA;
108  }
109 
110  if (BytesPerSample == 1)
111  {
112  /* FIXME perform over/under clipping */
113 
114  for(Index = 0; Index < Data.output_frames_gen * NumChannels; Index++)
115  ResultOut[Index] = (lrintf(FloatOut[Index]) >> 24);
116  }
117  else if (BytesPerSample == 2)
118  {
119  PUSHORT Res = (PUSHORT)ResultOut;
120 
121  src_float_to_short_array(FloatOut, (short*)Res, Data.output_frames_gen * NumChannels);
122  }
123  else if (BytesPerSample == 4)
124  {
125  PULONG Res = (PULONG)ResultOut;
126 
127  src_float_to_int_array(FloatOut, (int*)Res, Data.output_frames_gen * NumChannels);
128  }
129 
130 
131  *Result = ResultOut;
132  *ResultLength = Data.output_frames_gen * BytesPerSample * NumChannels;
133  HeapFree(GetProcessHeap(), 0,FloatIn);
134  HeapFree(GetProcessHeap(), 0,FloatOut);
135  src_delete(State);
136  return ERROR_SUCCESS;
137 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
SRC_STATE * src_new(int converter_type, int channels, int *error)
Definition: samplerate.c:15
void src_float_to_int_array(const float *in, int *out, int len)
Definition: samplerate.c:493
#define ERROR_SUCCESS
Definition: deptool.c:10
#define error(str)
Definition: mkdosfs.c:1605
unsigned char * PUCHAR
Definition: retypes.h:3
void src_int_to_float_array(const int *in, float *out, int len)
Definition: samplerate.c:482
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
FLOAT * PFLOAT
Definition: windef.h:174
struct SRC_STATE_tag SRC_STATE
Definition: samplerate.h:23
_In_ ULONG BufferLength
Definition: usbdlib.h:225
void src_float_to_short_array(const float *in, short *out, int len)
Definition: samplerate.c:460
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
SRC_STATE * src_delete(SRC_STATE *state)
Definition: samplerate.c:74
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
Definition: bufpool.h:45
_Check_return_ __CRT_INLINE long lrintf(_In_ float x)
Definition: math.h:268
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static const UCHAR Index[8]
Definition: usbohci.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned __int64 ULONG64
Definition: imports.h:198
#define ERROR_INVALID_DATA
Definition: winerror.h:116
enum State_ State
Definition: pofuncs.h:54
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
float FLOAT
Definition: typedefs.h:67
void src_short_to_float_array(const short *in, float *out, int len)
Definition: samplerate.c:449
int src_process(SRC_STATE *state, SRC_DATA *data)
Definition: samplerate.c:89
unsigned int ULONG
Definition: retypes.h:1
#define HeapFree(x, y, z)
Definition: compat.h:402
unsigned short * PUSHORT
Definition: retypes.h:2

Referenced by WriteFileEx_Remixer().

◆ WriteFileEx_Remixer()

MMRESULT WriteFileEx_Remixer ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance,
IN PVOID  OffsetPtr,
IN DWORD  Length,
IN PSOUND_OVERLAPPED  Overlap,
IN LPOVERLAPPED_COMPLETION_ROUTINE  CompletionRoutine 
)

Definition at line 423 of file mixer.c.

429 {
430  HANDLE Handle;
432  DWORD BufferLength, BufferLengthTemp;
433  PVOID BufferOut, BufferOutTemp;
434  DWORD Status;
435  BOOL Result;
436 
437  VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
438  VALIDATE_MMSYS_PARAMETER( OffsetPtr );
439  VALIDATE_MMSYS_PARAMETER( Overlap );
441 
442  GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
443 
445 
446  BufferOut = OffsetPtr;
448 
449  if (SoundDeviceInstance->WaveFormatEx.wBitsPerSample != 16)
450  {
451  Status = PerformQualityConversion(OffsetPtr,
452  Length,
453  SoundDeviceInstance->WaveFormatEx.wBitsPerSample,
454  16,
455  &BufferOut,
456  &BufferLength);
457  if (Status)
458  {
459  SND_TRACE(L"PerformQualityConversion failed\n");
460  return MMSYSERR_NOERROR;
461  }
462  }
463 
464  if (SoundDeviceInstance->WaveFormatEx.nChannels != 2)
465  {
466  Status = PerformChannelConversion(BufferOut,
467  BufferLength,
468  SoundDeviceInstance->WaveFormatEx.nChannels,
469  2,
470  16,
471  &BufferOutTemp,
472  &BufferLengthTemp);
473 
474  if (BufferOut != OffsetPtr)
475  {
476  HeapFree(GetProcessHeap(), 0, BufferOut);
477  }
478 
479  if (Status)
480  {
481  SND_TRACE(L"PerformChannelConversion failed\n");
482  return MMSYSERR_NOERROR;
483  }
484 
485  BufferOut = BufferOutTemp;
486  BufferLength = BufferLengthTemp;
487  }
488 
489  if (SoundDeviceInstance->WaveFormatEx.nSamplesPerSec != 44100)
490  {
492  BufferLength,
493  SoundDeviceInstance->WaveFormatEx.nSamplesPerSec,
494  44100,
495  2,
496  2,
497  &BufferOutTemp,
498  &BufferLengthTemp);
499 
500  if (BufferOut != OffsetPtr)
501  {
502  HeapFree(GetProcessHeap(), 0, BufferOut);
503  }
504 
505  if (Status)
506  {
507  SND_TRACE(L"PerformSampleRateConversion failed\n");
508  return MMSYSERR_NOERROR;
509  }
510 
511  BufferOut = BufferOutTemp;
512  BufferLength = BufferLengthTemp;
513  }
514 
516  DeviceInfo.hDevice = Handle;
517  DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME
518  DeviceInfo.Header.FrameExtent = BufferLength;
519  DeviceInfo.Header.DataUsed = BufferLength;
520  DeviceInfo.Header.Data = BufferOut;
521  DeviceInfo.Header.Size = sizeof(KSSTREAM_HEADER);
522  DeviceInfo.Header.PresentationTime.Numerator = 1;
523  DeviceInfo.Header.PresentationTime.Denominator = 1;
524 
525  Overlap->CompletionContext = UlongToPtr(Length);
526  Overlap->OriginalCompletionRoutine = CompletionRoutine;
527 
528  Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
529 
530  //SND_TRACE(L"OriginalLength %u NewLength %u\n", Length, BufferLength);
531 
532 #if 0
534 #else
536 #endif
537 
538  if ( ! Result )
539  {
540  SND_TRACE(L"WriteFileEx failed with %x\n", GetLastError());
541  return MMSYSERR_NOERROR;
542  }
543 
545 
546 #ifdef USERMODE_MIXER
547  // if (BufferOut != OffsetPtr)
548  // HeapFree(GetProcessHeap(), 0, BufferOut);
549 #endif
550 
551 
552  return MMSYSERR_NOERROR;
553 }
DWORD PerformQualityConversion(PUCHAR Buffer, ULONG BufferLength, ULONG OldWidth, ULONG NewWidth, PVOID *Result, PULONG ResultLength)
Definition: mixer.c:263
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define TRUE
Definition: types.h:120
DWORD PerformChannelConversion(PUCHAR Buffer, ULONG BufferLength, ULONG OldChannels, ULONG NewChannels, ULONG BitsPerSample, PVOID *Result, PULONG ResultLength)
Definition: mixer.c:140
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
unsigned int BOOL
Definition: ntddk_ex.h:94
_In_ ULONG BufferLength
Definition: usbdlib.h:225
smooth NULL
Definition: ftsmooth.c:416
#define SND_ASSERT(condition)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
WCHAR Data[ANYSIZE_ARRAY]
#define UlongToPtr(u)
Definition: config.h:106
_In_ HANDLE Handle
Definition: extypes.h:390
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:403
struct _DeviceInfo DeviceInfo
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
HANDLE KernelHandle
Definition: legacy.c:24
DWORD PerformSampleRateConversion(PUCHAR Buffer, ULONG BufferLength, ULONG OldRate, ULONG NewRate, ULONG BytesPerSample, ULONG NumChannels, PVOID *Result, PULONG ResultLength)
Definition: mixer.c:22
_In_ PIRP _In_opt_ PVOID _In_opt_ POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine
Definition: fsrtlfuncs.h:673
MMRESULT GetSoundDeviceInstanceHandle(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, OUT PVOID *Handle)
#define INFINITE
Definition: serial.h:102
BOOL WINAPI WriteFileEx(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:262
#define HeapFree(x, y, z)
Definition: compat.h:402
VOID CALLBACK MixerCompletionRoutine(IN DWORD dwErrorCode, IN DWORD dwNumberOfBytesTransferred, IN LPOVERLAPPED lpOverlapped)
Definition: mixer.c:411
#define SND_TRACE(...)

Referenced by PopulateWdmDeviceList().

Variable Documentation

◆ KernelHandle