Changeset 8495 for trunk/src


Ignore:
Timestamp:
May 27, 2002, 5:49:55 PM (23 years ago)
Author:
sandervl
Message:

implemented mixerGetControlDetailsA/W completely + mixer updates

Location:
trunk/src/winmm
Files:
2 edited

Legend:

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

    r8493 r8495  
    1 /* $Id: mixer.cpp,v 1.18 2002-05-26 10:52:30 sandervl Exp $ */
     1/* $Id: mixer.cpp,v 1.19 2002-05-27 15:49:54 sandervl Exp $ */
    22
    33/*
     
    4141#include "dbglocal.h"
    4242
    43 static MIXERCONTROLA *mixerAddControl(DWORD dwControl, MIXERLINEA *pSrcLine);
    44 static MIXERLINEA    *mixerAddSource(MIXERDEST *pDestLine, DWORD dwSource);
    45 static MIXERDEST     *mixerAddDestination(DWORD dwDest);
     43static MIXERCONTROLA *mixerAddControl(DWORD dwControl, MIXLINE *pSrcLine);
     44static MIXLINE       *mixerAddSource(MIXLINE *pDestLine, DWORD dwSource);
     45static MIXLINE       *mixerAddDestination(DWORD dwDest);
    4646
    4747//array of destination mixer lines
    48 static MIXERDEST     mixerDest[MAX_MIXER_DESTINATIONS];
     48static MIXLINE       mixerDest[MAX_MIXER_DESTINATIONS] = {0};
    4949//array of source mixer lines
    50 static MIXERLINEA    mixerSource[MAX_MIXER_SOURCES]                             = {0};
    51 //array of controls connected to mixer lines
    52 static int           mixerLineControls[MAX_MIXER_LINES][MAX_SOURCE_CONTROLS]    = {-1};
     50static MIXLINE       mixerSource[MAX_MIXER_SOURCES]    = {0};
    5351//array of all mixer lines
    54 static MIXERLINEA   *pmixerLines[MAX_MIXER_LINES]                               = {NULL};
    55 //mapping from src to line id
    56 static int           mixerSourceLineId[MAX_MIXER_SOURCES]                       = {-1};
    57 //array of all mixer controls
    58 static MIXERCONTROLA mixerControls[MAX_MIXER_CONTROLS]                          = {0};
    59 //mapping of mixer id to internal id
    60 static int           mixerControlId[MAX_MIXER_CONTROLS]                         = {0};
     52static MIXLINE      *pmixerLines[MAX_MIXER_LINES]      = {NULL};
     53//array of all mixer controls                         
     54static MIXCONTROL    mixerControls[MAX_MIXER_CONTROLS] = {0};
    6155
    6256static int           nrDestinations    = 0;
     
    8882        return MMSYSERR_INVALPARAM;
    8983    }
    90 
    9184    switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
    9285    case MIXER_GETCONTROLDETAILSF_VALUE:
    93         dprintf(("MIXER_GETCONTROLDETAILSF_VALUE %d (internal id %d)", lpmcd->dwControlID, mixerControlId[lpmcd->dwControlID]));
     86        dprintf(("MIXER_GETCONTROLDETAILSF_VALUE %d (internal id %d)", lpmcd->dwControlID, mixerControls[lpmcd->dwControlID].id));
    9487        if(lpmcd->dwControlID >= nrControls) {
    9588            dprintf(("invalid control %d", lpmcd->dwControlID));
    9689            return MIXERR_INVALCONTROL;
    9790        }
    98         switch(mixerControls[lpmcd->dwControlID].dwControlType) {
     91        if(lpmcd->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED)) {
     92            dprintf(("not enough room in buffer (%d)", lpmcd->cbDetails));
     93            return MMSYSERR_INVALPARAM;
     94        }
     95        switch(mixerControls[lpmcd->dwControlID].ctrl.dwControlType) {
    9996        case MIXERCONTROL_CONTROLTYPE_MUX:
     97        {
     98            MIXERCONTROLDETAILS_BOOLEAN *pDetails = (MIXERCONTROLDETAILS_BOOLEAN *)lpmcd->paDetails;
     99            DWORD dwRecSrc;
     100
    100101            dprintf(("MIXERCONTROL_CONTROLTYPE_MUX"));
    101             break;
    102         case MIXERCONTROL_CONTROLTYPE_MIXER:
    103             dprintf(("MIXERCONTROL_CONTROLTYPE_MIXER"));
    104             break;
    105         case MIXERCONTROL_CONTROLTYPE_FADER:
    106             dprintf(("MIXERCONTROL_CONTROLTYPE_FADER"));
    107             break;
     102            if(lpmcd->cChannels != 1) {//only accepts 1 in win2k
     103                dprintf(("invalid number of channels %d", lpmcd->cChannels));
     104                return MMSYSERR_INVALPARAM;
     105            }
     106            //this is also checked in win2k
     107            if(lpmcd->u.cMultipleItems != mixerControls[lpmcd->dwControlID].ctrl.cMultipleItems) {
     108                dprintf(("invalid cMultipleItems %d", lpmcd->u.cMultipleItems));
     109                return MMSYSERR_INVALPARAM;
     110            }
     111
     112            if(mixerControls[lpmcd->dwControlID].id != MIX_CTRL_MUX_IN_W_SRC) {
     113                dprintf(("oh, oh. not wavein mux"));
     114                DebugInt3();
     115                return MMSYSERR_INVALPARAM;
     116            }
     117
     118            if(OSLibMixGetRecSource(&dwRecSrc, NULL, NULL) == FALSE) {
     119                dprintf(("OSLibMixGetRecSource failed!!"));
     120                return MIXERR_INVALCONTROL;
     121            }
     122            //clear the array
     123            memset(pDetails, 0, sizeof(MIXERCONTROLDETAILS_BOOLEAN)*lpmcd->u.cMultipleItems);
     124            //mark recording source
     125            for(int i=0;i<nrDestinations;i++) {
     126                if(mixerDest[i].id == MIXER_DEST_WAVEIN) {
     127                    for(int j=0;j<mixerDest[i].cConnections;j++) {
     128                        dprintf(("wavein source %d (id %d)", pmixerLines[mixerDest[i].Connections[j]]->id, mixerDest[i].Connections[j]));
     129                        if(pmixerLines[mixerDest[i].Connections[j]]->id == dwRecSrc) {
     130                            pDetails[j].fValue = 1;
     131                            return MMSYSERR_NOERROR;
     132                        }
     133                    }
     134                }
     135            }
     136            dprintf(("recording source %d not found!!", dwRecSrc));
     137            break;
     138        }
     139
    108140        case MIXERCONTROL_CONTROLTYPE_VOLUME: //unsigned
    109141        {
     
    112144
    113145            dprintf(("MIXERCONTROL_CONTROLTYPE_VOLUME"));
    114             if(OSLibMixGetVolume(mixerControlId[lpmcd->dwControlID], NULL, &dwVolLeft, &dwVolRight) == FALSE) {
     146            if(OSLibMixGetVolume(mixerControls[lpmcd->dwControlID].id, NULL, &dwVolLeft, &dwVolRight) == FALSE) {
    115147                dprintf(("OSLibMixGetVolume failed!!"));
    116148                return MIXERR_INVALCONTROL;
     
    126158            return MMSYSERR_NOERROR;
    127159        }
    128         case MIXERCONTROL_CONTROLTYPE_BASS:
    129             dprintf(("MIXERCONTROL_CONTROLTYPE_BASS"));
    130             break;
    131         case MIXERCONTROL_CONTROLTYPE_TREBLE:
    132             dprintf(("MIXERCONTROL_CONTROLTYPE_TREBLE"));
    133             break;
    134         case MIXERCONTROL_CONTROLTYPE_MUTE:
     160
     161        case MIXERCONTROL_CONTROLTYPE_MUTE: //assuming boolean
    135162        {
    136             MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     163            MIXERCONTROLDETAILS_BOOLEAN *pDetails = (MIXERCONTROLDETAILS_BOOLEAN *)lpmcd->paDetails;
    137164            BOOL  fMute;
    138165
    139166            dprintf(("MIXERCONTROL_CONTROLTYPE_MUTE"));
    140             if(OSLibMixGetVolume(mixerControlId[lpmcd->dwControlID], &fMute, NULL, NULL) == FALSE) {
     167            if(OSLibMixGetVolume(mixerControls[lpmcd->dwControlID].id, &fMute, NULL, NULL) == FALSE) {
    141168                dprintf(("OSLibMixGetVolume failed!!"));
    142169                return MIXERR_INVALCONTROL;
    143170            }
    144             pDetails->dwValue = fMute;
     171            pDetails->fValue = fMute;
    145172            dprintf(("Left mute %d", fMute));
    146173            if(lpmcd->cChannels == 2) {
    147174                dprintf(("Right mute %d", fMute));
    148175                pDetails += 1;
    149                 pDetails->dwValue = fMute;
    150             }
    151             //todo > 2 channels
     176                pDetails->fValue = fMute;
     177            }
     178            //todo > 2 channels (usually only 1 channel is requested though)
    152179            return MMSYSERR_NOERROR;
    153180        }
     181
     182        case MIXERCONTROL_CONTROLTYPE_FADER:
     183        {
     184            MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     185            DWORD dwLevelL;
     186
     187            dprintf(("MIXERCONTROL_CONTROLTYPE_FADER"));
     188
     189            if(lpmcd->cChannels != 1) {
     190                dprintf(("Invalid nr of channels %d!!", lpmcd->cChannels));
     191                return MMSYSERR_INVALPARAM;
     192            }
     193            if(OSLibMixGetVolume(mixerControls[lpmcd->dwControlID].id, NULL, &dwLevelL, NULL) == FALSE) {
     194                dprintf(("OSLibMixGetVolume failed!!"));
     195                return MIXERR_INVALCONTROL;
     196            }
     197            pDetails->dwValue = dwLevelL;
     198#ifdef DEBUG
     199            if(mixerControls[lpmcd->dwControlID].id == MIX_CTRL_OUT_L_3DCENTER) {
     200                 dprintf(("3D center %d", dwLevelL));
     201            }
     202            else dprintf(("3D depth %d", dwLevelL));
     203#endif
     204            return MMSYSERR_NOERROR;
     205        }
     206
     207        case MIXERCONTROL_CONTROLTYPE_BASS:
     208        {
     209            MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     210            DWORD dwLevelL;
     211
     212            dprintf(("MIXERCONTROL_CONTROLTYPE_BASS"));
     213
     214            if(lpmcd->cChannels != 1) {
     215                dprintf(("Invalid nr of channels %d!!", lpmcd->cChannels));
     216                return MMSYSERR_INVALPARAM;
     217            }
     218            if(OSLibMixGetVolume(mixerControls[lpmcd->dwControlID].id, NULL, &dwLevelL, NULL) == FALSE) {
     219                dprintf(("OSLibMixGetVolume failed!!"));
     220                return MIXERR_INVALCONTROL;
     221            }
     222            pDetails->dwValue = dwLevelL;
     223            dprintf(("Bass %d", dwLevelL));
     224            return MMSYSERR_NOERROR;
     225        }
     226
     227        case MIXERCONTROL_CONTROLTYPE_TREBLE:
     228        {
     229            MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     230            DWORD dwLevelL;
     231
     232            dprintf(("MIXERCONTROL_CONTROLTYPE_TREBLE"));
     233
     234            if(lpmcd->cChannels != 1) {
     235                dprintf(("Invalid nr of channels %d!!", lpmcd->cChannels));
     236                return MMSYSERR_INVALPARAM;
     237            }
     238            if(OSLibMixGetVolume(mixerControls[lpmcd->dwControlID].id, NULL, &dwLevelL, NULL) == FALSE) {
     239                dprintf(("OSLibMixGetVolume failed!!"));
     240                return MIXERR_INVALCONTROL;
     241            }
     242            pDetails->dwValue = dwLevelL;
     243            dprintf(("Treble %d", dwLevelL));
     244            return MMSYSERR_NOERROR;
     245        }
     246       
     247#ifdef DEBUG
     248        case MIXERCONTROL_CONTROLTYPE_MIXER:
     249            dprintf(("MIXERCONTROL_CONTROLTYPE_MIXER"));
     250            break;
    154251        case MIXERCONTROL_CONTROLTYPE_CUSTOM:
    155252            dprintf(("MIXERCONTROL_CONTROLTYPE_CUSTOM"));
     
    221318            dprintf(("MIXERCONTROL_CONTROLTYPE_MILLITIME"));
    222319            break;
     320#endif
    223321        default:
    224322            DebugInt3();
     
    233331            return MIXERR_INVALCONTROL;
    234332        }
    235             break;
     333        switch(mixerControls[lpmcd->dwControlID].ctrl.dwControlType) {
     334        case MIXERCONTROL_CONTROLTYPE_MUX:
     335        {
     336            MIXERCONTROLDETAILS_LISTTEXTA *pDetails = (MIXERCONTROLDETAILS_LISTTEXTA *)lpmcd->paDetails;
     337            if(lpmcd->cChannels != 1) {//only accepts 1 in win2k
     338                dprintf(("invalid number of channels %d", lpmcd->cChannels));
     339                return MMSYSERR_INVALPARAM;
     340            }
     341            //this is also checked in win2k
     342            if(lpmcd->u.cMultipleItems != mixerControls[lpmcd->dwControlID].ctrl.cMultipleItems) {
     343                dprintf(("invalid cMultipleItems %d", lpmcd->u.cMultipleItems));
     344                return MMSYSERR_INVALPARAM;
     345            }
     346            //fails otherwise in win2k
     347            if(lpmcd->cbDetails != sizeof(MIXERCONTROLDETAILS_LISTTEXTA)) {
     348                dprintf(("invalid buffer size %d; should be %d", lpmcd->cbDetails, sizeof(MIXERCONTROLDETAILS_LISTTEXTA)));
     349                return MMSYSERR_INVALPARAM;
     350            }
     351            if(mixerControls[lpmcd->dwControlID].id != MIX_CTRL_MUX_IN_W_SRC) {
     352                dprintf(("oh, oh. not wavein mux"));
     353                DebugInt3();
     354                return MMSYSERR_INVALPARAM;
     355            }
     356            //clear the array
     357            memset(pDetails, 0, sizeof(MIXERCONTROLDETAILS_LISTTEXTA)*lpmcd->u.cMultipleItems);
     358            //set mux source details
     359            for(int i=0;i<nrDestinations;i++) {
     360                if(mixerDest[i].id == MIXER_DEST_WAVEIN) {
     361                    for(int j=0;j<mixerDest[i].cConnections;j++) {
     362                        dprintf(("wavein source %d (%s)", pmixerLines[mixerDest[i].Connections[j]]->id, pmixerLines[mixerDest[i].Connections[j]]->line.szName));
     363                        pDetails->dwParam1 = pmixerLines[mixerDest[i].Connections[j]]->line.dwLineID;
     364                        pDetails->dwParam2 = 0;
     365                        strncpy(pDetails->szName, pmixerLines[mixerDest[i].Connections[j]]->line.szName, sizeof(pDetails->szName));
     366                        pDetails++;
     367                    }
     368                    return MMSYSERR_NOERROR;
     369                }
     370            }
     371            DebugInt3();
     372            return MMSYSERR_INVALPARAM;
     373        }
     374        case MIXERCONTROL_CONTROLTYPE_EQUALIZER:
     375        case MIXERCONTROL_CONTROLTYPE_MIXER:
     376        case MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT:
     377        case MIXERCONTROL_CONTROLTYPE_SINGLESELECT:
     378            dprintf(("Only implemented for mux controls"));
     379            return MIXERR_INVALCONTROL;
     380           
     381        default:
     382            dprintf(("Only implemented for multiple item controls"));
     383            return MIXERR_INVALCONTROL;
     384        }
     385
    236386    default:
    237387            dprintf(("Unknown flag (%08lx)\n", fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK));
     
    257407    case MIXER_GETCONTROLDETAILSF_LISTTEXT:
    258408        {
    259             LPVOID      paDetailsW = lpmcd->paDetails;
    260             int         size = max(1, lpmcd->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
    261 
    262             if (lpmcd->u.cMultipleItems != 0 && lpmcd->u.cMultipleItems != lpmcd->u.hwndOwner) {
     409        MIXERCONTROLDETAILS_LISTTEXTW *pDetailsW = (MIXERCONTROLDETAILS_LISTTEXTW *)lpmcd->paDetails;
     410        MIXERCONTROLDETAILS_LISTTEXTA *pDetailsA;
     411            int size = max(1, lpmcd->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
     412        int i;
     413
     414            if (lpmcd->u.cMultipleItems != 0) {
    263415                    size *= lpmcd->u.cMultipleItems;
    264416            }
    265             lpmcd->paDetails = HeapAlloc(GetProcessHeap(), 0, size);
     417            pDetailsA = (MIXERCONTROLDETAILS_LISTTEXTA *)HeapAlloc(GetProcessHeap(), 0, size);
     418        lpmcd->paDetails = pDetailsA;
     419        lpmcd->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
    266420            /* set up lpmcd->paDetails */
    267421            ret = mixerGetControlDetailsA(hmxobj, lpmcd, fdwDetails);
    268422            /* copy from lpmcd->paDetails back to paDetailsW; */
    269             HeapFree(GetProcessHeap(), 0, lpmcd->paDetails);
    270             lpmcd->paDetails = paDetailsW;
     423        if(ret == MMSYSERR_NOERROR) {
     424            for(i=0;i<lpmcd->u.cMultipleItems*lpmcd->cChannels;i++) {
     425                pDetailsW->dwParam1 = pDetailsA->dwParam1;
     426                pDetailsW->dwParam2 = pDetailsA->dwParam2;
     427                MultiByteToWideChar( CP_ACP, 0, pDetailsA->szName, -1,
     428                                     pDetailsW->szName,
     429                                     sizeof(pDetailsW->szName)/sizeof(WCHAR) );
     430                pDetailsA++;
     431                pDetailsW++;
     432            }
     433            pDetailsA -= lpmcd->u.cMultipleItems*lpmcd->cChannels;
     434            pDetailsW -= lpmcd->u.cMultipleItems*lpmcd->cChannels;
     435        }
     436            HeapFree(GetProcessHeap(), 0, pDetailsA);
     437            lpmcd->paDetails = pDetailsW;
     438        lpmcd->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
    271439            break;
    272440        }
     
    305473    switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
    306474    case MIXER_GETCONTROLDETAILSF_VALUE:
    307         dprintf(("MIXER_GETCONTROLDETAILSF_VALUE"));
    308         break;
     475        dprintf(("MIXER_GETCONTROLDETAILSF_VALUE %d (internal id %d)", lpmcd->dwControlID, mixerControls[lpmcd->dwControlID].id));
     476        if(lpmcd->dwControlID >= nrControls) {
     477            dprintf(("invalid control %d", lpmcd->dwControlID));
     478            return MIXERR_INVALCONTROL;
     479        }
     480        if(lpmcd->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED)) {
     481            dprintf(("not enough room in buffer (%d)", lpmcd->cbDetails));
     482            return MMSYSERR_INVALPARAM;
     483        }
     484        switch(mixerControls[lpmcd->dwControlID].ctrl.dwControlType) {
     485        case MIXERCONTROL_CONTROLTYPE_MUX:
     486        {
     487            MIXERCONTROLDETAILS_BOOLEAN *pDetails = (MIXERCONTROLDETAILS_BOOLEAN *)lpmcd->paDetails;
     488            DWORD dwRecSrc;
     489
     490            dprintf(("MIXERCONTROL_CONTROLTYPE_MUX"));
     491            if(lpmcd->cChannels != 1) {//only accepts 1 in win2k
     492                dprintf(("invalid number of channels %d", lpmcd->cChannels));
     493                return MMSYSERR_INVALPARAM;
     494            }
     495            //this is also checked in win2k
     496            if(lpmcd->u.cMultipleItems != mixerControls[lpmcd->dwControlID].ctrl.cMultipleItems) {
     497                dprintf(("invalid cMultipleItems %d", lpmcd->u.cMultipleItems));
     498                return MMSYSERR_INVALPARAM;
     499            }
     500
     501            if(mixerControls[lpmcd->dwControlID].id != MIX_CTRL_MUX_IN_W_SRC) {
     502                dprintf(("oh, oh. not wavein mux"));
     503                DebugInt3();
     504                return MMSYSERR_INVALPARAM;
     505            }
     506#if 0
     507            if(OSLibMixGetRecSource(&dwRecSrc, NULL, NULL) == FALSE) {
     508                dprintf(("OSLibMixGetRecSource failed!!"));
     509                return MIXERR_INVALCONTROL;
     510            }
     511            //clear the array
     512            memset(pDetails, 0, sizeof(MIXERCONTROLDETAILS_BOOLEAN)*lpmcd->u.cMultipleItems);
     513            //mark recording source
     514            for(int i=0;i<nrDestinations;i++) {
     515                if(mixerDest[i].id == MIXER_DEST_WAVEIN) {
     516                    for(int j=0;j<mixerDest[i].cConnections;j++) {
     517                        dprintf(("wavein source %d (id %d)", pmixerLines[mixerDest[i].Connections[j]]->id, mixerDest[i].Connections[j]));
     518                        if(pmixerLines[mixerDest[i].Connections[j]]->id == dwRecSrc) {
     519                            pDetails[j].fValue = 1;
     520                            return MMSYSERR_NOERROR;
     521                        }
     522                    }
     523                }
     524            }
     525            dprintf(("recording source %d not found!!", dwRecSrc));
     526#endif
     527            break;
     528        }
     529
     530        case MIXERCONTROL_CONTROLTYPE_VOLUME: //unsigned
     531        {
     532            MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     533
     534            dprintf(("MIXERCONTROL_CONTROLTYPE_VOLUME"));
     535            dprintf(("Left volume %d", pDetails->dwValue));
     536            if(lpmcd->cChannels == 2) {
     537                pDetails += 1;
     538                dprintf(("Right volume %d", pDetails->dwValue));
     539            }
     540            //todo > 2 channels
     541            return MMSYSERR_NOERROR;
     542        }
     543
     544        case MIXERCONTROL_CONTROLTYPE_MUTE: //assuming boolean
     545        {
     546            MIXERCONTROLDETAILS_BOOLEAN *pDetails = (MIXERCONTROLDETAILS_BOOLEAN *)lpmcd->paDetails;
     547
     548            dprintf(("MIXERCONTROL_CONTROLTYPE_MUTE"));
     549            dprintf(("Left mute %d", pDetails->fValue));
     550            if(lpmcd->cChannels == 2) {
     551                pDetails += 1;
     552                dprintf(("Right mute %d", pDetails->fValue));
     553            }
     554            //todo > 2 channels (usually only 1 channel is requested though)
     555            return MMSYSERR_NOERROR;
     556        }
     557
     558        case MIXERCONTROL_CONTROLTYPE_FADER:
     559        {
     560            MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     561
     562            dprintf(("MIXERCONTROL_CONTROLTYPE_FADER"));
     563
     564            if(lpmcd->cChannels != 1) {
     565                dprintf(("Invalid nr of channels %d!!", lpmcd->cChannels));
     566                return MMSYSERR_INVALPARAM;
     567            }
     568#ifdef DEBUG
     569            if(mixerControls[lpmcd->dwControlID].id == MIX_CTRL_OUT_L_3DCENTER) {
     570                 dprintf(("3D center %d", pDetails->dwValue));
     571            }
     572            else dprintf(("3D depth %d", pDetails->dwValue));
     573#endif
     574            return MMSYSERR_NOERROR;
     575        }
     576
     577        case MIXERCONTROL_CONTROLTYPE_BASS:
     578        {
     579            MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     580
     581            dprintf(("MIXERCONTROL_CONTROLTYPE_BASS"));
     582
     583            if(lpmcd->cChannels != 1) {
     584                dprintf(("Invalid nr of channels %d!!", lpmcd->cChannels));
     585                return MMSYSERR_INVALPARAM;
     586            }
     587            dprintf(("Bass %d", pDetails->dwValue));
     588            return MMSYSERR_NOERROR;
     589        }
     590
     591        case MIXERCONTROL_CONTROLTYPE_TREBLE:
     592        {
     593            MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)lpmcd->paDetails;
     594
     595            dprintf(("MIXERCONTROL_CONTROLTYPE_TREBLE"));
     596
     597            if(lpmcd->cChannels != 1) {
     598                dprintf(("Invalid nr of channels %d!!", lpmcd->cChannels));
     599                return MMSYSERR_INVALPARAM;
     600            }
     601            dprintf(("Treble %d", pDetails->dwValue));
     602            return MMSYSERR_NOERROR;
     603        }
     604       
     605#ifdef DEBUG
     606        case MIXERCONTROL_CONTROLTYPE_MIXER:
     607            dprintf(("MIXERCONTROL_CONTROLTYPE_MIXER"));
     608            break;
     609        case MIXERCONTROL_CONTROLTYPE_CUSTOM:
     610            dprintf(("MIXERCONTROL_CONTROLTYPE_CUSTOM"));
     611            break;
     612        case MIXERCONTROL_CONTROLTYPE_BOOLEANMETER:
     613            dprintf(("MIXERCONTROL_CONTROLTYPE_BOOLEANMETER"));
     614            break;
     615        case MIXERCONTROL_CONTROLTYPE_SIGNEDMETER:
     616            dprintf(("MIXERCONTROL_CONTROLTYPE_SIGNEDMETER"));
     617            break;
     618        case MIXERCONTROL_CONTROLTYPE_PEAKMETER:
     619            dprintf(("MIXERCONTROL_CONTROLTYPE_PEAKMETER"));
     620            break;
     621        case MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER:
     622            dprintf(("MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER"));
     623            break;
     624        case MIXERCONTROL_CONTROLTYPE_BOOLEAN:
     625            dprintf(("MIXERCONTROL_CONTROLTYPE_BOOLEAN"));
     626            break;
     627        case MIXERCONTROL_CONTROLTYPE_ONOFF:
     628            dprintf(("MIXERCONTROL_CONTROLTYPE_ONOFF"));
     629            break;
     630        case MIXERCONTROL_CONTROLTYPE_MONO:
     631            dprintf(("MIXERCONTROL_CONTROLTYPE_MONO"));
     632            break;
     633        case MIXERCONTROL_CONTROLTYPE_LOUDNESS:
     634            dprintf(("MIXERCONTROL_CONTROLTYPE_LOUDNESS"));
     635            break;
     636        case MIXERCONTROL_CONTROLTYPE_STEREOENH:
     637            dprintf(("MIXERCONTROL_CONTROLTYPE_STEREOENH"));
     638            break;
     639        case MIXERCONTROL_CONTROLTYPE_BUTTON:
     640            dprintf(("MIXERCONTROL_CONTROLTYPE_BUTTON"));
     641            break;
     642        case MIXERCONTROL_CONTROLTYPE_DECIBELS:
     643            dprintf(("MIXERCONTROL_CONTROLTYPE_DECIBELS"));
     644            break;
     645        case MIXERCONTROL_CONTROLTYPE_SIGNED:
     646            dprintf(("MIXERCONTROL_CONTROLTYPE_SIGNED"));
     647            break;
     648        case MIXERCONTROL_CONTROLTYPE_UNSIGNED:
     649            dprintf(("MIXERCONTROL_CONTROLTYPE_UNSIGNED"));
     650            break;
     651        case MIXERCONTROL_CONTROLTYPE_PERCENT:
     652            dprintf(("MIXERCONTROL_CONTROLTYPE_PERCENT"));
     653            break;
     654        case MIXERCONTROL_CONTROLTYPE_SLIDER:
     655            dprintf(("MIXERCONTROL_CONTROLTYPE_SLIDER"));
     656            break;
     657        case MIXERCONTROL_CONTROLTYPE_PAN:
     658            dprintf(("MIXERCONTROL_CONTROLTYPE_PAN"));
     659            break;
     660        case MIXERCONTROL_CONTROLTYPE_QSOUNDPAN:
     661            dprintf(("MIXERCONTROL_CONTROLTYPE_QSOUNDPAN"));
     662            break;
     663        case MIXERCONTROL_CONTROLTYPE_EQUALIZER:
     664            dprintf(("MIXERCONTROL_CONTROLTYPE_EQUALIZER"));
     665            break;
     666        case MIXERCONTROL_CONTROLTYPE_SINGLESELECT:
     667            dprintf(("MIXERCONTROL_CONTROLTYPE_SINGLESELECT"));
     668            break;
     669        case MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT:
     670            dprintf(("MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT"));
     671            break;
     672        case MIXERCONTROL_CONTROLTYPE_MICROTIME:
     673            dprintf(("MIXERCONTROL_CONTROLTYPE_MICROTIME"));
     674            break;
     675        case MIXERCONTROL_CONTROLTYPE_MILLITIME:
     676            dprintf(("MIXERCONTROL_CONTROLTYPE_MILLITIME"));
     677            break;
     678#endif
     679        default:
     680            DebugInt3();
     681            return MIXERR_INVALCONTROL;
     682        }
     683        return MIXERR_INVALCONTROL;
    309684    case MIXER_GETCONTROLDETAILSF_LISTTEXT:
    310685        dprintf(("MIXER_GETCONTROLDETAILSF_LISTTEXT"));
     
    353728            return MIXERR_INVALLINE;
    354729        }
    355         pLine = pmixerLines[lpMlc->dwLineID];
     730        pLine = &pmixerLines[lpMlc->dwLineID]->line;
    356731        if(lpMlc->cControls != pLine->cControls || lpMlc->cbmxctrl < pLine->cControls*sizeof(MIXERCONTROLA)) {
    357732            dprintf(("ERROR: invalid nr of controls %d or structure size %d (%d) (ptr %x)", lpMlc->cControls, lpMlc->cbmxctrl, pLine->cControls*sizeof(MIXERCONTROLA), lpMlc->pamxctrl));
     
    360735        for(int i=0;i<lpMlc->cControls;i++) {
    361736            pCtrl = lpMlc->pamxctrl+i;
    362             memcpy(pCtrl, &mixerControls[mixerLineControls[lpMlc->dwLineID][i]], sizeof(MIXERCONTROLA));
     737            memcpy(pCtrl, &pmixerLines[lpMlc->dwLineID]->Controls[i], sizeof(MIXERCONTROLA));
    363738            dprintf(("found control %s (%s) control id %d", pCtrl->szName, pCtrl->szShortName, pCtrl->dwControlID));
    364739        }
     
    379754        //find line associated with this control
    380755        lpMlc->dwLineID = -1;
    381         for(int i=0;i<MAX_MIXER_LINES;i++) {
    382             for(int j=0;j<MAX_SOURCE_CONTROLS;j++) {
    383                 if(mixerLineControls[i][j] == lpMlc->u.dwControlID) {
     756        for(int i=0;i<nrLines;i++) {
     757            for(int j=0;j<pmixerLines[i]->cControls;j++) {
     758                if(pmixerLines[i]->Controls[j] == lpMlc->u.dwControlID) {
    384759                    lpMlc->dwLineID = i;
    385760                    break;
    386761                }
    387762                else
    388                 if(mixerLineControls[i][j] == -1) {
     763                if(pmixerLines[i]->Controls[j] == -1) {
    389764                    break;
    390765                }
     
    398773            return MIXERR_INVALCONTROL;
    399774        }
    400         memcpy(lpMlc->pamxctrl, &mixerControls[lpMlc->u.dwControlID], sizeof(MIXERCONTROLA));
     775        memcpy(lpMlc->pamxctrl, &mixerControls[lpMlc->u.dwControlID].ctrl, sizeof(MIXERCONTROLA));
    401776
    402777        dprintf(("found control %s (%s) associated line %d", lpMlc->pamxctrl->szName, lpMlc->pamxctrl->szShortName, lpMlc->dwLineID));
     
    509884        int idx;
    510885
    511         for(int i=0;i<MAX_SOURCE_CONTROLS;i++) {
    512             idx = mixerLineControls[lpMlc->dwLineID][i];
    513             if(idx == -1) break;
    514             if(mixerControls[idx].dwControlType == lpMlc->u.dwControlType) {
    515                 memcpy(lpMlc->pamxctrl, &mixerControls[idx], sizeof(MIXERCONTROLA));
     886        for(int i=0;i<pmixerLines[lpMlc->dwLineID]->cControls;i++) {
     887            idx = pmixerLines[lpMlc->dwLineID]->Controls[i];
     888            if(mixerControls[idx].ctrl.dwControlType == lpMlc->u.dwControlType) {
     889                memcpy(lpMlc->pamxctrl, &mixerControls[idx].ctrl, sizeof(MIXERCONTROLA));
    516890                dprintf(("found control %s (%s) control id %d", lpMlc->pamxctrl->szName, lpMlc->pamxctrl->szShortName, lpMlc->pamxctrl->dwControlID));
    517891                return MMSYSERR_NOERROR;
     
    623997            return MIXERR_INVALLINE;
    624998        }
    625         memcpy(lpMl, pmixerLines[lpMl->dwLineID], sizeof(MIXERLINEA));
     999        memcpy(lpMl, &pmixerLines[lpMl->dwLineID]->line, sizeof(MIXERLINEA));
    6261000        dprintf(("found line %s (%s) connections %d controls %d", lpMl->szName, lpMl->szShortName, lpMl->cConnections, lpMl->cControls));
    6271001        break;
     
    6371011            return MIXERR_INVALLINE;
    6381012        }
    639         if(mixerDest[lpMl->dwDestination].Sources[lpMl->dwSource] == -1) {
     1013        if(mixerDest[lpMl->dwDestination].Connections[lpMl->dwSource] == -1) {
    6401014            dprintf(("ERROR: Invalid destination/source combo (%d,%d)", lpMl->dwDestination, lpMl->dwSource));
    6411015            return MIXERR_INVALLINE;
    6421016        }
    643         memcpy(lpMl, &mixerSource[mixerDest[lpMl->dwDestination].Sources[lpMl->dwSource]], sizeof(MIXERLINEA));
     1017        memcpy(lpMl, &mixerSource[mixerDest[lpMl->dwDestination].Connections[lpMl->dwSource]], sizeof(MIXERLINEA));
    6441018        dprintf(("found line %s (%s) id %d connections %d controls %d", lpMl->szName, lpMl->szShortName, lpMl->dwLineID, lpMl->cConnections, lpMl->cControls));
    6451019        break;
     
    7181092        //search all lines (src & dest) for one with specified type
    7191093        for(int i=0;i<nrLines;i++) {
    720             if(pmixerLines[i]->dwComponentType == lpMl->dwComponentType) {
     1094            if(pmixerLines[i]->line.dwComponentType == lpMl->dwComponentType) {
    7211095                break;
    7221096            }
     
    7261100            return MIXERR_INVALLINE;
    7271101        }
    728         memcpy(lpMl, pmixerLines[i], sizeof(MIXERLINEA));
     1102        memcpy(lpMl, &pmixerLines[i]->line, sizeof(MIXERLINEA));
    7291103        dprintf(("found line %s (%s) id %d connections %d controls %d", lpMl->szName, lpMl->szShortName, lpMl->dwLineID, lpMl->cConnections, lpMl->cControls));
    7301104            break;
     
    7621136        //      (see below; unicode version doesn't copy pddname; change if these checks are required)
    7631137        for(int i=0;i<nrLines;i++) {
    764             if(pmixerLines[i]->Target.dwType == lpMl->Target.dwType) {
     1138            if(pmixerLines[i]->line.Target.dwType == lpMl->Target.dwType) {
    7651139                break;
    7661140            }
     
    7701144            return MIXERR_INVALLINE;
    7711145        }
    772         memcpy(lpMl, pmixerLines[i], sizeof(MIXERLINEA));
     1146        memcpy(lpMl, &pmixerLines[i]->line, sizeof(MIXERLINEA));
    7731147        dprintf(("found line %s (%s) id %d connections %d controls %d", lpMl->szName, lpMl->szShortName, lpMl->dwLineID, lpMl->cConnections, lpMl->cControls));
    7741148        break;
     
    9811355BOOL mixerInit()
    9821356{
    983     MIXERDEST *pDestLine;
     1357    MIXLINE *pDestLine;
    9841358    MIXERCONTROLA *pWaveInMux;
    9851359
    9861360    if(!fMMPMAvailable) return TRUE;
    9871361
    988     memset(mixerSourceLineId, -1, sizeof(mixerSourceLineId));
    989     memset(mixerLineControls, -1, sizeof(mixerLineControls));
    9901362    memset(mixerDest, 0, sizeof(mixerDest));
    9911363    for(int i=0;i<MIXER_DEST_MAX;i++) {
    992         memset(mixerDest[i].Sources, -1, sizeof(mixerDest[i].Sources));
    993     }
    994 
     1364        memset(mixerDest[i].Connections, -1, sizeof(mixerDest[i].Connections));
     1365        memset(mixerDest[i].Controls, -1, sizeof(mixerDest[i].Controls));
     1366    }
     1367    memset(mixerSource, 0, sizeof(mixerSource));
     1368    for(i=0;i<MIXER_SRC_MAX;i++) {
     1369        memset(mixerSource[i].Connections, -1, sizeof(mixerSource[i].Connections));
     1370        memset(mixerSource[i].Controls, -1, sizeof(mixerSource[i].Controls));
     1371        mixerSource[i].id = -1;
     1372    }
    9951373    if(OSLibMixerOpen() == FALSE) {
    9961374        //Line out destination
    9971375        pDestLine = mixerAddDestination(MIXER_DEST_LINEOUT);
    998         mixerAddControl(MIX_CTRL_VOL_OUT_LINE, &pDestLine->line);
    999         mixerAddControl(MIX_CTRL_MUTE_OUT_LINE, &pDestLine->line);
     1376        mixerAddControl(MIX_CTRL_VOL_OUT_LINE, pDestLine);
     1377        mixerAddControl(MIX_CTRL_MUTE_OUT_LINE, pDestLine);
    10001378
    10011379        //WaveIn destination
    10021380        pDestLine  = mixerAddDestination(MIXER_DEST_WAVEIN);
    1003         pWaveInMux = mixerAddControl(MIX_CTRL_MUX_IN_W_SRC, &pDestLine->line);
    1004         mixerAddControl(MIX_CTRL_VOL_IN_W_MIC, &pDestLine->line);
    1005         mixerAddControl(MIX_CTRL_VOL_IN_W_LINE, &pDestLine->line);
     1381        pWaveInMux = mixerAddControl(MIX_CTRL_MUX_IN_W_SRC, pDestLine);
     1382        mixerAddControl(MIX_CTRL_VOL_IN_W_MIC, pDestLine);
     1383        mixerAddControl(MIX_CTRL_VOL_IN_W_LINE, pDestLine);
    10061384        pWaveInMux->cMultipleItems = pDestLine->line.cConnections;
    10071385        return TRUE;
     
    10111389    pDestLine = mixerAddDestination(MIXER_DEST_LINEOUT);
    10121390
    1013     mixerAddControl(MIX_CTRL_VOL_OUT_LINE, &pDestLine->line);
    1014     mixerAddControl(MIX_CTRL_MUTE_OUT_LINE, &pDestLine->line);
     1391    mixerAddControl(MIX_CTRL_VOL_OUT_LINE, pDestLine);
     1392    mixerAddControl(MIX_CTRL_MUTE_OUT_LINE, pDestLine);
    10151393    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DCENTER)) {
    1016         mixerAddControl(MIX_CTRL_OUT_L_3DCENTER, &pDestLine->line);
     1394        mixerAddControl(MIX_CTRL_OUT_L_3DCENTER, pDestLine);
    10171395    }
    10181396    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_3DDEPTH)) {
    1019         mixerAddControl(MIX_CTRL_OUT_L_3DDEPTH, &pDestLine->line);
     1397        mixerAddControl(MIX_CTRL_OUT_L_3DDEPTH, pDestLine);
    10201398    }
    10211399    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_TREBLE)) {
    1022         mixerAddControl(MIX_CTRL_OUT_L_TREBLE, &pDestLine->line);
     1400        mixerAddControl(MIX_CTRL_OUT_L_TREBLE, pDestLine);
    10231401    }
    10241402    if(OSLibMixIsControlPresent(MIX_CTRL_OUT_L_BASS)) {
    1025         mixerAddControl(MIX_CTRL_OUT_L_BASS, &pDestLine->line);
     1403        mixerAddControl(MIX_CTRL_OUT_L_BASS, pDestLine);
    10261404    }
    10271405
    10281406    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_PCM)) {
    1029         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_PCM);
     1407        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_PCM);
    10301408        mixerAddControl(MIX_CTRL_VOL_IN_L_PCM, pLine);
    10311409        mixerAddControl(MIX_CTRL_MUTE_IN_L_PCM, pLine);
    10321410    }
    10331411    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_WAVETABLE)) {
    1034         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_WAVETABLE);
     1412        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_WAVETABLE);
    10351413        mixerAddControl(MIX_CTRL_VOL_IN_L_WAVETABLE, pLine);
    10361414        mixerAddControl(MIX_CTRL_MUTE_IN_L_WAVETABLE, pLine);
    10371415    }
    10381416    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MIDI)) {
    1039         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_MIDI);
     1417        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_MIDI);
    10401418        mixerAddControl(MIX_CTRL_VOL_IN_L_MIDI, pLine);
    10411419        mixerAddControl(MIX_CTRL_MUTE_IN_L_MIDI, pLine);
    10421420    }
    10431421    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MIC)) {
    1044         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_MIC);
     1422        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_MIC);
    10451423        mixerAddControl(MIX_CTRL_VOL_IN_L_MIC, pLine);
    10461424        mixerAddControl(MIX_CTRL_MUTE_IN_L_MIC, pLine);
     
    10501428    }
    10511429    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_LINE)) {
    1052         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_LINE);
     1430        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_LINE);
    10531431        mixerAddControl(MIX_CTRL_VOL_IN_L_LINE, pLine);
    10541432        mixerAddControl(MIX_CTRL_MUTE_IN_L_LINE, pLine);
    10551433    }
    10561434    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_CD)) {
    1057         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_CD);
     1435        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_CD);
    10581436        mixerAddControl(MIX_CTRL_VOL_IN_L_CD, pLine);
    10591437        mixerAddControl(MIX_CTRL_MUTE_IN_L_CD, pLine);
    10601438    }
    10611439    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_AUX)) {
    1062         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_AUX);
     1440        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_AUX);
    10631441        mixerAddControl(MIX_CTRL_VOL_IN_L_AUX, pLine);
    10641442        mixerAddControl(MIX_CTRL_MUTE_IN_L_AUX, pLine);
    10651443    }
    10661444    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_SPDIF)) {
    1067         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_SPDIF);
     1445        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_SPDIF);
    10681446        mixerAddControl(MIX_CTRL_VOL_IN_L_SPDIF, pLine);
    10691447        mixerAddControl(MIX_CTRL_MUTE_IN_L_SPDIF, pLine);
    10701448    }
    10711449    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_MONO)) {
    1072         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_MONOIN);
     1450        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_MONOIN);
    10731451        mixerAddControl(MIX_CTRL_VOL_IN_L_MONO, pLine);
    10741452        mixerAddControl(MIX_CTRL_MUTE_IN_L_MONO, pLine);
    10751453    }
    10761454    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_PHONE)) {
    1077         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_PHONE);
     1455        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_PHONE);
    10781456        mixerAddControl(MIX_CTRL_VOL_IN_L_PHONE, pLine);
    10791457        mixerAddControl(MIX_CTRL_MUTE_IN_L_PHONE, pLine);
    10801458    }
    10811459    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_IN_L_VIDEO)) {
    1082         MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_VIDEO);
     1460        MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_L_VIDEO);
    10831461        mixerAddControl(MIX_CTRL_VOL_IN_L_VIDEO, pLine);
    10841462        mixerAddControl(MIX_CTRL_MUTE_IN_L_VIDEO, pLine);
     
    10881466    if(OSLibMixIsControlPresent(MIX_CTRL_MUX_IN_W_SRC)) {
    10891467        pDestLine = mixerAddDestination(MIXER_DEST_WAVEIN);
    1090         pWaveInMux = mixerAddControl(MIX_CTRL_MUX_IN_W_SRC, &pDestLine->line);
     1468        pWaveInMux = mixerAddControl(MIX_CTRL_MUX_IN_W_SRC, pDestLine);
    10911469
    10921470        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_MIC)) {
    1093             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MIC);
     1471            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MIC);
    10941472            mixerAddControl(MIX_CTRL_VOL_IN_W_MIC, pLine);
    10951473        }
    10961474        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_LINE)) {
    1097             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_LINE);
     1475            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_LINE);
    10981476            mixerAddControl(MIX_CTRL_VOL_IN_W_LINE, pLine);
    10991477        }
    11001478        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_CD)) {
    1101             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_CD);
     1479            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_CD);
    11021480            mixerAddControl(MIX_CTRL_VOL_IN_W_CD, pLine);
    11031481        }
    11041482        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_AUX)) {
    1105             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_AUX);
     1483            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_AUX);
    11061484            mixerAddControl(MIX_CTRL_VOL_IN_W_AUX, pLine);
    11071485        }
    11081486        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_PCM)) {
    1109             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_PCM);
     1487            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_PCM);
    11101488            mixerAddControl(MIX_CTRL_VOL_IN_W_PCM, pLine);
    11111489        }
    11121490        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_WAVETABLE)) {
    1113             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_WAVETABLE);
     1491            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_WAVETABLE);
    11141492            mixerAddControl(MIX_CTRL_VOL_IN_W_WAVETABLE, pLine);
    11151493        }
    11161494        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_MIDI)) {
    1117             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MIDI);
     1495            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MIDI);
    11181496            mixerAddControl(MIX_CTRL_VOL_IN_W_MIDI, pLine);
    11191497        }
    11201498        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_MONOIN)) {
    1121             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MONOIN);
     1499            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MONOIN);
    11221500            mixerAddControl(MIX_CTRL_VOL_IN_W_MONO, pLine);
    11231501        }
    11241502        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_PHONE)) {
    1125             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_PHONE);
     1503            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_PHONE);
    11261504            mixerAddControl(MIX_CTRL_VOL_IN_W_PHONE, pLine);
    11271505        }
    11281506        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_SPDIF)) {
    1129             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_SPDIF);
     1507            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_SPDIF);
    11301508            mixerAddControl(MIX_CTRL_VOL_IN_W_SPDIF, pLine);
    11311509        }
    11321510        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_VIDEO)) {
    1133             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_VIDEO);
     1511            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_VIDEO);
    11341512            mixerAddControl(MIX_CTRL_VOL_IN_W_VIDEO, pLine);
    11351513        }
    11361514        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_STEREOMIX)) {
    1137             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_STEREOMIX);
     1515            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_STEREOMIX);
    11381516            mixerAddControl(MIX_CTRL_VOL_IN_W_STEREOMIX, pLine);
    11391517        }
    11401518        if(OSLibMixIsRecSourcePresent(MIXER_SRC_IN_W_MONOMIX)) {
    1141             MIXERLINEA *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MONOMIX);
     1519            MIXLINE *pLine = mixerAddSource(pDestLine, MIXER_SRC_IN_W_MONOMIX);
    11421520            mixerAddControl(MIX_CTRL_VOL_IN_W_MONOMIX, pLine);
    11431521        }
     
    11511529    if(OSLibMixIsControlPresent(MIX_CTRL_VOL_OUT_SPDIF)) {
    11521530        pDestLine = mixerAddDestination(MIXER_DEST_SPDIFOUT);
    1153         mixerAddControl(MIX_CTRL_VOL_OUT_SPDIF, &pDestLine->line);
    1154         mixerAddControl(MIX_CTRL_MUTE_OUT_SPDIF, &pDestLine->line);
     1531        mixerAddControl(MIX_CTRL_VOL_OUT_SPDIF, pDestLine);
     1532        mixerAddControl(MIX_CTRL_MUTE_OUT_SPDIF, pDestLine);
    11551533    }
    11561534
     
    11651543/******************************************************************************/
    11661544/******************************************************************************/
    1167 static MIXERLINEA *mixerAddSource(MIXERDEST *pDestLine, DWORD dwSource)
     1545static MIXLINE *mixerAddSource(MIXLINE *pDestLine, DWORD dwSource)
    11681546{
    1169     MIXERLINEA *pline = &mixerSource[nrSources];
     1547    MIXLINE    *pSource = &mixerSource[nrSources];
     1548    MIXERLINEA *pline   = &pSource->line;
    11701549
    11711550    if(nrSources >= MAX_MIXER_SOURCES) {
     
    11821561    pline->dwDestination         = 0;
    11831562    pline->fdwLine               = MIXERLINE_LINEF_SOURCE;
    1184     pline->dwSource              = nrSources;
    11851563    pline->Target.dwDeviceID     = 0;
    11861564    pline->Target.wMid           = WINMM_MIXER_CAPS_WMID;
    11871565    pline->Target.vDriverVersion = WINMM_MIXER_CAPS_VERSION;
     1566    pline->dwSource              = nrSources;
     1567    nrSources++;
    11881568
    11891569    switch(dwSource) {
     
    12631643    strncpy(pline->Target.szPname, WINMM_MIXERSTRING_A, sizeof(pline->Target.szPname));
    12641644
    1265     dprintf(("Adding Source %s (%s)", pline->szName, pline->szShortName));
    1266     nrSources++;
    1267 
     1645    //add to array of mixer line pointers
    12681646    pline->dwLineID      = nrLines;
    1269     pmixerLines[nrLines] = pline;
     1647    pmixerLines[nrLines] = pSource;
    12701648    nrLines++;
     1649
     1650    //store line id in source to line mapping array
     1651    pSource->id = dwSource;
    12711652
    12721653    //increase nr of inputs at destination line
    12731654    pDestLine->line.cConnections++;
    1274     pDestLine->Sources[pDestLine->cSources] = pline->dwSource;
    1275     pDestLine->cSources++;
    1276 
    1277     //store line id in source to line mapping array
    1278     mixerSourceLineId[dwSource] = pline->dwLineID;
    1279 
    1280     return pline;
     1655    pDestLine->Connections[pDestLine->cConnections] = pline->dwLineID;
     1656    pDestLine->cConnections++;
     1657
     1658    dprintf(("Adding Source %s (%s) with destination %s (%d -> %d)", pline->szName, pline->szShortName, pDestLine->line.szName, dwSource, pline->dwLineID));
     1659
     1660    return pSource;
    12811661}
    12821662/******************************************************************************/
    12831663/******************************************************************************/
    1284 static MIXERDEST *mixerAddDestination(DWORD dwDest)
     1664static MIXLINE *mixerAddDestination(DWORD dwDest)
    12851665{
    1286     MIXERDEST  *pDest  = &mixerDest[nrDestinations];
     1666    MIXLINE    *pDest  = &mixerDest[nrDestinations];
    12871667    MIXERLINEA *pline  = &pDest->line;
    12881668
     
    13371717
    13381718    pline->dwLineID      = nrLines;
    1339     pmixerLines[nrLines] = pline;
     1719    pmixerLines[nrLines] = pDest;
    13401720    nrLines++;
     1721
     1722    //save internal id
     1723    pDest->id = dwDest;
    13411724    return pDest;
    13421725}
    13431726/******************************************************************************/
    13441727/******************************************************************************/
    1345 static MIXERCONTROLA * mixerAddControl(DWORD dwControl, MIXERLINEA *pSrcLine)
     1728static MIXERCONTROLA * mixerAddControl(DWORD dwControl, MIXLINE *pSrcLine)
    13461729{
    1347     MIXERCONTROLA *pctrl  = &mixerControls[nrControls];
     1730    MIXCONTROL    *pmixctrl = &mixerControls[nrControls];
     1731    MIXERCONTROLA *pctrl    = &pmixctrl->ctrl;
    13481732
    13491733    if(nrControls >= MAX_MIXER_CONTROLS) {
     
    14671851 
    14681852    //add control to list of controls associated with source line
    1469     for(int i=0;i<MAX_SOURCE_CONTROLS;i++) {
    1470         if(mixerLineControls[pSrcLine->dwLineID][i] == -1) {
    1471             mixerLineControls[pSrcLine->dwLineID][i] = pctrl->dwControlID;
    1472             break;
    1473         }
    1474     }
    1475     if(i == MAX_SOURCE_CONTROLS) {
    1476         DebugInt3();
    1477     }
    1478     //increase nr of controls of corresponding source line
     1853    pSrcLine->Controls[pSrcLine->cControls] = pctrl->dwControlID;
    14791854    pSrcLine->cControls++;
    14801855
     
    14831858
    14841859    //save internal id
    1485     mixerControlId[nrControls] = dwControl;
     1860    pmixctrl->id = dwControl;
    14861861    nrControls++;
    14871862    dprintf(("Adding control %s (%s)", pctrl->szName, pctrl->szShortName));
  • trunk/src/winmm/mixer.h

    r8493 r8495  
    1 /* $Id: mixer.h,v 1.4 2002-05-26 10:52:31 sandervl Exp $ */
     1/* $Id: mixer.h,v 1.5 2002-05-27 15:49:55 sandervl Exp $ */
    22
    33/*
     
    2626#define MAX_MIXER_SOURCES           16
    2727#define MAX_MIXER_CONTROLS          64
    28 
     28#define MAX_MIXER_CONTROL_VAL       16
    2929
    3030#ifdef __WINE_MMSYSTEM_H
    3131typedef struct {
    32   MIXERLINEA line;
    33   //number of connected source lines
    34   int        cSources;
    35   int        Sources[MAX_MIXER_SOURCES];
    36 } MIXERDEST;
     32    MIXERLINEA line;
     33    int        cControls;
     34    //array of associated control (index in mixerControls)
     35    int        Controls[MAX_SOURCE_CONTROLS];
     36    int        cConnections;
     37    //array of connected line (index in pmixerLines)
     38    int        Connections[MAX_MIXER_SOURCES];
     39    int        id;      //internal id
     40} MIXLINE, *PMIXLINE;
     41
     42typedef struct {
     43    MIXERCONTROLA                 ctrl;
     44    //control value(s)
     45    MIXERCONTROLDETAILS_UNSIGNED  val[MAX_MIXER_CONTROL_VAL];
     46    int                           id;   //internal id
     47} MIXCONTROL, *PMIXCONTROL;
     48
    3749#endif
    3850
Note: See TracChangeset for help on using the changeset viewer.