Ignore:
Timestamp:
May 23, 2002, 10:42:06 PM (23 years ago)
Author:
sandervl
Message:

mixer updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/winmm/mixer.cpp

    r8477 r8479  
    1 /* $Id: mixer.cpp,v 1.13 2002-05-23 13:50:15 sandervl Exp $ */
     1/* $Id: mixer.cpp,v 1.14 2002-05-23 20:42:06 sandervl Exp $ */
    22
    33/*
     
    1010 * NOTE: Not really flexible (capabilities, > 1 audio card)
    1111 *
     12 * Some portions borrowed from Wine (X11): (dll\winmm\mmsystem.c)
     13 * (mixerGetLineControlsW/mixerGetControlDetailsW)
     14 * Copyright 1993 Martin Ayotte
     15 *                Eric POUECH
     16 *
    1217 * Project Odin Software License can be found in LICENSE.TXT
    1318 *
     
    3641#include "dbglocal.h"
    3742
    38 static BOOL mixerAddControl(DWORD dwControl);
    39 static BOOL mixerAddSource(DWORD dwDest);
    40 static BOOL mixerAddDestination(DWORD dwSource);
    41 
    42 static MIXERLINEA    mixerDest[MAX_MIXER_DESTINATIONS] = {0};
    43 static MIXERLINEA    mixerSource[MAX_MIXER_SOURCES]    = {0};
    44 static MIXERCONTROLA mixerControls[MAX_MIXER_CONTROLS] = {0};
    45 static int           nrDestinations                    = 0;
    46 static int           nrSources                         = 0;
    47 static int           nrControls                        = 0;
    48 static int           nrLineOutInputs                   = 0;
    49 static int           nrLineOutControls                 = 0;
    50 static int           nrWaveInInputs                    = 0;
    51 static int           nrWaveInControls                  = 0;
    52 static int           nrSPDIFInputs                     = 0;
    53 static int           nrSPDIFControls                   = 0;
     43static BOOL        mixerAddControl(MIXERLINEA *pDestLine, DWORD dwControl, MIXERLINEA *pSrcLine);
     44static MIXERLINEA *mixerAddSource(MIXERLINEA *pDestLine, DWORD dwSource);
     45static MIXERLINEA *mixerAddDestination(DWORD dwDest);
     46
     47//array of destination mixer lines
     48static MIXERLINEA    mixerDest[MAX_MIXER_DESTINATIONS]                          = {0};
     49//array of connected sources to destinations
     50static int           mixerDestInputs[MAX_MIXER_DESTINATIONS][MAX_MIXER_SOURCES] = {-1};
     51//array of source mixer lines
     52static MIXERLINEA    mixerSource[MAX_MIXER_SOURCES]                             = {0};
     53//array of controls connected to mixer lines
     54static int           mixerLineControls[MAX_MIXER_LINES][MAX_SOURCE_CONTROLS]    = {-1};
     55//array of all mixer lines
     56static MIXERLINEA   *pmixerLines[MAX_MIXER_LINES]                               = {NULL};
     57//mapping from src to line id
     58static int           mixerSourceLineId[MAX_MIXER_SOURCES]                       = {-1};
     59//array of all mixer controls
     60static MIXERCONTROLA mixerControls[MAX_MIXER_CONTROLS]                          = {0};
     61
     62static int           nrDestinations    = 0;
     63static int           nrSources         = 0;
     64static int           nrControls        = 0;
     65static int           nrLines           = 0;
     66static int           nrLineOutInputs   = 0;
     67static int           nrWaveInInputs    = 0;
    5468
    5569/******************************************************************************/
     
    5872{
    5973    DWORD       lineID, controlType;
     74    DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
    6075   
     76    if(fdwDetails == MIXER_OBJECTF_HMIXER) {
     77        if(!pMixInfo) {
     78            return MMSYSERR_INVALHANDLE;
     79        }
     80    }
     81    else
     82    if(fdwDetails == MIXER_OBJECTF_MIXER) {
     83        if(hmxobj > 0) {
     84            return MMSYSERR_NODRIVER;
     85        }
     86    }
     87
    6188    if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
    6289
     
    75102/******************************************************************************/
    76103/******************************************************************************/
    77 MMRESULT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)
    78 {
    79     dprintf(("WINMM:mixerGetControlDetailsW - stub\n" ));
    80     return MIXERR_INVALCONTROL;
     104MMRESULT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
     105{
     106    DWORD ret = MMSYSERR_NOTENABLED;
     107
     108    if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
     109            return MMSYSERR_INVALPARAM;
     110
     111    switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
     112    case MIXER_GETCONTROLDETAILSF_VALUE:
     113            /* can safely use W structure as it is, no string inside */
     114            ret = mixerGetControlDetailsA(hmxobj, lpmcd, fdwDetails);
     115            break;
     116
     117    case MIXER_GETCONTROLDETAILSF_LISTTEXT:
     118        {
     119            LPVOID      paDetailsW = lpmcd->paDetails;
     120            int         size = max(1, lpmcd->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
     121
     122            if (lpmcd->u.cMultipleItems != 0 && lpmcd->u.cMultipleItems != lpmcd->u.hwndOwner) {
     123                    size *= lpmcd->u.cMultipleItems;
     124            }
     125            lpmcd->paDetails = HeapAlloc(GetProcessHeap(), 0, size);
     126            /* set up lpmcd->paDetails */
     127            ret = mixerGetControlDetailsA(hmxobj, lpmcd, fdwDetails);
     128            /* copy from lpmcd->paDetails back to paDetailsW; */
     129            HeapFree(GetProcessHeap(), 0, lpmcd->paDetails);
     130            lpmcd->paDetails = paDetailsW;
     131            break;
     132        }
     133    default:
     134        dprintf(("Unsupported fdwDetails=0x%08lx\n", fdwDetails));
     135        break;
     136    }
     137
     138    return ret;
    81139}
    82140/******************************************************************************/
     
    87145    DWORD       lineID, controlType;
    88146    int         val;
     147    DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
    89148     
     149    if(fdwDetails == MIXER_OBJECTF_HMIXER) {
     150        if(!pMixInfo) {
     151            return MMSYSERR_INVALHANDLE;
     152        }
     153    }
     154    else
     155    if(fdwDetails == MIXER_OBJECTF_MIXER) {
     156        if(hmxobj > 0) {
     157            return MMSYSERR_NODRIVER;
     158        }
     159    }
    90160    if (lpmcd == NULL) return MMSYSERR_INVALPARAM;
    91161   
     
    110180    DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
    111181
    112     if(!pMixInfo) {
    113         return MMSYSERR_INVALHANDLE;
     182    if(fdwControls == MIXER_OBJECTF_HMIXER) {
     183        if(!pMixInfo) {
     184            return MMSYSERR_INVALHANDLE;
     185        }
     186    }
     187    else
     188    if(fdwControls == MIXER_OBJECTF_MIXER) {
     189        if(hmxobj > 0) {
     190            return MMSYSERR_NODRIVER;
     191        }
    114192    }
    115193
     
    122200    {
    123201    case MIXER_GETLINECONTROLSF_ALL:
    124             if (lpMlc->cControls != 2) {
    125             dwRet = MMSYSERR_INVALPARAM;
    126         }
    127         else {
    128             }
     202        dprintf(("MIXER_GETLINECONTROLSF_ALL"));
     203        return MIXERR_INVALLINE;
    129204            break;
     205
    130206    case MIXER_GETLINECONTROLSF_ONEBYID:
     207        dprintf(("MIXER_GETLINECONTROLSF_ONEBYID %x", lpMlc->u.dwControlID));
     208        if(lpMlc->cControls != 1 || lpMlc->cbmxctrl != sizeof(MIXERCONTROLA)) {
     209            dprintf(("invalid parameters"));
     210            return MMSYSERR_INVALPARAM;
     211        }
     212        if(lpMlc->u.dwControlID >= nrControls) {
     213            dprintf(("invalid control"));
     214            return MIXERR_INVALCONTROL;
     215        }
     216        memcpy(lpMlc->pamxctrl, &mixerControls[lpMlc->u.dwControlID], sizeof(MIXERCONTROLA));
     217        dprintf(("found control %s (%s)", lpMlc->pamxctrl->szName, lpMlc->pamxctrl->szShortName));
    131218            break;
    132219
    133220    case MIXER_GETLINECONTROLSF_ONEBYTYPE:
    134             switch (lpMlc->u.dwControlType & MIXERCONTROL_CT_CLASS_MASK) {
    135             case MIXERCONTROL_CT_CLASS_FADER:
    136                 break;
    137             case MIXERCONTROL_CT_CLASS_SWITCH:
    138                 break;
     221    {
     222        dprintf(("MIXER_GETLINECONTROLSF_ONEBYTYPE %x %d", lpMlc->u.dwControlType, lpMlc->dwLineID));
     223        if(lpMlc->dwLineID >= nrLines) {
     224            dprintf(("ERROR: Invalid line %d", lpMlc->dwLineID));
     225            return MIXERR_INVALLINE;
     226        }
     227#ifdef DEBUG
     228            switch (lpMlc->u.dwControlType) {
     229        case MIXERCONTROL_CONTROLTYPE_CUSTOM:
     230            dprintf(("MIXERCONTROL_CONTROLTYPE_CUSTOM"));
     231            break;
     232        case MIXERCONTROL_CONTROLTYPE_BOOLEANMETER:
     233            dprintf(("MIXERCONTROL_CONTROLTYPE_BOOLEANMETER"));
     234            break;
     235        case MIXERCONTROL_CONTROLTYPE_SIGNEDMETER:
     236            dprintf(("MIXERCONTROL_CONTROLTYPE_SIGNEDMETER"));
     237            break;
     238        case MIXERCONTROL_CONTROLTYPE_PEAKMETER:
     239            dprintf(("MIXERCONTROL_CONTROLTYPE_PEAKMETER"));
     240            break;
     241        case MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER:
     242            dprintf(("MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER"));
     243            break;
     244        case MIXERCONTROL_CONTROLTYPE_BOOLEAN:
     245            dprintf(("MIXERCONTROL_CONTROLTYPE_BOOLEAN"));
     246            break;
     247        case MIXERCONTROL_CONTROLTYPE_ONOFF:
     248            dprintf(("MIXERCONTROL_CONTROLTYPE_ONOFF"));
     249            break;
     250        case MIXERCONTROL_CONTROLTYPE_MUTE:
     251            dprintf(("MIXERCONTROL_CONTROLTYPE_MUTE"));
     252            break;
     253        case MIXERCONTROL_CONTROLTYPE_MONO:
     254            dprintf(("MIXERCONTROL_CONTROLTYPE_MONO"));
     255            break;
     256        case MIXERCONTROL_CONTROLTYPE_LOUDNESS:
     257            dprintf(("MIXERCONTROL_CONTROLTYPE_LOUDNESS"));
     258            break;
     259        case MIXERCONTROL_CONTROLTYPE_STEREOENH:
     260            dprintf(("MIXERCONTROL_CONTROLTYPE_STEREOENH"));
     261            break;
     262        case MIXERCONTROL_CONTROLTYPE_BUTTON:
     263            dprintf(("MIXERCONTROL_CONTROLTYPE_BUTTON"));
     264            break;
     265        case MIXERCONTROL_CONTROLTYPE_DECIBELS:
     266            dprintf(("MIXERCONTROL_CONTROLTYPE_DECIBELS"));
     267            break;
     268        case MIXERCONTROL_CONTROLTYPE_SIGNED:
     269            dprintf(("MIXERCONTROL_CONTROLTYPE_SIGNED"));
     270            break;
     271        case MIXERCONTROL_CONTROLTYPE_UNSIGNED:
     272            dprintf(("MIXERCONTROL_CONTROLTYPE_UNSIGNED"));
     273            break;
     274        case MIXERCONTROL_CONTROLTYPE_PERCENT:
     275            dprintf(("MIXERCONTROL_CONTROLTYPE_PERCENT"));
     276            break;
     277        case MIXERCONTROL_CONTROLTYPE_SLIDER:
     278            dprintf(("MIXERCONTROL_CONTROLTYPE_SLIDER"));
     279            break;
     280        case MIXERCONTROL_CONTROLTYPE_PAN:
     281            dprintf(("MIXERCONTROL_CONTROLTYPE_PAN"));
     282            break;
     283        case MIXERCONTROL_CONTROLTYPE_QSOUNDPAN:
     284            dprintf(("MIXERCONTROL_CONTROLTYPE_QSOUNDPAN"));
     285            break;
     286        case MIXERCONTROL_CONTROLTYPE_FADER:
     287            dprintf(("MIXERCONTROL_CONTROLTYPE_FADER"));
     288            break;
     289        case MIXERCONTROL_CONTROLTYPE_VOLUME:
     290            dprintf(("MIXERCONTROL_CONTROLTYPE_VOLUME"));
     291            break;
     292        case MIXERCONTROL_CONTROLTYPE_BASS:
     293            dprintf(("MIXERCONTROL_CONTROLTYPE_BASS"));
     294            break;
     295        case MIXERCONTROL_CONTROLTYPE_TREBLE:
     296            dprintf(("MIXERCONTROL_CONTROLTYPE_TREBLE"));
     297            break;
     298        case MIXERCONTROL_CONTROLTYPE_EQUALIZER:
     299            dprintf(("MIXERCONTROL_CONTROLTYPE_EQUALIZER"));
     300            break;
     301        case MIXERCONTROL_CONTROLTYPE_SINGLESELECT:
     302            dprintf(("MIXERCONTROL_CONTROLTYPE_SINGLESELECT"));
     303            break;
     304        case MIXERCONTROL_CONTROLTYPE_MUX:
     305            dprintf(("MIXERCONTROL_CONTROLTYPE_MUX"));
     306            break;
     307        case MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT:
     308            dprintf(("MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT"));
     309            break;
     310        case MIXERCONTROL_CONTROLTYPE_MIXER:
     311            dprintf(("MIXERCONTROL_CONTROLTYPE_MIXER"));
     312            break;
     313        case MIXERCONTROL_CONTROLTYPE_MICROTIME:
     314            dprintf(("MIXERCONTROL_CONTROLTYPE_MICROTIME"));
     315            break;
     316        case MIXERCONTROL_CONTROLTYPE_MILLITIME:
     317            dprintf(("MIXERCONTROL_CONTROLTYPE_MILLITIME"));
     318            break;
    139319            default:
    140             dwRet = MMSYSERR_INVALPARAM;
     320            return MMSYSERR_INVALPARAM;
    141321        }
    142         break;
    143 
     322#endif
     323        int idx;
     324
     325        for(int i=0;i<MAX_SOURCE_CONTROLS;i++) {
     326            idx = mixerLineControls[lpMlc->dwLineID][i];
     327            if(idx == -1) break;
     328            if(mixerControls[idx].dwControlType == lpMlc->u.dwControlType) {
     329                memcpy(lpMlc->pamxctrl, &mixerControls[idx], sizeof(MIXERCONTROLA));
     330                dprintf(("found control %s (%s)", lpMlc->pamxctrl->szName, lpMlc->pamxctrl->szShortName));
     331                return MMSYSERR_NOERROR;
     332            }
     333
     334        }
     335        return MIXERR_INVALLINE;
     336    }
    144337    default:
    145338            dprintf(("Unknown flag %08lx\n", fdwControls & MIXER_GETLINECONTROLSF_QUERYMASK));
    146339            dwRet = MMSYSERR_INVALPARAM;
     340        break;
    147341    }
    148342
     
    151345/******************************************************************************/
    152346/******************************************************************************/
    153 MMRESULT WINAPI mixerGetLineControlsW(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls)
     347MMRESULT WINAPI mixerGetLineControlsW(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW lpmlcW, DWORD fdwControls)
     348{
     349    MIXERLINECONTROLSA  mlcA;
     350    DWORD               ret;
     351    int                 i;
     352
     353    if (lpmlcW == NULL || lpmlcW->cbStruct != sizeof(*lpmlcW) || lpmlcW->cbmxctrl != sizeof(MIXERCONTROLW))
     354            return MMSYSERR_INVALPARAM;
     355
     356    mlcA.cbStruct = sizeof(mlcA);
     357    mlcA.dwLineID = lpmlcW->dwLineID;
     358    mlcA.u.dwControlID = lpmlcW->u.dwControlID;
     359    mlcA.u.dwControlType = lpmlcW->u.dwControlType;
     360    mlcA.cControls = lpmlcW->cControls;
     361    mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
     362    mlcA.pamxctrl = (MIXERCONTROLA *)HeapAlloc(GetProcessHeap(), 0, mlcA.cControls * mlcA.cbmxctrl);
     363
     364    ret = mixerGetLineControlsA(hmxobj, &mlcA, fdwControls);
     365
     366    if (ret == MMSYSERR_NOERROR) {
     367            lpmlcW->dwLineID = mlcA.dwLineID;
     368            lpmlcW->u.dwControlID = mlcA.u.dwControlID;
     369            lpmlcW->u.dwControlType = mlcA.u.dwControlType;
     370            lpmlcW->cControls = mlcA.cControls;
     371       
     372        for (i = 0; i < mlcA.cControls; i++) {
     373                lpmlcW->pamxctrl[i].cbStruct = sizeof(MIXERCONTROLW);
     374                lpmlcW->pamxctrl[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
     375                lpmlcW->pamxctrl[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
     376                lpmlcW->pamxctrl[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
     377                lpmlcW->pamxctrl[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
     378            MultiByteToWideChar( CP_ACP, 0, mlcA.pamxctrl[i].szShortName, -1,
     379                                 lpmlcW->pamxctrl[i].szShortName,
     380                                 sizeof(lpmlcW->pamxctrl[i].szShortName)/sizeof(WCHAR) );
     381            MultiByteToWideChar( CP_ACP, 0, mlcA.pamxctrl[i].szName, -1,
     382                                 lpmlcW->pamxctrl[i].szName,
     383                                 sizeof(lpmlcW->pamxctrl[i].szName)/sizeof(WCHAR) );
     384                /* sizeof(lpmlcW->pamxctrl[i].Bounds) ==
     385                 * sizeof(mlcA.pamxctrl[i].Bounds) */
     386                memcpy(&lpmlcW->pamxctrl[i].Bounds, &mlcA.pamxctrl[i].Bounds,
     387                           sizeof(mlcA.pamxctrl[i].Bounds));
     388                /* sizeof(lpmlcW->pamxctrl[i].Metrics) ==
     389                 * sizeof(mlcA.pamxctrl[i].Metrics) */
     390                memcpy(&lpmlcW->pamxctrl[i].Metrics, &mlcA.pamxctrl[i].Metrics,
     391                           sizeof(mlcA.pamxctrl[i].Metrics));
     392            }
     393    }
     394
     395    HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
     396    return ret;
     397}
     398/******************************************************************************/
     399/******************************************************************************/
     400MMRESULT WINAPI mixerGetLineInfoA(HMIXEROBJ hmxobj, LPMIXERLINEA lpMl, DWORD fdwInfo)
    154401{
    155402    DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
    156403
    157     if(!pMixInfo) {
    158         return MMSYSERR_INVALHANDLE;
    159     }
    160 
    161     dprintf(("WINMM:mixerGetGetLineControlsW - stub\n" ));
    162     return MIXERR_INVALLINE;
    163 }
    164 /******************************************************************************/
    165 /******************************************************************************/
    166 MMRESULT WINAPI mixerGetLineInfoA(HMIXEROBJ hmxobj, LPMIXERLINEA lpMl, DWORD fdwInfo)
    167 {
    168     DEVICE_STRUCT *pMixInfo = (DEVICE_STRUCT *)hmxobj;
    169 
    170     if(!pMixInfo) {
    171         return MMSYSERR_INVALHANDLE;
     404    if(fdwInfo & MIXER_OBJECTF_HMIXER) {
     405        if(!pMixInfo) {
     406            return MMSYSERR_INVALHANDLE;
     407        }
     408    }
     409    else
     410    if((fdwInfo & MIXER_OBJECTF_MIXER) == MIXER_OBJECTF_MIXER) {
     411        if(hmxobj > 0) {
     412            return MMSYSERR_NODRIVER;
     413        }
    172414    }
    173415
     
    180422    {
    181423    case MIXER_GETLINEINFOF_DESTINATION:
    182         dprintf(("MIXER_GETLINEINFOF_DESTINATION"));
     424        dprintf(("MIXER_GETLINEINFOF_DESTINATION %d", lpMl->dwDestination));
    183425        if(lpMl->dwDestination >= nrDestinations) {
    184             dprintf(("ERROR: Invalid desitnation %d", lpMl->dwDestination));
     426            dprintf(("ERROR: Invalid destination %d", lpMl->dwDestination));
    185427            return MMSYSERR_INVALPARAM;
    186428        }
    187429        memcpy(lpMl, &mixerDest[lpMl->dwDestination], sizeof(MIXERLINEA));
     430        dprintf(("found line %s (%s) connections %d controls %d", lpMl->szName, lpMl->szShortName, lpMl->cConnections, lpMl->cControls));
    188431        break;
    189432
    190433    case MIXER_GETLINEINFOF_LINEID:
    191         dprintf(("MIXER_GETLINEINFOF_LINEID"));
     434        dprintf(("MIXER_GETLINEINFOF_LINEID %d", lpMl->dwLineID));
     435        if(lpMl->dwLineID >= nrLines) {
     436            dprintf(("ERROR: Invalid destination %d", lpMl->dwLineID));
     437            return MIXERR_INVALLINE;
     438        }
     439        memcpy(lpMl, pmixerLines[lpMl->dwLineID], sizeof(MIXERLINEA));
     440        dprintf(("found line %s (%s) connections %d controls %d", lpMl->szName, lpMl->szShortName, lpMl->cConnections, lpMl->cControls));
    192441        break;
    193442
    194443    case MIXER_GETLINEINFOF_SOURCE:
    195         dprintf(("MIXER_GETLINEINFOF_SOURCE"));
     444        dprintf(("MIXER_GETLINEINFOF_SOURCE %d %d", lpMl->dwDestination, lpMl->dwSource));
    196445        if(lpMl->dwDestination >= nrDestinations) {
    197             dprintf(("ERROR: Invalid desitnation %d", lpMl->dwDestination));
    198             return MMSYSERR_INVALPARAM;
    199         }
     446            dprintf(("ERROR: Invalid destination %d", lpMl->dwDestination));
     447            return MIXERR_INVALLINE;
     448        }
     449        if(lpMl->dwSource >= MIXER_SRC_MAX) {
     450            dprintf(("ERROR: Invalid destination %d", lpMl->dwDestination));
     451            return MIXERR_INVALLINE;
     452        }
     453        if(mixerDestInputs[lpMl->dwDestination][lpMl->dwSource] == -1) {
     454            dprintf(("ERROR: Invalid destination %d", lpMl->dwDestination));
     455            return MIXERR_INVALLINE;
     456        }
     457        memcpy(lpMl, &mixerSource[mixerDestInputs[lpMl->dwDestination][lpMl->dwSource]], sizeof(MIXERLINEA));
     458        dprintf(("found line %s (%s) connections %d controls %d", lpMl->szName, lpMl->szShortName, lpMl->cConnections, lpMl->cControls));
    200459        break;
    201460
     
    204463            switch (lpMl->dwComponentType)
    205464            {
    206             case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
    207                 break;
    208         case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT:
    209                 break;
     465        case MIXERLINE_COMPONENTTYPE_DST_UNDEFINED:
     466            dprintf(("MIXERLINE_COMPONENTTYPE_DST_UNDEFINED"));
     467            break;
     468        case MIXERLINE_COMPONENTTYPE_DST_DIGITAL:
     469            dprintf(("MIXERLINE_COMPONENTTYPE_DST_DIGITAL"));
     470            break;
     471        case MIXERLINE_COMPONENTTYPE_DST_LINE:
     472            dprintf(("MIXERLINE_COMPONENTTYPE_DST_LINE"));
     473            break;
     474        case MIXERLINE_COMPONENTTYPE_DST_MONITOR:
     475            dprintf(("MIXERLINE_COMPONENTTYPE_DST_MONITOR"));
     476            break;
     477        case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
     478            dprintf(("MIXERLINE_COMPONENTTYPE_DST_SPEAKERS"));
     479            break;
     480        case MIXERLINE_COMPONENTTYPE_DST_HEADPHONES:
     481            dprintf(("MIXERLINE_COMPONENTTYPE_DST_HEADPHONES"));
     482            break;
     483        case MIXERLINE_COMPONENTTYPE_DST_TELEPHONE:
     484            dprintf(("MIXERLINE_COMPONENTTYPE_DST_TELEPHONE"));
     485            break;
     486        case MIXERLINE_COMPONENTTYPE_DST_WAVEIN:
     487            dprintf(("MIXERLINE_COMPONENTTYPE_DST_WAVEIN"));
     488            break;
     489        case MIXERLINE_COMPONENTTYPE_DST_VOICEIN:
     490            dprintf(("MIXERLINE_COMPONENTTYPE_DST_VOICEIN"));
     491            break;
    210492        default:
    211493                dprintf(("Unhandled component type (%08lx)\n", lpMl->dwComponentType));
    212494                return MMSYSERR_INVALPARAM;
    213495            }
     496        return MIXERR_INVALLINE;
    214497            break;
    215498
    216499    case MIXER_GETLINEINFOF_TARGETTYPE:
    217500            dprintf(("_TARGETTYPE not implemented yet.\n"));
     501        return MIXERR_INVALLINE;
    218502            break;
    219503    default:
    220504            dprintf(("Unknown flag (%08lx)\n", fdwInfo & MIXER_GETLINEINFOF_QUERYMASK));
     505            return MMSYSERR_INVALPARAM;
    221506            break;
    222507    }   
     
    231516    MMRESULT       result;
    232517
    233     if(!pMixInfo) {
    234         return MMSYSERR_INVALHANDLE;
    235     }
    236518    line.cbStruct              = sizeof(MIXERLINEA);
    237519    line.cChannels             = pmxl->cChannels;
     
    281563{
    282564    dprintf(("WINMM:mixerMessage - stub\n" ));
    283     return 0;
     565    return MMSYSERR_INVALPARAM;
    284566}
    285567/******************************************************************************/
     
    425707BOOL mixerInit()
    426708{
     709    MIXERLINEA *pDestLine;
     710
    427711    if(!fMMPMAvailable) return TRUE;
     712
     713    memset(mixerSourceLineId, -1, sizeof(mixerSourceLineId));
     714    memset(mixerLineControls, -1, sizeof(mixerLineControls));
     715    memset(mixerDestInputs, -1, sizeof(mixerDestInputs));
    428716
    429717    if(OSLibMixerOpen() == FALSE) {
    430718        //Line out destination
    431         mixerAddControl(MIX_CTRL_VOL_OUT_LINE);
    432         mixerAddControl(MIX_CTRL_MUTE_OUT_LINE);
    433         //muast add after all controls (for counting controls & inputs)
    434         mixerAddDestination(MIXER_DEST_LINEOUT);
     719        pDestLine = mixerAddDestination(MIXER_DEST_LINEOUT);
     720
     721        mixerAddControl(pDestLine, MIX_CTRL_VOL_OUT_LINE, pDestLine);
     722        mixerAddControl(pDestLine, MIX_CTRL_MUTE_OUT_LINE, pDestLine);
    435723
    436724        //WaveIn destination
    437         mixerAddControl(MIX_CTRL_VOL_IN_W_MIC);
    438         mixerAddControl(MIX_CTRL_VOL_IN_W_LINE);
     725        pDestLine = mixerAddDestination(MIXER_DEST_WAVEIN);
     726        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_MIC, pDestLine);
     727        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_LINE, pDestLine);
    439728        //must add after all recording inputs (to count them)
    440         mixerAddControl(MIX_CTRL_MUX_IN_W_SRC);
    441         //muast add after all wave in controls (for counting controls & inputs)
    442         mixerAddDestination(MIXER_DEST_WAVEIN);
     729        mixerAddControl(pDestLine, MIX_CTRL_MUX_IN_W_SRC, pDestLine);
    443730        return TRUE;
    444731    }
    445732    //Line out destination
    446     mixerAddControl(MIX_CTRL_VOL_OUT_LINE);
    447     mixerAddControl(MIX_CTRL_MUTE_OUT_LINE);
     733    pDestLine = mixerAddDestination(MIXER_DEST_LINEOUT);
     734
     735    mixerAddControl(pDestLine, MIX_CTRL_VOL_OUT_LINE, pDestLine);
     736    mixerAddControl(pDestLine, MIX_CTRL_MUTE_OUT_LINE, pDestLine);
     737    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DCENTER)) {
     738        mixerAddControl(pDestLine, MIX_CTRL_OUT_L_3DCENTER, pDestLine);
     739    }
     740    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DDEPTH)) {
     741        mixerAddControl(pDestLine, MIX_CTRL_OUT_L_3DDEPTH, pDestLine);
     742    }
     743    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_TREBLE)) {
     744        mixerAddControl(pDestLine, MIX_CTRL_OUT_L_TREBLE, pDestLine);
     745    }
     746    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_BASS)) {
     747        mixerAddControl(pDestLine, MIX_CTRL_OUT_L_BASS, pDestLine);
     748    }
    448749
    449750    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_SPDIF)) {
    450         mixerAddSource(MIXER_SRC_SPDIF);
    451         mixerAddControl(MIX_CTRL_VOL_IN_L_SPDIF);
    452         mixerAddControl(MIX_CTRL_MUTE_IN_L_SPDIF);
     751        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_SPDIF);
     752        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_SPDIF, pLine);
     753        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_SPDIF, pLine);
    453754    }
    454755
    455756    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MONO)) {
    456         mixerAddSource(MIXER_SRC_MONOIN);
    457         mixerAddControl(MIX_CTRL_VOL_IN_L_MONO);
    458         mixerAddControl(MIX_CTRL_MUTE_IN_L_MONO);
     757        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_MONOIN);
     758        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_MONO, pLine);
     759        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_MONO, pLine);
    459760    }
    460761    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_PHONE)) {
    461         mixerAddSource(MIXER_SRC_PHONE);
    462         mixerAddControl(MIX_CTRL_VOL_IN_L_PHONE);
    463         mixerAddControl(MIX_CTRL_MUTE_IN_L_PHONE);
     762        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_PHONE);
     763        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_PHONE, pLine);
     764        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_PHONE, pLine);
    464765    }
    465766    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MIC)) {
    466         mixerAddSource(MIXER_SRC_MIC);
    467         mixerAddControl(MIX_CTRL_VOL_IN_L_MIC);
    468         mixerAddControl(MIX_CTRL_MUTE_IN_L_MIC);
     767        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_MIC);
     768        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_MIC, pLine);
     769        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_MIC, pLine);
    469770        if(OSLibMixIsControlPresent(MIX_CTRL_BOOST_IN_L_MIC)) {
    470             mixerAddControl(MIX_CTRL_BOOST_IN_L_MIC);
     771            mixerAddControl(pDestLine, MIX_CTRL_BOOST_IN_L_MIC, pLine);
    471772        }
    472773    }
    473774    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_LINE)) {
    474         mixerAddSource(MIXER_SRC_LINE);
    475         mixerAddControl(MIX_CTRL_VOL_IN_L_LINE);
    476         mixerAddControl(MIX_CTRL_MUTE_IN_L_LINE);
     775        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_LINE);
     776        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_LINE, pLine);
     777        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_LINE, pLine);
    477778    }
    478779    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_CD)) {
    479         mixerAddSource(MIXER_SRC_CD);
    480         mixerAddControl(MIX_CTRL_VOL_IN_L_CD);
    481         mixerAddControl(MIX_CTRL_MUTE_IN_L_CD);
     780        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_CD);
     781        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_CD, pLine);
     782        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_CD, pLine);
    482783    }
    483784    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_VIDEO)) {
    484         mixerAddSource(MIXER_SRC_VIDEO);
    485         mixerAddControl(MIX_CTRL_VOL_IN_L_VIDEO);
    486         mixerAddControl(MIX_CTRL_MUTE_IN_L_VIDEO);
     785        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_VIDEO);
     786        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_VIDEO, pLine);
     787        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_VIDEO, pLine);
    487788    }
    488789    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_AUX)) {
    489         mixerAddSource(MIXER_SRC_AUX);
    490         mixerAddControl(MIX_CTRL_VOL_IN_L_AUX);
    491         mixerAddControl(MIX_CTRL_MUTE_IN_L_AUX);
     790        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_AUX);
     791        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_AUX, pLine);
     792        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_AUX, pLine);
    492793    }
    493794    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_PCM)) {
    494         mixerAddSource(MIXER_SRC_PCM);
    495         mixerAddControl(MIX_CTRL_VOL_IN_L_PCM);
    496         mixerAddControl(MIX_CTRL_MUTE_IN_L_PCM);
     795        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_PCM);
     796        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_PCM, pLine);
     797        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_PCM, pLine);
    497798    }
    498799    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_WAVETABLE)) {
    499         mixerAddSource(MIXER_SRC_WAVETABLE);
    500         mixerAddControl(MIX_CTRL_VOL_IN_L_WAVETABLE);
    501         mixerAddControl(MIX_CTRL_MUTE_IN_L_WAVETABLE);
     800        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_WAVETABLE);
     801        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_WAVETABLE, pLine);
     802        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_WAVETABLE, pLine);
    502803    }
    503804    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MIDI)) {
    504         mixerAddSource(MIXER_SRC_MIDI);
    505         mixerAddControl(MIX_CTRL_VOL_IN_L_MIDI);
    506         mixerAddControl(MIX_CTRL_MUTE_IN_L_MIDI);
    507     }
    508     if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DCENTER)) {
    509         mixerAddControl(MIX_CTRL_OUT_L_3DCENTER);
    510     }
    511     if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DDEPTH)) {
    512         mixerAddControl(MIX_CTRL_OUT_L_3DDEPTH);
    513     }
    514     if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_TREBLE)) {
    515         mixerAddControl(MIX_CTRL_OUT_L_TREBLE);
    516     }
    517     if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_BASS)) {
    518         mixerAddControl(MIX_CTRL_OUT_L_BASS);
    519     }
    520     //muast add after all controls (for counting controls & inputs)
    521     mixerAddDestination(MIXER_DEST_LINEOUT);
     805        MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_MIDI);
     806        mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_L_MIDI, pLine);
     807        mixerAddControl(pDestLine, MIX_CTRL_MUTE_IN_L_MIDI, pLine);
     808    }
    522809
    523810    //Wave In Destination
    524811    if(OSLibMixIsControlPresent(MIX_CTRL_MUX_IN_W_SRC)) {
     812        pDestLine = mixerAddDestination(MIXER_DEST_WAVEIN);
    525813        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_MONO)) {
    526             mixerAddControl(MIX_CTRL_VOL_IN_W_MONO);
     814            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_MONO, pDestLine);
    527815        }
    528816        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_PHONE)) {
    529             mixerAddControl(MIX_CTRL_VOL_IN_W_PHONE);
     817            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_PHONE, pDestLine);
    530818        }
    531819        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_MIC)) {
    532             mixerAddControl(MIX_CTRL_VOL_IN_W_MIC);
     820            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_MIC, pDestLine);
    533821        }
    534822        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_LINE)) {
    535             mixerAddControl(MIX_CTRL_VOL_IN_W_LINE);
     823            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_LINE, pDestLine);
    536824        }
    537825        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_CD)) {
    538             mixerAddControl(MIX_CTRL_VOL_IN_W_CD);
     826            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_CD, pDestLine);
    539827        }
    540828        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_SPDIF)) {
    541             mixerAddControl(MIX_CTRL_VOL_IN_W_SPDIF);
     829            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_SPDIF, pDestLine);
    542830        }
    543831        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_VIDEO)) {
    544             mixerAddControl(MIX_CTRL_VOL_IN_W_VIDEO);
     832            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_VIDEO, pDestLine);
    545833        }
    546834        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_AUX)) {
    547             mixerAddControl(MIX_CTRL_VOL_IN_W_AUX);
     835            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_AUX, pDestLine);
    548836        }
    549837        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_PCM)) {
    550             mixerAddControl(MIX_CTRL_VOL_IN_W_PCM);
     838            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_PCM, pDestLine);
    551839        }
    552840        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_WAVETABLE)) {
    553             mixerAddControl(MIX_CTRL_VOL_IN_W_WAVETABLE);
     841            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_WAVETABLE, pDestLine);
    554842        }
    555843        if(OSLibMixIsRecSourcePresent(MIX_CTRL_VOL_IN_W_MIDI)) {
    556             mixerAddControl(MIX_CTRL_VOL_IN_W_MIDI);
     844            mixerAddControl(pDestLine, MIX_CTRL_VOL_IN_W_MIDI, pDestLine);
    557845        }
    558846        //must add after all recording inputs (to count them)
    559         mixerAddControl(MIX_CTRL_MUX_IN_W_SRC);
    560         //muast add after all wave in controls (for counting controls & inputs)
    561         mixerAddDestination(MIXER_DEST_WAVEIN);
     847        mixerAddControl(pDestLine, MIX_CTRL_MUX_IN_W_SRC, pDestLine);
    562848    }
    563849
    564850    //SPDIF destination
    565851    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_OUT_SPDIF)) {
    566         mixerAddControl(MIX_CTRL_VOL_OUT_SPDIF);
    567         mixerAddControl(MIX_CTRL_MUTE_OUT_SPDIF);
    568         mixerAddDestination(MIXER_DEST_SPDIFOUT);
     852        pDestLine = mixerAddDestination(MIXER_DEST_SPDIFOUT);
     853        mixerAddControl(pDestLine, MIX_CTRL_VOL_OUT_SPDIF, pDestLine);
     854        mixerAddControl(pDestLine, MIX_CTRL_MUTE_OUT_SPDIF, pDestLine);
    569855    }
    570856
     
    579865/******************************************************************************/
    580866/******************************************************************************/
    581 static BOOL mixerAddSource(DWORD dwSource)
     867static MIXERLINEA *mixerAddSource(MIXERLINEA *pDestLine, DWORD dwSource)
    582868{
    583869    MIXERLINEA *pline  = &mixerSource[nrSources];
     
    586872        dprintf(("ERROR: mixerAddSource: out of room!!!"));
    587873        DebugInt3();
    588         return FALSE;
     874        return NULL;
    589875    }
    590876
    591877    pline->cbStruct = sizeof(MIXERLINEA);
    592878    memset(pline, 0, sizeof(MIXERLINEA));
     879
     880    pline->cConnections    = 0;
     881    pline->cControls       = 0;
     882    pline->dwDestination   = 0;
     883    pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
     884    pline->dwSource        = nrSources;
    593885
    594886    switch(dwSource) {
    595887    case MIXER_SRC_MONOIN:
    596888    case MIXER_SRC_PHONE:
    597         pline->dwSource        = nrSources;
    598889        pline->cChannels       = 1;
    599         pline->cConnections    = 0;
    600         pline->cControls       = 0;
    601890        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE;
    602         pline->dwDestination   = 0;
    603         pline->dwLineID        = (DWORD)-1;
    604         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    605891        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
    606         nrLineOutInputs++;
    607892        break;
    608893
    609894    case MIXER_SRC_MIC:
    610         pline->dwSource        = nrSources;
    611895        pline->cChannels       = 1;
    612         pline->cConnections    = 0;
    613         pline->cControls       = 0;
    614896        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
    615         pline->dwDestination   = 0;
    616         pline->dwLineID        = (DWORD)-1;
    617         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    618897        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
    619         nrLineOutInputs++;
    620898        break;
    621899
    622900    case MIXER_SRC_LINE:
    623         pline->dwSource        = nrSources;
    624901        pline->cChannels       = 2;
    625         pline->cConnections    = 0;
    626         pline->cControls       = 0;
    627902        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
    628         pline->dwDestination   = 0;
    629         pline->dwLineID        = (DWORD)-1;
    630         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    631903        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
    632         nrLineOutInputs++;
    633904        break;
    634905
    635906    case MIXER_SRC_CD:
    636         pline->dwSource        = nrSources;
    637907        pline->cChannels       = 2;
    638         pline->cConnections    = 0;
    639         pline->cControls       = 0;
    640908        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
    641         pline->dwDestination   = 0;
    642         pline->dwLineID        = (DWORD)-1;
    643         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    644909        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
    645         nrLineOutInputs++;
    646910        break;
    647911
    648912    case MIXER_SRC_SPDIF:
    649         pline->dwSource        = nrSources;
    650913        pline->cChannels       = 2;
    651         pline->cConnections    = 0;
    652         pline->cControls       = 0;
    653914        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_DIGITAL;
    654         pline->dwDestination   = 0;
    655         pline->dwLineID        = (DWORD)-1;
    656         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    657915        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
    658         nrLineOutInputs++;
    659916        break;
    660917
    661918    case MIXER_SRC_VIDEO:
    662         pline->dwSource        = nrSources;
    663919        pline->cChannels       = 2;
    664         pline->cConnections    = 0;
    665         pline->cControls       = 0;
    666920        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED;
    667         pline->dwDestination   = 0;
    668         pline->dwLineID        = (DWORD)-1;
    669         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    670921        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
    671         nrLineOutInputs++;
    672922        break;
    673923
    674924    case MIXER_SRC_AUX:
    675         pline->dwSource        = nrSources;
    676925        pline->cChannels       = 2;
    677         pline->cConnections    = 0;
    678         pline->cControls       = 0;
    679926        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY;
    680         pline->dwDestination   = 0;
    681         pline->dwLineID        = (DWORD)-1;
    682         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    683927        pline->Target.dwType   = MIXERLINE_TARGETTYPE_AUX;
    684         nrLineOutInputs++;
    685928        break;
    686929
    687930    case MIXER_SRC_PCM:
    688         pline->dwSource        = nrSources;
    689931        pline->cChannels       = 2;
    690         pline->cConnections    = 0;
    691         pline->cControls       = 0;
    692932        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
    693         pline->dwDestination   = 0;
    694         pline->dwLineID        = (DWORD)-1;
    695         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    696933        pline->Target.dwType   = MIXERLINE_TARGETTYPE_WAVEOUT;
    697         nrLineOutInputs++;
    698934        break;
    699935
    700936    case MIXER_SRC_WAVETABLE:
    701937    case MIXER_SRC_MIDI:
    702         pline->dwSource        = nrSources;
    703938        pline->cChannels       = 2;
    704         pline->cConnections    = 0;
    705         pline->cControls       = 0;
    706939        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
    707         pline->dwDestination   = 0;
    708         pline->dwLineID        = (DWORD)-1;
    709         pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    710940        pline->Target.dwType   = MIXERLINE_TARGETTYPE_MIDIOUT;
    711         nrLineOutInputs++;
    712941        break;
    713942
    714943    default:
    715944        DebugInt3();
    716         return FALSE;
     945        return NULL;
    717946    }
    718947    strncpy(pline->szShortName, szSourceName[dwSource][0], sizeof(pline->szShortName));
     
    720949
    721950    dprintf(("Adding Source %s (%s)", pline->szName, pline->szShortName));
    722 
    723951    nrSources++;
    724     return TRUE;
    725 }
    726 /******************************************************************************/
    727 /******************************************************************************/
    728 static BOOL mixerAddDestination(DWORD dwDest)
     952
     953    mixerDestInputs[MIXER_DEST_LINEOUT][nrLineOutInputs] = pline->dwSource;
     954    nrLineOutInputs++;
     955
     956    pline->dwLineID      = nrLines;
     957    pmixerLines[nrLines] = pline;
     958    nrLines++;
     959
     960    //increase nr of inputs at destinateion line
     961    pDestLine->cConnections++;
     962
     963    //store line id in source to line mapping array
     964    mixerSourceLineId[dwSource] = pline->dwLineID;
     965
     966    return pline;
     967}
     968/******************************************************************************/
     969/******************************************************************************/
     970static MIXERLINEA *mixerAddDestination(DWORD dwDest)
    729971{
    730972    MIXERLINEA *pline  = &mixerDest[nrDestinations];
     
    733975        dprintf(("ERROR: mixerAddDestination: out of room!!!"));
    734976        DebugInt3();
    735         return FALSE;
     977        return NULL;
    736978    }
    737979    pline->cbStruct = sizeof(MIXERLINEA);
     
    742984        pline->dwDestination   = nrDestinations;
    743985        pline->cChannels       = 2;
    744         pline->cConnections    = nrLineOutInputs;
    745         pline->cControls       = nrLineOutControls;
     986        pline->cConnections    = 0;
     987        pline->cControls       = 0;
    746988        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
    747989        pline->dwSource        = 0;
    748         pline->dwLineID        = (DWORD)-1;
    749990        pline->fdwLine         = MIXERLINE_LINEF_ACTIVE;
    750991        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
     
    754995        pline->dwDestination   = nrDestinations;
    755996        pline->cChannels       = 2;
    756         pline->cConnections    = nrSPDIFInputs;
    757         pline->cControls       = nrSPDIFControls;
     997        pline->cConnections    = 0;
     998        pline->cControls       = 0;
    758999        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_DIGITAL;
    7591000        pline->dwSource        = 0;
    760         pline->dwLineID        = (DWORD)-1;
    761         pline->fdwLine         = 0;
     1001        pline->fdwLine         = MIXERLINE_LINEF_ACTIVE;
    7621002        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
    7631003        break;
    7641004
    7651005    case MIXER_DEST_WAVEIN:
    766         pline->dwSource        = nrSources;
     1006        pline->dwSource        = nrDestinations;
    7671007        pline->cChannels       = 2;
    768         pline->cConnections    = nrWaveInInputs;
    769         pline->cControls       = nrWaveInControls;
     1008        pline->cConnections    = 0;
     1009        pline->cControls       = 0;
    7701010        pline->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
    7711011        pline->dwDestination   = 0;
    772         pline->dwLineID        = (DWORD)-1;
    7731012        pline->fdwLine         = MIXERLINE_LINEF_SOURCE;
    7741013        pline->Target.dwType   = MIXERLINE_TARGETTYPE_UNDEFINED;
     
    7771016    default:
    7781017        DebugInt3();
    779         return FALSE;
     1018        return NULL;
    7801019    }
    7811020    strncpy(pline->szShortName, szDestName[dwDest][0], sizeof(pline->szShortName));
    7821021    strncpy(pline->szName,      szDestName[dwDest][1], sizeof(pline->szName));
    783     dprintf(("Adding destination %s (%s)", pline->szName, pline->szShortName));
     1022    dprintf(("Adding destination %s (%s) connections %d controls %d", pline->szName, pline->szShortName, pline->cConnections, pline->cControls));
    7841023    nrDestinations++;
    785     return TRUE;
    786 }
    787 /******************************************************************************/
    788 /******************************************************************************/
    789 static BOOL mixerAddControl(DWORD dwControl)
     1024
     1025    pline->dwLineID      = nrLines;
     1026    pmixerLines[nrLines] = pline;
     1027    nrLines++;
     1028    return pline;
     1029}
     1030/******************************************************************************/
     1031/******************************************************************************/
     1032static int mixerWaveInVolToSource(DWORD dwControl)
     1033{
     1034    switch(dwControl) {
     1035    case MIX_CTRL_VOL_IN_W_MONO:
     1036        return MIXER_SRC_MONOIN;
     1037    case MIX_CTRL_VOL_IN_W_PHONE:
     1038        return MIXER_SRC_PHONE;
     1039    case MIX_CTRL_VOL_IN_W_MIC:
     1040        return MIXER_SRC_MIC;
     1041    case MIX_CTRL_VOL_IN_W_LINE:
     1042        return MIXER_SRC_LINE;
     1043    case MIX_CTRL_VOL_IN_W_CD:
     1044        return MIXER_SRC_CD;
     1045    case MIX_CTRL_VOL_IN_W_SPDIF:
     1046        return MIXER_SRC_SPDIF;
     1047    case MIX_CTRL_VOL_IN_W_VIDEO:
     1048        return MIXER_SRC_VIDEO;
     1049    case MIX_CTRL_VOL_IN_W_AUX:
     1050        return MIXER_SRC_AUX;
     1051    case MIX_CTRL_VOL_IN_W_PCM:
     1052        return MIXER_SRC_PCM;
     1053    case MIX_CTRL_VOL_IN_W_WAVETABLE:
     1054        return MIXER_SRC_WAVETABLE;
     1055    case MIX_CTRL_VOL_IN_W_MIDI:
     1056        return MIXER_SRC_MIDI;
     1057    default:
     1058        DebugInt3();
     1059        return 0;
     1060    }
     1061}
     1062/******************************************************************************/
     1063/******************************************************************************/
     1064static BOOL mixerAddControl(MIXERLINEA *pDestLine, DWORD dwControl, MIXERLINEA *pSrcLine)
    7901065{
    7911066    MIXERCONTROLA *pctrl  = &mixerControls[nrControls];
     
    8001075    memset(pctrl, 0, sizeof(MIXERCONTROLA));
    8011076
     1077    pctrl->cMultipleItems   = 0;
     1078    pctrl->dwControlID      = nrControls;
     1079    pctrl->fdwControl       = 0;
    8021080    switch(dwControl) {
    8031081    case MIX_CTRL_VOL_OUT_LINE:
     
    8131091    case MIX_CTRL_VOL_IN_L_WAVETABLE:
    8141092    case MIX_CTRL_VOL_IN_L_MIDI:
    815         pctrl->cMultipleItems   = 0;
    816         pctrl->fdwControl       = 0;
    817         pctrl->dwControlID      = nrControls;
    8181093        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_VOLUME;
    819         strncpy(pctrl->szShortName, szCtrlName[dwControl][0], sizeof(pctrl->szShortName));
    820         strncpy(pctrl->szName,      szCtrlName[dwControl][1], sizeof(pctrl->szName));
    8211094        pctrl->Bounds.s.lMinimum = 0;
    8221095        pctrl->Bounds.s.lMaximum = 100;
    8231096        pctrl->Metrics.cSteps    = 1;
    824         nrControls++;
    825         nrLineOutControls++;
    8261097        break;
    8271098
     
    8371108    case MIX_CTRL_VOL_IN_W_WAVETABLE:
    8381109    case MIX_CTRL_VOL_IN_W_MIDI:
    839         pctrl->cMultipleItems   = 0;
    840         pctrl->fdwControl       = 0;
    841         pctrl->dwControlID      = nrControls;
    8421110        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_VOLUME;
    843         strncpy(pctrl->szShortName, szCtrlName[dwControl][0], sizeof(pctrl->szShortName));
    844         strncpy(pctrl->szName,      szCtrlName[dwControl][1], sizeof(pctrl->szName));
    8451111        pctrl->Bounds.s.lMinimum = 0;
    8461112        pctrl->Bounds.s.lMaximum = 100;
    8471113        pctrl->Metrics.cSteps    = 1;
    848         nrControls++;
    849         nrWaveInControls++;
     1114        mixerDestInputs[MIXER_DEST_WAVEIN][nrWaveInInputs] = mixerSourceLineId[mixerWaveInVolToSource(dwControl)];
    8501115        nrWaveInInputs++;
    8511116        break;
     
    8611126    case MIX_CTRL_MUTE_IN_L_AUX:
    8621127    case MIX_CTRL_MUTE_IN_L_PCM:
    863         pctrl->cMultipleItems   = 0;
    8641128        pctrl->fdwControl       = MIXERCONTROL_CONTROLF_UNIFORM;
    865         pctrl->dwControlID      = nrControls;
    8661129        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_MUTE;
    867         strncpy(pctrl->szShortName, szCtrlName[dwControl][0], sizeof(pctrl->szShortName));
    868         strncpy(pctrl->szName,      szCtrlName[dwControl][1], sizeof(pctrl->szName));
    8691130        pctrl->Bounds.s.lMinimum = 0;
    8701131        pctrl->Bounds.s.lMaximum = 1;
    8711132        pctrl->Metrics.cSteps    = 0;
    872         nrControls++;
    873         nrLineOutControls++;
    8741133        break;
    8751134
    8761135    case MIX_CTRL_VOL_OUT_SPDIF:
    877         pctrl->cMultipleItems   = 0;
    878         pctrl->fdwControl       = 0;
    879         pctrl->dwControlID      = nrControls;
    8801136        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_VOLUME;
    881         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_VOL_OUT_SPDIF][0], sizeof(pctrl->szShortName));
    882         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_VOL_OUT_SPDIF][1], sizeof(pctrl->szName));
    8831137        pctrl->Bounds.s.lMinimum = 0;
    8841138        pctrl->Bounds.s.lMaximum = 100;
    8851139        pctrl->Metrics.cSteps    = 1;
    886         nrControls++;
    887         nrSPDIFControls++;
    8881140        break;
    8891141
    8901142    case MIX_CTRL_MUTE_OUT_SPDIF:
    891         pctrl->cMultipleItems   = 0;
    8921143        pctrl->fdwControl       = MIXERCONTROL_CONTROLF_UNIFORM;
    893         pctrl->dwControlID      = nrControls;
    8941144        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_MUTE;
    895         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_MUTE_OUT_SPDIF][0], sizeof(pctrl->szShortName));
    896         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_MUTE_OUT_SPDIF][1], sizeof(pctrl->szName));
    8971145        pctrl->Bounds.s.lMinimum = 0;
    8981146        pctrl->Bounds.s.lMaximum = 1;
    8991147        pctrl->Metrics.cSteps    = 0;
    900         nrControls++;
    901         nrSPDIFControls++;
    9021148        break;
    9031149
    9041150    case MIX_CTRL_BOOST_IN_L_MIC:
    905         pctrl->cMultipleItems   = 0;
    9061151        pctrl->fdwControl       = MIXERCONTROL_CONTROLF_UNIFORM;
    907         pctrl->dwControlID      = nrControls;
    9081152        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_ONOFF;
    909         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_BOOST_IN_L_MIC][0], sizeof(pctrl->szShortName));
    910         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_BOOST_IN_L_MIC][1], sizeof(pctrl->szName));
    9111153        pctrl->Bounds.s.lMinimum = 0;
    9121154        pctrl->Bounds.s.lMaximum = 1;
    9131155        pctrl->Metrics.cSteps    = 0;
    914         nrControls++;
    915         nrLineOutControls++;
    9161156        break;
    9171157
    9181158    case MIX_CTRL_OUT_L_3DDEPTH:
    919         pctrl->cMultipleItems   = 0;
    9201159        pctrl->fdwControl       = MIXERCONTROL_CONTROLF_UNIFORM;
    921         pctrl->dwControlID      = nrControls;
    9221160        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_FADER;
    923         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_3DDEPTH][0], sizeof(pctrl->szShortName));
    924         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_OUT_L_3DDEPTH][1], sizeof(pctrl->szName));
    9251161        pctrl->Bounds.s.lMinimum = 0;
    9261162        pctrl->Bounds.s.lMaximum = 100;
    9271163        pctrl->Metrics.cSteps    = 1;
    928         nrControls++;
    929         nrLineOutControls++;
    9301164        break;
    9311165
    9321166    case MIX_CTRL_OUT_L_3DCENTER:
    933         pctrl->cMultipleItems   = 0;
    9341167        pctrl->fdwControl       = MIXERCONTROL_CONTROLF_UNIFORM;
    935         pctrl->dwControlID      = nrControls;
    9361168        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_FADER;
    937         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_3DCENTER][0], sizeof(pctrl->szShortName));
    938         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_OUT_L_3DCENTER][1], sizeof(pctrl->szName));
    9391169        pctrl->Bounds.s.lMinimum = 0;
    9401170        pctrl->Bounds.s.lMaximum = 100;
    9411171        pctrl->Metrics.cSteps    = 1;
    942         nrControls++;
    943         nrLineOutControls++;
    9441172        break;
    9451173
    9461174    case MIX_CTRL_MUX_IN_W_SRC:
    947         pctrl->cMultipleItems   = nrWaveInControls;
    9481175        pctrl->fdwControl       = MIXERCONTROL_CONTROLF_MULTIPLE | MIXERCONTROL_CONTROLF_UNIFORM;
    949         pctrl->dwControlID      = nrControls;
    9501176        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_MUX;
    951         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_MUX_IN_W_SRC][0], sizeof(pctrl->szShortName));
    952         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_MUX_IN_W_SRC][1], sizeof(pctrl->szName));
    9531177        pctrl->Bounds.s.lMinimum = 0;
    9541178        pctrl->Bounds.s.lMaximum = 1;
    9551179        pctrl->Metrics.cSteps    = 1;
    956         nrControls++;
    957         nrWaveInControls++;
    9581180        break;
    9591181
    9601182    case MIX_CTRL_OUT_L_TREBLE:
    961         pctrl->cMultipleItems   = 0;
    962         pctrl->fdwControl       = 0;
    963         pctrl->dwControlID      = nrControls;
    9641183        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_TREBLE;
    965         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_TREBLE][0], sizeof(pctrl->szShortName));
    966         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_OUT_L_TREBLE][1], sizeof(pctrl->szName));
    9671184        pctrl->Bounds.s.lMinimum = 0;
    9681185        pctrl->Bounds.s.lMaximum = 100;
    9691186        pctrl->Metrics.cSteps    = 1;
    970         nrControls++;
    971         nrLineOutControls++;
    9721187        break;
    9731188
    9741189    case MIX_CTRL_OUT_L_BASS:
    975         pctrl->cMultipleItems   = 0;
    976         pctrl->fdwControl       = 0;
    977         pctrl->dwControlID      = nrControls;
    9781190        pctrl->dwControlType    = MIXERCONTROL_CONTROLTYPE_BASS;
    979         strncpy(pctrl->szShortName, szCtrlName[MIX_CTRL_OUT_L_BASS][0], sizeof(pctrl->szShortName));
    980         strncpy(pctrl->szName,      szCtrlName[MIX_CTRL_OUT_L_BASS][1], sizeof(pctrl->szName));
    9811191        pctrl->Bounds.s.lMinimum = 0;
    9821192        pctrl->Bounds.s.lMaximum = 100;
    9831193        pctrl->Metrics.cSteps    = 1;
    984         nrControls++;
    985         nrLineOutControls++;
    9861194        break;
    9871195
     
    9901198        return FALSE;
    9911199    }
     1200    //increase nr of controls of corresponding destinateion line
     1201    pDestLine->cControls++;
     1202
     1203    //add control to list of controls associated with source line
     1204    for(int i=0;i<MAX_SOURCE_CONTROLS;i++) {
     1205        if(mixerLineControls[pSrcLine->dwLineID][i] == -1) {
     1206            mixerLineControls[pSrcLine->dwLineID][i] = pctrl->dwControlID;
     1207            break;
     1208        }
     1209    }
     1210    if(i == MAX_SOURCE_CONTROLS) {
     1211        DebugInt3();
     1212    }
     1213
     1214    strncpy(pctrl->szShortName, szCtrlName[dwControl][0], sizeof(pctrl->szShortName));
     1215    strncpy(pctrl->szName,      szCtrlName[dwControl][1], sizeof(pctrl->szName));
     1216    nrControls++;
    9921217    dprintf(("Adding control %s (%s)", pctrl->szName, pctrl->szShortName));
    9931218    return TRUE;
Note: See TracChangeset for help on using the changeset viewer.