TS3TestHiLevel.c

/*
 *  File:       TS3TestHiLevel.c
 *
 *  Copyright © 1996 Apple Computer, Inc.
 */
 
#include <assert.h>
#include <math.h>
#include <string.h>
 
#include <Dialogs.h>
#include <Fonts.h>
#include <Menus.h>
#include <Timer.h>
#include <fp.h>
 
#include <QD3D.h>
#include <QD3DMath.h>
 
#include "TS3Menu.h"
#include "TS3Message.h"
#include "TS3Resource.h"
#include "TS3Sound.h"
#include "TS3TestHiLevel.h"
#include "TS3Utils.h"
#include "TS3Window.h"
 
#include "SoundSprocket.h"
 
 
typedef struct TTestHiLevelData {
    float           duration;
    
    TQ3Vector3D     listenerTranslate1;
    TQ3Vector3D     listenerTranslate2;
    Boolean         listenerTranslateRange;
    
    TQ3Vector3D     listenerRotationAxis1;
    TQ3Vector3D     listenerRotationAxis2;
    Boolean         listenerRotationAxisRange;
    
    float           listenerRotationAngle1;
    float           listenerRotationAngle2;
    Boolean         listenerRotationAngleRange;
    
    TQ3Vector3D     listenerScale1;
    TQ3Vector3D     listenerScale2;
    Boolean         listenerScaleRange;
    
    TQ3Vector3D     listenerPosition1;
    TQ3Vector3D     listenerPosition2;
    Boolean         listenerPositionRange;
    
    TQ3Vector3D     listenerOrientation1;
    TQ3Vector3D     listenerOrientation2;
    Boolean         listenerOrientationRange;
    
    TQ3Vector3D     listenerUpVector1;
    TQ3Vector3D     listenerUpVector2;
    Boolean         listenerUpVectorRange;
    
    TQ3Vector3D     listenerVelocity1;
    TQ3Vector3D     listenerVelocity2;
    Boolean         listenerVelocityRange;
    
    UInt32          medium;
    
    float           humidity1;
    float           humidity2;
    Boolean         humidityRange;
    
    float           roomSize1;
    float           roomSize2;
    Boolean         roomSizeRange;
    
    float           roomReflectivity1;
    float           roomReflectivity2;
    Boolean         roomReflectivityRange;
    
    float           reverbAttenuation1;
    float           reverbAttenuation2;
    Boolean         reverbAttenuationRange;
    
    UInt32          cpuLoad1;
    UInt32          cpuLoad2;
    Boolean         cpuLoadRange;
    
    TQ3Vector3D     sourceTranslate1;
    TQ3Vector3D     sourceTranslate2;
    Boolean         sourceTranslateRange;
    
    TQ3Vector3D     sourceRotationAxis1;
    TQ3Vector3D     sourceRotationAxis2;
    Boolean         sourceRotationAxisRange;
    
    float           sourceRotationAngle1;
    float           sourceRotationAngle2;
    Boolean         sourceRotationAngleRange;
    
    TQ3Vector3D     sourceScale1;
    TQ3Vector3D     sourceScale2;
    Boolean         sourceScaleRange;
    
    TQ3Vector3D     sourcePosition1;
    TQ3Vector3D     sourcePosition2;
    Boolean         sourcePositionRange;
    
    TQ3Vector3D     sourceOrientation1;
    TQ3Vector3D     sourceOrientation2;
    Boolean         sourceOrientationRange;
    
    TQ3Vector3D     sourceUpVector1;
    TQ3Vector3D     sourceUpVector2;
    Boolean         sourceUpVectorRange;
    
    TQ3Vector3D     sourceVelocity1;
    TQ3Vector3D     sourceVelocity2;
    Boolean         sourceVelocityRange;
    
    UInt32          sourceMode;
    
    float           referenceDistance1;
    float           referenceDistance2;
    Boolean         referenceDistanceRange;
    
    float           length1;
    float           length2;
    Boolean         lengthRange;
    
    float           width1;
    float           width2;
    Boolean         widthRange;
    
    float           height1;
    float           height2;
    Boolean         heightRange;
    
    float           coneAngleDeg1;
    float           coneAngleDeg2;
    Boolean         coneAngleDegRange;
    
    float           coneAttenuation1;
    float           coneAttenuation2;
    Boolean         coneAttenuationRange;
    
    float           coneAngleCos1;
    float           coneAngleCos2;
} TTestHiLevelData;
 
 
static MenuHandle               gTestHiLevelPresetMenu          = NULL;
static DialogPtr                gTestHiLevelDialog              = NULL;
static UserItemUPP              gTestHiLevelProgressUserItem    = NULL;
static UInt32                   gTestHiLevelCPULoadLimit;
static TTestHiLevelData         gTestHiLevelData;
static Boolean                  gTestHiLevelUpdate              = true;
static SSpListenerReference     gTestHiLevelListener            = NULL;
static SSpSourceReference       gTestHiLevelSource              = NULL;
 
static UnsignedWide             gTestHiLevelCycleStart;
static float                    gTestHiLevelInterpolant         = 0.0;
 
static TQ3Vector3D              gTestHiLevelListenerActual      = {-1.23456, -1.23456, -1.23456};
static TQ3Vector3D              gTestHiLevelSourceActual        = {-1.23456, -1.23456, -1.23456};
 
 
static WindowMethodPtr TestHiLevel_MetaHandler(
    WindowMethod        inMethod);
 
static void TestHiLevel_GetSleep(
    WindowPtr           inWindow,
    UInt32*             outSleep);
 
static void TestHiLevel_ConsumeEvent(
    WindowPtr           inWindow,
    const EventRecord*  inEvent,
    Boolean*            outConsumed);
 
static void TestHiLevel_Update(
    WindowPtr           inWindow);
 
static void TestHiLevel_Activate(
    WindowPtr           inWindow);
 
static void TestHiLevel_Deactivate(
    WindowPtr           inWindow);
 
static pascal void TestHiLevel_ProgressUserItem(
    DialogPtr           inDialog,
    short               inItem);
 
static void TestHiLevel_Interpolate(
    void);
 
static float TestHiLevel_InterpolateFloat(
    float               inWhere,
    float               inVal0,
    float               inVal1,
    Boolean             inIsRange);
 
static void TestHiLevel_InterpolateVector3D(
    float               inWhere,
    const TQ3Vector3D*  inVal0,
    const TQ3Vector3D*  inVal1,
    Boolean             inIsRange,
    TQ3Vector3D*        outResult);
 
static void TestHiLevel_InterpolateNormalVector3D(
    float               inWhere,
    const TQ3Vector3D*  inVal0,
    const TQ3Vector3D*  inVal1,
    Boolean             inIsRange,
    TQ3Vector3D*        outResult);
 
static void TestHiLevel_DeriveData(
    void);
 
static void TestHiLevel_SetDialogFields(
    void);
 
static void TestHiLevel_GetDialogFields(
    void);
 
 
/* =============================================================================
 *      TestHiLevel_Init (external)
 *
 *  Initializes our thing.
 * ========================================================================== */
void TestHiLevel_Init(
    void)
{
    OSStatus            err;
    TEHandle            textEdit;
    FontInfo            fontInfo;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    Str255              str;
    short               fNum;   
    
    // Make sure we didn't mess up the dialog items
    assert(kHiLevelItem_COUNT == kHiLevelItem_ExpectedCOUNT);
    
    // Grab the maximum CPU load limit value
    gTestHiLevelCPULoadLimit = 999;
    err = SSpGetCPULoadLimit(&gTestHiLevelCPULoadLimit);
    Message_CheckError(err, "TestHiLevel_Init", "SSpGetCPULoadLimit");
    
    //¥ TODO: Read in gTestHiLevelData from preferences
    
    // Set up our listener and source
    err = SSpListener_New(&gTestHiLevelListener);
    Message_CheckError(err, "TestHiLevel_Init", "SSpListener_New");
    
    assert(gTestHiLevelListener != NULL);
    
    err = SSpSource_New(&gTestHiLevelSource);
    Message_CheckError(err, "TestHiLevel_Init", "SSpSource_New");
    
    assert(gTestHiLevelSource != NULL);
    
    // Grab the menu
    gTestHiLevelPresetMenu = GetMenu(kMenuID_HiLevelPreset);
    
    // Grab the dialog
    gTestHiLevelDialog = GetNewDialog(kDlogID_HiLevel, NULL, (WindowPtr) -1);
    assert(gTestHiLevelDialog != NULL);
    
    SetPort(gTestHiLevelDialog);
    GetFNum("\pGeneva", &fNum);
    TextFont(fNum);
    TextSize(10);
    
    // Fix up the line height
    GetFontInfo(&fontInfo);
    
    textEdit = ((DialogPeek) gTestHiLevelDialog)->textH;
    
    (*textEdit)->lineHeight = fontInfo.ascent+fontInfo.descent+fontInfo.leading;
    (*textEdit)->fontAscent = fontInfo.ascent;
    
    // Set up our method table
    Window_New(gTestHiLevelDialog, TestHiLevel_MetaHandler);
    
    // Do the user items
    GetDialogItem(gTestHiLevelDialog, kHiLevelItem_UpdateHilite, &itemType, &itemHandle, &itemBounds);
    SetDialogItem(gTestHiLevelDialog, kHiLevelItem_UpdateHilite, itemType, (Handle) Utils_GetOKUserItemProc(), &itemBounds);
    
    gTestHiLevelProgressUserItem = NewUserItemProc(TestHiLevel_ProgressUserItem);
    assert(gTestHiLevelProgressUserItem != NULL);
    
    GetDialogItem(gTestHiLevelDialog, kHiLevelItem_Progress, &itemType, &itemHandle, &itemBounds);
    SetDialogItem(gTestHiLevelDialog, kHiLevelItem_Progress, itemType, (Handle) gTestHiLevelProgressUserItem, &itemBounds);
    
    // Show the quality limit
    sprintf((char*) str, "x[0..%ld]", gTestHiLevelCPULoadLimit);
    str[0] = strlen((char*) str)-1;
    
    GetDialogItem(gTestHiLevelDialog, kHiLevelItem_CPULoadUnits, &itemType, &itemHandle, &itemBounds);
    SetDialogItemText(itemHandle, str);
    
    // Set the initial field values
    TestHiLevel_Preset(1);
    
    // Select the first field
    SelectDialogItemText(gTestHiLevelDialog, kHiLevelItem_Duration, 0, 32767);
    
    // Show the dialog
    ShowWindow(gTestHiLevelDialog);
    
    // Initialize our cycle timer
    Microseconds(&gTestHiLevelCycleStart);
}
 
 
/* =============================================================================
 *      TestHiLevel_Exit (external)
 *
 *  Cleans up.
 * ========================================================================== */
void TestHiLevel_Exit(
    void)
{
    //¥ TODO: Save gTestHiLevel to preferences
    
    if (gTestHiLevelDialog != NULL)
    {
        DisposeDialog(gTestHiLevelDialog);
        gTestHiLevelDialog = NULL;
    }
    
    if (gTestHiLevelProgressUserItem != NULL)
    {
        DisposeRoutineDescriptor(gTestHiLevelProgressUserItem);
        gTestHiLevelProgressUserItem = NULL;
    }
    
    if (gTestHiLevelListener != NULL)
    {
        SSpListener_Dispose(gTestHiLevelListener);
        gTestHiLevelListener = NULL;
    }
    
    if (gTestHiLevelSource != NULL)
    {
        SSpSource_Dispose(gTestHiLevelSource);
        gTestHiLevelSource = NULL;
    }
}
 
 
/* =============================================================================
 *      TestHiLevel_MetaHandler (internal)
 *
 *  Returns the method function pointer that corresponds to the given ID.
 * ========================================================================== */
WindowMethodPtr TestHiLevel_MetaHandler(
    WindowMethod        inMethod)
{
    WindowMethodPtr     result;
    
    result = NULL;
    
    switch (inMethod)
    {
        case kWindowMethod_GetSleep:
            result = (WindowMethodPtr) TestHiLevel_GetSleep;
        break;
        
        case kWindowMethod_ConsumeEvent:
            result = (WindowMethodPtr) TestHiLevel_ConsumeEvent;
        break;
        
        case kWindowMethod_Update:
            result = (WindowMethodPtr) TestHiLevel_Update;
        break;
        
        case kWindowMethod_Activate:
            result = (WindowMethodPtr) TestHiLevel_Activate;
        break;
        
        case kWindowMethod_Deactivate:
            result = (WindowMethodPtr) TestHiLevel_Deactivate;
        break;
    }
    
    return result;
}
 
 
/* =============================================================================
 *      TestHiLevel_GetSleep (internal)
 *
 *  Returns the sleep time to pass to WaitNextEvent when we're in front.
 * ========================================================================== */
void TestHiLevel_GetSleep(
    WindowPtr           inWindow,
    UInt32*             outSleep)
{
    #pragma unused (inWindow)
    assert(outSleep != NULL);
    
    *outSleep = 0;
}
 
 
/* =============================================================================
 *      TestHiLevel_ConsumeEvent (internal)
 *
 *  Called for each event when this is the front window.
 * ========================================================================== */
void TestHiLevel_ConsumeEvent(
    WindowPtr           inWindow,
    const EventRecord*  inEvent,
    Boolean*            outConsumed)
{
    #pragma unused (inWindow)
 
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    ControlHandle       updateButton;
    Boolean             consumed;
    Boolean             passToDialog;
    WindowPtr           window;
    short               item;
    unsigned long       timeout;
    UnsignedWide        now;
    
    assert(inEvent != NULL);
    assert(outConsumed != NULL);
    
    consumed = false;
    passToDialog = true;
    
    // We want to handle some events ourself
    switch (inEvent->what)
    {
        case keyDown:
        case autoKey:
            passToDialog = false;
            
            if (inEvent->modifiers & cmdKey)
            {
                if (inEvent->what != autoKey)
                {
                    switch (inEvent->message & charCodeMask)
                    {
                        case '.':
                            // anything here?
                        break;
                    }
                }
            }
            else
            {
                switch (inEvent->message & charCodeMask)
                {
                    case 0x08:  // backspace
                    case 0x09:  // tab
                    case 0x1C:  // cursor left
                    case 0x1D:  // cursor right
                    case 0x1E:  // cursor up
                    case 0x1F:  // cursor down
                    case ' ':
                    case '.':
                    case '-':
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        // Pass it to the dialog
                        passToDialog = true;
                    break;
                    
                    case 0x03:  // enter
                    case 0x0D:  // return
                        if (inEvent->what != autoKey)
                        {
                            // Update button equivalent
                            GetDialogItem(gTestHiLevelDialog, kHiLevelItem_Update, &itemType, &itemHandle, &itemBounds);
                            updateButton = (ControlHandle) itemHandle;
                            
                            if ((*updateButton)->contrlHilite == 0)
                            {
                                HiliteControl(updateButton, 1);
                                
                                timeout = TickCount()+6;
                                while (TickCount() < timeout) /* wait */;
                                
                                HiliteControl(updateButton, 0);
                                
                                TestHiLevel_GetDialogFields();
                                
                                consumed = true;
                            }
                        }
                    break;
                    
                    default:
                        SysBeep(10);
                        consumed = true;
                }
            }
        break;
        
        case activateEvt:
            // We need to look at the activate event here because it is
            // consumed by IsDialogEvent/DialogSelect below and so never
            // gets to the window stuff
            window = (WindowPtr) inEvent->message;
            
            if (inEvent->modifiers & activeFlag)
            {
                Window_Activate(window);
            }
            else
            {
                Window_Deactivate(window);
            }
        break;
        
        case nullEvent:
            // Find where we are in the cycle (0 is start, 1 is end)
            Microseconds(&now);
            gTestHiLevelInterpolant = Utils_Interval(&gTestHiLevelCycleStart, &now) / gTestHiLevelData.duration;
            
            switch (Menu_GetInterpolation())
            {
                case kInterpolationItem_Sinusoidal:
                    gTestHiLevelInterpolant = 0.5*sinf(gTestHiLevelInterpolant * pi * 2.0) + 0.5;
                break;
                
                case kInterpolationItem_Triangular:
                    gTestHiLevelInterpolant = 2.0*fmodf(gTestHiLevelInterpolant, 1.0);
                    
                    if (gTestHiLevelInterpolant > 1.0)
                    {
                        gTestHiLevelInterpolant = 2.0-gTestHiLevelInterpolant;
                    }
                break;
                
                case kInterpolationItem_Sawtooth:
                    gTestHiLevelInterpolant = fmodf(2.0*gTestHiLevelInterpolant, 1.0);
                break;
            }
            
            TestHiLevel_Interpolate();
        break;
    }
    
    // Do dialog stuff
    if (passToDialog)
    {
        consumed = IsDialogEvent(inEvent);
        if (consumed)
        {
            if (DialogSelect(inEvent, &window, &item))
            {
                switch (item)
                {
                    case kHiLevelItem_Update:
                        TestHiLevel_GetDialogFields();
                    break;
                }
            }
        }
    }
    
    // Return the result
    *outConsumed = consumed;
}
 
 
/* =============================================================================
 *      TestHiLevel_Update (internal)
 *
 *  Updates the contents of the window.
 * ========================================================================== */
void TestHiLevel_Update(
    WindowPtr           inWindow)
{
    DrawDialog(inWindow);
}
 
 
/* =============================================================================
 *      TestHiLevel_Activate (internal)
 *
 *  Handles window activation.
 * ========================================================================== */
void TestHiLevel_Activate(
    WindowPtr           inWindow)
{
    #pragma unused (inWindow)
    InsertMenu(gTestHiLevelPresetMenu, 0);
    DrawMenuBar();
}
 
 
/* =============================================================================
 *      TestHiLevel_Deactivate (internal)
 *
 *  Handles window deactivation.
 * ========================================================================== */
void TestHiLevel_Deactivate(
    WindowPtr           inWindow)
{
    #pragma unused (inWindow)
    DeleteMenu(kMenuID_HiLevelPreset);
    DrawMenuBar();
}
 
 
/* =============================================================================
 *      TestHiLevel_ProgressUserItem (internal)
 *
 *  Draws the user item used for progress bar, based on gTestHiLevelInterpolant.
 * ========================================================================== */
pascal void TestHiLevel_ProgressUserItem(
    DialogPtr           inDialog,
    short               inItem)
{
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    short               size;
    Rect                leftWhite;
    Rect                rightWhite;
    Rect                indicator;
    
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    
    FrameRect(&itemBounds);
    
    InsetRect(&itemBounds, 1, 1);
    size = itemBounds.bottom-itemBounds.top;
    
    indicator = itemBounds;
    indicator.left = itemBounds.left + (long) (gTestHiLevelInterpolant*(itemBounds.right-itemBounds.left-size) + 0.5);
    indicator.right = indicator.left+size;
    
    leftWhite = itemBounds;
    leftWhite.right = indicator.left;
    
    rightWhite = itemBounds;
    rightWhite.left = indicator.right;
    
    FrameRect(&indicator);
    
    InsetRect(&indicator, 1, 1);
    FillRect(&indicator, &qd.gray);
    
    EraseRect(&leftWhite);
    EraseRect(&rightWhite);
}
 
 
/* =============================================================================
 *      TestHiLevel_Interpolate (internal)
 *
 *  Changes the sound channel to the correct values for the point between
 *  zero and one determined by gTestHiLevelInterpolant.
 * ========================================================================== */
void TestHiLevel_Interpolate(
    void)
{
    OSStatus            err;
    TQ3Vector3D         v0;
    TQ3Vector3D         v1;
    TQ3Vector3D         v2;
    TQ3Point3D          origin = {0.0, 0.0, 0.0};
    TQ3Matrix4x4        m0;
    TQ3Matrix4x4        m1;
    TQ3Matrix4x4        m2;
    TQ3Matrix4x4        m;
    SSpLocalizationData snd3DInfo;
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.listenerTranslateRange     ||
        gTestHiLevelData.listenerRotationAxisRange  ||
        gTestHiLevelData.listenerRotationAngleRange ||
        gTestHiLevelData.listenerScaleRange)
    {
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.listenerTranslate1,
                &gTestHiLevelData.listenerTranslate2,
                gTestHiLevelData.listenerTranslateRange,
                &v0);
        
        TestHiLevel_InterpolateNormalVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.listenerRotationAxis1,
                &gTestHiLevelData.listenerRotationAxis2,
                gTestHiLevelData.listenerRotationAxisRange,
                &v1);
        
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.listenerScale1,
                &gTestHiLevelData.listenerScale2,
                gTestHiLevelData.listenerScaleRange,
                &v2);
        
        Q3Matrix4x4_SetTranslate(
                &m0,
                v0.x,
                v0.y,
                v0.z);
        
        Q3Matrix4x4_SetRotateAboutAxis(
                &m1,
                &origin,
                &v1,
                Q3Math_DegreesToRadians(TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.listenerRotationAngle1,
                        gTestHiLevelData.listenerRotationAngle2,
                        gTestHiLevelData.listenerRotationAngleRange)));
        
        Q3Matrix4x4_SetScale(
                &m2,
                v2.x,
                v2.y,
                v2.z);
        
        Q3Matrix4x4_Multiply(
                &m0,
                &m1,
                &m);
        
        Q3Matrix4x4_Multiply(
                &m,
                &m2,
                &m);
        
        err = SSpListener_SetTransform(gTestHiLevelListener, &m);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_SetTransform");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.listenerPositionRange)
    {
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.listenerPosition1,
                &gTestHiLevelData.listenerPosition2,
                gTestHiLevelData.listenerPositionRange,
                &v0);
        
        err = SSpListener_SetPosition(gTestHiLevelListener, (const TQ3Point3D*) &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_SetPosition");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.listenerOrientationRange)
    {
        TestHiLevel_InterpolateNormalVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.listenerOrientation1,
                &gTestHiLevelData.listenerOrientation2,
                gTestHiLevelData.listenerOrientationRange,
                &v0);
        
        err = SSpListener_SetOrientation(gTestHiLevelListener, &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_SetOrientation");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.listenerUpVectorRange)
    {
        TestHiLevel_InterpolateNormalVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.listenerUpVector1,
                &gTestHiLevelData.listenerUpVector2,
                gTestHiLevelData.listenerUpVectorRange,
                &v0);
        
        err = SSpListener_SetUpVector(gTestHiLevelListener, &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_SetUpVector");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.listenerVelocityRange)
    {
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.listenerVelocity1,
                &gTestHiLevelData.listenerVelocity2,
                gTestHiLevelData.listenerVelocityRange,
                &v0);
        
        err = SSpListener_SetVelocity(gTestHiLevelListener, &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_SetVelocity");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.humidityRange)
    {
        err = SSpListener_SetMedium(
                gTestHiLevelListener,
                gTestHiLevelData.medium,
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.humidity1,
                        gTestHiLevelData.humidity2,
                        gTestHiLevelData.humidityRange));
        
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_SetMedium");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.roomSizeRange              ||
        gTestHiLevelData.roomReflectivityRange      ||
        gTestHiLevelData.reverbAttenuationRange)
    {
        err = SSpListener_SetReverb(
                gTestHiLevelListener,
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.roomSize1,
                        gTestHiLevelData.roomSize2,
                        gTestHiLevelData.roomSizeRange),
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.roomReflectivity1,
                        gTestHiLevelData.roomReflectivity2,
                        gTestHiLevelData.roomReflectivityRange),
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.reverbAttenuation1,
                        gTestHiLevelData.reverbAttenuation2,
                        gTestHiLevelData.reverbAttenuationRange));
        
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_SetReverb");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.cpuLoadRange)
    {
        err = SSpSource_SetCPULoad(
                gTestHiLevelSource,
                (UInt32) (TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        (float) gTestHiLevelData.cpuLoad1,
                        (float) gTestHiLevelData.cpuLoad2,
                        gTestHiLevelData.cpuLoadRange) + 0.5));
        
        Message_CheckError(err, "TestHiLevel_Interpolate", "SetSourceCPULoad");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.sourceTranslateRange       ||
        gTestHiLevelData.sourceRotationAxisRange    ||
        gTestHiLevelData.sourceRotationAngleRange   ||
        gTestHiLevelData.sourceScaleRange)
    {
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.sourceTranslate1,
                &gTestHiLevelData.sourceTranslate2,
                gTestHiLevelData.sourceTranslateRange,
                &v0);
        
        TestHiLevel_InterpolateNormalVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.sourceRotationAxis1,
                &gTestHiLevelData.sourceRotationAxis2,
                gTestHiLevelData.sourceRotationAxisRange,
                &v1);
        
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.sourceScale1,
                &gTestHiLevelData.sourceScale2,
                gTestHiLevelData.sourceScaleRange,
                &v2);
        
        Q3Matrix4x4_SetTranslate(
                &m0,
                v0.x,
                v0.y,
                v0.z);
        
        Q3Matrix4x4_SetRotateAboutAxis(
                &m1,
                &origin,
                &v1,
                Q3Math_DegreesToRadians(TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.sourceRotationAngle1,
                        gTestHiLevelData.sourceRotationAngle2,
                        gTestHiLevelData.sourceRotationAngleRange)));
        
        Q3Matrix4x4_SetScale(
                &m2,
                v2.x,
                v2.y,
                v2.z);
        
        Q3Matrix4x4_Multiply(
                &m0,
                &m1,
                &m);
        
        Q3Matrix4x4_Multiply(
                &m,
                &m2,
                &m);
        
        err = SSpSource_SetTransform(gTestHiLevelSource, &m);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetTransform");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.sourcePositionRange)
    {
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.sourcePosition1,
                &gTestHiLevelData.sourcePosition2,
                gTestHiLevelData.sourcePositionRange,
                &v0);
        
        err = SSpSource_SetPosition(gTestHiLevelSource, (const TQ3Point3D*) &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetPosition");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.sourceOrientationRange)
    {
        TestHiLevel_InterpolateNormalVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.sourceOrientation1,
                &gTestHiLevelData.sourceOrientation2,
                gTestHiLevelData.sourceOrientationRange,
                &v0);
        
        err = SSpSource_SetOrientation(gTestHiLevelSource, &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetOrientation");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.sourceUpVectorRange)
    {
        TestHiLevel_InterpolateNormalVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.sourceUpVector1,
                &gTestHiLevelData.sourceUpVector2,
                gTestHiLevelData.sourceUpVectorRange,
                &v0);
        
        err = SSpSource_SetUpVector(gTestHiLevelSource, &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetUpVector");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.sourceVelocityRange)
    {
        TestHiLevel_InterpolateVector3D(
                gTestHiLevelInterpolant,
                &gTestHiLevelData.sourceVelocity1,
                &gTestHiLevelData.sourceVelocity2,
                gTestHiLevelData.sourceVelocityRange,
                &v0);
        
        err = SSpSource_SetVelocity(gTestHiLevelSource, &v0);
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetVelocity");
    }
    
    if (gTestHiLevelUpdate)
    {
        err = SSpSource_SetMode(
                gTestHiLevelSource,
                gTestHiLevelData.sourceMode);
        
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetMode");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.referenceDistanceRange)
    {
        err = SSpSource_SetReferenceDistance(
                gTestHiLevelSource,
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.referenceDistance1,
                        gTestHiLevelData.referenceDistance2,
                        gTestHiLevelData.referenceDistanceRange));
        
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetReferenceDistance");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.lengthRange                ||
        gTestHiLevelData.widthRange                 ||
        gTestHiLevelData.heightRange)
    {
        err = SSpSource_SetSize(
                gTestHiLevelSource,
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.length1,
                        gTestHiLevelData.length2,
                        gTestHiLevelData.lengthRange),
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.width1,
                        gTestHiLevelData.width2,
                        gTestHiLevelData.widthRange),
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.height1,
                        gTestHiLevelData.height2,
                        gTestHiLevelData.heightRange));
        
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetSize");
    }
    
    if (gTestHiLevelUpdate                          ||
        gTestHiLevelData.coneAngleDegRange          ||
        gTestHiLevelData.coneAttenuationRange)
    {
        err = SSpSource_SetAngularAttenuation(
                gTestHiLevelSource,
                Q3Math_DegreesToRadians(TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.coneAngleDeg1,
                        gTestHiLevelData.coneAngleDeg2,
                        gTestHiLevelData.coneAngleDegRange)),
                TestHiLevel_InterpolateFloat(
                        gTestHiLevelInterpolant,
                        gTestHiLevelData.coneAttenuation1,
                        gTestHiLevelData.coneAttenuation2,
                        gTestHiLevelData.coneAttenuationRange));
        
        Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_SetAngularAttenuation");
    }
    
    // Make the filter changes
    err = SSpSource_CalcLocalization(gTestHiLevelSource, gTestHiLevelListener, &snd3DInfo);
    Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_CalcLocalization");
    
    Sound_Set3DInfo(&snd3DInfo);
    
    // Update the progress bar
    SetPort(gTestHiLevelDialog);
    TestHiLevel_ProgressUserItem(gTestHiLevelDialog, kHiLevelItem_Progress);
    
    // Show the actual velocities
    err = SSpListener_GetActualVelocity(gTestHiLevelListener, &v0);
    Message_CheckError(err, "TestHiLevel_Interpolate", "SSpListener_GetActualVelocity");
    
    if (gTestHiLevelListenerActual.x != v0.x ||
        gTestHiLevelListenerActual.y != v0.y ||
        gTestHiLevelListenerActual.z != v0.z)
    {
        gTestHiLevelListenerActual = v0;
        
        Utils_SetVector3DField(
                gTestHiLevelDialog,
                kHiLevelItem_ListenerActualVelocity,
                &gTestHiLevelListenerActual,
                true);
    }
    
    err = SSpSource_GetActualVelocity(gTestHiLevelSource, &v0);
    Message_CheckError(err, "TestHiLevel_Interpolate", "SSpSource_GetActualVelocity");
    
    if (gTestHiLevelSourceActual.x != v0.x ||
        gTestHiLevelSourceActual.y != v0.y ||
        gTestHiLevelSourceActual.z != v0.z)
    {
        gTestHiLevelSourceActual = v0;
        
        Utils_SetVector3DField(
                gTestHiLevelDialog,
                kHiLevelItem_SourceActualVelocity,
                &gTestHiLevelSourceActual,
                true);
    }
    
    // Done
    gTestHiLevelUpdate = false;
}
 
 
/* =============================================================================
 *      TestHiLevel_InterpolateFloat (internal)
 *
 *  Linear interpolation.  When inWhere is zero, inVal0 is returned.  When it
 *  is one, inVal1 is returned.  In between is linear.  If inIsRange is false
 *  then we ignore inVal1 and always return inVal0.
 * ========================================================================== */
float TestHiLevel_InterpolateFloat(
    float               inWhere,
    float               inVal0,
    float               inVal1,
    Boolean             inIsRange)
{
    float               result;
    
    if (inIsRange)
    {
        result = inWhere*(inVal1-inVal0) + inVal0;
    }
    else
    {
        result = inVal0;
    }
    
    return result;
}
 
 
/* =============================================================================
 *      TestHiLevel_InterpolateVector3D (internal)
 *
 *  Linear interpolation on vectors.
 * ========================================================================== */
static void TestHiLevel_InterpolateVector3D(
    float               inWhere,
    const TQ3Vector3D*  inVal0,
    const TQ3Vector3D*  inVal1,
    Boolean             inIsRange,
    TQ3Vector3D*        outResult)
{
    if (inIsRange)
    {
        outResult->x = TestHiLevel_InterpolateFloat(inWhere, inVal0->x, inVal1->x, true);
        outResult->y = TestHiLevel_InterpolateFloat(inWhere, inVal0->y, inVal1->y, true);
        outResult->z = TestHiLevel_InterpolateFloat(inWhere, inVal0->z, inVal1->z, true);
    }
    else
    {
        *outResult = *inVal0;
    }
}
 
 
/* =============================================================================
 *      TestHiLevel_InterpolateNormalVector3D (internal)
 *
 *  Interpolation on unit-length vectors.
 *
 *  NOTE:   We could do a better job of this, e. g. spherical interpolation,
 *          but why bother?
 * ========================================================================== */
static void TestHiLevel_InterpolateNormalVector3D(
    float               inWhere,
    const TQ3Vector3D*  inVal0,
    const TQ3Vector3D*  inVal1,
    Boolean             inIsRange,
    TQ3Vector3D*        outResult)
{
    float               scale;
    
    TestHiLevel_InterpolateVector3D(inWhere, inVal0, inVal1, inIsRange, outResult);
    
    scale = outResult->x*outResult->x +
            outResult->y*outResult->y +
            outResult->z*outResult->z;
    
    if (scale > 0.001)
    {
        scale = 1.0/sqrtf(scale);
        
        outResult->x *= scale;
        outResult->y *= scale;
        outResult->z *= scale;
    }
}
 
 
/* =============================================================================
 *      TestHiLevel_DeriveData (internal)
 *
 *  Compute the derived fields in gTestHiLevelData.
 * ========================================================================== */
void TestHiLevel_DeriveData(
    void)
{
    gTestHiLevelData.coneAngleCos1 = cosf(0.5*(pi/180.0)*gTestHiLevelData.coneAngleDeg1);
    gTestHiLevelData.coneAngleCos2 = cosf(0.5*(pi/180.0)*gTestHiLevelData.coneAngleDeg2);
    
    //¥ FOR THE NON-RANGE VALUES, SET THEM IN THE SOURCE AND LISTENER
}
 
 
/* =============================================================================
 *      TestHiLevel_SetDialogFields (internal)
 *
 *  Changes the dialog's fields to reflect gTestHiLevelData.
 * ========================================================================== */
void TestHiLevel_SetDialogFields(
    void)
{
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    short               value;
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Duration,
            gTestHiLevelData.duration,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerTranslate1,
            &gTestHiLevelData.listenerTranslate1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerTranslate2,
            &gTestHiLevelData.listenerTranslate2,
            gTestHiLevelData.listenerTranslateRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAxis1,
            &gTestHiLevelData.listenerRotationAxis1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAxis2,
            &gTestHiLevelData.listenerRotationAxis2,
            gTestHiLevelData.listenerRotationAxisRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAngle1,
            gTestHiLevelData.listenerRotationAngle1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAngle2,
            gTestHiLevelData.listenerRotationAngle2,
            gTestHiLevelData.listenerRotationAngleRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerScale1,
            &gTestHiLevelData.listenerScale1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerScale2,
            &gTestHiLevelData.listenerScale2,
            gTestHiLevelData.listenerScaleRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerPosition1,
            &gTestHiLevelData.listenerPosition1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerPosition2,
            &gTestHiLevelData.listenerPosition2,
            gTestHiLevelData.listenerPositionRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerOrientation1,
            &gTestHiLevelData.listenerOrientation1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerOrientation2,
            &gTestHiLevelData.listenerOrientation2,
            gTestHiLevelData.listenerOrientationRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerUpVector1,
            &gTestHiLevelData.listenerUpVector1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerUpVector2,
            &gTestHiLevelData.listenerUpVector2,
            gTestHiLevelData.listenerUpVectorRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerVelocity1,
            &gTestHiLevelData.listenerVelocity1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerVelocity2,
            &gTestHiLevelData.listenerVelocity2,
            gTestHiLevelData.listenerVelocityRange);
    
    GetDialogItem(gTestHiLevelDialog, kHiLevelItem_Medium, &itemType, &itemHandle, &itemBounds);
    SetControlValue((ControlHandle) itemHandle,
            (gTestHiLevelData.medium == kSSpMedium_Water)
                    ? kMediumItem_Water
                    : kMediumItem_Air);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Humidity1,
            gTestHiLevelData.humidity1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Humidity2,
            gTestHiLevelData.humidity2,
            gTestHiLevelData.humidityRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomSize1,
            gTestHiLevelData.roomSize1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomSize2,
            gTestHiLevelData.roomSize2,
            gTestHiLevelData.roomSizeRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomReflectivity1,
            gTestHiLevelData.roomReflectivity1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomReflectivity2,
            gTestHiLevelData.roomReflectivity2,
            gTestHiLevelData.roomReflectivityRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReverbAttenuation1,
            gTestHiLevelData.reverbAttenuation1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReverbAttenuation2,
            gTestHiLevelData.reverbAttenuation2,
            gTestHiLevelData.reverbAttenuationRange);
    
    Utils_SetUInt32Field(
            gTestHiLevelDialog,
            kHiLevelItem_CPULoad1,
            gTestHiLevelData.cpuLoad1,
            true);
    
    Utils_SetUInt32Field(
            gTestHiLevelDialog,
            kHiLevelItem_CPULoad2,
            gTestHiLevelData.cpuLoad2,
            gTestHiLevelData.cpuLoadRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceTranslate1,
            &gTestHiLevelData.sourceTranslate1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceTranslate2,
            &gTestHiLevelData.sourceTranslate2,
            gTestHiLevelData.sourceTranslateRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAxis1,
            &gTestHiLevelData.sourceRotationAxis1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAxis2,
            &gTestHiLevelData.sourceRotationAxis2,
            gTestHiLevelData.sourceRotationAxisRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAngle1,
            gTestHiLevelData.sourceRotationAngle1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAngle2,
            gTestHiLevelData.sourceRotationAngle2,
            gTestHiLevelData.sourceRotationAngleRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceScale1,
            &gTestHiLevelData.sourceScale1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceScale2,
            &gTestHiLevelData.sourceScale2,
            gTestHiLevelData.sourceScaleRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourcePosition1,
            &gTestHiLevelData.sourcePosition1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourcePosition2,
            &gTestHiLevelData.sourcePosition2,
            gTestHiLevelData.sourcePositionRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceOrientation1,
            &gTestHiLevelData.sourceOrientation1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceOrientation2,
            &gTestHiLevelData.sourceOrientation2,
            gTestHiLevelData.sourceOrientationRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceUpVector1,
            &gTestHiLevelData.sourceUpVector1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceUpVector2,
            &gTestHiLevelData.sourceUpVector2,
            gTestHiLevelData.sourceUpVectorRange);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceVelocity1,
            &gTestHiLevelData.sourceVelocity1,
            true);
    
    Utils_SetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceVelocity2,
            &gTestHiLevelData.sourceVelocity2,
            gTestHiLevelData.sourceVelocityRange);
    
    value = kSourceModeItem_Unfiltered;
    switch (gTestHiLevelData.sourceMode)
    {
        case kSSpSourceMode_Localized:
            value = kSourceModeItem_Localized;
        break;
        
        case kSSpSourceMode_Ambient:
            value = kSourceModeItem_Ambient;
        break;
        
        case kSSpSourceMode_Binaural:
            value = kSourceModeItem_Binaural;
        break;
    }
    
    GetDialogItem(gTestHiLevelDialog, kHiLevelItem_SourceMode, &itemType, &itemHandle, &itemBounds);
    SetControlValue((ControlHandle) itemHandle, value);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReferenceDistance1,
            gTestHiLevelData.referenceDistance1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReferenceDistance2,
            gTestHiLevelData.referenceDistance2,
            gTestHiLevelData.referenceDistanceRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Length1,
            gTestHiLevelData.length1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Length2,
            gTestHiLevelData.length2,
            gTestHiLevelData.lengthRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Width1,
            gTestHiLevelData.width1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Width2,
            gTestHiLevelData.width2,
            gTestHiLevelData.widthRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Height1,
            gTestHiLevelData.height1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Height2,
            gTestHiLevelData.height2,
            gTestHiLevelData.heightRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAngleDeg1,
            gTestHiLevelData.coneAngleDeg1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAngleDeg2,
            gTestHiLevelData.coneAngleDeg2,
            gTestHiLevelData.coneAngleDegRange);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAttenuation1,
            gTestHiLevelData.coneAttenuation1,
            true);
    
    Utils_SetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAttenuation2,
            gTestHiLevelData.coneAttenuation2,
            gTestHiLevelData.coneAttenuationRange);
}
 
 
/* =============================================================================
 *      TestHiLevel_GetDialogFields (internal)
 *
 *  Grabs the contents of the dialog fields and puts them into gTestHiLevelData.
 * ========================================================================== */
void TestHiLevel_GetDialogFields(
    void)
{
    const float         small = 0.000001;
    const float         big = 10000000.0;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    TTestHiLevelData    data;
    short               badItem;
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Duration,
            &data.duration,
            NULL,
            small,
            big))
    {
        badItem = kHiLevelItem_Duration;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerTranslate1,
            &data.listenerTranslate1,
            NULL))
    {
        badItem = kHiLevelItem_ListenerTranslate1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerTranslate2,
            &data.listenerTranslate2,
            &data.listenerTranslateRange))
    {
        badItem = kHiLevelItem_ListenerTranslate2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAxis1,
            &data.listenerRotationAxis1,
            NULL))
    {
        badItem = kHiLevelItem_ListenerRotationAxis1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAxis2,
            &data.listenerRotationAxis2,
            &data.listenerRotationAxisRange))
    {
        badItem = kHiLevelItem_ListenerRotationAxis2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAngle1,
            &data.listenerRotationAngle1,
            NULL,
            -big,
            big))
    {
        badItem = kHiLevelItem_ListenerRotationAngle1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerRotationAngle2,
            &data.listenerRotationAngle2,
            &data.listenerRotationAngleRange,
            -big,
            big))
    {
        badItem = kHiLevelItem_ListenerRotationAngle2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerScale1,
            &data.listenerScale1,
            NULL))
    {
        badItem = kHiLevelItem_ListenerScale1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerScale2,
            &data.listenerScale2,
            &data.listenerScaleRange))
    {
        badItem = kHiLevelItem_ListenerScale2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerPosition1,
            &data.listenerPosition1,
            NULL))
    {
        badItem = kHiLevelItem_ListenerPosition1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerPosition2,
            &data.listenerPosition2,
            &data.listenerPositionRange))
    {
        badItem = kHiLevelItem_ListenerPosition2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerOrientation1,
            &data.listenerOrientation1,
            NULL))
    {
        badItem = kHiLevelItem_ListenerOrientation1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerOrientation2,
            &data.listenerOrientation2,
            &data.listenerOrientationRange))
    {
        badItem = kHiLevelItem_ListenerOrientation2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerUpVector1,
            &data.listenerUpVector1,
            NULL))
    {
        badItem = kHiLevelItem_ListenerUpVector1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerUpVector2,
            &data.listenerUpVector2,
            &data.listenerUpVectorRange))
    {
        badItem = kHiLevelItem_ListenerUpVector2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerVelocity1,
            &data.listenerVelocity1,
            NULL))
    {
        badItem = kHiLevelItem_ListenerVelocity1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_ListenerVelocity2,
            &data.listenerVelocity2,
            &data.listenerVelocityRange))
    {
        badItem = kHiLevelItem_ListenerVelocity2;
        goto bail;
    }
    
    GetDialogItem(gTestHiLevelDialog, kHiLevelItem_Medium, &itemType, &itemHandle, &itemBounds);
    switch (GetControlValue((ControlHandle) itemHandle))
    {
        case kMediumItem_Air:
            data.medium = kSSpMedium_Air;
        break;
        
        case kMediumItem_Water:
            data.medium = kSSpMedium_Water;
        break;
        
        default:
            assert(0);
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Humidity1,
            &data.humidity1,
            NULL,
            0.0,
            100.0))
    {
        badItem = kHiLevelItem_Humidity1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Humidity2,
            &data.humidity2,
            &data.humidityRange,
            0.0,
            100.0))
    {
        badItem = kHiLevelItem_Humidity2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomSize1,
            &data.roomSize1,
            NULL,
            0.0,
            big))
    {
        badItem = kHiLevelItem_RoomSize1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomSize2,
            &data.roomSize2,
            &data.roomSizeRange,
            0.0,
            big))
    {
        badItem = kHiLevelItem_RoomSize2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomReflectivity1,
            &data.roomReflectivity1,
            NULL,
            -big,
            -small))
    {
        badItem = kHiLevelItem_RoomReflectivity1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_RoomReflectivity2,
            &data.roomReflectivity2,
            &data.roomReflectivityRange,
            -big,
            -small))
    {
        badItem = kHiLevelItem_RoomReflectivity2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReverbAttenuation1,
            &data.reverbAttenuation1,
            NULL,
            -big,
            big))
    {
        badItem = kHiLevelItem_ReverbAttenuation1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReverbAttenuation2,
            &data.reverbAttenuation2,
            &data.reverbAttenuationRange,
            -big,
            big))
    {
        badItem = kHiLevelItem_ReverbAttenuation2;
        goto bail;
    }
    
    if (!Utils_GetUInt32Field(
            gTestHiLevelDialog,
            kHiLevelItem_CPULoad1,
            &data.cpuLoad1,
            NULL,
            0,
            gTestHiLevelCPULoadLimit))
    {
        badItem = kHiLevelItem_CPULoad1;
        goto bail;
    }
    
    if (!Utils_GetUInt32Field(
            gTestHiLevelDialog,
            kHiLevelItem_CPULoad2,
            &data.cpuLoad2,
            &data.cpuLoadRange,
            0,
            gTestHiLevelCPULoadLimit))
    {
        badItem = kHiLevelItem_CPULoad2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceTranslate1,
            &data.sourceTranslate1,
            NULL))
    {
        badItem = kHiLevelItem_SourceTranslate1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceTranslate2,
            &data.sourceTranslate2,
            &data.sourceTranslateRange))
    {
        badItem = kHiLevelItem_SourceTranslate2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAxis1,
            &data.sourceRotationAxis1,
            NULL))
    {
        badItem = kHiLevelItem_SourceRotationAxis1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAxis2,
            &data.sourceRotationAxis2,
            &data.sourceRotationAxisRange))
    {
        badItem = kHiLevelItem_SourceRotationAxis2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAngle1,
            &data.sourceRotationAngle1,
            NULL,
            -big,
            big))
    {
        badItem = kHiLevelItem_SourceRotationAngle1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceRotationAngle2,
            &data.sourceRotationAngle2,
            &data.sourceRotationAngleRange,
            -big,
            big))
    {
        badItem = kHiLevelItem_SourceRotationAngle2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceScale1,
            &data.sourceScale1,
            NULL))
    {
        badItem = kHiLevelItem_SourceScale1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceScale2,
            &data.sourceScale2,
            &data.sourceScaleRange))
    {
        badItem = kHiLevelItem_SourceScale2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourcePosition1,
            &data.sourcePosition1,
            NULL))
    {
        badItem = kHiLevelItem_SourcePosition1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourcePosition2,
            &data.sourcePosition2,
            &data.sourcePositionRange))
    {
        badItem = kHiLevelItem_SourcePosition2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceOrientation1,
            &data.sourceOrientation1,
            NULL))
    {
        badItem = kHiLevelItem_SourceOrientation1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceOrientation2,
            &data.sourceOrientation2,
            &data.sourceOrientationRange))
    {
        badItem = kHiLevelItem_SourceOrientation2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceUpVector1,
            &data.sourceUpVector1,
            NULL))
    {
        badItem = kHiLevelItem_SourceUpVector1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceUpVector2,
            &data.sourceUpVector2,
            &data.sourceUpVectorRange))
    {
        badItem = kHiLevelItem_SourceUpVector2;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceVelocity1,
            &data.sourceVelocity1,
            NULL))
    {
        badItem = kHiLevelItem_SourceVelocity1;
        goto bail;
    }
    
    if (!Utils_GetVector3DField(
            gTestHiLevelDialog,
            kHiLevelItem_SourceVelocity2,
            &data.sourceVelocity2,
            &data.sourceVelocityRange))
    {
        badItem = kHiLevelItem_SourceVelocity2;
        goto bail;
    }
    
    GetDialogItem(gTestHiLevelDialog, kHiLevelItem_SourceMode, &itemType, &itemHandle, &itemBounds);
    switch (GetControlValue((ControlHandle) itemHandle))
    {
        case kSourceModeItem_Unfiltered:
            data.sourceMode = kSSpSourceMode_Unfiltered;
        break;
        
        case kSourceModeItem_Localized:
            data.sourceMode = kSSpSourceMode_Localized;
        break;
        
        case kSourceModeItem_Ambient:
            data.sourceMode = kSSpSourceMode_Ambient;
        break;
        
        case kSourceModeItem_Binaural:
            data.sourceMode = kSSpSourceMode_Binaural;
        break;
        
        default:
            assert(0);
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReferenceDistance1,
            &data.referenceDistance1,
            NULL,
            small,
            big))
    {
        badItem = kHiLevelItem_ReferenceDistance1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ReferenceDistance2,
            &data.referenceDistance2,
            &data.referenceDistanceRange,
            small,
            big))
    {
        badItem = kHiLevelItem_ReferenceDistance2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Length1,
            &data.length1,
            NULL,
            -big,
            0.0))
    {
        badItem = kHiLevelItem_Length1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Length2,
            &data.length2,
            &data.lengthRange,
            0.0,
            big))
    {
        badItem = kHiLevelItem_Length2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Width1,
            &data.width1,
            NULL,
            0.0,
            big))
    {
        badItem = kHiLevelItem_Width1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Width2,
            &data.width2,
            &data.widthRange,
            0.0,
            big))
    {
        badItem = kHiLevelItem_Width2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Height1,
            &data.height1,
            NULL,
            0.0,
            big))
    {
        badItem = kHiLevelItem_Height1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_Height2,
            &data.height2,
            &data.heightRange,
            0.0,
            big))
    {
        badItem = kHiLevelItem_Height2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAngleDeg1,
            &data.coneAngleDeg1,
            NULL,
            0.0,
            360.0))
    {
        badItem = kHiLevelItem_ConeAngleDeg1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAngleDeg2,
            &data.coneAngleDeg2,
            &data.coneAngleDegRange,
            0.0,
            360.0))
    {
        badItem = kHiLevelItem_ConeAngleDeg2;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAttenuation1,
            &data.coneAttenuation1,
            NULL,
            -big,
            big))
    {
        badItem = kHiLevelItem_ConeAttenuation1;
        goto bail;
    }
    
    if (!Utils_GetFloatField(
            gTestHiLevelDialog,
            kHiLevelItem_ConeAttenuation2,
            &data.coneAttenuation2,
            &data.coneAttenuationRange,
            -big,
            big))
    {
        badItem = kHiLevelItem_ConeAttenuation2;
        goto bail;
    }
    
    // All fields are good -- finish up
    gTestHiLevelData = data;
    TestHiLevel_DeriveData();
    
    TestHiLevel_SetDialogFields();
    
    gTestHiLevelUpdate = true;
    
    return;
    
    // Error exit
bail:
    SelectDialogItemText(gTestHiLevelDialog, badItem, 0, 32767);
    StopAlert(kAlrtID_BadField, NULL);
}
 
 
/* =============================================================================
 *      TestHiLevel_Preset (external)
 *
 *  Updates the fields to the chosen preset value.
 * ========================================================================== */
void TestHiLevel_Preset(
    UInt32          index)
{
    TTestHiLevelData preset[] = {
        { /* nothing for index zero */ 0 },
        { /* Left-Right Ahead */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  0.0, 0.0, false,
                /* roomReflectivity         */  -10.0, 0.0, false,
                /* reverbAttenuation        */  -15.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {1.0, 0.0, -10.0}, {1.0, 0.0, 10.0}, true,
                /* sourceOrientation        */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  0.0, 0.0, false,
                /* width                    */  0.0, 0.0, false,
                /* height                   */  0.0, 0.0, false,
                /* coneAngleDeg             */  0.0, 0.0, false,
                /* coneAttenuation          */  0.0, 0.0, false
        },
        { /* Front-Back Above */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  0.0, 0.0, false,
                /* roomReflectivity         */  -10.0, 0.0, false,
                /* reverbAttenuation        */  -15.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {10.0, 1.0, 0.0}, {-10.0, 1.0, 0.0}, true,
                /* sourceOrientation        */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  0.0, 0.0, false,
                /* width                    */  0.0, 0.0, false,
                /* height                   */  0.0, 0.0, false,
                /* coneAngleDeg             */  0.0, 0.0, false,
                /* coneAttenuation          */  0.0, 0.0, false
        },
        { /* Up-Down Ahead */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  0.0, 0.0, false,
                /* roomReflectivity         */  -10.0, 0.0, false,
                /* reverbAttenuation        */  -15.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {1.0, -10.0, 0.0}, {1.0, 10.0, 0.0}, true,
                /* sourceOrientation        */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  0.0, 0.0, false,
                /* width                    */  0.0, 0.0, false,
                /* height                   */  0.0, 0.0, false,
                /* coneAngleDeg             */  0.0, 0.0, false,
                /* coneAttenuation          */  0.0, 0.0, false
        },
        { /* dividing line */ 0 },
        { /* Reverb Ñ Living Room */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  10.0, 0.0, false,
                /* roomReflectivity         */  -20.0, 0.0, false,
                /* reverbAttenuation        */  0.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {2.0, 0.0, 0.0}, {10.0, 0.0, 0.0}, true,
                /* sourceOrientation        */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  0.0, 0.0, false,
                /* width                    */  0.0, 0.0, false,
                /* height                   */  0.0, 0.0, false,
                /* coneAngleDeg             */  0.0, 0.0, false,
                /* coneAttenuation          */  0.0, 0.0, false
        },
        { /* Reverb Ñ Cave */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  100.0, 0.0, false,
                /* roomReflectivity         */  -40.0, 0.0, false,
                /* reverbAttenuation        */  20.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {2.0, 0.0, 0.0}, {10.0, 0.0, 0.0}, true,
                /* sourceOrientation        */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  0.0, 0.0, false,
                /* width                    */  0.0, 0.0, false,
                /* height                   */  0.0, 0.0, false,
                /* coneAngleDeg             */  0.0, 0.0, false,
                /* coneAttenuation          */  0.0, 0.0, false
        },
        { /* Reverb Ñ Stadium */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  250.0, 0.0, false,
                /* roomReflectivity         */  -15.0, 0.0, false,
                /* reverbAttenuation        */  -5.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {2.0, 0.0, 0.0}, {10.0, 0.0, 0.0}, true,
                /* sourceOrientation        */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  0.0, 0.0, false,
                /* width                    */  0.0, 0.0, false,
                /* height                   */  0.0, 0.0, false,
                /* coneAngleDeg             */  0.0, 0.0, false,
                /* coneAttenuation          */  0.0, 0.0, false
        },
        { /* dividing line */ 0 },
        { /* Searchlight */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  0.0, 0.0, false,
                /* roomReflectivity         */  -10.0, 0.0, false,
                /* reverbAttenuation        */  -15.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceOrientation        */  {-0.1, 0.0, -1.0}, {-0.1, 0.0, 1.0}, true,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  0.0, 0.0, false,
                /* width                    */  0.0, 0.0, false,
                /* height                   */  0.0, 0.0, false,
                /* coneAngleDeg             */  180.0, 0.0, false,
                /* coneAttenuation          */  -20.0, 0.0, false
        },
        { /* dividing line */ 0 },
        { /* Box Left-Right Ahead */
                /* duration                 */  4.0,
                /* listenerTranslate        */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAxis     */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerRotationAngle    */  0.0, 0.0, false,
                /* listenerScale            */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* listenerPosition         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerOrientation      */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerUpVector         */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* listenerVelocity         */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpMedium_Air,
                /* humidity                 */  0.0, 0.0, false,
                /* roomSize                 */  0.0, 0.0, false,
                /* roomReflectivity         */  -10.0, 0.0, false,
                /* reverbAttenuation        */  -15.0, 0.0, false,
                /* cpuLoad                  */  0, 0, false,
                /* sourceTranslate          */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAxis       */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceRotationAngle      */  0.0, 0.0, false,
                /* sourceScale              */  {1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}, false,
                /* sourcePosition           */  {2.0, 0.0, -10.0}, {2.0, 0.0, 10.0}, true,
                /* sourceOrientation        */  {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceUpVector           */  {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* sourceVelocity           */  {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, false,
                /* medium                   */  kSSpSourceMode_Localized,
                /* referenceDistance        */  1.0, 0.0, false,
                /* length                   */  1.0, 0.0, false,
                /* width                    */  1.0, 0.0, false,
                /* height                   */  1.0, 0.0, false,
                /* coneAngleDeg             */  0.0, 0.0, false,
                /* coneAttenuation          */  0.0, 0.0, false
        },
    };
    
    gTestHiLevelData = preset[index];
    
    TestHiLevel_DeriveData();
    TestHiLevel_SetDialogFields();
    
    gTestHiLevelUpdate = true;
}