How do I set the volume of an mpeg file played with the mci api so that it doesn't change the master mixer volume in windows.

Winamp has an alternate setting for the volume control that works independently of the windows mixer wave volume. Wondering how they do that.

Was looking at using the mixer api but didn't see anything that would create a new mixer. Also the mci volume commands do change the volume of the entire system.
Posted on 2002-05-10 23:20:54 by grv575
I would say since win amp is generating the discretized sound waves, it can do anything it wants to it in terms of the amplitude of these genereated signals, before its given up for the OS to deal with.... Hence, an intenral volume control, rather than using the external one.

( Which doesnt leave you with much to work with :rolleyes: )

:NaN:
Posted on 2002-05-11 00:54:02 by NaN
Ok I kinda suspected that but wouldn't it be a bit difficult to code? I see a lot of media player apps coded in vb and such and they have their own independent volume controls as well.
Posted on 2002-05-11 02:11:03 by grv575
Scaling the Volume wouldnt be hard at all.. Actually the MMX alpha blend has a routine that would work nicely for this purpose, (can dig it up for you if interested), but what i would find hard (mainly from lack of experience) is getting the sound information stream, and sending it back out after modifying its amplitude.

Im not familiar with the Media API's that windows has to offer, this might be ez for all i know.

:NaN:
Posted on 2002-05-11 04:15:08 by NaN
Yeah could you post the alpha blend code? I need some place to start.

As far as I know, you can either go through MCI or use the devcaps routines which are more low-level and interface directly with the sound card. How to actually grab the stream that's playing I still have to figure out.
Posted on 2002-05-11 05:26:06 by grv575
Before i yeild a solution, i have to ask something about the nature of the 'control' you wish to program.

Do you intend to control a pass-thru volume where the input amplitude is considered the max, and your control will allow a percentange of the amplitude to leave? (( This is what i originally had in mind))

Or, Do you wish to amplify the signal greater than it is coming in. This is possible, but overlooked originally. The real problem with this is normalization. Since amplitude is realative to the bit-resolution of the sound. Ie) if only a byte is used to represent the sound, the amplitude can only reach a max of 127 +/-, after this you start clipping the signal as you have saturated the byte's container and cant increase any further. The sound will begin to sound ringy or slightly distored at this point.

Normalization is usually done in this scenario, where it parses the entire piece of music and determines the 'largest' found value. Then it looks at the biggest *possible* value, and the volume increase is determined between these two points. If your writing a real-time app, this will not be of any use to you, and still leave the potential of staturation.

However, to feed you some tangible information, here is what i was thinking of from my first post:

MMX (as i have learned from bitRake) provides a fast way of ratio'ing numbers when designed right.

- Say your Wave data is Limited to 1 Byte each (DATA=BYTE)
- Say you volume is from 0 -> 255 (0 -> 100%)
-There is a MMX mul command that will multiply two words to produce a dword, but the neat thing is it only keeps the UPPER WORD. This essentially is (X*Y)/2^16 !! ( Note the division here)

If you let:
X = WAV BYTE DATA (BYTE)
Y = VOLUME LEVEL * (2^8)
Then:
X*Y = WAVE DATA *( VOLUME * 2^8 )

The mmx mul will then yield:

X*Y/2^16 = WAVE DATA *[ (VOLUME *2^8)/2^16 ]

The [] is the ratio.
- If VOLUME = 256 then 2^8*2^8/2^16 == 1 * WAVE DATA
- If VOLUME = 128 then 2^7*2^8/2^16 == 0.5 * WAVE DATA
- IF VOLUME = 0 then 0*2^8/2^16 == 0.0 * WAVE DATA

This is a percent volume funciton.

This can be adjusted to amplify as well by setting the VOLUME to WORD length, rather than a byte. Then Volume values above 255 will amplify the value up to 256 Times, and values below 256 will diminish the amplitue up to 1/256th, and then zero. But again, there is a problem here. 256*BYTE DATA fits in a WORD! The data field saturates at 255!! So better design and considerations are needed for amplification of the signal data.

I hope this helps paint the picture better?
:NaN:
Posted on 2002-05-11 19:29:53 by NaN
Hi.
Just one thing, WinAMP doesn't modify the master volume, but it does modify the Wave/MP3 volume.
Bye.
Posted on 2002-05-11 20:16:27 by GogetaSSJ4
Isn?t there a function in mmedia.dll?
Posted on 2002-05-11 21:07:32 by CodeLover
Ok thanks NaN for the math. I don't need to amplify the signal. I think I'll have to rewrite the code to use DirectSound instead of MCI though. Doesn't look like the simple mci routines give you access to the wave buffers.

GogetaSSJ4,
Yeah I meant the wave volume, not the master level.
Posted on 2002-05-11 21:08:18 by grv575
Good luck, and keep the topic in touch ;)

I would be interested in hearing any successes you learn/implement... however its too bad that Direct Sound is your only alternative. It would be nice to know there is more universal support.
Posted on 2002-05-12 02:36:06 by NaN
I could play the media files without the mci layer but that would involve createfile, parsing header info, etc. Too much to code. I guess they didn't anticipate mixing more than one wav file with the mci api.
Posted on 2002-05-12 09:25:37 by grv575
Wav headers arnt all that much to have to deal with.. if this is your only hurdle. I wrote a DOS app that did this once in college.

I didnt know much about how M$ deals with sound info, i expected this to be harder than your making it sound... I would go this way over the direct sound myself. But again, i would need to know for sure that if i send a buffer of data to some api, i will get played.

If you know that much, the 'too much code' should not be all that much at all (with a properly planned structure to get the header stuff quickly).

NaN
Posted on 2002-05-12 13:26:12 by NaN