This patch aims at removing dependency on hardware mixers to all other supported platforms save, irix, solaris, and qnx as there is absolutely no way i can test them or know anybody who can.
This patch is nearly entirely untested...i'm looking for some feedback on how it behaves. software controlled mixers are as follows esound,dsound, soundcard (linux and win32 and beos), arts, and alsa (even though it's the 0.5x version). Some tweaks may be needed so any modulations in volume when playing audio or other errors should be reported so i can follow up on them and tweak the code there. Also, dead code has not been removed completely yet, still working on that... so use this patch at your own risk. (not ready to be used in cvs) the june_23.patch patch must be applied prior to this one.
diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/alsa/unix/linux/include/alsapmo.h ./freeamp/io/alsa/unix/linux/include/alsapmo.h --- ../clean/freeamp/io/alsa/unix/linux/include/alsapmo.h Sun May 7 17:38:51 2000 +++ ./freeamp/io/alsa/unix/linux/include/alsapmo.h Sun Jun 23 15:40:14 2002 @@ -49,6 +49,9 @@ #define BIT_SELECT 0x1f #define SLEEPTIME 256 +int Right=0; +int Left=0; + static const uint32 OBUFFERSIZE = 2 * 1152; enum { diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/alsa/unix/linux/src/alsapmo.cpp ./freeamp/io/alsa/unix/linux/src/alsapmo.cpp --- ../clean/freeamp/io/alsa/unix/linux/src/alsapmo.cpp Thu Oct 19 13:04:10 2000 +++ ./freeamp/io/alsa/unix/linux/src/alsapmo.cpp Sun Jun 23 15:40:01 2002 @@ -182,65 +182,17 @@ void AlsaPMO::SetVolume(int32 left, int32 right) { - int err; - snd_mixer_t *pMixer; - - err = snd_mixer_open(&pMixer, m_iCard, 0); - if (err < 0) - return; - - if (m_iChannel >= 0) - { - err = snd_mixer_group_read(pMixer, &m_group); - if (err < 0) - return; - - left = (int)((double)(m_group.max - m_group.min) * - (double)left * 0.01) + m_group.min; - right = (int)((double)(m_group.max - m_group.min) * - (double)right * 0.01) + m_group.min; - for (int chn = 0; chn <= SND_MIXER_CHN_LAST; chn++) { - if (!(m_group.channels & (1<<chn))) - continue; - - if (chn == 0) - m_group.volume.values[chn] = left; - else - if (chn == 1) - m_group.volume.values[chn] = right; - else - m_group.volume.values[chn] = (left + right) / 2; - } - snd_mixer_group_write(pMixer, &m_group); - } - snd_mixer_close(pMixer); + static int vol_scale[] = {0,1,2,4,7,12,18,26,35,45,56,69,75,87,100 }; + Right = vol_scale[(int)(14*((double)right/100))]; + Left = vol_scale[(int)(14*((double)left/100))]; } void AlsaPMO::GetVolume(int32 &left, int32 &right) { - int err; - snd_mixer_t *pMixer = NULL; - - err = snd_mixer_open(&pMixer, m_iCard, 0); - if (err != 0) - { - return; - } - - if (m_iChannel >= 0) - { - err = snd_mixer_group_read(pMixer, &m_group); - if (err < 0) - return; - } - else - return; - - snd_mixer_close(pMixer); - left = (int)(((float)((m_group.volume.values[0] - m_group.min) * 100) / - (float)(m_group.max - m_group.min)) + 0.5); - right = (int)(((float)((m_group.volume.values[1] - m_group.min) * 100) / - (float)(m_group.max - m_group.min)) + 0.5); + if(Left == 0 && Right == 0){ + left = Left; + right = Right; + } } Error AlsaPMO::Init(OutputInfo* info) @@ -529,6 +481,14 @@ // Now write the block to the audio device. If the block doesn't // all fit, pause and loop until the entire block has been played. // This loop could be written using non-blocking io... + short *data = (short *)pBuffer; + if(Right == -1) Right = Left; + for (int i=0; i < m_iDataSize << 1; i+=8) { + int v=(int) ((*(data) * Left) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + v=(int) ((*(data) * Right) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + } for(;!m_bExit && !m_bPause;) { iRet = snd_pcm_write(m_handle,pBuffer,m_iDataSize); diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/arts/include/artspmo.h ./freeamp/io/arts/include/artspmo.h --- ../clean/freeamp/io/arts/include/artspmo.h Thu Jan 11 17:34:08 2001 +++ ./freeamp/io/arts/include/artspmo.h Sun Jun 23 15:24:46 2002 @@ -34,6 +34,8 @@ #include "pmoevent.h" #include "eventbuffer.h" +int Right=0; +int Left=0; enum { pmoError_MinimumError = 4000, diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/arts/src/artspmo.cpp ./freeamp/io/arts/src/artspmo.cpp --- ../clean/freeamp/io/arts/src/artspmo.cpp Mon Mar 5 17:51:36 2001 +++ ./freeamp/io/arts/src/artspmo.cpp Sun Jun 23 15:24:24 2002 @@ -97,28 +97,19 @@ } } -void artsPMO::SetVolume(int32 left, int32 right) { - int mixFd = open("/dev/mixer",O_RDWR); - int32 v; - - if (mixFd != -1) { - v = (right << 8) | left; - ioctl(mixFd, SOUND_MIXER_WRITE_PCM, &v); - close(mixFd); - } +void artsPMO::SetVolume(int32 left, int32 right) +{ + static int vol_scale[] = {0,1,2,4,7,12,18,26,35,45,56,69,75,87,100 }; + Right = vol_scale[(int)(14*((double)right/100))]; + Left = vol_scale[(int)(14*((double)left/100))]; } -void artsPMO::GetVolume(int32 &left, int32 &right) { - int mixFd = open("/dev/mixer",O_RDWR); - int volume = 0; - - if (mixFd != -1) { - ioctl(mixFd, SOUND_MIXER_READ_PCM, &volume); - close(mixFd); - } - - right = (volume >> 8) & 0xFF; - left = volume & 0xFF; +void artsPMO::GetVolume(int32 &left, int32 &right) +{ + if(Left == 0 && Right == 0){ + left = Left; + right = Right; + } } Error artsPMO::Init(OutputInfo * info) { @@ -312,6 +303,14 @@ continue; } + short *data = (short *)pBuffer; + if(Right == -1) Right = Left; + for (int i=0; i < m_iDataSize << 1; i+=8) { + int v=(int) ((*(data) * Left) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + v=(int) ((*(data) * Right) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + } iRet = arts_write(audio_stream, pBuffer, m_iDataSize); if ((int)iRet < 0) { m_pInputBuffer->EndRead(0); diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/dsound/win32/include/dsoundcardpmo.h ./freeamp/io/dsound/win32/include/dsoundcardpmo.h --- ../clean/freeamp/io/dsound/win32/include/dsoundcardpmo.h Thu May 4 06:54:56 2000 +++ ./freeamp/io/dsound/win32/include/dsoundcardpmo.h Sun Jun 23 15:14:46 2002 @@ -38,6 +38,9 @@ #include "facontext.h" #include "preferences.h" +int Left=0; +int Right=0; + typedef enum { UNDERFLOW, NORMAL, diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/dsound/win32/src/dsoundcardpmo.cpp ./freeamp/io/dsound/win32/src/dsoundcardpmo.cpp --- ../clean/freeamp/io/dsound/win32/src/dsoundcardpmo.cpp Thu Jun 22 14:53:10 2000 +++ ./freeamp/io/dsound/win32/src/dsoundcardpmo.cpp Sun Jun 23 15:14:02 2002 @@ -268,46 +268,6 @@ bool DSoundCardPMO::SetupVolumeControl(void) { - MIXERLINE mxl; - MIXERCONTROL mxc; - MIXERLINECONTROLS mxlc; - - m_oDstLineName = ""; - m_oVolumeControlName = ""; - - if (m_hmixer == NULL) - return FALSE; - - mxl.cbStruct = sizeof(MIXERLINE); - mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; - if (mixerGetLineInfo((HMIXEROBJ)m_hmixer, - &mxl, - MIXER_OBJECTF_HMIXER | - MIXER_GETLINEINFOF_COMPONENTTYPE) - != MMSYSERR_NOERROR) - return false; - - mxlc.cbStruct = sizeof(MIXERLINECONTROLS); - mxlc.dwLineID = mxl.dwLineID; - mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; - mxlc.cControls = 1; - mxlc.cbmxctrl = sizeof(MIXERCONTROL); - mxlc.pamxctrl = &mxc; - - if (mixerGetLineControls((HMIXEROBJ)m_hmixer, - &mxlc, - MIXER_OBJECTF_HMIXER | - MIXER_GETLINECONTROLSF_ONEBYTYPE) - != MMSYSERR_NOERROR) - return false; - - // record dwControlID - m_oDstLineName = mxl.szName; - m_oVolumeControlName = mxc.szName; - m_dwMinimum = mxc.Bounds.dwMinimum; - m_dwMaximum = mxc.Bounds.dwMaximum; - m_dwVolumeControlID = mxc.dwControlID; - return TRUE; } @@ -316,54 +276,19 @@ DSoundCardPMO:: GetVolume(int32 &left, int32 &right) { - MIXERCONTROLDETAILS_UNSIGNED mxcdVolume[2]; - MIXERCONTROLDETAILS mxcd; - int ret; - - mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); - mxcd.dwControlID = m_dwVolumeControlID; - mxcd.cChannels = 2; - mxcd.cMultipleItems = 0; - mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - mxcd.paDetails = &mxcdVolume; - ret = mixerGetControlDetails((HMIXEROBJ)m_hmixer, - &mxcd, - MIXER_OBJECTF_HMIXER | - MIXER_GETCONTROLDETAILSF_VALUE); - if (ret != MMSYSERR_NOERROR) - return; - - left = (int)(((float)((mxcdVolume[0].dwValue - m_dwMinimum) * 100) / - (float)(m_dwMaximum - m_dwMinimum)) + 0.5); - right = (int)(((float)((mxcdVolume[1].dwValue - m_dwMinimum) * 100) / - (float)(m_dwMaximum - m_dwMinimum)) + 0.5); + if(Left == 0 && Right == 0) { + left = Left; + right = Right; + } } void DSoundCardPMO:: SetVolume(int32 left, int32 right) { - DWORD dwLeft, dwRight; - - dwLeft = (left * (m_dwMaximum - m_dwMinimum) / 100); - dwRight = (right * (m_dwMaximum - m_dwMinimum) / 100); - - MIXERCONTROLDETAILS_UNSIGNED mxcdVolume[2]; - MIXERCONTROLDETAILS mxcd; - - memcpy(&mxcdVolume[0], &dwLeft, sizeof(MIXERCONTROLDETAILS_UNSIGNED)); - memcpy(&mxcdVolume[1], &dwRight, sizeof(MIXERCONTROLDETAILS_UNSIGNED)); - - mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); - mxcd.dwControlID = m_dwVolumeControlID; - mxcd.cChannels = 2; - mxcd.cMultipleItems = 0; - mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - mxcd.paDetails = &mxcdVolume; - - mixerSetControlDetails((HMIXEROBJ)m_hmixer, &mxcd, - MIXER_OBJECTF_HMIXER | - MIXER_SETCONTROLDETAILSF_VALUE); + static int vol_scale[] = {0,1,2,4,7,12,18,26,35,45,56,69,75,87,100 }; + Right = vol_scale[(int)(14*((double)right/100))]; + Left = vol_scale[(int)(14*((double)left/100))]; } Error @@ -599,7 +524,6 @@ eRet = ((EventBuffer *)m_pInputBuffer)->EndRead(0); if (eRet != kError_NoErr) return eRet; - return kError_NoErr; } @@ -609,7 +533,16 @@ { int nState; int32 wrote; - + + short *data = (short *)pBuffer; + if(Right == -1) Right = Left; + for (int i=0; i < m_data_size << 1; i+=8) { + int v=(int) ((*(data) * Left) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + v=(int) ((*(data) * Right) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + } + for(; !m_bExit;) { // wait until we are in a good state to write diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/esound/include/esoundpmo.h ./freeamp/io/esound/include/esoundpmo.h --- ../clean/freeamp/io/esound/include/esoundpmo.h Thu May 4 06:54:56 2000 +++ ./freeamp/io/esound/include/esoundpmo.h Sun Jun 23 15:00:53 2002 @@ -34,6 +34,9 @@ #include "pmoevent.h" #include "eventbuffer.h" +int Right=0; +int Left=0; + enum { pmoError_MinimumError = 4000, diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/esound/src/esoundpmo.cpp ./freeamp/io/esound/src/esoundpmo.cpp --- ../clean/freeamp/io/esound/src/esoundpmo.cpp Wed Oct 11 10:13:30 2000 +++ ./freeamp/io/esound/src/esoundpmo.cpp Sun Jun 23 14:57:06 2002 @@ -117,45 +117,17 @@ void EsounDPMO::GetVolume(int32 &left, int32 &right) { - left = right = -1; - - mixer_fd = esd_open_sound(m_espeaker); - if (mixer_fd > 0) - { - esd_info_t *info; - esd_player_info_t *plr; - - info = esd_get_all_info(mixer_fd); - - if (!info) - return; - - for (plr = info->player_list; plr; plr = plr->next) - { - if (!strncmp(stream_name, plr->name, ESD_NAME_MAX)) - { - left = plr->left_vol_scale; - right = plr->right_vol_scale; - break; - } - } - left = 100 * left / ESD_VOLUME_BASE; - right = 100 * right / ESD_VOLUME_BASE; - esd_free_all_info(info); - esd_close(mixer_fd); - } + if(Left == 0 && Right == 0){ + left = Left; + right = Right; + } } void EsounDPMO::SetVolume(int32 left, int32 right) { - mixer_fd = esd_open_sound(m_espeaker); - if (mixer_fd > 0) - { - left = ESD_VOLUME_BASE * left / 100; - right = ESD_VOLUME_BASE * right / 100; - esd_set_stream_pan(mixer_fd, stream_id, left, right); - esd_close(mixer_fd); - } + static int vol_scale[] = {0,1,2,4,7,12,18,26,35,45,56,69,75,87,100 }; + Right = vol_scale[(int)(14*((double)right/100))]; + Left = vol_scale[(int)(14*((double)left/100))]; } Error EsounDPMO::Init(OutputInfo * info) @@ -361,6 +333,14 @@ // Is there an event pending that we need to take care of // before we play this block of samples? + short *data = (short *)pBuffer; + if(Right == -1) Right = Left; + for (int i=0; i < m_iDataSize << 1; i+=8) { + int v=(int) ((*(data) * Left) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + v=(int) ((*(data) * Right) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + } if (eErr == kError_EventPending) { pEvent = ((EventBuffer *)m_pInputBuffer)->GetEvent(); diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/soundcard/beos/include/soundcardpmo.h ./freeamp/io/soundcard/beos/include/soundcardpmo.h --- ../clean/freeamp/io/soundcard/beos/include/soundcardpmo.h Tue Jul 11 12:00:12 2000 +++ ./freeamp/io/soundcard/beos/include/soundcardpmo.h Sun Jun 23 16:13:08 2002 @@ -43,6 +43,8 @@ #define USE_DUMMY_PLAYER 0 #define DEBUG_SAVE_PCM 0 +int Right=0; +int Left=0; class Thread; class FAContext; class VolumeManager; diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/soundcard/beos/src/soundcardpmo.cpp ./freeamp/io/soundcard/beos/src/soundcardpmo.cpp --- ../clean/freeamp/io/soundcard/beos/src/soundcardpmo.cpp Tue Jul 11 12:00:13 2000 +++ ./freeamp/io/soundcard/beos/src/soundcardpmo.cpp Sun Jun 23 16:12:52 2002 @@ -121,27 +121,18 @@ void SoundCardPMO::GetVolume( int32& left, int32& right ) { - PRINT(( "SoundCardPMO::GetVolume\n" )); - if ( !m_player ) - { - left = right = s_lastVolume; - } - else - { - left = right = int32( m_player->Volume() * 100.0 ); - } + if(Left == 0 && Right == 0){ + left = Left; + right = Right; + } } void SoundCardPMO::SetVolume( int32 left, int32 right ) { - PRINT(( "SoundCardPMO::SetVolume\n" )); - int32 volume = ( left + right ) / 2; - if ( m_player ) - { - m_player->SetVolume( float( volume ) / 100.0 ); - } - s_lastVolume = volume; + static int vol_scale[] = {0,1,2,4,7,12,18,26,35,45,56,69,75,87,100 }; + Right = vol_scale[(int)(14*((double)right/100))]; + Left = vol_scale[(int)(14*((double)left/100))]; } void @@ -591,6 +582,14 @@ { PRINT(( "SoundCardPMO::Player: end of data?\n" )); } + short *data = (short *)bufferIn; + if(Right == -1) Right = Left; + for (int i=0; i < bytesToCopy << 1; i+=8) { + int v=(int) ((*(data) * Left) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + v=(int) ((*(data) * Right) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + } memcpy( bufferOut, bufferIn, bytesToCopy ); #if DEBUG_SAVE_PCM fwrite( bufferIn, 1, bytesToCopy, m_pcmSaveFile ); diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/soundcard/win32/src/soundcardpmo.cpp ./freeamp/io/soundcard/win32/src/soundcardpmo.cpp --- ../clean/freeamp/io/soundcard/win32/src/soundcardpmo.cpp Wed Feb 27 14:42:08 2002 +++ ./freeamp/io/soundcard/win32/src/soundcardpmo.cpp Sun Jun 23 16:01:40 2002 @@ -613,6 +613,14 @@ // Is there an event pending that we need to take care of // before we play this block of samples? + short *data = (short *)pBuffer; + if(Right == -1) Right = Left; + for (int i=0; i < m_iDataSize << 1; i+=8) { + int v=(int) ((*(data) * Left) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + v=(int) ((*(data) * Right) / 100); + *(data++)=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v); + } if (eErr == kError_EventPending) { pEvent = ((EventBuffer *)m_pInputBuffer)->PeekEvent(); diff -Naur -x CVS -x corba -x *.log -x *.orig -x *.rej ../clean/freeamp/io/src/win32volume.cpp ./freeamp/io/src/win32volume.cpp --- ../clean/freeamp/io/src/win32volume.cpp Wed Sep 20 06:17:54 2000 +++ ./freeamp/io/src/win32volume.cpp Sun Jun 23 15:27:47 2002 @@ -36,156 +36,20 @@ void Win32Volume::GetVolume(int32 &left, int32 &right) { - MIXERCONTROLDETAILS_UNSIGNED mxcdVolume[2]; - MIXERCONTROLDETAILS mxcd; - int ret; - - mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); - mxcd.dwControlID = m_dwVolumeControlID; - mxcd.cChannels = 2; - mxcd.cMultipleItems = 0; - mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - mxcd.paDetails = &mxcdVolume; - ret = mixerGetControlDetails((HMIXEROBJ)m_hMixer, - &mxcd, - MIXER_OBJECTF_HMIXER | - MIXER_GETCONTROLDETAILSF_VALUE); - if (ret != MMSYSERR_NOERROR) - return; - - left = (int)(((float)((mxcdVolume[0].dwValue - m_dwMinimum) * 100) / - (float)(m_dwMaximum - m_dwMinimum)) + 0.5); - right = (int)(((float)((mxcdVolume[1].dwValue - m_dwMinimum) * 100) / - (float)(m_dwMaximum - m_dwMinimum)) + 0.5); + if(Left == 0 && Right == 0){ + left = Left; + right = Right; + } } void Win32Volume::SetVolume(int32 left, int32 right) { - DWORD dwValLeft, dwValRight; - - dwValLeft = (left * (m_dwMaximum - m_dwMinimum) / 100); - dwValRight = (right * (m_dwMaximum - m_dwMinimum) / 100); - - MIXERCONTROLDETAILS_UNSIGNED mxcdVolume[2]; - MIXERCONTROLDETAILS mxcd; - - memcpy(&mxcdVolume[0], &dwValLeft, sizeof(MIXERCONTROLDETAILS_UNSIGNED)); - memcpy(&mxcdVolume[1], &dwValRight, sizeof(MIXERCONTROLDETAILS_UNSIGNED)); - - mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); - mxcd.dwControlID = m_dwVolumeControlID; - mxcd.cChannels = 2; - mxcd.cMultipleItems = 0; - mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); - mxcd.paDetails = &mxcdVolume; - - mixerSetControlDetails((HMIXEROBJ)m_hMixer, &mxcd, - MIXER_OBJECTF_HMIXER | - MIXER_SETCONTROLDETAILSF_VALUE); + static int vol_scale[] = {0,1,2,4,7,12,18,26,35,45,56,69,75,87,100 }; + Right = vol_scale[(int)(14*((double)right/100))]; + Left = vol_scale[(int)(14*((double)left/100))]; } bool Win32Volume::InitVolumeControl( eDeviceType eType, HWND hWnd ) { - MMRESULT mmresult = 0; - //HWND hWnd = 0; - mmresult = mixerOpen(&m_hMixer, 0, (DWORD)hWnd, NULL, - MIXER_OBJECTF_MIXER | CALLBACK_WINDOW); - //if (mmresult != MMSYSERR_NOERROR) - //{ - // m_hMixer = NULL; - //m_pContext->log->Error("Cannot open Mixer device."); - //} - - switch ( mmresult ) { - - case MMSYSERR_NOERROR : - // All Is Well... - break; - - case MMSYSERR_ALLOCATED : - m_hMixer = NULL; - break; - - case MMSYSERR_BADDEVICEID : - m_hMixer = NULL; - break; - - case MMSYSERR_INVALFLAG : - m_hMixer = NULL; - break; - - case MMSYSERR_INVALHANDLE : - m_hMixer = NULL; - break; - - case MMSYSERR_INVALPARAM : - m_hMixer = NULL; - break; - - case MMSYSERR_NODRIVER : - m_hMixer = NULL; - break; - - case MMSYSERR_NOMEM : - m_hMixer = NULL; - break; - - default: - m_hMixer = NULL; - break; - - } - - m_oDstLineName = ""; - m_oVolumeControlName = ""; - - if (m_hMixer == NULL) - return FALSE; - - mxl.cbStruct = sizeof(MIXERLINE); - - switch ( eType ) { - - case eWaveOut : - mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; - break; - - case eCDOut : - mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC; - break; - - default: - mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; - break; - - } - - if (mixerGetLineInfo((HMIXEROBJ)m_hMixer, - &mxl, - MIXER_OBJECTF_HMIXER | - MIXER_GETLINEINFOF_COMPONENTTYPE) - != MMSYSERR_NOERROR) - return false; - mxlc.cbStruct = sizeof(MIXERLINECONTROLS); - mxlc.dwLineID = mxl.dwLineID; - mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; - mxlc.cControls = 1; - mxlc.cbmxctrl = sizeof(MIXERCONTROL); - mxlc.pamxctrl = &mxc; - - if (mixerGetLineControls((HMIXEROBJ)m_hMixer, - &mxlc, - MIXER_OBJECTF_HMIXER | - MIXER_GETLINECONTROLSF_ONEBYTYPE) - != MMSYSERR_NOERROR) - return false; - - // record dwControlID - m_oDstLineName = mxl.szName; - m_oVolumeControlName = mxc.szName; - m_dwMinimum = mxc.Bounds.dwMinimum; - m_dwMaximum = mxc.Bounds.dwMaximum; - m_dwVolumeControlID = mxc.dwControlID; - return TRUE; }