Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmixer.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/mmixer.c 00005 * PURPOSE: Mixer Handling Functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 00010 00011 #include "priv.h" 00012 00013 ULONG 00014 MMixerGetCount( 00015 IN PMIXER_CONTEXT MixerContext) 00016 { 00017 PMIXER_LIST MixerList; 00018 MIXER_STATUS Status; 00019 00020 /* verify mixer context */ 00021 Status = MMixerVerifyContext(MixerContext); 00022 00023 if (Status != MM_STATUS_SUCCESS) 00024 { 00025 /* invalid context passed */ 00026 return Status; 00027 } 00028 00029 /* grab mixer list */ 00030 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00031 00032 // return number of mixers 00033 return MixerList->MixerListCount; 00034 } 00035 00036 MIXER_STATUS 00037 MMixerGetCapabilities( 00038 IN PMIXER_CONTEXT MixerContext, 00039 IN ULONG MixerIndex, 00040 OUT LPMIXERCAPSW MixerCaps) 00041 { 00042 MIXER_STATUS Status; 00043 LPMIXER_INFO MixerInfo; 00044 00045 /* verify mixer context */ 00046 Status = MMixerVerifyContext(MixerContext); 00047 00048 if (Status != MM_STATUS_SUCCESS) 00049 { 00050 /* invalid context passed */ 00051 return Status; 00052 } 00053 00054 /* get mixer info */ 00055 MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, MixerIndex); 00056 00057 if (!MixerInfo) 00058 { 00059 // invalid device index 00060 return MM_STATUS_INVALID_PARAMETER; 00061 } 00062 00063 MixerCaps->wMid = MixerInfo->MixCaps.wMid; 00064 MixerCaps->wPid = MixerInfo->MixCaps.wPid; 00065 MixerCaps->vDriverVersion = MixerInfo->MixCaps.vDriverVersion; 00066 MixerCaps->fdwSupport = MixerInfo->MixCaps.fdwSupport; 00067 MixerCaps->cDestinations = MixerInfo->MixCaps.cDestinations; 00068 00069 ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == 0); 00070 wcscpy(MixerCaps->szPname, MixerInfo->MixCaps.szPname); 00071 00072 return MM_STATUS_SUCCESS; 00073 } 00074 00075 MIXER_STATUS 00076 MMixerOpen( 00077 IN PMIXER_CONTEXT MixerContext, 00078 IN ULONG MixerId, 00079 IN PVOID MixerEventContext, 00080 IN PMIXER_EVENT MixerEventRoutine, 00081 OUT PHANDLE MixerHandle) 00082 { 00083 MIXER_STATUS Status; 00084 LPMIXER_INFO MixerInfo; 00085 00086 /* verify mixer context */ 00087 Status = MMixerVerifyContext(MixerContext); 00088 00089 if (Status != MM_STATUS_SUCCESS) 00090 { 00091 /* invalid context passed */ 00092 DPRINT1("invalid context\n"); 00093 return Status; 00094 } 00095 00096 /* get mixer info */ 00097 MixerInfo = (LPMIXER_INFO)MMixerGetMixerInfoByIndex(MixerContext, MixerId); 00098 if (!MixerInfo) 00099 { 00100 /* invalid mixer id */ 00101 DPRINT1("invalid mixer id %lu\n", MixerId); 00102 return MM_STATUS_INVALID_PARAMETER; 00103 } 00104 00105 /* add the event */ 00106 Status = MMixerAddEvent(MixerContext, MixerInfo, MixerEventContext, MixerEventRoutine); 00107 00108 00109 /* store result */ 00110 *MixerHandle = (HANDLE)MixerInfo; 00111 return MM_STATUS_SUCCESS; 00112 } 00113 00114 MIXER_STATUS 00115 MMixerGetLineInfo( 00116 IN PMIXER_CONTEXT MixerContext, 00117 IN HANDLE MixerHandle, 00118 IN ULONG MixerId, 00119 IN ULONG Flags, 00120 OUT LPMIXERLINEW MixerLine) 00121 { 00122 MIXER_STATUS Status; 00123 LPMIXER_INFO MixerInfo; 00124 LPMIXERLINE_EXT MixerLineSrc; 00125 ULONG DestinationLineID; 00126 00127 /* verify mixer context */ 00128 Status = MMixerVerifyContext(MixerContext); 00129 00130 if (Status != MM_STATUS_SUCCESS) 00131 { 00132 /* invalid context passed */ 00133 return Status; 00134 } 00135 if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER) 00136 { 00137 /* caller passed mixer id */ 00138 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId); 00139 00140 if (!MixerHandle) 00141 { 00142 /* invalid parameter */ 00143 return MM_STATUS_INVALID_PARAMETER; 00144 } 00145 } 00146 00147 if (MixerLine->cbStruct != sizeof(MIXERLINEW)) 00148 { 00149 DPRINT1("MixerLine Expected %lu but got %lu\n", sizeof(MIXERLINEW), MixerLine->cbStruct); 00150 return MM_STATUS_INVALID_PARAMETER; 00151 } 00152 00153 /* clear hmixer from flags */ 00154 Flags &=~MIXER_OBJECTF_HMIXER; 00155 00156 DPRINT("MMixerGetLineInfo MixerId %lu Flags %lu\n", MixerId, Flags); 00157 00158 if (Flags == MIXER_GETLINEINFOF_DESTINATION) 00159 { 00160 /* cast to mixer info */ 00161 MixerInfo = (LPMIXER_INFO)MixerHandle; 00162 00163 /* calculate destination line id */ 00164 DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE); 00165 00166 /* get destination line */ 00167 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID); 00168 00169 if (MixerLineSrc == NULL) 00170 { 00171 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination); 00172 return MM_STATUS_UNSUCCESSFUL; 00173 } 00174 /* copy mixer line */ 00175 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW)); 00176 00177 /* make sure it is null terminated */ 00178 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0'; 00179 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0'; 00180 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0'; 00181 00182 /* done */ 00183 return MM_STATUS_SUCCESS; 00184 } 00185 else if (Flags == MIXER_GETLINEINFOF_SOURCE) 00186 { 00187 /* cast to mixer info */ 00188 MixerInfo = (LPMIXER_INFO)MixerHandle; 00189 00190 /* calculate destination line id */ 00191 DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE); 00192 00193 /* get destination line */ 00194 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID); 00195 00196 if (MixerLineSrc == NULL) 00197 { 00198 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination); 00199 return MM_STATUS_UNSUCCESSFUL; 00200 } 00201 00202 /* check if dwSource is out of bounds */ 00203 if (MixerLine->dwSource >= MixerLineSrc->Line.cConnections) 00204 { 00205 DPRINT1("MixerCaps Name %S MixerLineName %S Connections %lu dwSource %lu not found\n", MixerInfo->MixCaps.szPname, MixerLineSrc->Line.szName, MixerLineSrc->Line.cConnections, MixerLine->dwSource); 00206 return MM_STATUS_UNSUCCESSFUL; 00207 } 00208 00209 /* calculate destination line id */ 00210 DestinationLineID = (MixerLine->dwSource * SOURCE_LINE) + MixerLine->dwDestination; 00211 00212 DPRINT("MixerName %S cDestinations %lu MixerLineName %S cConnections %lu dwSource %lu dwDestination %lu ID %lx\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, 00213 MixerLineSrc->Line.szName, MixerLineSrc->Line.cConnections, 00214 MixerLine->dwSource, MixerLine->dwDestination, 00215 DestinationLineID); 00216 /* get target destination line id */ 00217 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID); 00218 00219 /* sanity check */ 00220 ASSERT(MixerLineSrc); 00221 00222 DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName); 00223 00224 /* copy mixer line */ 00225 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW)); 00226 00227 /* make sure it is null terminated */ 00228 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0'; 00229 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0'; 00230 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0'; 00231 00232 /* done */ 00233 return MM_STATUS_SUCCESS; 00234 } 00235 else if (Flags == MIXER_GETLINEINFOF_LINEID) 00236 { 00237 /* cast to mixer info */ 00238 MixerInfo = (LPMIXER_INFO)MixerHandle; 00239 00240 /* try to find line */ 00241 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwLineID); 00242 if (!MixerLineSrc) 00243 { 00244 /* invalid parameter */ 00245 DPRINT1("MMixerGetLineInfo: MixerName %S Line not found 0x%lx\n", MixerInfo->MixCaps.szPname, MixerLine->dwLineID); 00246 return MM_STATUS_INVALID_PARAMETER; 00247 } 00248 00249 DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName); 00250 00251 /* copy mixer line*/ 00252 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW)); 00253 00254 /* make sure it is null terminated */ 00255 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0'; 00256 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0'; 00257 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0'; 00258 00259 return MM_STATUS_SUCCESS; 00260 } 00261 else if (Flags == MIXER_GETLINEINFOF_COMPONENTTYPE) 00262 { 00263 /* cast to mixer info */ 00264 MixerInfo = (LPMIXER_INFO)MixerHandle; 00265 00266 /* find mixer line by component type */ 00267 MixerLineSrc = MMixerGetSourceMixerLineByComponentType(MixerInfo, MixerLine->dwComponentType); 00268 if (!MixerLineSrc) 00269 { 00270 DPRINT1("Failed to find component type %x\n", MixerLine->dwComponentType); 00271 return MM_STATUS_UNSUCCESSFUL; 00272 } 00273 00274 /* copy mixer line */ 00275 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW)); 00276 00277 /* make sure it is null terminated */ 00278 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0'; 00279 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0'; 00280 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0'; 00281 00282 /* done */ 00283 return MM_STATUS_SUCCESS; 00284 } 00285 else if (Flags == MIXER_GETLINEINFOF_TARGETTYPE) 00286 { 00287 DPRINT1("MIXER_GETLINEINFOF_TARGETTYPE handling is unimplemented\n"); 00288 } 00289 else 00290 { 00291 DPRINT1("Unknown Flags %lx handling is unimplemented\n", Flags); 00292 } 00293 00294 return MM_STATUS_NOT_IMPLEMENTED; 00295 } 00296 00297 MIXER_STATUS 00298 MMixerGetLineControls( 00299 IN PMIXER_CONTEXT MixerContext, 00300 IN HANDLE MixerHandle, 00301 IN ULONG MixerId, 00302 IN ULONG Flags, 00303 OUT LPMIXERLINECONTROLSW MixerLineControls) 00304 { 00305 LPMIXER_INFO MixerInfo; 00306 LPMIXERLINE_EXT MixerLineSrc; 00307 LPMIXERCONTROL_EXT MixerControl; 00308 MIXER_STATUS Status; 00309 PLIST_ENTRY Entry; 00310 ULONG Index; 00311 00312 /* verify mixer context */ 00313 Status = MMixerVerifyContext(MixerContext); 00314 00315 if (Status != MM_STATUS_SUCCESS) 00316 { 00317 /* invalid context passed */ 00318 return Status; 00319 } 00320 00321 if (MixerLineControls->cbStruct != sizeof(MIXERLINECONTROLSW)) 00322 { 00323 DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW)); 00324 /* invalid parameter */ 00325 return MM_STATUS_INVALID_PARAMETER; 00326 } 00327 00328 if (MixerLineControls->cbmxctrl != sizeof(MIXERCONTROLW)) 00329 { 00330 DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW)); 00331 /* invalid parameter */ 00332 return MM_STATUS_INVALID_PARAMETER; 00333 } 00334 00335 if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER) 00336 { 00337 /* caller passed mixer id */ 00338 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId); 00339 00340 if (!MixerHandle) 00341 { 00342 /* invalid parameter */ 00343 return MM_STATUS_INVALID_PARAMETER; 00344 } 00345 } 00346 00347 Flags &= ~MIXER_OBJECTF_HMIXER; 00348 00349 DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId, Flags); 00350 00351 if (Flags == MIXER_GETLINECONTROLSF_ALL) 00352 { 00353 /* cast to mixer info */ 00354 MixerInfo = (LPMIXER_INFO)MixerHandle; 00355 00356 /* get mixer line */ 00357 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID); 00358 00359 if (!MixerLineSrc) 00360 { 00361 /* invalid line id */ 00362 DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID); 00363 return MM_STATUS_INVALID_PARAMETER; 00364 } 00365 00366 if (MixerLineSrc->Line.cControls != MixerLineControls->cControls) 00367 { 00368 /* invalid parameter */ 00369 DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls->cControls, MixerLineSrc->Line.cControls); 00370 return MM_STATUS_INVALID_PARAMETER; 00371 } 00372 00373 /* copy line control(s) */ 00374 Entry = MixerLineSrc->ControlsList.Flink; 00375 Index = 0; 00376 while(Entry != &MixerLineSrc->ControlsList) 00377 { 00378 /* get mixer control */ 00379 MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry); 00380 00381 /* copy mixer control */ 00382 MixerContext->Copy(&MixerLineControls->pamxctrl[Index], &MixerControl->Control, sizeof(MIXERCONTROLW)); 00383 00384 /* move to next */ 00385 Entry = Entry->Flink; 00386 00387 /* increment mixer control offset */ 00388 Index++; 00389 } 00390 return MM_STATUS_SUCCESS; 00391 } 00392 else if (Flags == MIXER_GETLINECONTROLSF_ONEBYTYPE) 00393 { 00394 /* cast to mixer info */ 00395 MixerInfo = (LPMIXER_INFO)MixerHandle; 00396 00397 /* get mixer line */ 00398 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID); 00399 00400 if (!MixerLineSrc) 00401 { 00402 /* invalid line id */ 00403 DPRINT1("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID); 00404 return MM_STATUS_INVALID_PARAMETER; 00405 } 00406 00407 /* sanity checks */ 00408 ASSERT(MixerLineControls->cControls == 1); 00409 ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW)); 00410 ASSERT(MixerLineControls->pamxctrl != NULL); 00411 00412 Entry = MixerLineSrc->ControlsList.Flink; 00413 while(Entry != &MixerLineSrc->ControlsList) 00414 { 00415 MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry); 00416 if (MixerLineControls->dwControlType == MixerControl->Control.dwControlType) 00417 { 00418 /* found a control with that type */ 00419 MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW)); 00420 return MM_STATUS_SUCCESS; 00421 } 00422 00423 /* move to next entry */ 00424 Entry = Entry->Flink; 00425 } 00426 00427 DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls->dwControlType, MixerLineControls->dwLineID, MixerLineSrc->Line.cControls); 00428 return MM_STATUS_UNSUCCESSFUL; 00429 } 00430 else if (Flags == MIXER_GETLINECONTROLSF_ONEBYID) 00431 { 00432 /* cast to mixer info */ 00433 MixerInfo = (LPMIXER_INFO)MixerHandle; 00434 00435 Status = MMixerGetMixerControlById(MixerInfo, MixerLineControls->dwControlID, NULL, &MixerControl, NULL); 00436 00437 if (Status != MM_STATUS_SUCCESS) 00438 { 00439 /* invalid parameter */ 00440 DPRINT("MMixerGetLineControls ControlID not found %lx\n", MixerLineControls->dwLineID); 00441 return MM_STATUS_INVALID_PARAMETER; 00442 } 00443 00444 ASSERT(MixerLineControls->cControls == 1); 00445 ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW)); 00446 ASSERT(MixerLineControls->pamxctrl != NULL); 00447 00448 DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl->Control.dwControlID, MixerControl->Control.dwControlType, MixerControl->Control.szName); 00449 00450 /* copy the controls */ 00451 MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW)); 00452 MixerLineControls->pamxctrl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0'; 00453 MixerLineControls->pamxctrl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0'; 00454 00455 return MM_STATUS_SUCCESS; 00456 } 00457 UNIMPLEMENTED 00458 return MM_STATUS_NOT_IMPLEMENTED; 00459 } 00460 00461 MIXER_STATUS 00462 MMixerSetControlDetails( 00463 IN PMIXER_CONTEXT MixerContext, 00464 IN HANDLE MixerHandle, 00465 IN ULONG MixerId, 00466 IN ULONG Flags, 00467 OUT LPMIXERCONTROLDETAILS MixerControlDetails) 00468 { 00469 MIXER_STATUS Status; 00470 ULONG NodeId; 00471 LPMIXER_INFO MixerInfo; 00472 LPMIXERLINE_EXT MixerLine; 00473 LPMIXERCONTROL_EXT MixerControl; 00474 00475 /* verify mixer context */ 00476 Status = MMixerVerifyContext(MixerContext); 00477 00478 if (Status != MM_STATUS_SUCCESS) 00479 { 00480 /* invalid context passed */ 00481 DPRINT1("invalid context\n"); 00482 return Status; 00483 } 00484 00485 if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER) 00486 { 00487 /* caller passed mixer id */ 00488 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId); 00489 00490 if (!MixerHandle) 00491 { 00492 /* invalid parameter */ 00493 DPRINT1("invalid handle\n"); 00494 return MM_STATUS_INVALID_PARAMETER; 00495 } 00496 } 00497 00498 /* get mixer info */ 00499 MixerInfo = (LPMIXER_INFO)MixerHandle; 00500 00501 /* get mixer control */ 00502 Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId); 00503 00504 /* check for success */ 00505 if (Status != MM_STATUS_SUCCESS) 00506 { 00507 /* failed to find control id */ 00508 DPRINT1("invalid control id %lu\n", MixerControlDetails->dwControlID); 00509 return MM_STATUS_INVALID_PARAMETER; 00510 } 00511 00512 DPRINT("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl->Control.dwControlType, MixerControl->Control.szName, MixerLine->Line.szName, NodeId); 00513 switch(MixerControl->Control.dwControlType) 00514 { 00515 case MIXERCONTROL_CONTROLTYPE_MUTE: 00516 Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, TRUE); 00517 break; 00518 case MIXERCONTROL_CONTROLTYPE_VOLUME: 00519 Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine); 00520 break; 00521 case MIXERCONTROL_CONTROLTYPE_MUX: 00522 Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId, TRUE, Flags, MixerControl, MixerControlDetails, MixerLine); 00523 break; 00524 default: 00525 Status = MM_STATUS_NOT_IMPLEMENTED; 00526 } 00527 00528 return Status; 00529 } 00530 00531 MIXER_STATUS 00532 MMixerGetControlDetails( 00533 IN PMIXER_CONTEXT MixerContext, 00534 IN HANDLE MixerHandle, 00535 IN ULONG MixerId, 00536 IN ULONG Flags, 00537 OUT LPMIXERCONTROLDETAILS MixerControlDetails) 00538 { 00539 MIXER_STATUS Status; 00540 ULONG NodeId; 00541 LPMIXER_INFO MixerInfo; 00542 LPMIXERLINE_EXT MixerLine; 00543 LPMIXERCONTROL_EXT MixerControl; 00544 00545 /* verify mixer context */ 00546 Status = MMixerVerifyContext(MixerContext); 00547 00548 if (Status != MM_STATUS_SUCCESS) 00549 { 00550 /* invalid context passed */ 00551 return Status; 00552 } 00553 00554 if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER) 00555 { 00556 /* caller passed mixer id */ 00557 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId); 00558 00559 if (!MixerHandle) 00560 { 00561 /* invalid parameter */ 00562 return MM_STATUS_INVALID_PARAMETER; 00563 } 00564 } 00565 00566 /* get mixer info */ 00567 MixerInfo = (LPMIXER_INFO)MixerHandle; 00568 00569 /* get mixer control */ 00570 Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId); 00571 00572 /* check for success */ 00573 if (Status != MM_STATUS_SUCCESS) 00574 { 00575 /* failed to find control id */ 00576 return MM_STATUS_INVALID_PARAMETER; 00577 } 00578 00579 switch(MixerControl->Control.dwControlType) 00580 { 00581 case MIXERCONTROL_CONTROLTYPE_MUTE: 00582 Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, FALSE); 00583 break; 00584 case MIXERCONTROL_CONTROLTYPE_VOLUME: 00585 Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine); 00586 break; 00587 case MIXERCONTROL_CONTROLTYPE_ONOFF: 00588 DPRINT1("Not Implemented MIXERCONTROL_CONTROLTYPE_ONOFF\n"); 00589 break; 00590 case MIXERCONTROL_CONTROLTYPE_MUX: 00591 Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId, FALSE, Flags, MixerControl, MixerControlDetails, MixerLine); 00592 break; 00593 00594 default: 00595 Status = MM_STATUS_NOT_IMPLEMENTED; 00596 DPRINT1("ControlType %lx not implemented\n", MixerControl->Control.dwControlType); 00597 } 00598 00599 return Status; 00600 } 00601 00602 VOID 00603 MMixerPrintMixerLineControls( 00604 IN LPMIXERLINE_EXT MixerLine) 00605 { 00606 PLIST_ENTRY Entry; 00607 LPMIXERCONTROL_EXT MixerControl; 00608 ULONG Index = 0; 00609 00610 Entry = MixerLine->ControlsList.Flink; 00611 while(Entry != &MixerLine->ControlsList) 00612 { 00613 MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry); 00614 00615 DPRINT1("\n"); 00616 DPRINT1("Control Index: %lu\n", Index); 00617 DPRINT("\n"); 00618 DPRINT1("cbStruct %u\n", MixerControl->Control.cbStruct); 00619 DPRINT1("dwControlID %lu\n", MixerControl->Control.dwControlID); 00620 DPRINT1("dwControlType %lx\n", MixerControl->Control.dwControlType); 00621 DPRINT1("fdwControl %lu\n", MixerControl->Control.fdwControl); 00622 DPRINT1("cMultipleItems %lu\n", MixerControl->Control.cMultipleItems); 00623 DPRINT1("szShortName %S\n", MixerControl->Control.szShortName); 00624 DPRINT1("szName %S\n", MixerControl->Control.szName); 00625 DPRINT1("Bounds.dwMinimum %lu\n", MixerControl->Control.Bounds.dwMinimum); 00626 DPRINT1("Bounds.dwMaximum %lu\n", MixerControl->Control.Bounds.dwMaximum); 00627 00628 DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl->Control.Metrics.dwReserved[0]); 00629 DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl->Control.Metrics.dwReserved[1]); 00630 DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl->Control.Metrics.dwReserved[2]); 00631 DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl->Control.Metrics.dwReserved[3]); 00632 DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl->Control.Metrics.dwReserved[4]); 00633 DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl->Control.Metrics.dwReserved[5]); 00634 00635 Entry = Entry->Flink; 00636 Index++; 00637 } 00638 } 00639 00640 VOID 00641 MMixerPrintMixers( 00642 IN PMIXER_CONTEXT MixerContext, 00643 IN PMIXER_LIST MixerList) 00644 { 00645 ULONG Index, SubIndex, DestinationLineID, SrcIndex; 00646 LPMIXER_INFO MixerInfo; 00647 LPMIXERLINE_EXT DstMixerLine, SrcMixerLine; 00648 00649 DPRINT1("MixerList %p\n", MixerList); 00650 DPRINT1("MidiInCount %lu\n", MixerList->MidiInListCount); 00651 DPRINT1("MidiOutCount %lu\n", MixerList->MidiOutListCount); 00652 DPRINT1("WaveInCount %lu\n", MixerList->WaveInListCount); 00653 DPRINT1("WaveOutCount %lu\n", MixerList->WaveOutListCount); 00654 DPRINT1("MixerCount %p\n", MixerList->MixerListCount); 00655 00656 00657 for(Index = 0; Index < MixerList->MixerListCount; Index++) 00658 { 00659 /* get mixer info */ 00660 MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, Index); 00661 00662 ASSERT(MixerInfo); 00663 DPRINT1("\n"); 00664 DPRINT1("Name :%S\n", MixerInfo->MixCaps.szPname); 00665 DPRINT1("cDestinations: %lu\n", MixerInfo->MixCaps.cDestinations); 00666 DPRINT1("fdwSupport %lu\n", MixerInfo->MixCaps.fdwSupport); 00667 DPRINT1("vDriverVersion %lx\n", MixerInfo->MixCaps.vDriverVersion); 00668 DPRINT1("wMid %lx\n", MixerInfo->MixCaps.wMid); 00669 DPRINT1("wPid %lx\n", MixerInfo->MixCaps.wPid); 00670 00671 for(SubIndex = 0; SubIndex < MixerInfo->MixCaps.cDestinations; SubIndex++) 00672 { 00673 /* calculate destination line id */ 00674 DestinationLineID = (SubIndex + DESTINATION_LINE); 00675 00676 /* get destination line */ 00677 DstMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID); 00678 DPRINT1("//----------------------------------------------------------------------------------------------\n"); 00679 DPRINT1("\n"); 00680 DPRINT1("Destination Index %lu\n", SubIndex); 00681 DPRINT1("\n"); 00682 DPRINT1("cChannels %lu\n", DstMixerLine->Line.cChannels); 00683 DPRINT1("cConnections %lu\n", DstMixerLine->Line.cConnections); 00684 DPRINT1("cControls %lu\n", DstMixerLine->Line.cControls); 00685 DPRINT1("dwComponentType %lx\n", DstMixerLine->Line.dwComponentType); 00686 DPRINT1("dwDestination %lu\n", DstMixerLine->Line.dwDestination); 00687 DPRINT1("dwLineID %lx\n", DstMixerLine->Line.dwLineID); 00688 DPRINT1("dwSource %lx\n", DstMixerLine->Line.dwSource); 00689 DPRINT1("dwUser %lu\n", DstMixerLine->Line.dwUser); 00690 DPRINT1("fdwLine %lu\n", DstMixerLine->Line.fdwLine); 00691 DPRINT1("szName %S\n", DstMixerLine->Line.szName); 00692 DPRINT1("szShortName %S\n", DstMixerLine->Line.szShortName); 00693 DPRINT1("Target.dwDeviceId %lu\n", DstMixerLine->Line.Target.dwDeviceID); 00694 DPRINT1("Target.dwType %lu\n", DstMixerLine->Line.Target.dwType); 00695 DPRINT1("Target.szName %S\n", DstMixerLine->Line.Target.szPname); 00696 DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine->Line.Target.vDriverVersion); 00697 DPRINT1("Target.wMid %lx\n", DstMixerLine->Line.Target.wMid ); 00698 DPRINT1("Target.wPid %lx\n", DstMixerLine->Line.Target.wPid); 00699 MMixerPrintMixerLineControls(DstMixerLine); 00700 00701 for(SrcIndex = 0; SrcIndex < DstMixerLine->Line.cConnections; SrcIndex++) 00702 { 00703 /* calculate destination line id */ 00704 DestinationLineID = (SOURCE_LINE * SrcIndex) + SubIndex; 00705 00706 /* get source line */ 00707 SrcMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID); 00708 DPRINT1("//==============================================================================================\n"); 00709 DPRINT1("\n"); 00710 DPRINT1("SrcLineIndex : %lu\n", SrcIndex); 00711 DPRINT1("\n"); 00712 DPRINT1("cChannels %lu\n", SrcMixerLine->Line.cChannels); 00713 DPRINT1("cConnections %lu\n", SrcMixerLine->Line.cConnections); 00714 DPRINT1("cControls %lu\n", SrcMixerLine->Line.cControls); 00715 DPRINT1("dwComponentType %lx\n", SrcMixerLine->Line.dwComponentType); 00716 DPRINT1("dwDestination %lu\n", SrcMixerLine->Line.dwDestination); 00717 DPRINT1("dwLineID %lx\n", SrcMixerLine->Line.dwLineID); 00718 DPRINT1("dwSource %lx\n", SrcMixerLine->Line.dwSource); 00719 DPRINT1("dwUser %lu\n", SrcMixerLine->Line.dwUser); 00720 DPRINT1("fdwLine %lu\n", SrcMixerLine->Line.fdwLine); 00721 DPRINT1("szName %S\n", SrcMixerLine->Line.szName); 00722 DPRINT1("szShortName %S\n", SrcMixerLine->Line.szShortName); 00723 DPRINT1("Target.dwDeviceId %lu\n", SrcMixerLine->Line.Target.dwDeviceID); 00724 DPRINT1("Target.dwType %lu\n", SrcMixerLine->Line.Target.dwType); 00725 DPRINT1("Target.szName %S\n", SrcMixerLine->Line.Target.szPname); 00726 DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine->Line.Target.vDriverVersion); 00727 DPRINT1("Target.wMid %lx\n", SrcMixerLine->Line.Target.wMid ); 00728 DPRINT1("Target.wPid %lx\n", SrcMixerLine->Line.Target.wPid); 00729 MMixerPrintMixerLineControls(SrcMixerLine); 00730 } 00731 } 00732 } 00733 } 00734 00735 MIXER_STATUS 00736 MMixerInitialize( 00737 IN PMIXER_CONTEXT MixerContext, 00738 IN PMIXER_ENUM EnumFunction, 00739 IN PVOID EnumContext) 00740 { 00741 MIXER_STATUS Status; 00742 HANDLE hMixer, hKey; 00743 ULONG DeviceIndex, Count; 00744 LPWSTR DeviceName; 00745 LPMIXER_DATA MixerData; 00746 PMIXER_LIST MixerList; 00747 PLIST_ENTRY Entry; 00748 00749 if (!MixerContext || !EnumFunction || !EnumContext) 00750 { 00751 /* invalid parameter */ 00752 return MM_STATUS_INVALID_PARAMETER; 00753 } 00754 00755 if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || 00756 !MixerContext->AllocEventData || !MixerContext->FreeEventData || 00757 !MixerContext->Close || !MixerContext->OpenKey || !MixerContext->QueryKeyValue || !MixerContext->CloseKey) 00758 { 00759 /* invalid parameter */ 00760 return MM_STATUS_INVALID_PARAMETER; 00761 } 00762 00763 /* allocate a mixer list */ 00764 MixerList = (PMIXER_LIST)MixerContext->Alloc(sizeof(MIXER_LIST)); 00765 if (!MixerList) 00766 { 00767 /* no memory */ 00768 return MM_STATUS_NO_MEMORY; 00769 } 00770 00771 /* initialize mixer list */ 00772 MixerList->MixerListCount = 0; 00773 MixerList->MixerDataCount = 0; 00774 MixerList->WaveInListCount = 0; 00775 MixerList->WaveOutListCount = 0; 00776 MixerList->MidiInListCount = 0; 00777 MixerList->MidiOutListCount = 0; 00778 InitializeListHead(&MixerList->MixerList); 00779 InitializeListHead(&MixerList->MixerData); 00780 InitializeListHead(&MixerList->WaveInList); 00781 InitializeListHead(&MixerList->WaveOutList); 00782 InitializeListHead(&MixerList->MidiInList); 00783 InitializeListHead(&MixerList->MidiOutList); 00784 00785 /* store mixer list */ 00786 MixerContext->MixerContext = (PVOID)MixerList; 00787 00788 /* start enumerating all available devices */ 00789 Count = 0; 00790 DeviceIndex = 0; 00791 00792 do 00793 { 00794 /* enumerate a device */ 00795 Status = EnumFunction(EnumContext, DeviceIndex, &DeviceName, &hMixer, &hKey); 00796 00797 if (Status != MM_STATUS_SUCCESS) 00798 { 00799 /* check error code */ 00800 if (Status == MM_STATUS_NO_MORE_DEVICES) 00801 { 00802 /* enumeration has finished */ 00803 break; 00804 } 00805 else 00806 { 00807 DPRINT1("Failed to enumerate device %lu\n", DeviceIndex); 00808 00809 /* TODO cleanup */ 00810 return Status; 00811 } 00812 } 00813 else 00814 { 00815 /* create a mixer data entry */ 00816 Status = MMixerCreateMixerData(MixerContext, MixerList, DeviceIndex, DeviceName, hMixer, hKey); 00817 if (Status != MM_STATUS_SUCCESS) 00818 break; 00819 } 00820 00821 /* increment device index */ 00822 DeviceIndex++; 00823 }while(TRUE); 00824 00825 /* now all filters have been pre-opened 00826 * lets enumerate the filters 00827 */ 00828 Entry = MixerList->MixerData.Flink; 00829 while(Entry != &MixerList->MixerData) 00830 { 00831 MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry); 00832 MMixerSetupFilter(MixerContext, MixerList, MixerData, &Count); 00833 Entry = Entry->Flink; 00834 } 00835 00836 Entry = MixerList->MixerData.Flink; 00837 while(Entry != &MixerList->MixerData) 00838 { 00839 MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry); 00840 00841 /* now handle alternative mixer types */ 00842 MMixerHandleAlternativeMixers(MixerContext, MixerList, MixerData, MixerData->Topology); 00843 Entry = Entry->Flink; 00844 } 00845 00846 //MMixerPrintMixers(MixerContext, MixerList); 00847 00848 /* done */ 00849 return MM_STATUS_SUCCESS; 00850 } Generated on Sun May 27 2012 04:17:44 for ReactOS by
1.7.6.1
|