/*
 * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


#define USE_ERROR
//#define USE_TRACE

#ifndef WIN32_EXTRA_LEAN
#define WIN32_EXTRA_LEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <mmsystem.h>
#include "Ports.h"

#if USE_PORTS == TRUE

typedef struct tag_PortControlID PortControlID;

typedef struct tag_PortInfo {
    // Windows API stuff
    HMIXER handle;
    INT32 mixerIndex;
    int dstLineCount;        // how many MIXERLINE structs in dstMixerLine
    MIXERLINE* dstLines;
    int srcLineCount;        // how many MIXERLINE structs in srcMixerLine
    MIXERLINE* srcLines;     // contains all the Source Lines of dstLines
    // Java Sound mapping
    int targetPortCount;     // one port per dstLine (playback)
    int sourcePortCount;     // only WAVEIN; one port maps to one srcLine
    LPMIXERLINE* ports;      // points into dstLines and dstLines. Starts with Target Ports (Playback)
    int maxControlCount;       // upper bound of number of controls
    int usedControlIDs;        // number of items already filled in controlIDs
    PortControlID* controlIDs; // the control IDs themselves
    int usedMuxData;
    MIXERCONTROLDETAILS_BOOLEAN* muxData;
} PortInfo;

#define PORT_CONTROL_TYPE_BOOLEAN     1
#define PORT_CONTROL_TYPE_SIGNED      2
#define PORT_CONTROL_TYPE_UNSIGNED    3
//#define PORT_CONTROL_TYPE_UNSIGNED_DB 4
#define PORT_CONTROL_TYPE_FAKE_VOLUME 5
#define PORT_CONTROL_TYPE_FAKE_BALANCE 6
#define PORT_CONTROL_TYPE_MUX         5
#define PORT_CONTROL_TYPE_MIXER       6

typedef struct tag_PortControlID {
    PortInfo*           portInfo;
    INT32               controlType;  // one of PORT_CONTROL_TYPE_XX
    INT32               min;
    INT32               max;
    MIXERCONTROLDETAILS details;
    union {
        MIXERCONTROLDETAILS_BOOLEAN  boolValue;
        MIXERCONTROLDETAILS_SIGNED   signedValue;
        MIXERCONTROLDETAILS_UNSIGNED unsignedValue[2];
        INT32                        muxIndex;
    };
} PortControlID;


int getControlInfo(HMIXER handle, MIXERLINE* line, MIXERLINECONTROLS* controls);

INT32 PORT_GetPortMixerCount() {
    return (INT32) mixerGetNumDevs();
}

#ifdef USE_TRACE

char* getLineFlags(DWORD flags) {
    static char ret[100];
    ret[0]=0;
    if (flags & MIXERLINE_LINEF_ACTIVE) {
        strcat(ret, "ACTIVE ");
        flags ^= MIXERLINE_LINEF_ACTIVE;
    }
    if (flags & MIXERLINE_LINEF_DISCONNECTED) {
        strcat(ret, "DISCONNECTED ");
        flags ^= MIXERLINE_LINEF_DISCONNECTED;
    }
    if (flags & MIXERLINE_LINEF_SOURCE) {
        strcat(ret, "SOURCE ");
        flags ^= MIXERLINE_LINEF_SOURCE;
    }
    if (flags!=0) {
        UINT_PTR r = (UINT_PTR) ret;
        r += strlen(ret);
        sprintf((char*) r, "%d", flags);
    }
    return ret;
}

char* getComponentType(int componentType) {
    switch (componentType) {
        case MIXERLINE_COMPONENTTYPE_DST_HEADPHONES:   return "DST_HEADPHONES";
        case MIXERLINE_COMPONENTTYPE_DST_LINE:         return "DST_LINE";
        case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:     return "DST_SPEAKERS";
        case MIXERLINE_COMPONENTTYPE_DST_DIGITAL:      return "DST_DIGITAL";
        case MIXERLINE_COMPONENTTYPE_DST_MONITOR:      return "DST_MONITOR";
        case MIXERLINE_COMPONENTTYPE_DST_TELEPHONE:    return "DST_TELEPHONE";
        case MIXERLINE_COMPONENTTYPE_DST_UNDEFINED:    return "DST_UNDEFINED";
        case MIXERLINE_COMPONENTTYPE_DST_VOICEIN:      return "DST_VOICEIN";
        case MIXERLINE_COMPONENTTYPE_DST_WAVEIN:       return "DST_WAVEIN";

        case MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC:  return "SRC_COMPACTDISC";
        case MIXERLINE_COMPONENTTYPE_SRC_LINE:         return "SRC_LINE";
        case MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE:   return "SRC_MICROPHONE";
        case MIXERLINE_COMPONENTTYPE_SRC_ANALOG:       return "SRC_ANALOG";
        case MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY:    return "SRC_AUXILIARY";
        case MIXERLINE_COMPONENTTYPE_SRC_DIGITAL:      return "SRC_DIGITAL";
        case MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER:    return "SRC_PCSPEAKER";
        case MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER:  return "SRC_SYNTHESIZER";
        case MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE:    return "SRC_TELEPHONE";
        case MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED:    return "SRC_UNDEFINED";
        case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT:      return "SRC_WAVEOUT";
    }
    return "";
}

void printMixerLine(MIXERLINE* mixerLine) {
    TRACE2("MIXERLINE destination=%d, source=%d, ", mixerLine->dwDestination, mixerLine->dwSource);
    TRACE3("channels=%d, connections=%d, controls=%d, ", mixerLine->cChannels, mixerLine->cConnections, mixerLine->cControls);
    TRACE3("\"%s\", fdwLine=%s, componentType=%s\n", mixerLine->szName,  getLineFlags(mixerLine->fdwLine), getComponentType(mixerLine->dwComponentType));
}

char* getControlClass(int controlType) {
    switch (controlType & MIXERCONTROL_CT_CLASS_MASK) {
        case MIXERCONTROL_CT_CLASS_CUSTOM : return "CLASS_CUSTOM";
        case MIXERCONTROL_CT_CLASS_FADER  : return "CLASS_FADER ";
        case MIXERCONTROL_CT_CLASS_LIST   : return "CLASS_LIST  ";
        case MIXERCONTROL_CT_CLASS_METER  : return "CLASS_METER ";
        case MIXERCONTROL_CT_CLASS_NUMBER : return "CLASS_NUMBER";
        case MIXERCONTROL_CT_CLASS_SLIDER : return "CLASS_SLIDER";
        case MIXERCONTROL_CT_CLASS_SWITCH : return "CLASS_SWITCH";
        case MIXERCONTROL_CT_CLASS_TIME   : return "CLASS_TIME  ";
    }
    return "unknown class";
}

char* getControlType(int controlType) {
    switch (controlType) {
        case MIXERCONTROL_CONTROLTYPE_CUSTOM          : return "CUSTOM         ";
        case MIXERCONTROL_CONTROLTYPE_BASS            : return "BASS           ";
        case MIXERCONTROL_CONTROLTYPE_EQUALIZER       : return "EQUALIZER      ";
        case MIXERCONTROL_CONTROLTYPE_FADER           : return "FADER          ";
        case MIXERCONTROL_CONTROLTYPE_TREBLE          : return "TREBLE         ";
        case MIXERCONTROL_CONTROLTYPE_VOLUME          : return "VOLUME         ";
        case MIXERCONTROL_CONTROLTYPE_MIXER           : return "MIXER          ";
        case MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT  : return "MULTIPLESELECT ";
        case MIXERCONTROL_CONTROLTYPE_MUX             : return "MUX            ";
        case MIXERCONTROL_CONTROLTYPE_SINGLESELECT    : return "SINGLESELECT   ";
        case MIXERCONTROL_CONTROLTYPE_BOOLEANMETER    : return "BOOLEANMETER   ";
        case MIXERCONTROL_CONTROLTYPE_PEAKMETER       : return "PEAKMETER      ";
        case MIXERCONTROL_CONTROLTYPE_SIGNEDMETER     : return "SIGNEDMETER    ";
        case MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER   : return "UNSIGNEDMETER  ";
        case MIXERCONTROL_CONTROLTYPE_DECIBELS        : return "DECIBELS       ";
        case MIXERCONTROL_CONTROLTYPE_PERCENT         : return "PERCENT        ";
        case MIXERCONTROL_CONTROLTYPE_SIGNED          : return "SIGNED         ";
        case MIXERCONTROL_CONTROLTYPE_UNSIGNED        : return "UNSIGNED       ";
        case MIXERCONTROL_CONTROLTYPE_PAN             : return "PAN            ";
        case MIXERCONTROL_CONTROLTYPE_QSOUNDPAN       : return "QSOUNDPAN      ";
        case MIXERCONTROL_CONTROLTYPE_SLIDER          : return "SLIDER         ";
        case MIXERCONTROL_CONTROLTYPE_BOOLEAN         : return "BOOLEAN        ";
        case MIXERCONTROL_CONTROLTYPE_BUTTON          : return "BUTTON         ";
        case MIXERCONTROL_CONTROLTYPE_LOUDNESS        : return "LOUDNESS       ";
        case MIXERCONTROL_CONTROLTYPE_MONO            : return "MONO           ";
        case MIXERCONTROL_CONTROLTYPE_MUTE            : return "MUTE           ";
        case MIXERCONTROL_CONTROLTYPE_ONOFF           : return "ONOFF          ";
        case MIXERCONTROL_CONTROLTYPE_STEREOENH       : return "STEREOENH      ";
        case MIXERCONTROL_CONTROLTYPE_MICROTIME       : return "MICROTIME      ";
        case MIXERCONTROL_CONTROLTYPE_MILLITIME       : return "MILLITIME      ";
    }
    return "unknown";
}

char* getControlState(DWORD controlState) {
    static char ret[100];
    ret[0]=0;
    if (controlState & MIXERCONTROL_CONTROLF_DISABLED) {
        strcat(ret, "DISABLED ");
        controlState ^= MIXERCONTROL_CONTROLF_DISABLED;
    }
    if (controlState & MIXERCONTROL_CONTROLF_MULTIPLE) {
        strcat(ret, "MULTIPLE ");
        controlState ^= MIXERCONTROL_CONTROLF_MULTIPLE;
    }
    if (controlState & MIXERCONTROL_CONTROLF_UNIFORM) {
        strcat(ret, "UNIFORM ");
        controlState ^= MIXERCONTROL_CONTROLF_UNIFORM;
    }
    if (controlState!=0) {
        UINT_PTR r = (UINT_PTR) ret;
        r += strlen(ret);
        sprintf((char*) r, "%d", controlState);
    }
    return ret;
}

void printControl(MIXERCONTROL* control) {
    TRACE3("    %s: dwControlType=%s/%s, ", control->szName, getControlClass(control->dwControlType), getControlType(control->dwControlType));
    TRACE3("multpleItems=%d, state=%d, %s\n", control->cMultipleItems, control->fdwControl, getControlState(control->fdwControl));
}

void printMixerLineControls(HMIXER handle, MIXERLINE* mixerLine) {
    MIXERLINECONTROLS controls;
    DWORD i;
    TRACE1("  Controls for %s:\n", mixerLine->szName);
    if (getControlInfo(handle, mixerLine, &controls)) {
        for (i = 0; i < controls.cControls; i++) {
            printControl(&controls.pamxctrl[i]);
        }
        if (controls.pamxctrl) {
            free(controls.pamxctrl);
            controls.pamxctrl = NULL;
        }
    }
}

void printInfo(PortInfo* info) {
    TRACE5(" PortInfo %p: handle=%p, mixerIndex=%d, dstLineCount=%d, dstLines=%p, ", info, (void*) info->handle, info->mixerIndex, info->dstLineCount, info->dstLines);
    TRACE5("srcLineCount=%d, srcLines=%p, targetPortCount=%d, sourcePortCount=%d, ports=%p, ", info->srcLineCount, info->srcLines, info->targetPortCount, info->sourcePortCount, info->ports);
    TRACE3("maxControlCount=%d, usedControlIDs=%d, controlIDs=%p \n", info->maxControlCount, info->usedControlIDs, info->controlIDs);
    TRACE2("usedMuxData=%d, muxData=%p, controlIDs=%p \n", info->usedMuxData, info->muxData);
}

#endif // USE_TRACE

// internal utility functions

int getMixerLineByDestination(HMIXER handle, DWORD dstIndex, MIXERLINE* mixerLine) {
    mixerLine->cbStruct = sizeof(MIXERLINE);
    mixerLine->dwDestination = dstIndex;
    if (mixerGetLineInfo((HMIXEROBJ) handle, mixerLine,
                          MIXER_GETLINEINFOF_DESTINATION | MIXER_OBJECTF_HMIXER
                         ) == MMSYSERR_NOERROR) {
        return TRUE;
    }
    mixerLine->cControls = 0;
    mixerLine->cConnections = 0;
    return FALSE;
}

int getMixerLineByType(HMIXER handle, DWORD linetype, MIXERLINE* mixerLine) {
    mixerLine->cbStruct = sizeof(MIXERLINE);
    mixerLine->dwComponentType = linetype;
    if (mixerGetLineInfo((HMIXEROBJ) handle, mixerLine,
                          MIXER_GETLINEINFOF_COMPONENTTYPE | MIXER_OBJECTF_HMIXER
                         ) == MMSYSERR_NOERROR) {
        return TRUE;
    }
    mixerLine->cControls = 0;
    mixerLine->cConnections = 0;
    return FALSE;
}

int getMixerLineBySource(HMIXER handle, DWORD dstIndex, DWORD srcIndex, MIXERLINE* mixerLine) {
    mixerLine->cbStruct = sizeof(MIXERLINE);
    mixerLine->dwDestination = dstIndex;
    mixerLine->dwSource = srcIndex;
    if (mixerGetLineInfo((HMIXEROBJ) handle, mixerLine,
                          MIXER_GETLINEINFOF_SOURCE | MIXER_OBJECTF_HMIXER
                         ) == MMSYSERR_NOERROR) {
        return TRUE;
    }
    mixerLine->cControls = 0;
    mixerLine->cConnections = 0;
    return FALSE;
}

int getControlInfo(HMIXER handle, MIXERLINE* line, MIXERLINECONTROLS* controls) {
    int ret = FALSE;

    //TRACE2(">getControlInfo for line %s with %d controls\n", line->szName, line->cControls);
    controls->pamxctrl = NULL;
    if (line->cControls > 0) {
        // line points to the requested line.
        // Reserve memory for the control infos
        controls->cbStruct = sizeof(MIXERLINECONTROLS);
        controls->dwLineID = line->dwLineID;
        controls->cControls = line->cControls;
        controls->cbmxctrl = sizeof(MIXERCONTROL);
        controls->pamxctrl = (MIXERCONTROL*) malloc(sizeof(MIXERCONTROL) * line->cControls);
        if (controls->pamxctrl) {
            //TRACE0(" calling mixerGetLineControls\n");
            ret = mixerGetLineControls((HMIXEROBJ) handle, controls,
                                       MIXER_GETLINECONTROLSF_ALL | MIXER_OBJECTF_HMIXER) == MMSYSERR_NOERROR;
        }
    }
    if (!ret) {
        if (controls->pamxctrl) {
            free(controls->pamxctrl);
            controls->pamxctrl = NULL;
        }
    }
    //TRACE0("<getControlInfo \n");
    return ret;
}

// returns TRUE if there are more than MIXER/MUX controls in this line
// if controls is non-NULL, it will be filled with the info
int lineHasControls(HMIXER handle, MIXERLINE* line, MIXERLINECONTROLS* controls) {
    MIXERLINECONTROLS localControls;
    int ret = FALSE;
    UINT i;

    localControls.pamxctrl = NULL;
    if (controls == NULL) {
        controls = &localControls;
    }
    if (getControlInfo(handle, line, controls)) {
        for (i = 0; !ret && (i < controls->cControls); i++) {
            switch (controls->pamxctrl[i].dwControlType & MIXERCONTROL_CT_CLASS_MASK) {
                case MIXERCONTROL_CT_CLASS_FADER  : // fall through
                case MIXERCONTROL_CT_CLASS_SLIDER : // fall through
                case MIXERCONTROL_CT_CLASS_SWITCH : ret = TRUE;
            }
        }
    }
    if (localControls.pamxctrl) {
        free(localControls.pamxctrl);
        localControls.pamxctrl = NULL;
    }
    return ret;
}


///// implemented functions of Ports.h

INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) {
    MIXERCAPS mixerCaps;
    if (mixerGetDevCaps(mixerIndex, &mixerCaps, sizeof(MIXERCAPS)) == MMSYSERR_NOERROR) {
        strncpy(description->name, mixerCaps.szPname, PORT_STRING_LENGTH-1);
        description->name[PORT_STRING_LENGTH-1] = 0;
        sprintf(description->version, "%d.%d", (mixerCaps.vDriverVersion & 0xFF00) >> 8, mixerCaps.vDriverVersion & 0xFF);
        strncpy(description->description, "Port Mixer", PORT_STRING_LENGTH-1);
        return TRUE;
    }
    return FALSE;
}

int getDestinationCount(HMIXER handle) {
    int ret = 0;
    MIXERCAPS mixerCaps;

    if (mixerGetDevCaps((UINT_PTR) handle, &mixerCaps, sizeof(MIXERCAPS)) == MMSYSERR_NOERROR) {
        ret = mixerCaps.cDestinations;
    }
    return ret;
}

void* PORT_Open(INT32 mixerIndex) {
    PortInfo* info = NULL;
    MMRESULT mmres;
    HMIXER handle;
    MIXERLINE* waveInLine;
    int success = FALSE;
    int src, dst, srcIndex, waveInHasControls;
    int dstCount;

    TRACE0("PORT_Open\n");
    mmres = mixerOpen((LPHMIXER) &handle, mixerIndex, 0, 0, MIXER_OBJECTF_MIXER);
    if (mmres != MMSYSERR_NOERROR) {
        return NULL;
    }

    info = (PortInfo*) malloc(sizeof(PortInfo));
    if (info != NULL) {
        success = TRUE;
        memset(info, 0, sizeof(PortInfo));
        info->handle = handle;
        info->mixerIndex = mixerIndex;
        waveInLine = NULL;
        waveInHasControls = FALSE;
        // number of destinations
        dstCount = getDestinationCount(handle);
        if (dstCount) {
            info->dstLines = (MIXERLINE*) malloc(dstCount * sizeof(MIXERLINE));
            success = (info->dstLines != NULL);
        }
        if (success && info->dstLines) {
            // go through all destinations and fill the structures in PortInfo
            for (dst = 0; dst < dstCount; dst++) {
                if (getMixerLineByDestination(handle, dst, &info->dstLines[info->dstLineCount])) {
                    info->srcLineCount += info->dstLines[info->dstLineCount].cConnections;
                    if (info->dstLines[info->dstLineCount].dwComponentType == MIXERLINE_COMPONENTTYPE_DST_WAVEIN && !waveInLine) {
                        waveInLine = &info->dstLines[info->dstLineCount];
                        info->sourcePortCount = waveInLine->cConnections;
                        if (lineHasControls(handle, waveInLine, NULL)) {
                            // add a single port for all the controls that do not show in the MUX/MIXER controls
                            info->sourcePortCount++;
                            waveInHasControls = TRUE;
                        }
                    } else {
                        info->targetPortCount++;
                    }
                    info->dstLineCount++;
                }
            }
        }
        if (info->srcLineCount) {
            info->srcLines = (MIXERLINE*) malloc(info->srcLineCount * sizeof(MIXERLINE));
            success = (info->srcLines != NULL);
        }
        if (success && info->srcLines) {
            // go through all destinations and fill the source line structures in PortInfo
            srcIndex = 0;
            for (dst = 0; dst < info->dstLineCount; dst++) {
                // remember the srcIndex for mapping the srcLines to this destination line
                info->dstLines[dst].dwUser = srcIndex;
                for (src = 0; src < (int) info->dstLines[dst].cConnections; src++) {
                    getMixerLineBySource(handle, dst, src, &info->srcLines[srcIndex++]);
                }
            }
        }
        // now create the mapping to Java Sound
        if ((info->targetPortCount + info->sourcePortCount) > 0) {
            info->ports = (LPMIXERLINE*) malloc((info->targetPortCount + info->sourcePortCount) * sizeof(LPMIXERLINE));
            success = (info->ports != NULL);
        }
        if (success && info->ports) {
            // first add the target MIXERLINEs to the array
            srcIndex = 0;
            for (dst = 0; dst < info->dstLineCount; dst++) {
                if (waveInLine != &info->dstLines[dst]) {
                    info->ports[srcIndex++] = &info->dstLines[dst];
                }
            }
            if (srcIndex != info->targetPortCount) {
                ERROR2("srcIndex=%d is NOT targetPortCount=%d !\n", srcIndex, info->targetPortCount);
            }
            //srcIndex = info->targetPortCount; // should be automatic!
            if (waveInLine) {
                // if the recording destination line has controls, add the line
                if (waveInHasControls) {
                    info->ports[srcIndex++] = waveInLine;
                }
                for (src = 0; src < (int) waveInLine->cConnections; src++) {
                    info->ports[srcIndex++] = &info->srcLines[src + waveInLine->dwUser];
                }
            }
            if (srcIndex != (info->targetPortCount + info->sourcePortCount)) {
                ERROR2("srcIndex=%d is NOT PortCount=%d !\n", srcIndex, (info->targetPortCount + info->sourcePortCount));
            }
        }
    }
    if (!success) {
        if (handle != NULL) {
            mixerClose(handle);
        }
        PORT_Close((void*) info);
        info = NULL;
    }
    return info;
}

void PORT_Close(void* id) {
    TRACE0("PORT_Close\n");
    if (id != NULL) {
        PortInfo* info = (PortInfo*) id;
        if (info->handle) {
            mixerClose(info->handle);
            info->handle = NULL;
        }
        if (info->dstLines) {
            free(info->dstLines);
            info->dstLines = NULL;
        }
        if (info->srcLines) {
            free(info->srcLines);
            info->srcLines=NULL;
        }
        if (info->ports) {
            free(info->ports);
            info->ports = NULL;
        }
        if (info->controlIDs) {
            free(info->controlIDs);
            info->controlIDs = NULL;
        }
        if (info->muxData) {
            free(info->muxData);
            info->muxData = NULL;
        }
        free(info);
    }
}

INT32 PORT_GetPortCount(void* id) {
    int ret = 0;
    PortInfo* info = (PortInfo*) id;
    if (info != NULL) {
        ret = info->targetPortCount + info->sourcePortCount;
    }
    return ret;
}

int componentType2type(DWORD componentType) {
    int ret = 0;
    if (componentType >= MIXERLINE_COMPONENTTYPE_DST_FIRST && componentType <= MIXERLINE_COMPONENTTYPE_DST_LAST) {
        ret = PORT_DST_UNKNOWN;
    }
    else if (componentType >= MIXERLINE_COMPONENTTYPE_SRC_FIRST && componentType <= MIXERLINE_COMPONENTTYPE_SRC_LAST) {
        ret = PORT_SRC_UNKNOWN;
    }
    // handle special cases
    switch (componentType) {
        case MIXERLINE_COMPONENTTYPE_DST_HEADPHONES:  ret = PORT_DST_HEADPHONE; break;
        case MIXERLINE_COMPONENTTYPE_DST_LINE:        ret = PORT_DST_LINE_OUT; break;
        case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:    ret = PORT_DST_SPEAKER; break;
        case MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC: ret = PORT_SRC_COMPACT_DISC; break;
        case MIXERLINE_COMPONENTTYPE_SRC_LINE:        ret = PORT_SRC_LINE_IN; break;
        case MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE:  ret = PORT_SRC_MICROPHONE; break;
    }
    return ret;
}

INT32 PORT_GetPortType(void* id, INT32 portIndex) {
    MIXERLINE* line;
    PortInfo* info = (PortInfo*) id;
    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
        line = info->ports[portIndex];
        if (line) {
            return componentType2type(line->dwComponentType);
        }
    }
    return 0;
}

INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) {
    MIXERLINE* line;
    PortInfo* info = (PortInfo*) id;

    if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) {
        line = info->ports[portIndex];
        if (line) {
            strncpy(name, line->szName, len-1);
            name[len-1] = 0;
            return TRUE;
        }
    }
    return FALSE;
}

int getControlCount(HMIXER handle, MIXERLINE* line, INT32* muxCount) {
    MIXERLINECONTROLS controls;
    int ret = 0;
    UINT i;

    controls.pamxctrl = NULL;
    if (getControlInfo(handle, line, &controls)) {
        for (i = 0; i < controls.cControls; i++) {
            switch (controls.pamxctrl[i].dwControlType & MIXERCONTROL_CT_CLASS_MASK) {
                case MIXERCONTROL_CT_CLASS_FADER   : // fall through
                case MIXERCONTROL_CT_CLASS_SLIDER  : // fall through
                case MIXERCONTROL_CT_CLASS_SWITCH  : // fall through
                case MIXERCONTROL_CT_CLASS_LIST    : ret++; break;
            }
            if ((controls.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_MIXER)
                 || (controls.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)) {
                ret += controls.pamxctrl[i].cMultipleItems;
                if (muxCount) {
                    (*muxCount) += controls.pamxctrl[i].cMultipleItems;
                }
            }
            else if ((controls.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
                    && (line->cChannels == 2)) {
                ret++; // for FAKE volume/balance pairs
            }
        }
    }
    if (controls.pamxctrl) {
        free(controls.pamxctrl);
        controls.pamxctrl = NULL;
    }
    return ret;
}

MIXERLINE* findDestLine(PortInfo* info, DWORD dwDestination) {
    int i;
    TRACE0(">findDestLine\n");
    for (i = 0; i < info->dstLineCount; i++) {
        if (info->dstLines[i].dwDestination == dwDestination) {
                TRACE0("<findDestLine\n");
            return &(info->dstLines[i]);
        }
    }
    TRACE0("<findDestLine NULL\n");
    return NULL;
}

void createMuxControl(PortInfo* info, PortControlCreator* creator, MIXERLINE* dstLine, DWORD srcLineID, void** controlObjects, int* controlCount) {
    MIXERLINECONTROLS controlInfos;
    MIXERCONTROLDETAILS* details;
    MIXERCONTROLDETAILS_LISTTEXT* listTextDetails = NULL;
    UINT listTextDetailCount = 0;
    PortControlID* controlID;
    UINT i, c;
    int m;

    TRACE0(">createMuxControl\n");
    // go through all controls of dstline
    controlInfos.pamxctrl = NULL;
    if (getControlInfo(info->handle, dstLine, &controlInfos)) {
        for (i = 0; i < controlInfos.cControls; i++) {
            if (((controlInfos.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_MIXER)
                 || (controlInfos.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX))
                && (controlInfos.pamxctrl[i].cMultipleItems > 0)) {
                if (info->usedControlIDs >= info->maxControlCount) {
                    ERROR1("not enough free controlIDs !! maxControlIDs = %d\n", info->maxControlCount);
                    break;
                }
                // get the details for this mux control
                controlID = &(info->controlIDs[info->usedControlIDs]);
                controlID->portInfo = info;
                if (controlInfos.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_MIXER) {
                    controlID->controlType = PORT_CONTROL_TYPE_MIXER;
                } else {
                    controlID->controlType = PORT_CONTROL_TYPE_MUX;
                }
                details = &(controlID->details);
                details->cbStruct = sizeof(MIXERCONTROLDETAILS);
                details->dwControlID = controlInfos.pamxctrl[i].dwControlID;
                details->cChannels = 1;
                details->cMultipleItems = controlInfos.pamxctrl[i].cMultipleItems;
                details->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
                if (!listTextDetails || (listTextDetailCount < (details->cMultipleItems * details->cChannels))) {
                    // need to allocate new listTextDetails
                    if (listTextDetails) {
                        free(listTextDetails);
                        listTextDetails = NULL;
                    }
                    listTextDetailCount = details->cMultipleItems * details->cChannels;
                    listTextDetails = (MIXERCONTROLDETAILS_LISTTEXT*) malloc(listTextDetailCount * sizeof(MIXERCONTROLDETAILS_LISTTEXT));
                    if (!listTextDetails) {
                        ERROR0("createMuxControl: unable to allocate listTextDetails!\n");
                        if (controlInfos.pamxctrl) {
                            free(controlInfos.pamxctrl);
                            controlInfos.pamxctrl = NULL;
                        }
                        TRACE0("<createMuxControl ERROR\n");
                        return;
                    }
                }
                details->paDetails = listTextDetails;
                if (mixerGetControlDetails((HMIXEROBJ) info->handle, details, MIXER_GETCONTROLDETAILSF_LISTTEXT | MIXER_OBJECTF_HMIXER) != MMSYSERR_NOERROR) {
                    ERROR0("createMuxControl: unable to get control details!\n");
                    continue;
                }
                // prevent freeing this data
                details->paDetails = NULL;
                // go through all mux items. If the line matches, then add a BOOLEAN select control
                for (c = 0; c < details->cMultipleItems; c++) {
                    if (listTextDetails[c].dwParam1 == srcLineID) {
                        // we have found the line in the MUX lines.
                        controlID->muxIndex = c;
                        details->cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
                        // now look if any other controlID was already part of this MUX line
                        for (m = 0; m < info->usedControlIDs; m++) {
                            if (info->controlIDs[m].details.dwControlID == details->dwControlID) {
                                // reuse the MUX Data
                                TRACE2("Reusing paDetails=%p of controlID[%d]\n", info->controlIDs[m].details.paDetails, m);
                                details->paDetails = info->controlIDs[m].details.paDetails;
                                break;
                            }
                        }
                        if (!details->paDetails) {
                            // first time this MUX control is used, allocate some of the muxData
                            details->paDetails = &(info->muxData[info->usedMuxData]);
                            TRACE2("Setting paDetails=%p to muxData[%d] \n", details->paDetails, info->usedMuxData);
                            info->usedMuxData += details->cMultipleItems;
                        }
                        // finally this line can be added
                        controlObjects[*controlCount] = (creator->newBooleanControl)(creator, controlID, CONTROL_TYPE_SELECT);
                        (*controlCount)++;
                        info->usedControlIDs++;
                        break;
                    }
                }
            }
        }
    }
    if (listTextDetails) {
        free(listTextDetails);
        listTextDetails = NULL;
    }
    if (controlInfos.pamxctrl) {
        free(controlInfos.pamxctrl);
        controlInfos.pamxctrl = NULL;
    }
    TRACE0("<createMuxControl\n");
}

void createPortControl(PortInfo* info, PortControlCreator* creator, MIXERCONTROL* mixerControl,
                       INT32 type, void** controlObjects, int* controlCount) {
    PortControlID* controlID;
    void* newControl = NULL;
    char* typeName = mixerControl->szName;
    float min;
    TRACE0(">createPortControl\n");

    // fill the ControlID structure and add this control
    if (info->usedControlIDs >= info->maxControlCount) {
        ERROR1("not enough free controlIDs !! maxControlIDs = %d\n", info->maxControlCount);
        return;
    }
    controlID = &(info->controlIDs[info->usedControlIDs]);
    controlID->portInfo = info;
    controlID->controlType = type;
    controlID->details.cbStruct = sizeof(MIXERCONTROLDETAILS);
    controlID->details.dwControlID = mixerControl->dwControlID;
    controlID->details.cChannels = 1; // uniform
    controlID->details.cMultipleItems = 0;
    switch (type) {
        case PORT_CONTROL_TYPE_BOOLEAN:
            TRACE0(" PORT_CONTROL_TYPE_BOOLEAN\n");
            controlID->details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
            controlID->details.paDetails = &(controlID->boolValue);
            if (mixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) {
                typeName = CONTROL_TYPE_MUTE;
            }
            newControl = (creator->newBooleanControl)(creator, controlID, typeName);
            break;
        case PORT_CONTROL_TYPE_SIGNED:
            TRACE0(" PORT_CONTROL_TYPE_SIGNED\n");
            controlID->details.cbDetails = sizeof(MIXERCONTROLDETAILS_SIGNED);
            controlID->details.paDetails = &(controlID->signedValue);
            controlID->min = (INT32) mixerControl->Bounds.lMinimum;
            controlID->max = (INT32) mixerControl->Bounds.lMaximum;
            if (mixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_PAN) {
                typeName = CONTROL_TYPE_PAN;
            }
            newControl = (creator->newFloatControl)(creator, controlID, typeName,
                -1.0f, 1.0f, 2.0f / (controlID->max - controlID->min + 1), "");
            break;
        case PORT_CONTROL_TYPE_FAKE_VOLUME:  // fall through
        case PORT_CONTROL_TYPE_FAKE_BALANCE: // fall through
        case PORT_CONTROL_TYPE_UNSIGNED:
            TRACE0(" PORT_CONTROL_TYPE_UNSIGNED\n");
            controlID->details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
            controlID->details.paDetails = &(controlID->unsignedValue[0]);
            controlID->min = (INT32) mixerControl->Bounds.dwMinimum;
            controlID->max = (INT32) mixerControl->Bounds.dwMaximum;
            min = 0.0f;
            if ((type == PORT_CONTROL_TYPE_FAKE_VOLUME)
               || (mixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)) {
                typeName = CONTROL_TYPE_VOLUME;
            }
            if (type == PORT_CONTROL_TYPE_FAKE_BALANCE) {
                typeName = CONTROL_TYPE_BALANCE;
                min = -1.0f;
            }
            if ((type == PORT_CONTROL_TYPE_FAKE_VOLUME)
               || (type == PORT_CONTROL_TYPE_FAKE_BALANCE)) {
                controlID->details.cChannels = 2;
            }
            TRACE0(" ....PORT_CONTROL_TYPE_UNSIGNED\n");
            newControl = (creator->newFloatControl)(creator, controlID, typeName,
                min, 1.0f, 1.0f / (controlID->max - controlID->min + 1), "");
            break;
        default:
            ERROR1("createPortControl: unknown type %d !", type);
            break;
    }
    if (newControl) {
        controlObjects[*controlCount] = newControl;
        (*controlCount)++;
        info->usedControlIDs++;
    }
    TRACE0("<createPortControl\n");
}

void createLineControls(PortInfo* info, PortControlCreator* creator, MIXERLINE* line, void** controlObjects, int* controlCount) {
    MIXERLINECONTROLS controlInfos;
    MIXERCONTROL* mixerControl;
    UINT i;
    INT32 type;

    TRACE1(">createLineControls for line %s\n", line->szName);
    // go through all controls of line
    controlInfos.pamxctrl = NULL;
    if (getControlInfo(info->handle, line, &controlInfos)) {
        for (i = 0; i < controlInfos.cControls; i++) {
            TRACE1("  %d\n", i);
            mixerControl = &(controlInfos.pamxctrl[i]);
            type = 0;
            switch (mixerControl->dwControlType) {
                case MIXERCONTROL_CONTROLTYPE_BOOLEAN  : // fall through
                case MIXERCONTROL_CONTROLTYPE_BUTTON   : // fall through
                case MIXERCONTROL_CONTROLTYPE_LOUDNESS : // fall through
                case MIXERCONTROL_CONTROLTYPE_MONO     : // fall through
                case MIXERCONTROL_CONTROLTYPE_MUTE     : // fall through
                case MIXERCONTROL_CONTROLTYPE_ONOFF    : // fall through
                case MIXERCONTROL_CONTROLTYPE_STEREOENH: type = PORT_CONTROL_TYPE_BOOLEAN; break;

                case MIXERCONTROL_CONTROLTYPE_PAN      : // fall through
                case MIXERCONTROL_CONTROLTYPE_QSOUNDPAN: // fall through
                case MIXERCONTROL_CONTROLTYPE_SLIDER   : type = PORT_CONTROL_TYPE_SIGNED; break;

                case MIXERCONTROL_CONTROLTYPE_BASS     : // fall through
                //case MIXERCONTROL_CONTROLTYPE_EQUALIZER: // fall through
                case MIXERCONTROL_CONTROLTYPE_FADER    : // fall through
                case MIXERCONTROL_CONTROLTYPE_TREBLE   : type = PORT_CONTROL_TYPE_UNSIGNED; break;
                case MIXERCONTROL_CONTROLTYPE_VOLUME   :
                    type = PORT_CONTROL_TYPE_UNSIGNED;
                    if (line->cChannels == 2 && ((mixerControl->fdwControl & MIXERCONTROL_CONTROLF_UNIFORM) == 0)) {
                        type = PORT_CONTROL_TYPE_FAKE_VOLUME;
                    }
                    break;
            }
            if (type != 0) {
                createPortControl(info, creator, mixerControl, type, controlObjects, controlCount);
                // create fake balance for fake volume
                if (type == PORT_CONTROL_TYPE_FAKE_VOLUME) {
                    createPortControl(info, creator, mixerControl, PORT_CONTROL_TYPE_FAKE_BALANCE, controlObjects, controlCount);
                }
            }
        }
    }
    if (controlInfos.pamxctrl) {
        free(controlInfos.pamxctrl);
        controlInfos.pamxctrl = NULL;
    }
    TRACE0("<createLineControls\n");
}

void addCompoundControl(PortInfo* info, PortControlCreator* creator, char* name, void** controlObjects, int* controlCount) {
    void* compControl;

    TRACE1(">addCompoundControl %d controls\n", *controlCount);
    if (*controlCount) {
        // create compound control and add it to the vector
        compControl = (creator->newCompoundControl)(creator, name, controlObjects, *controlCount);
        if (compControl) {
            TRACE1(" addCompoundControl: calling addControl %p\n", compControl);
            (creator->addControl)(creator, compControl);
        }
        *controlCount = 0;
    }
    TRACE0("<addCompoundControl\n");
}

void addAllControls(PortInfo* info, PortControlCreator* creator, void** controlObjects, int* controlCount) {
    int i = 0;

    TRACE0(">addAllControl\n");
    // go through all controls and add them to the vector
    for (i = 0; i < *controlCount; i++) {
        (creator->addControl)(creator, controlObjects[i]);
    }
    *controlCount = 0;
    TRACE0("<addAllControl\n");
}



void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
    MIXERLINE* line;
    PortInfo* info = (PortInfo*) id;
    int portCount = PORT_GetPortCount(id);
    void** controls = NULL;
    int controlCount;
    UINT i;

    TRACE4(">PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n", id, portIndex, info->controlIDs, info->maxControlCount);
    if ((portIndex >= 0) && (portIndex < portCount)) {
        line = info->ports[portIndex];
        if (line) {
            // if the memory isn't reserved for the control structures, allocate it
            if (!info->controlIDs) {
                int i, maxCount = 0, muxCount = 0;
                TRACE0("getControl: allocate mem\n");
                // get a maximum number of controls
                // first for all destination lines
                for (i = 0; i < info->dstLineCount; i++) {
                    MIXERLINE* thisLine = &(info->dstLines[i]);
                    maxCount += getControlCount(info->handle, thisLine, &muxCount);
                }
                // then all source lines
                for (i = 0; i < info->srcLineCount; i++) {
                    MIXERLINE* thisLine = &(info->srcLines[i]);
                    maxCount += getControlCount(info->handle, thisLine, &muxCount);
                }
                info->maxControlCount = maxCount;
                if (maxCount > 0) {
                    info->controlIDs = (PortControlID*) malloc(sizeof(PortControlID) * maxCount);
                } else {
                    // no ports: nothing to do !
                    return;
                }
                TRACE2("Creating muxData for %d elements and %d controlIDs.\n", muxCount, maxCount);
                if (muxCount > 0) {
                    info->muxData = (MIXERCONTROLDETAILS_BOOLEAN*) malloc(sizeof(MIXERCONTROLDETAILS_BOOLEAN) * muxCount);
                }
                if (!info->controlIDs || (muxCount && !info->muxData)) {
                    ERROR3("PORT_GetControls: info->controlIDs=%p, muxCount=%d,  info->muxData=%p !!\n", info->controlIDs, muxCount, info->muxData);
                    return;
                }
            }
            if (info->maxControlCount == 0) {
                return;
            }
            controls = (void*) malloc(info->maxControlCount * sizeof(void*));
            if (!controls) {
                ERROR0("PORT_GetControls: couldn't allocate controls!\n");
                return;
            }

            // add controls of this line
            controlCount = 0;
            // if this line is part of MUX, add the respective BOOLEANCONTROL as a control
            if ((line->fdwLine & MIXERLINE_LINEF_SOURCE) == MIXERLINE_LINEF_SOURCE) {
                MIXERLINE* dstLine = findDestLine(info, line->dwDestination);
                TRACE0("Port_getControls: this is a source line\n");
                if (dstLine) {
                    // selection controls (implemented as Mute control)
                    createMuxControl(info, creator, dstLine, line->dwLineID, controls, &controlCount);
                }
                // then add all controls in one compound control
                createLineControls(info, creator, line, controls, &controlCount);
                addCompoundControl(info, creator, line->szName, controls, &controlCount);
            } else {
                TRACE0("getControl: this is a dest line\n");
                // if this is a destination line, add its controls
                createLineControls(info, creator, line, controls, &controlCount);
                addAllControls(info, creator, controls, &controlCount);
                // then add all controls of its source lines as one compound control
                for (i = 0; i < line->cConnections; i++) {
                    // then add all controls
                    MIXERLINE* srcLine = &(info->srcLines[line->dwUser + i]);
                    TRACE1("PORT_getControls: add source line %d\n", i);
                    createLineControls(info, creator, srcLine, controls, &controlCount);
                    addCompoundControl(info, creator, srcLine->szName, controls, &controlCount);
                }
            }
        }
    }
    if (controls) {
        free(controls);
    }
    TRACE0("< PORT_getControls\n");
}

int getControlValue(PortControlID* controlID) {
    if (mixerGetControlDetails((HMIXEROBJ) controlID->portInfo->handle, &(controlID->details),
            MIXER_GETCONTROLDETAILSF_VALUE | MIXER_OBJECTF_HMIXER) != MMSYSERR_NOERROR) {
        ERROR0("getControlValue: unable to get control details!\n");
        //ERROR3("   cbStruct=%d, dwControlID=%d, cChannels=%d, ", controlID->details.cbStruct, controlID->details.dwControlID, controlID->details.cChannels);
        //ERROR2("   cMultipleItems=%d, cbDetails=%d\n", controlID->details.cMultipleItems, controlID->details.cbDetails);
        return FALSE;
    }
    return TRUE;
}

int setControlValue(PortControlID* controlID) {
    if (mixerSetControlDetails((HMIXEROBJ) controlID->portInfo->handle, &(controlID->details),
            MIXER_SETCONTROLDETAILSF_VALUE | MIXER_OBJECTF_HMIXER) != MMSYSERR_NOERROR) {
        ERROR0("setControlValue: unable to set control details!\n");
        //ERROR3("   cbStruct=%d, dwControlID=%d, cChannels=%d, ", controlID->details.cbStruct, controlID->details.dwControlID, controlID->details.cChannels);
        //ERROR2("   cMultipleItems=%d, cbDetails=%d\n", controlID->details.cMultipleItems, controlID->details.cbDetails);
        return FALSE;
    }
    return TRUE;
}

INT32 PORT_GetIntValue(void* controlIDV) {
    PortControlID* controlID = (PortControlID*) controlIDV;
    MIXERCONTROLDETAILS_BOOLEAN* bools;
    int ret = 0;
    if (getControlValue(controlID)) {
        switch (controlID->controlType) {
        case PORT_CONTROL_TYPE_MUX:   // fall through
        case PORT_CONTROL_TYPE_MIXER:
                bools = (MIXERCONTROLDETAILS_BOOLEAN*) controlID->details.paDetails;
                ret = (bools[controlID->muxIndex].fValue)?TRUE:FALSE;
                break;
        case PORT_CONTROL_TYPE_BOOLEAN:
                ret = (controlID->boolValue.fValue)?TRUE:FALSE;
                break;
        default: ERROR1("PORT_GetIntValue: wrong controlType=%d !\n", controlID->controlType);
        }
    }
    return ret;
}

void PORT_SetIntValue(void* controlIDV, INT32 value) {
    PortControlID* controlID = (PortControlID*) controlIDV;
    MIXERCONTROLDETAILS_BOOLEAN* bools;
    UINT i;

    switch (controlID->controlType) {
    case PORT_CONTROL_TYPE_MUX:
        if (!value) {
            // cannot unselect a MUX line
            return;
        }
        if (!getControlValue(controlID)) {
            return;
        }
        bools = (MIXERCONTROLDETAILS_BOOLEAN*) controlID->details.paDetails;
        for (i = 0; i < controlID->details.cMultipleItems; i++) {
            bools[i].fValue = (i == (UINT) controlID->muxIndex)?TRUE:FALSE;
        }
        break;
    case PORT_CONTROL_TYPE_MIXER:
        if (!getControlValue(controlID)) {
            return;
        }
        bools = (MIXERCONTROLDETAILS_BOOLEAN*) controlID->details.paDetails;
        bools[controlID->muxIndex].fValue = (value?TRUE:FALSE);
        break;
    case PORT_CONTROL_TYPE_BOOLEAN:
        controlID->boolValue.fValue = (value?TRUE:FALSE);
        break;
    default:
        ERROR1("PORT_SetIntValue: wrong controlType=%d !\n", controlID->controlType);
        return;
    }
    setControlValue(controlID);
}

float getFakeBalance(PortControlID* controlID) {
    float volL, volR;
    float range = (float) (controlID->max - controlID->min);
    // pan is the ratio of left and right
    volL = (((float) (controlID->unsignedValue[0].dwValue - controlID->min)) / range);
    volR = (((float) (controlID->unsignedValue[1].dwValue - controlID->min)) / range);
    if (volL > volR) {
        return -1.0f + (volR / volL);
    }
    else if (volR > volL) {
        return 1.0f - (volL / volR);
    }
    return 0.0f;
}

float getFakeVolume(PortControlID* controlID) {
    // volume is the greater value of both
    UINT vol = controlID->unsignedValue[0].dwValue;
    if (controlID->unsignedValue[1].dwValue > vol) {
        vol = controlID->unsignedValue[1].dwValue;
    }
    return (((float) (vol - controlID->min)) / (controlID->max - controlID->min));
}

/*
 * sets the unsigned values for left and right volume according to
 * the given volume (0...1) and balance (-1..0..+1)
 */
void setFakeVolume(PortControlID* controlID, float vol, float bal) {
    vol = vol * (controlID->max - controlID->min);
    if (bal < 0.0f) {
        controlID->unsignedValue[0].dwValue = (UINT) (vol  + 0.5f) + controlID->min;
        controlID->unsignedValue[1].dwValue = (UINT) ((vol * (bal + 1.0f)) + 0.5f) + controlID->min;
    } else {
        controlID->unsignedValue[1].dwValue = (UINT) (vol  + 0.5f) + controlID->min;
        controlID->unsignedValue[0].dwValue = (UINT) ((vol * (1.0f - bal)) + 0.5f) + controlID->min;
    }
}

float PORT_GetFloatValue(void* controlIDV) {
    PortControlID* controlID = (PortControlID*) controlIDV;
    float ret = 0.0f;
    float range = (float) (controlID->max - controlID->min);
    if (getControlValue(controlID)) {
        switch (controlID->controlType) {
        case PORT_CONTROL_TYPE_SIGNED:
                ret = ((float) controlID->signedValue.lValue) / controlID->max;
                break;
        case PORT_CONTROL_TYPE_UNSIGNED:
                ret = (((float) (controlID->unsignedValue[0].dwValue - controlID->min)) / range);
                break;
        case PORT_CONTROL_TYPE_FAKE_VOLUME:
                ret = getFakeVolume(controlID);
                break;
        case PORT_CONTROL_TYPE_FAKE_BALANCE:
                ret = getFakeBalance(controlID);
                break;
        default: ERROR1("PORT_GetFloatValue: wrong controlType=%d !\n", controlID->controlType);
        }
    }
    return ret;
}

void PORT_SetFloatValue(void* controlIDV, float value) {
    PortControlID* controlID = (PortControlID*) controlIDV;
    float range = (float) (controlID->max - controlID->min);
    switch (controlID->controlType) {
    case PORT_CONTROL_TYPE_SIGNED:
        controlID->signedValue.lValue = (INT32) ((value * controlID->max) + 0.5f);
        break;
    case PORT_CONTROL_TYPE_UNSIGNED:
        controlID->unsignedValue[0].dwValue = (INT32) ((value * range) + 0.5f) + controlID->min;
        break;
    case PORT_CONTROL_TYPE_FAKE_VOLUME:
        if (!getControlValue(controlID)) {
            return;
        }
        setFakeVolume(controlID, value, getFakeBalance(controlID));
        break;
    case PORT_CONTROL_TYPE_FAKE_BALANCE:
        if (!getControlValue(controlID)) {
            return;
        }
        setFakeVolume(controlID, getFakeVolume(controlID), value);
        break;
    default:
        ERROR1("PORT_SetFloatValue: wrong controlType=%d !\n", controlID->controlType);
        return;
    }
    setControlValue(controlID);
}

#endif // USE_PORTS
