# Control MIDI left and right volume

4 replies to this topic

### #1123abcd1983

New Member

• Members
• 3 posts

Posted 26 March 2007 - 08:38 PM

Hi,
I have some problem by using the midi file. I wish to control the left and the right channels volumes, and i got some information from msdn library, but it didn't tell me the exact way to do it. Could anyone tell me what is the meaning of

"The low-order word contains the left-channel volume setting, and the high-order word contains the right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence."

The sentence above i copy from the the msdn library of MidiOutGetVolume and midiOutSetVolume. Does it mean the low order is 0x000 to 0x7777(left channel) and 0x8000 to 0xFFFF is high order (right channel)?

The code below is modified from an example from internet. Although I set the midiOutSetVolume(hdev, 0xF000); But it didn't work at all.

Anyone have similar example could control the left and right volumes? I already stuck on this step quite a while.

I wish someone could give some suggestion for me. Thanks a lot.


#include <windows.h>

#include <stdio.h>

#pragma comment(lib, "Winmm.lib")

#define NOTE_ON 0x90

#define NOTE_OFF 0x80

//command, note, velocity

#define MAKE_MSG(X, Y, Z) (X + (Y<<8) + (Z<<16))

int playChord(HMIDIOUT hdev)

{

midiOutSetVolume(hdev, 0x0000);

midiOutShortMsg(hdev, MAKE_MSG(NOTE_ON, 62, 65));

Sleep(1000);

midiOutSetVolume(hdev, 0xF000);

midiOutShortMsg(hdev, MAKE_MSG(NOTE_ON, 62, 65));

Sleep(1000);

midiOutSetVolume(hdev, 0x5555);

midiOutShortMsg(hdev, MAKE_MSG(NOTE_ON, 62, 65));

Sleep(1000);

midiOutSetVolume(hdev, 0xFFF0);

midiOutShortMsg(hdev, MAKE_MSG(NOTE_ON, 62, 65));

Sleep(1000);

midiOutShortMsg(hdev, MAKE_MSG(NOTE_OFF, 62, 65));

midiOutShortMsg(hdev, MAKE_MSG(NOTE_OFF, 62, 65));

midiOutShortMsg(hdev, MAKE_MSG(NOTE_OFF, 62, 65));

midiOutShortMsg(hdev, MAKE_MSG(NOTE_OFF, 62, 65));

return 0;

}

int main()

{

HMIDIOUT hdev;

static MIDIOUTCAPS devCaps;

static LPMIDIOUTCAPS lpCaps = &devCaps;

DWORD abc;

devCaps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;

abc = devCaps.dwSupport;

if (devCaps.dwSupport == MIDICAPS_VOLUME|MIDICAPS_LRVOLUME)

{

wprintf(L"abc");

}

midiOutGetDevCaps(0, lpCaps, sizeof(MIDIOUTCAPS)); // Get device capabilities for first device (curDevice == 0)

midiOutOpen(&hdev, -1, NULL, NULL, CALLBACK_NULL);

midiOutSetVolume(hdev, 0x0000);

{

wprintf(L"Midi test app\nc: play chord\nd: change device\nv: set volume\nq: quit\n");

{

case 'q':

break;

case 'c':

playChord(hdev);

break;

default:

wprintf(L"try again\n");

break;

}

}

midiOutClose(hdev);

return 0;

}



### #2karligula

Valued Member

• Members
• 180 posts

Posted 27 March 2007 - 02:54 PM

This might be totally wrong, but I interpret the sentence you quoted given by the msdn library as saying, the bottom eight bits contain the left channel volume and the top eight bits contain the right channel volume.

So to set the right volume to maximum and the left volume to silence, you'd use:

midiOutSetVolume(hdev, 0xff00);

Never used it myself but it's worth a try!

### #3Reedbeta

DevMaster Staff

• 5340 posts
• LocationSanta Clara, CA

Posted 27 March 2007 - 05:41 PM

It's the low and high order word (16-bit) of a 32 bit value, not the low and high byte of a 16-bit value. So, it should be midiOutSetVolume(hdev, 0xffff0000). Another way to control it would be to set the pan controller, which is a built in MIDI message.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #4123abcd1983

New Member

• Members
• 3 posts

Posted 28 March 2007 - 04:04 AM

Reedbeta said:

It's the low and high order word (16-bit) of a 32 bit value, not the low and high byte of a 16-bit value. So, it should be midiOutSetVolume(hdev, 0xffff0000). Another way to control it would be to set the pan controller, which is a built in MIDI message.

hi i already try your's way, but it still didn't work. The text below i copied from msdn library. I think i understand the first paragraph. But i'm not really understand the paragraph 2 and 3. Could you give me some suggestion?

http://msdn2.microso...y/ms711639.aspx

"You can also determine whether the device supports volume control on both the left and right channels by querying the device using the midiOutGetDevCaps function and the MIDICAPS_LRVOLUME flag.

Devices that do not support a full 16 bits of volume-level control use the high-order bits of the requested volume setting. For example, a device that supports 4 bits of volume control produces the same volume setting for the following volume-level values: 0x4000, 0x43be, and 0x4fff. The midiOutGetVolume function returns the full 16-bit value, as set by midiOutSetVolume, irrespective of the device's capabilities.

Volume settings are interpreted logarithmically. This means that the perceived increase in volume is the same when increasing the volume level from 0x5000 to 0x6000 as it is from 0x4000 to 0x5000."

### #5Reedbeta

DevMaster Staff

• 5340 posts
• LocationSanta Clara, CA

Posted 28 March 2007 - 04:08 AM

The second paragraph basically means you don't need to worry about whether the device supports a full 16 bits of volume control or not. You can use the same volume settings anyway. The third paragraph is pretty much irrelevant.

Have you checked the midiOutGetDevCaps function to see if the MIDICAPS_LRVOLUME is supported?
reedbeta.com - developer blog, OpenGL demos, and other projects

#### 1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users