< prev index next >

src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_Ports.cpp

Print this page
rev 56159 : 8230480: check malloc/calloc results in java.desktop


 397     return TRUE;
 398 }
 399 
 400 
 401 // counts number of valid (non-NULL) elements in the array of AudioControls
 402 static int ValidControlCount(AudioControl **arr, int offset, int len) {
 403     int result = 0;
 404     int end = offset + len;
 405     for (int i=offset; i<end; i++) {
 406         if (arr[i] != NULL)
 407             result++;
 408     }
 409     return result;
 410 }
 411 
 412 // returns java control
 413 static void* CreatePortControl(PortMixer *mixer, PortControlCreator *creator, PortControl::ControlType type,
 414                                AudioControl **audioControls, int offset, int len) {
 415     void *jControl = NULL;
 416     PortControl *control = (PortControl *)calloc(1, sizeof(PortControl));



 417     float precision = 0.01;
 418 
 419     control->type = type;
 420     control->controlCount = len;
 421     control->audioControls = (AudioControl **)malloc(len * sizeof(AudioControl *));




 422     memcpy(control->audioControls, audioControls + offset, len * sizeof(AudioControl *));
 423 
 424     switch (control->type) {
 425     case PortControl::Volume:
 426         jControl = creator->newFloatControl(creator, control, CONTROL_TYPE_VOLUME, 0, 1, precision, "");
 427         break;
 428     case PortControl::Mute:
 429         jControl = creator->newBooleanControl(creator, control, CONTROL_TYPE_MUTE);
 430         break;
 431     case PortControl::Balance:
 432         jControl = creator->newFloatControl(creator, control, CONTROL_TYPE_BALANCE, -1, 1, precision, "");
 433         break;
 434     };
 435 
 436     if (jControl == NULL) {
 437         ERROR0("CreatePortControl: javaControl was not created\n");
 438         free(control->audioControls);
 439         free(control);
 440         return NULL;
 441     }


 465         // deviceControlCount is overestimated
 466         // because we don't actually filter by if the owned objects are controls
 467         err = GetAudioObjectPropertySize(mixer->deviceID, kAudioObjectPropertyScopeGlobal,
 468             kAudioObjectPropertyOwnedObjects, &size);
 469 
 470         if (err) {
 471             OS_ERROR1(err, "PORT_GetControls (portIndex = %d) get OwnedObject size", portIndex);
 472         } else {
 473             mixer->deviceControlCount = size / sizeof(AudioObjectID);
 474             TRACE1("  PORT_GetControls: detected %d owned objects\n", mixer->deviceControlCount);
 475 
 476             AudioObjectID controlIDs[mixer->deviceControlCount];
 477 
 478             err = GetAudioObjectProperty(mixer->deviceID, kAudioObjectPropertyScopeGlobal,
 479                 kAudioObjectPropertyOwnedObjects, sizeof(controlIDs), controlIDs, 1);
 480 
 481             if (err) {
 482                 OS_ERROR1(err, "PORT_GetControls (portIndex = %d) get OwnedObject values", portIndex);
 483             } else {
 484                 mixer->deviceControls = (AudioControl *)calloc(mixer->deviceControlCount, sizeof(AudioControl));



 485 
 486                 for (int i = 0; i < mixer->deviceControlCount; i++) {
 487                     AudioControl *control = &mixer->deviceControls[i];
 488 
 489                     control->controlID = controlIDs[i];
 490 
 491                     OSStatus err1 = GetAudioObjectProperty(control->controlID, kAudioObjectPropertyScopeGlobal,
 492                         kAudioObjectPropertyClass, sizeof(control->classID), &control->classID, 1);
 493                     OSStatus err2 = GetAudioObjectProperty(control->controlID, kAudioObjectPropertyScopeGlobal,
 494                         kAudioControlPropertyScope, sizeof(control->scope), &control->scope, 1);
 495                     OSStatus err3 = GetAudioObjectProperty(control->controlID, kAudioObjectPropertyScopeGlobal,
 496                         kAudioControlPropertyElement, sizeof(control->channel), &control->channel, 1);
 497                     if (err1 || err2 || err3) { // not a control or other error
 498                         control->classID = 0;
 499                         continue;
 500                     }
 501 
 502                     TRACE4("- control 0x%x, class='%s', scope='%s', channel=%d\n",
 503                         control->controlID, FourCC2Str(control->classID), FourCC2Str(control->scope), control->channel);
 504                 }


 598     if (masterMute != NULL) {
 599         creator->addControl(creator, masterMute);
 600     }
 601 
 602     // don't add per-channel controls for mono & stereo - they are handled by "master" controls
 603     // TODO: this should be reviewed to handle controls other than mute & volume
 604     if (totalChannels > 2) {
 605         // add separate compound control for each channel (containing volume and mute)
 606         // (ensure that we have controls)
 607         if (ValidControlCount(volumeControls, 1, totalChannels) > 0 || ValidControlCount(muteControls, 1, totalChannels) > 0) {
 608             for (int ch=1; ch<=totalChannels; ch++) {
 609                 // get the channel name
 610                 char *channelName;
 611                 CFStringRef cfname = NULL;
 612                 const AudioObjectPropertyAddress address = {kAudioObjectPropertyElementName, port->scope, (unsigned)ch};
 613                 UInt32 size = sizeof(cfname);
 614                 OSStatus err = AudioObjectGetPropertyData(mixer->deviceID, &address, 0, NULL, &size, &cfname);
 615                 if (err == noErr) {
 616                     CFIndex length = CFStringGetLength(cfname) + 1;
 617                     channelName = (char *)malloc(length);



 618                     CFStringGetCString(cfname, channelName, length, kCFStringEncodingUTF8);
 619                     CFRelease(cfname);
 620                 } else {
 621                     channelName = (char *)malloc(16);



 622                     sprintf(channelName, "Ch %d", ch);
 623                 }
 624 
 625                 void* jControls[2];
 626                 int controlCount = 0;
 627                 if (volumeControls[ch] != NULL) {
 628                     jControls[controlCount++] = CreatePortControl(mixer, creator, PortControl::Volume, volumeControls, ch, 1);
 629                 }
 630                 if (muteControls[ch] != NULL) {
 631                     jControls[controlCount++] = CreatePortControl(mixer, creator, PortControl::Mute, muteControls, ch, 1);
 632                 }
 633                 // TODO: add any extra controls for "other" controls for the channel
 634 
 635                 void *compoundControl = creator->newCompoundControl(creator, channelName, jControls, controlCount);
 636                 creator->addControl(creator, compoundControl);
 637 
 638                 free(channelName);
 639             }
 640         }
 641     }




 397     return TRUE;
 398 }
 399 
 400 
 401 // counts number of valid (non-NULL) elements in the array of AudioControls
 402 static int ValidControlCount(AudioControl **arr, int offset, int len) {
 403     int result = 0;
 404     int end = offset + len;
 405     for (int i=offset; i<end; i++) {
 406         if (arr[i] != NULL)
 407             result++;
 408     }
 409     return result;
 410 }
 411 
 412 // returns java control
 413 static void* CreatePortControl(PortMixer *mixer, PortControlCreator *creator, PortControl::ControlType type,
 414                                AudioControl **audioControls, int offset, int len) {
 415     void *jControl = NULL;
 416     PortControl *control = (PortControl *)calloc(1, sizeof(PortControl));
 417     if (control == NULL) {
 418         return NULL;
 419     }
 420     float precision = 0.01;
 421 
 422     control->type = type;
 423     control->controlCount = len;
 424     control->audioControls = (AudioControl **)malloc(len * sizeof(AudioControl *));
 425     if (control->audioControls == NULL) {
 426         free(control);
 427         return NULL;
 428     }
 429     memcpy(control->audioControls, audioControls + offset, len * sizeof(AudioControl *));
 430 
 431     switch (control->type) {
 432     case PortControl::Volume:
 433         jControl = creator->newFloatControl(creator, control, CONTROL_TYPE_VOLUME, 0, 1, precision, "");
 434         break;
 435     case PortControl::Mute:
 436         jControl = creator->newBooleanControl(creator, control, CONTROL_TYPE_MUTE);
 437         break;
 438     case PortControl::Balance:
 439         jControl = creator->newFloatControl(creator, control, CONTROL_TYPE_BALANCE, -1, 1, precision, "");
 440         break;
 441     };
 442 
 443     if (jControl == NULL) {
 444         ERROR0("CreatePortControl: javaControl was not created\n");
 445         free(control->audioControls);
 446         free(control);
 447         return NULL;
 448     }


 472         // deviceControlCount is overestimated
 473         // because we don't actually filter by if the owned objects are controls
 474         err = GetAudioObjectPropertySize(mixer->deviceID, kAudioObjectPropertyScopeGlobal,
 475             kAudioObjectPropertyOwnedObjects, &size);
 476 
 477         if (err) {
 478             OS_ERROR1(err, "PORT_GetControls (portIndex = %d) get OwnedObject size", portIndex);
 479         } else {
 480             mixer->deviceControlCount = size / sizeof(AudioObjectID);
 481             TRACE1("  PORT_GetControls: detected %d owned objects\n", mixer->deviceControlCount);
 482 
 483             AudioObjectID controlIDs[mixer->deviceControlCount];
 484 
 485             err = GetAudioObjectProperty(mixer->deviceID, kAudioObjectPropertyScopeGlobal,
 486                 kAudioObjectPropertyOwnedObjects, sizeof(controlIDs), controlIDs, 1);
 487 
 488             if (err) {
 489                 OS_ERROR1(err, "PORT_GetControls (portIndex = %d) get OwnedObject values", portIndex);
 490             } else {
 491                 mixer->deviceControls = (AudioControl *)calloc(mixer->deviceControlCount, sizeof(AudioControl));
 492                 if (mixer->deviceControls == NULL) {
 493                     return;
 494                 }
 495 
 496                 for (int i = 0; i < mixer->deviceControlCount; i++) {
 497                     AudioControl *control = &mixer->deviceControls[i];
 498 
 499                     control->controlID = controlIDs[i];
 500 
 501                     OSStatus err1 = GetAudioObjectProperty(control->controlID, kAudioObjectPropertyScopeGlobal,
 502                         kAudioObjectPropertyClass, sizeof(control->classID), &control->classID, 1);
 503                     OSStatus err2 = GetAudioObjectProperty(control->controlID, kAudioObjectPropertyScopeGlobal,
 504                         kAudioControlPropertyScope, sizeof(control->scope), &control->scope, 1);
 505                     OSStatus err3 = GetAudioObjectProperty(control->controlID, kAudioObjectPropertyScopeGlobal,
 506                         kAudioControlPropertyElement, sizeof(control->channel), &control->channel, 1);
 507                     if (err1 || err2 || err3) { // not a control or other error
 508                         control->classID = 0;
 509                         continue;
 510                     }
 511 
 512                     TRACE4("- control 0x%x, class='%s', scope='%s', channel=%d\n",
 513                         control->controlID, FourCC2Str(control->classID), FourCC2Str(control->scope), control->channel);
 514                 }


 608     if (masterMute != NULL) {
 609         creator->addControl(creator, masterMute);
 610     }
 611 
 612     // don't add per-channel controls for mono & stereo - they are handled by "master" controls
 613     // TODO: this should be reviewed to handle controls other than mute & volume
 614     if (totalChannels > 2) {
 615         // add separate compound control for each channel (containing volume and mute)
 616         // (ensure that we have controls)
 617         if (ValidControlCount(volumeControls, 1, totalChannels) > 0 || ValidControlCount(muteControls, 1, totalChannels) > 0) {
 618             for (int ch=1; ch<=totalChannels; ch++) {
 619                 // get the channel name
 620                 char *channelName;
 621                 CFStringRef cfname = NULL;
 622                 const AudioObjectPropertyAddress address = {kAudioObjectPropertyElementName, port->scope, (unsigned)ch};
 623                 UInt32 size = sizeof(cfname);
 624                 OSStatus err = AudioObjectGetPropertyData(mixer->deviceID, &address, 0, NULL, &size, &cfname);
 625                 if (err == noErr) {
 626                     CFIndex length = CFStringGetLength(cfname) + 1;
 627                     channelName = (char *)malloc(length);
 628                     if (channelName == NULL) {
 629                         return;
 630                     }
 631                     CFStringGetCString(cfname, channelName, length, kCFStringEncodingUTF8);
 632                     CFRelease(cfname);
 633                 } else {
 634                     channelName = (char *)malloc(16);
 635                     if (channelName == NULL) {
 636                         return;
 637                     }
 638                     sprintf(channelName, "Ch %d", ch);
 639                 }
 640 
 641                 void* jControls[2];
 642                 int controlCount = 0;
 643                 if (volumeControls[ch] != NULL) {
 644                     jControls[controlCount++] = CreatePortControl(mixer, creator, PortControl::Volume, volumeControls, ch, 1);
 645                 }
 646                 if (muteControls[ch] != NULL) {
 647                     jControls[controlCount++] = CreatePortControl(mixer, creator, PortControl::Mute, muteControls, ch, 1);
 648                 }
 649                 // TODO: add any extra controls for "other" controls for the channel
 650 
 651                 void *compoundControl = creator->newCompoundControl(creator, channelName, jControls, controlCount);
 652                 creator->addControl(creator, compoundControl);
 653 
 654                 free(channelName);
 655             }
 656         }
 657     }


< prev index next >