Volume Control with multiple soundcards

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Volume Control with multiple soundcards

Scott-2
I am looking for a way to handle the Volume Control functions (set
volume, mute) on different soundcards on the same machine (ex
SoundCardOne set Wave volume to 50, or SoundCardTwo set LineIn to
Mute).  I have not found any free activeX controls that seem to work
with multiple soundcards (example - SGuard).  I would like to either
use an ActiveX control (free) or do it via ExternalLibrary functions
from Smalltalk.

I have been looking at the api for WinMM and I believe that I should
be able to do this using api's beginning with 'mixer' (at least that
is where to start).  Can I generate ExternalLibrary methods and
structures to access these methods.  I have not been able to find
these api's defined in a IDL or TLB type file to be able the use the
TKindModuleAnalyzer (This would be the great if someone can do this).
Is there an Analyzer that can either read include files or dlls and
generate the ExternalLibrary methods and structures?

Any help or samples to do this would be greatly appreciated.

Thanks,
Scott


Reply | Threaded
Open this post in threaded view
|

Re: Volume Control with multiple soundcards

Ian Bartholomew-18
Scott,

> I am looking for a way to handle the Volume Control functions
[]
> I have been looking at the api for WinMM and I believe that I should
> be able to do this using api's beginning with 'mixer' (at least that
> is where to start).
[]
> Any help or samples to do this would be greatly appreciated.

If you get anywhere with this I, for one, would be grateful if you could
share it :-)

About a year ago I acquired a USB FM radio that fed its audio into the audio
card's "wave in" input.  I wanted to write my own applications to control
the radio, its audio output and also enable me to record at will.  I
investigated WinMMLibrary and didn't have too much trouble using the
aux/waveIn/waveOut functions, but the mixer interface had me completely
stumped - I could not make head nor tail of it.  In the end I just resorted
to a button opening the Windows volume control when needed.

I can't help with the type file (I tend to create the external classes and
methods by hand) but I have got a few interface methods and structures that
might get you started if you can't find an easier way.  NB There are a lot
more mixer related structures and methods that I never got round to!

(structures)
MIXERCAPS
MIXERCONTROLDETAILS

(WinMMLibrary wrappers)
mixerClose
mixerGetDevCaps....
mixerGetNumDevs
mixerOpen....

Regards
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: Volume Control with multiple soundcards

Ian Bartholomew-18
I wrote ...

> I can't help with the type file (I tend to create the external classes and
> methods by hand) but I have got a few interface methods and structures
> that might get you started if you can't find an easier way.  NB There are
> a lot more mixer related structures and methods that I never got round to!

I just *knew* I wouldn't be able to leave it at that (I lasted half a day
though - quite good I thought) so I've now implemented all the required
Structures and the WinMMLibrary mixer* interface.  I've got to the stage
where I can actually alter the volume of both channels (independently!) on
the Line-in channel.  I won't pretend that I know just *how* I'm doing it -
but it's a start.

If anybody (Scott?) wants the Structure and function definitions to have a
play then give me a shout.

Regards
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: Volume Control with multiple soundcards

Ian Upright
In reply to this post by Scott-2
Here's some cobbled together C code I wrote a long time ago to set the sound
volume.  You can use it as a basis for ideas to port to Smalltalk.

Ian


#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>

   void ShowVolume(void)
   {
       // This is the function that can be added to the Generic Sample to
       // illustrate the use of waveOutGetVolume() and waveOutSetVolume().

       char buffer[40];
       char printbuf[80];
       UINT uRetVal, uNumDevs;
       DWORD volume;
       long lLeftVol, lRightVol;

       WAVEOUTCAPS waveCaps;

       // Make sure there is at least one
       // wave output device to work with.
       if (uNumDevs = waveOutGetNumDevs())
       {
      itoa((int)uNumDevs, buffer, 10);
      wsprintf(printbuf, "Number of devices is %s\n", (LPSTR)buffer);
      MessageBox(GetFocus(), printbuf, "NumDevs", MB_OK);
       }

       // This sample uses a hard-coded 0 as the device ID, but retail
       // applications should loop on devices 0 through N-1, where N is the
       // number of devices returned by waveOutGetNumDevs().
       if (!waveOutGetDevCaps((HWAVEOUT)1,(LPWAVEOUTCAPS)&waveCaps,
          sizeof(WAVEOUTCAPS)))

       {
      // Verify the device supports volume changes
      if(waveCaps.dwSupport & WAVECAPS_VOLUME)
      {
          // The low word is the left volume, the high word is the right.
          // Set left channel: 2000h is one-eighth volume (8192 base ten).
          // Set right channel: 4000h is quarter volume (16384 base ten).
          uRetVal = waveOutSetVolume((HWAVEOUT)1, (DWORD)0x40002000UL);

          // Now get and display the volumes.
          uRetVal = waveOutGetVolume((HWAVEOUT)1, (LPDWORD)&volume);

          lLeftVol = (long)LOWORD(volume);
          lRightVol = (long)HIWORD(volume);

          ltoa(lLeftVol, buffer, 10);
          wsprintf(printbuf, "Left Volume is %s\n", (LPSTR)buffer);
          MessageBox(GetFocus(), printbuf, "Left Volume", MB_OK);

          ltoa(lRightVol, buffer, 10);
          wsprintf(printbuf, "Right Volume is %s\n", (LPSTR)buffer);
          MessageBox(GetFocus(), printbuf, "Right Volume", MB_OK);

          // The low word is the left volume, the high word is the right.
          // Set left channel: 8000h is half volume (32768 base ten).
          // Set right channel: 4000h is quarter volume (16384 base ten).
          uRetVal = waveOutSetVolume((HWAVEOUT)1, (DWORD)0x40008000UL);

          // Now get and display the volumes.
          uRetVal = waveOutGetVolume((HWAVEOUT)1, (LPDWORD)&volume);

          lLeftVol = (long)LOWORD(volume);
          lRightVol = (long)HIWORD(volume);

          ltoa(lLeftVol, buffer, 10);
          wsprintf(printbuf, "Left Volume is %s\n", (LPSTR)buffer);
          MessageBox(GetFocus(), printbuf, "Left Volume", MB_OK);

          ltoa(lRightVol, buffer, 10);
          wsprintf(printbuf, "Right Volume is %s\n", (LPSTR)buffer);
          MessageBox(GetFocus(), printbuf, "Right Volume", MB_OK);

      }
       }
   }

int PASCAL WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance,
                   LPSTR lpszcmdparam, int ncmdshow)
{
int   volume;
int  oldvolume;
int   rerror;
int   deviceId;
BOOL  error = sscanf(lpszcmdparam, "%d %d", &deviceId, &volume) != 1;
WORD  half;
DWORD both;
char printbuf[80];

error = 0;

//wsprintf(printbuf, "Current Volume is %d %d\n", deviceId, volume);
//  MessageBox(GetFocus(), printbuf, "NumDevs", MB_OK);

//ShowVolume();

if (!error && volume >= 0 && volume <= 255)
  {
      //itoa((int)volume, buffer, 10);
 
  //rerror = waveOutGetVolume((HWAVEOUT)1, (LPDWORD)&oldvolume);
        //wsprintf(printbuf, "Current Volume is %d %d\n", oldvolume,
rerror);
        //MessageBox(GetFocus(), printbuf, "NumDevs", MB_OK);

  half = ((WORD) volume) * 256 + ((WORD) volume);
  both = (half << 16) + half;

    rerror = waveOutSetVolume((HWAVEOUT)deviceId, both);

        //wsprintf(printbuf, "New Volume is %d %d\n", both, rerror);
        //MessageBox(GetFocus(), printbuf, "NumDevs", MB_OK);

        //rerror = waveOutGetVolume((HWAVEOUT)1, (LPDWORD)&oldvolume);
        //wsprintf(printbuf, "Now Volume is %d %d\n", oldvolume, rerror);
// MessageBox(GetFocus(), printbuf, "NumDevs", MB_OK);
        //waveOutSetVolume(1, (DWORD)0x40002000UL);
  }

ExitProcess(0);
}

---
http://www.upright.net/ian/