| 8304 | |
| 8305 | |
| 8306 | ResultType Line::SoundSetGet(char *aSetting, DWORD aComponentType, int aComponentInstance |
| 8307 | , DWORD aControlType, UINT aMixerID) |
| 8308 | // If the caller specifies NULL for aSetting, the mode will be "Get". Otherwise, it will be "Set". |
| 8309 | { |
| 8310 | #define SOUND_MODE_IS_SET aSetting // Boolean: i.e. if it's not NULL, the mode is "SET". |
| 8311 | double setting_percent; |
| 8312 | Var *output_var; |
| 8313 | if (SOUND_MODE_IS_SET) |
| 8314 | { |
| 8315 | output_var = NULL; // To help catch bugs. |
| 8316 | setting_percent = ATOF(aSetting); |
| 8317 | if (setting_percent < -100) |
| 8318 | setting_percent = -100; |
| 8319 | else if (setting_percent > 100) |
| 8320 | setting_percent = 100; |
| 8321 | } |
| 8322 | else // The mode is GET. |
| 8323 | { |
| 8324 | if ( !(output_var = ResolveVarOfArg(0)) ) |
| 8325 | return FAIL; // Don't bother setting ErrorLevel if there's a critical error like this. |
| 8326 | output_var->Assign(); // Init to empty string regardless of whether we succeed here. |
| 8327 | } |
| 8328 | |
| 8329 | // Rare, since load-time validation would have caught problems unless the params were variable references. |
| 8330 | // Text values for ErrorLevels should be kept below 64 characters in length so that the variable doesn't |
| 8331 | // have to be expanded with a different memory allocation method: |
| 8332 | if (aControlType == MIXERCONTROL_CONTROLTYPE_INVALID || aComponentType == MIXERLINE_COMPONENTTYPE_DST_UNDEFINED) |
| 8333 | return g_ErrorLevel->Assign("Invalid Control Type or Component Type"); |
| 8334 | |
| 8335 | // Open the specified mixer ID: |
| 8336 | HMIXER hMixer; |
| 8337 | if (mixerOpen(&hMixer, aMixerID, 0, 0, 0) != MMSYSERR_NOERROR) |
| 8338 | return g_ErrorLevel->Assign("Can't Open Specified Mixer"); |
| 8339 | |
| 8340 | // Find out how many destinations are available on this mixer (should always be at least one): |
| 8341 | int dest_count; |
| 8342 | MIXERCAPS mxcaps; |
| 8343 | if (mixerGetDevCaps((UINT_PTR)hMixer, &mxcaps, sizeof(mxcaps)) == MMSYSERR_NOERROR) |
| 8344 | dest_count = mxcaps.cDestinations; |
| 8345 | else |
| 8346 | dest_count = 1; // Assume it has one so that we can try to proceed anyway. |
| 8347 | |
| 8348 | // Find specified line (aComponentType + aComponentInstance): |
| 8349 | MIXERLINE ml = {0}; |
| 8350 | ml.cbStruct = sizeof(ml); |
| 8351 | if (aComponentInstance == 1) // Just get the first line of this type, the easy way. |
| 8352 | { |
| 8353 | ml.dwComponentType = aComponentType; |
| 8354 | if (mixerGetLineInfo((HMIXEROBJ)hMixer, &ml, MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR) |
| 8355 | { |
| 8356 | mixerClose(hMixer); |
| 8357 | return g_ErrorLevel->Assign("Mixer Doesn't Support This Component Type"); |
| 8358 | } |
| 8359 | } |
| 8360 | else |
| 8361 | { |
| 8362 | // Search through each source of each destination, looking for the indicated instance |
| 8363 | // number for the indicated component type: |