Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwave.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: lib/drivers/sound/mmixer/wave.c 00005 * PURPOSE: Wave Handling Functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "priv.h" 00010 00011 const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00012 const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; 00013 const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; 00014 const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; 00015 const GUID KSINTERFACESETID_Standard = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00016 const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00017 00018 typedef struct 00019 { 00020 ULONG SampleRate; 00021 ULONG Bit8Mono; 00022 ULONG Bit8Stereo; 00023 ULONG Bit16Mono; 00024 ULONG Bit16Stereo; 00025 }AUDIO_RANGE; 00026 00027 #define AUDIO_TEST_RANGE (5) 00028 00029 static AUDIO_RANGE TestRange[AUDIO_TEST_RANGE] = 00030 { 00031 { 00032 11025, 00033 WAVE_FORMAT_1M08, 00034 WAVE_FORMAT_1S08, 00035 WAVE_FORMAT_1M16, 00036 WAVE_FORMAT_1S16 00037 }, 00038 { 00039 22050, 00040 WAVE_FORMAT_2M08, 00041 WAVE_FORMAT_2S08, 00042 WAVE_FORMAT_2M16, 00043 WAVE_FORMAT_2S16 00044 }, 00045 { 00046 44100, 00047 WAVE_FORMAT_4M08, 00048 WAVE_FORMAT_4S08, 00049 WAVE_FORMAT_4M16, 00050 WAVE_FORMAT_4S16 00051 }, 00052 { 00053 48000, 00054 WAVE_FORMAT_48M08, 00055 WAVE_FORMAT_48S08, 00056 WAVE_FORMAT_48M16, 00057 WAVE_FORMAT_48S16 00058 }, 00059 { 00060 96000, 00061 WAVE_FORMAT_96M08, 00062 WAVE_FORMAT_96S08, 00063 WAVE_FORMAT_96M16, 00064 WAVE_FORMAT_96S16 00065 } 00066 }; 00067 00068 PKSPIN_CONNECT 00069 MMixerAllocatePinConnect( 00070 IN PMIXER_CONTEXT MixerContext, 00071 ULONG DataFormatSize) 00072 { 00073 return MixerContext->Alloc(sizeof(KSPIN_CONNECT) + DataFormatSize); 00074 } 00075 00076 MIXER_STATUS 00077 MMixerGetWaveInfoByIndexAndType( 00078 IN PMIXER_LIST MixerList, 00079 IN ULONG DeviceIndex, 00080 IN ULONG bWaveInType, 00081 OUT LPWAVE_INFO *OutWaveInfo) 00082 { 00083 ULONG Index = 0; 00084 PLIST_ENTRY Entry, ListHead; 00085 LPWAVE_INFO WaveInfo; 00086 00087 if (bWaveInType) 00088 ListHead = &MixerList->WaveInList; 00089 else 00090 ListHead = &MixerList->WaveOutList; 00091 00092 /* get first entry */ 00093 Entry = ListHead->Flink; 00094 00095 while(Entry != ListHead) 00096 { 00097 WaveInfo = (LPWAVE_INFO)CONTAINING_RECORD(Entry, WAVE_INFO, Entry); 00098 00099 if (Index == DeviceIndex) 00100 { 00101 *OutWaveInfo = WaveInfo; 00102 return MM_STATUS_SUCCESS; 00103 } 00104 Index++; 00105 Entry = Entry->Flink; 00106 } 00107 00108 return MM_STATUS_INVALID_PARAMETER; 00109 } 00110 00111 00112 00113 00114 VOID 00115 MMixerInitializeDataFormat( 00116 IN PKSDATAFORMAT_WAVEFORMATEX DataFormat, 00117 LPWAVEFORMATEX WaveFormatEx) 00118 { 00119 00120 DataFormat->WaveFormatEx.wFormatTag = WaveFormatEx->wFormatTag; 00121 DataFormat->WaveFormatEx.nChannels = WaveFormatEx->nChannels; 00122 DataFormat->WaveFormatEx.nSamplesPerSec = WaveFormatEx->nSamplesPerSec; 00123 DataFormat->WaveFormatEx.nBlockAlign = WaveFormatEx->nBlockAlign; 00124 DataFormat->WaveFormatEx.nAvgBytesPerSec = WaveFormatEx->nAvgBytesPerSec; 00125 DataFormat->WaveFormatEx.wBitsPerSample = WaveFormatEx->wBitsPerSample; 00126 DataFormat->WaveFormatEx.cbSize = 0; 00127 DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX); 00128 DataFormat->DataFormat.Flags = 0; 00129 DataFormat->DataFormat.Reserved = 0; 00130 DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; 00131 00132 DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 00133 DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; 00134 DataFormat->DataFormat.SampleSize = 4; 00135 } 00136 00137 00138 MIXER_STATUS 00139 MMixerGetAudioPinDataRanges( 00140 IN PMIXER_CONTEXT MixerContext, 00141 IN HANDLE hDevice, 00142 IN ULONG PinId, 00143 IN OUT PKSMULTIPLE_ITEM * OutMultipleItem) 00144 { 00145 KSP_PIN PinProperty; 00146 ULONG BytesReturned = 0; 00147 MIXER_STATUS Status; 00148 PKSMULTIPLE_ITEM MultipleItem; 00149 00150 /* retrieve size of data ranges buffer */ 00151 PinProperty.Reserved = 0; 00152 PinProperty.PinId = PinId; 00153 PinProperty.Property.Set = KSPROPSETID_Pin; 00154 PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES; 00155 PinProperty.Property.Flags = KSPROPERTY_TYPE_GET; 00156 00157 Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned); 00158 if (Status != MM_STATUS_MORE_ENTRIES) 00159 { 00160 return Status; 00161 } 00162 00163 MultipleItem = MixerContext->Alloc(BytesReturned); 00164 if (!MultipleItem) 00165 { 00166 /* not enough memory */ 00167 return MM_STATUS_NO_MEMORY; 00168 } 00169 00170 Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned); 00171 if (Status != MM_STATUS_SUCCESS) 00172 { 00173 /* failed */ 00174 MixerContext->Free(MultipleItem); 00175 return Status; 00176 } 00177 00178 /* save result */ 00179 *OutMultipleItem = MultipleItem; 00180 return Status; 00181 } 00182 00183 MIXER_STATUS 00184 MMixerFindAudioDataRange( 00185 PKSMULTIPLE_ITEM MultipleItem, 00186 PKSDATARANGE_AUDIO * OutDataRangeAudio) 00187 { 00188 ULONG Index; 00189 PKSDATARANGE_AUDIO DataRangeAudio; 00190 PKSDATARANGE DataRange; 00191 00192 DataRange = (PKSDATARANGE) (MultipleItem + 1); 00193 for(Index = 0; Index < MultipleItem->Count; Index++) 00194 { 00195 if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO)) 00196 { 00197 DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange; 00198 if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) && 00199 IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) && 00200 IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) 00201 { 00202 DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u\n", DataRangeAudio->MinimumSampleFrequency, DataRangeAudio->MaximumSampleFrequency, 00203 DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample, DataRangeAudio->MaximumChannels); 00204 *OutDataRangeAudio = DataRangeAudio; 00205 return MM_STATUS_SUCCESS; 00206 } 00207 } 00208 DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize); 00209 } 00210 return MM_STATUS_UNSUCCESSFUL; 00211 } 00212 00213 MIXER_STATUS 00214 MMixerOpenWavePin( 00215 IN PMIXER_CONTEXT MixerContext, 00216 IN PMIXER_LIST MixerList, 00217 IN ULONG DeviceId, 00218 IN ULONG PinId, 00219 IN LPWAVEFORMATEX WaveFormatEx, 00220 IN ACCESS_MASK DesiredAccess, 00221 IN PIN_CREATE_CALLBACK CreateCallback, 00222 IN PVOID Context, 00223 OUT PHANDLE PinHandle) 00224 { 00225 PKSPIN_CONNECT PinConnect; 00226 PKSDATAFORMAT_WAVEFORMATEX DataFormat; 00227 LPMIXER_DATA MixerData; 00228 NTSTATUS Status; 00229 MIXER_STATUS MixerStatus; 00230 00231 MixerData = MMixerGetDataByDeviceId(MixerList, DeviceId); 00232 if (!MixerData) 00233 return MM_STATUS_INVALID_PARAMETER; 00234 00235 /* allocate pin connect */ 00236 PinConnect = MMixerAllocatePinConnect(MixerContext, sizeof(KSDATAFORMAT_WAVEFORMATEX)); 00237 if (!PinConnect) 00238 { 00239 /* no memory */ 00240 return MM_STATUS_NO_MEMORY; 00241 } 00242 00243 /* initialize pin connect struct */ 00244 MMixerInitializePinConnect(PinConnect, PinId); 00245 00246 /* get offset to dataformat */ 00247 DataFormat = (PKSDATAFORMAT_WAVEFORMATEX) (PinConnect + 1); 00248 /* initialize with requested wave format */ 00249 MMixerInitializeDataFormat(DataFormat, WaveFormatEx); 00250 00251 if (CreateCallback) 00252 { 00253 /* let the callback handle the creation */ 00254 MixerStatus = CreateCallback(Context, DeviceId, PinId, MixerData->hDevice, PinConnect, DesiredAccess, PinHandle); 00255 } 00256 else 00257 { 00258 /* now create the pin */ 00259 Status = KsCreatePin(MixerData->hDevice, PinConnect, DesiredAccess, PinHandle); 00260 00261 /* normalize status */ 00262 if (Status == STATUS_SUCCESS) 00263 MixerStatus = MM_STATUS_SUCCESS; 00264 else 00265 MixerStatus = MM_STATUS_UNSUCCESSFUL; 00266 } 00267 00268 /* free create info */ 00269 MixerContext->Free(PinConnect); 00270 00271 /* done */ 00272 return MixerStatus; 00273 } 00274 00275 VOID 00276 MMixerCheckFormat( 00277 IN PKSDATARANGE_AUDIO DataRangeAudio, 00278 IN LPWAVE_INFO WaveInfo, 00279 IN ULONG bInput) 00280 { 00281 ULONG Index, SampleFrequency; 00282 ULONG Result = 0; 00283 00284 for(Index = 0; Index < AUDIO_TEST_RANGE; Index++) 00285 { 00286 SampleFrequency = TestRange[Index].SampleRate; 00287 00288 if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency && DataRangeAudio->MaximumSampleFrequency >= SampleFrequency) 00289 { 00290 /* the audio adapter supports the sample frequency */ 00291 if (DataRangeAudio->MinimumBitsPerSample <= 8 && DataRangeAudio->MaximumBitsPerSample >= 8) 00292 { 00293 Result |= TestRange[Index].Bit8Mono; 00294 00295 if (DataRangeAudio->MaximumChannels > 1) 00296 { 00297 /* check if pin supports the sample rate in 8-Bit Stereo */ 00298 Result |= TestRange[Index].Bit8Stereo; 00299 } 00300 } 00301 00302 if (DataRangeAudio->MinimumBitsPerSample <= 16 && DataRangeAudio->MaximumBitsPerSample >= 16) 00303 { 00304 /* check if pin supports the sample rate in 16-Bit Mono */ 00305 Result |= TestRange[Index].Bit16Mono; 00306 00307 00308 if (DataRangeAudio->MaximumChannels > 1) 00309 { 00310 /* check if pin supports the sample rate in 16-Bit Stereo */ 00311 Result |= TestRange[Index].Bit16Stereo; 00312 } 00313 } 00314 } 00315 } 00316 00317 00318 if (bInput) 00319 WaveInfo->u.InCaps.dwFormats = Result; 00320 else 00321 WaveInfo->u.OutCaps.dwFormats = Result; 00322 00323 DPRINT("Format %lx bInput %u\n", Result, bInput); 00324 } 00325 00326 MIXER_STATUS 00327 MMixerInitializeWaveInfo( 00328 IN PMIXER_CONTEXT MixerContext, 00329 IN PMIXER_LIST MixerList, 00330 IN LPMIXER_DATA MixerData, 00331 IN LPWSTR DeviceName, 00332 IN ULONG bWaveIn, 00333 IN ULONG PinCount, 00334 IN PULONG Pins) 00335 { 00336 MIXER_STATUS Status; 00337 PKSMULTIPLE_ITEM MultipleItem; 00338 PKSDATARANGE_AUDIO DataRangeAudio; 00339 LPWAVE_INFO WaveInfo; 00340 00341 WaveInfo = (LPWAVE_INFO)MixerContext->Alloc(sizeof(WAVE_INFO)); 00342 if (!WaveInfo) 00343 return MM_STATUS_NO_MEMORY; 00344 00345 if (PinCount > 1) 00346 { 00347 /* FIXME support multiple pins for wave device */ 00348 DPRINT1("Implement support for multiple pins\n"); 00349 //ASSERT(PinCount == 1); 00350 } 00351 00352 /* initialize wave info */ 00353 WaveInfo->DeviceId = MixerData->DeviceId; 00354 WaveInfo->PinId = Pins[0]; 00355 00356 /* sanity check */ 00357 ASSERT(wcslen(DeviceName) + 1 < MAXPNAMELEN); 00358 00359 /* copy device name */ 00360 if (bWaveIn) 00361 { 00362 wcscpy(WaveInfo->u.InCaps.szPname, DeviceName); 00363 } 00364 else 00365 { 00366 wcscpy(WaveInfo->u.OutCaps.szPname, DeviceName); 00367 } 00368 00369 /* FIXME determine manufacturer / product id */ 00370 if (bWaveIn) 00371 { 00372 WaveInfo->u.InCaps.wMid = MM_MICROSOFT; 00373 WaveInfo->u.InCaps.wPid = MM_PID_UNMAPPED; 00374 WaveInfo->u.InCaps.vDriverVersion = 1; 00375 } 00376 else 00377 { 00378 WaveInfo->u.OutCaps.wMid = MM_MICROSOFT; 00379 WaveInfo->u.OutCaps.wPid = MM_PID_UNMAPPED; 00380 WaveInfo->u.OutCaps.vDriverVersion = 1; 00381 } 00382 00383 /* get audio pin data ranges */ 00384 Status = MMixerGetAudioPinDataRanges(MixerContext, MixerData->hDevice, Pins[0], &MultipleItem); 00385 if (Status != MM_STATUS_SUCCESS) 00386 { 00387 /* failed to get audio pin data ranges */ 00388 MixerContext->Free(WaveInfo); 00389 return MM_STATUS_UNSUCCESSFUL; 00390 } 00391 00392 /* find an KSDATARANGE_AUDIO range */ 00393 Status = MMixerFindAudioDataRange(MultipleItem, &DataRangeAudio); 00394 if (Status != MM_STATUS_SUCCESS) 00395 { 00396 /* failed to find audio pin data range */ 00397 MixerContext->Free(MultipleItem); 00398 MixerContext->Free(WaveInfo); 00399 return MM_STATUS_UNSUCCESSFUL; 00400 } 00401 00402 /* store channel count */ 00403 if (bWaveIn) 00404 { 00405 WaveInfo->u.InCaps.wChannels = DataRangeAudio->MaximumChannels; 00406 } 00407 else 00408 { 00409 WaveInfo->u.OutCaps.wChannels = DataRangeAudio->MaximumChannels; 00410 } 00411 00412 /* get all supported formats */ 00413 MMixerCheckFormat(DataRangeAudio, WaveInfo, bWaveIn); 00414 00415 /* free dataranges buffer */ 00416 MixerContext->Free(MultipleItem); 00417 00418 if (bWaveIn) 00419 { 00420 InsertTailList(&MixerList->WaveInList, &WaveInfo->Entry); 00421 MixerList->WaveInListCount++; 00422 } 00423 else 00424 { 00425 InsertTailList(&MixerList->WaveOutList, &WaveInfo->Entry); 00426 MixerList->WaveOutListCount++; 00427 } 00428 00429 return MM_STATUS_SUCCESS; 00430 } 00431 00432 MIXER_STATUS 00433 MMixerOpenWave( 00434 IN PMIXER_CONTEXT MixerContext, 00435 IN ULONG DeviceIndex, 00436 IN ULONG bWaveIn, 00437 IN LPWAVEFORMATEX WaveFormat, 00438 IN PIN_CREATE_CALLBACK CreateCallback, 00439 IN PVOID Context, 00440 OUT PHANDLE PinHandle) 00441 { 00442 PMIXER_LIST MixerList; 00443 MIXER_STATUS Status; 00444 LPWAVE_INFO WaveInfo; 00445 ACCESS_MASK DesiredAccess = 0; 00446 00447 /* verify mixer context */ 00448 Status = MMixerVerifyContext(MixerContext); 00449 00450 if (Status != MM_STATUS_SUCCESS) 00451 { 00452 /* invalid context passed */ 00453 return Status; 00454 } 00455 00456 /* grab mixer list */ 00457 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00458 00459 if (WaveFormat->wFormatTag != WAVE_FORMAT_PCM) 00460 { 00461 /* not implemented */ 00462 return MM_STATUS_NOT_IMPLEMENTED; 00463 } 00464 00465 /* find destination wave */ 00466 Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, bWaveIn, &WaveInfo); 00467 if (Status != MM_STATUS_SUCCESS) 00468 { 00469 /* failed to find wave info */ 00470 return MM_STATUS_INVALID_PARAMETER; 00471 } 00472 00473 /* get desired access */ 00474 if (bWaveIn) 00475 { 00476 DesiredAccess |= GENERIC_READ; 00477 } 00478 else 00479 { 00480 DesiredAccess |= GENERIC_WRITE; 00481 } 00482 00483 /* now try open the pin */ 00484 return MMixerOpenWavePin(MixerContext, MixerList, WaveInfo->DeviceId, WaveInfo->PinId, WaveFormat, DesiredAccess, CreateCallback, Context, PinHandle); 00485 } 00486 00487 MIXER_STATUS 00488 MMixerWaveInCapabilities( 00489 IN PMIXER_CONTEXT MixerContext, 00490 IN ULONG DeviceIndex, 00491 OUT LPWAVEINCAPSW Caps) 00492 { 00493 PMIXER_LIST MixerList; 00494 MIXER_STATUS Status; 00495 LPWAVE_INFO WaveInfo; 00496 00497 /* verify mixer context */ 00498 Status = MMixerVerifyContext(MixerContext); 00499 00500 if (Status != MM_STATUS_SUCCESS) 00501 { 00502 /* invalid context passed */ 00503 return Status; 00504 } 00505 00506 /* grab mixer list */ 00507 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00508 00509 /* find destination wave */ 00510 Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, TRUE, &WaveInfo); 00511 if (Status != MM_STATUS_SUCCESS) 00512 { 00513 /* failed to find wave info */ 00514 return MM_STATUS_UNSUCCESSFUL; 00515 } 00516 00517 /* copy capabilities */ 00518 MixerContext->Copy(Caps, &WaveInfo->u.InCaps, sizeof(WAVEINCAPSW)); 00519 00520 return MM_STATUS_SUCCESS; 00521 } 00522 00523 MIXER_STATUS 00524 MMixerWaveOutCapabilities( 00525 IN PMIXER_CONTEXT MixerContext, 00526 IN ULONG DeviceIndex, 00527 OUT LPWAVEOUTCAPSW Caps) 00528 { 00529 PMIXER_LIST MixerList; 00530 MIXER_STATUS Status; 00531 LPWAVE_INFO WaveInfo; 00532 00533 /* verify mixer context */ 00534 Status = MMixerVerifyContext(MixerContext); 00535 00536 if (Status != MM_STATUS_SUCCESS) 00537 { 00538 /* invalid context passed */ 00539 return Status; 00540 } 00541 00542 /* grab mixer list */ 00543 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00544 00545 /* find destination wave */ 00546 Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, FALSE, &WaveInfo); 00547 if (Status != MM_STATUS_SUCCESS) 00548 { 00549 /* failed to find wave info */ 00550 return MM_STATUS_UNSUCCESSFUL; 00551 } 00552 00553 /* copy capabilities */ 00554 MixerContext->Copy(Caps, &WaveInfo->u.OutCaps, sizeof(WAVEOUTCAPSW)); 00555 00556 return MM_STATUS_SUCCESS; 00557 } 00558 00559 ULONG 00560 MMixerGetWaveInCount( 00561 IN PMIXER_CONTEXT MixerContext) 00562 { 00563 PMIXER_LIST MixerList; 00564 MIXER_STATUS Status; 00565 00566 /* verify mixer context */ 00567 Status = MMixerVerifyContext(MixerContext); 00568 00569 if (Status != MM_STATUS_SUCCESS) 00570 { 00571 /* invalid context passed */ 00572 return Status; 00573 } 00574 00575 /* grab mixer list */ 00576 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00577 00578 return MixerList->WaveInListCount; 00579 } 00580 00581 ULONG 00582 MMixerGetWaveOutCount( 00583 IN PMIXER_CONTEXT MixerContext) 00584 { 00585 PMIXER_LIST MixerList; 00586 MIXER_STATUS Status; 00587 00588 /* verify mixer context */ 00589 Status = MMixerVerifyContext(MixerContext); 00590 00591 if (Status != MM_STATUS_SUCCESS) 00592 { 00593 /* invalid context passed */ 00594 return Status; 00595 } 00596 00597 /* grab mixer list */ 00598 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00599 00600 return MixerList->WaveOutListCount; 00601 } 00602 00603 MIXER_STATUS 00604 MMixerSetWaveStatus( 00605 IN PMIXER_CONTEXT MixerContext, 00606 IN HANDLE PinHandle, 00607 IN KSSTATE State) 00608 { 00609 KSPROPERTY Property; 00610 ULONG Length; 00611 MIXER_STATUS Status; 00612 00613 /* verify mixer context */ 00614 Status = MMixerVerifyContext(MixerContext); 00615 00616 if (Status != MM_STATUS_SUCCESS) 00617 { 00618 /* invalid context passed */ 00619 return Status; 00620 } 00621 00622 /* setup property request */ 00623 Property.Set = KSPROPSETID_Connection; 00624 Property.Id = KSPROPERTY_CONNECTION_STATE; 00625 Property.Flags = KSPROPERTY_TYPE_SET; 00626 00627 return MixerContext->Control(PinHandle, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &Length); 00628 } 00629 00630 MIXER_STATUS 00631 MMixerSetWaveResetState( 00632 IN PMIXER_CONTEXT MixerContext, 00633 IN HANDLE PinHandle, 00634 IN ULONG bBegin) 00635 { 00636 ULONG Length; 00637 MIXER_STATUS Status; 00638 KSRESET Reset; 00639 00640 /* verify mixer context */ 00641 Status = MMixerVerifyContext(MixerContext); 00642 00643 if (Status != MM_STATUS_SUCCESS) 00644 { 00645 /* invalid context passed */ 00646 return Status; 00647 } 00648 00649 /* begin / stop reset */ 00650 Reset = (bBegin ? KSRESET_BEGIN : KSRESET_END); 00651 00652 return MixerContext->Control(PinHandle, IOCTL_KS_RESET_STATE, &Reset, sizeof(KSRESET), NULL, 0, &Length); 00653 } 00654 00655 MIXER_STATUS 00656 MMixerGetWaveDevicePath( 00657 IN PMIXER_CONTEXT MixerContext, 00658 IN ULONG bWaveIn, 00659 IN ULONG DeviceId, 00660 OUT LPWSTR * DevicePath) 00661 { 00662 PMIXER_LIST MixerList; 00663 LPMIXER_DATA MixerData; 00664 LPWAVE_INFO WaveInfo; 00665 ULONG Length; 00666 MIXER_STATUS Status; 00667 00668 /* verify mixer context */ 00669 Status = MMixerVerifyContext(MixerContext); 00670 00671 if (Status != MM_STATUS_SUCCESS) 00672 { 00673 /* invalid context passed */ 00674 return Status; 00675 } 00676 00677 /* grab mixer list */ 00678 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00679 00680 /* find destination wave */ 00681 Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceId, bWaveIn, &WaveInfo); 00682 if (Status != MM_STATUS_SUCCESS) 00683 { 00684 /* failed to find wave info */ 00685 return MM_STATUS_INVALID_PARAMETER; 00686 } 00687 00688 /* get associated device id */ 00689 MixerData = MMixerGetDataByDeviceId(MixerList, WaveInfo->DeviceId); 00690 if (!MixerData) 00691 return MM_STATUS_INVALID_PARAMETER; 00692 00693 /* calculate length */ 00694 Length = wcslen(MixerData->DeviceName)+1; 00695 00696 /* allocate destination buffer */ 00697 *DevicePath = MixerContext->Alloc(Length * sizeof(WCHAR)); 00698 00699 if (!*DevicePath) 00700 { 00701 /* no memory */ 00702 return MM_STATUS_NO_MEMORY; 00703 } 00704 00705 /* copy device path */ 00706 MixerContext->Copy(*DevicePath, MixerData->DeviceName, Length * sizeof(WCHAR)); 00707 00708 /* done */ 00709 return MM_STATUS_SUCCESS; 00710 } 00711 Generated on Sun May 27 2012 04:24:43 for ReactOS by
1.7.6.1
|