how to control the midi play from left to right channel

Started by
2 comments, last by Promit 17 years, 1 month ago
Hi, I wish to play a midi file from left to right ear phone. I have used some midi function like midiOutOpen, midiOutShortMsg, midiOutReset,midiOutClose, i found a sample code like below, but it just didn't teach how to change the sound from left to right... wish anyone could help C

//NOTE: Add winmm.lib in your link//

#include "dxstdafx.h"
#include <conio.h>     /* include for kbhit() and getch() functions */
#include <stdio.h>     /* for printf() function */
#include <windows.h>   /* required before including mmsystem.h */
#include <mmsystem.h>  /* multimedia functions (such as MIDI) for Windows */

int main(int argc, char** argv) {
   int ckey;           // storage for the current keyboard key being pressed
   int notestate = 0;  // keeping track of when the note is on or off
   int velocity = 100; // MIDI note velocity parameter value
   int midiport;       // select which MIDI output port to open
   int flag;           // monitor the status of returning functions
   int duration = 10;
   HMIDIOUT device;    // MIDI device interface for sending MIDI output

   // variable which is both an integer and an array of characters:
   union { unsigned long word; unsigned char data[4]; } message;

   // message.data[0] = command byte of the MIDI message, for example: 0x90
   // message.data[1] = first data byte of the MIDI message, for example: 60
   // message.data[2] = second data byte of the MIDI message, for example 100
   // message.data[3] = not used for any MIDI messages, so set to 0
   message.data[0] = 0x90;  // MIDI note-on message (requires to data bytes)
   message.data[1] = 96;    // MIDI note-on message: Key number (60 = middle C)
   message.data[2] = 100;   // MIDI note-on message: Key velocity (100 = loud)
   message.data[3] = 0;     // Unused parameter

   // Assign the MIDI output port number (from input or default to 0)
   if (argc < 2) {
      midiport = 0;
   } else {
      midiport = atoi(argv[1]);
   }

   printf("MIDI output port set to %d.\n", midiport);

   // Open the MIDI output port
   flag = midiOutOpen(&device, midiport, 0, 0, CALLBACK_NULL);
   if (flag != MMSYSERR_NOERROR) {
      printf("Error opening MIDI Output.\n");
      return 1;
   }

   // Main event loop
   printf("Press \"q\" to quit.\n");
   while (1) {         // event loop
      if (kbhit()) {   // If a key on the computer keyboard has been pressed 
         ckey = getch();
         if (notestate == 0) {
            // Note is currently off, turn on note.
	      message.data[3] = duration;
            message.data[2] = velocity;
            notestate = 1;
            printf("Note turned ON.\n");
         } else {
            // Note is currently on, turn off note.
            message.data[2] = 0;  // 0 velocity = note off
            notestate = 0;
            printf("Note turned OFF.\n");
         }
         flag = midiOutShortMsg(device, message.word);//THIS IS THE ONE WHICH PLAYS THE MIDI NOTE
         
		 if (flag != MMSYSERR_NOERROR) {
            printf("Warning: MIDI Output is not open.\n");
         }

         if (ckey == 'q') break;
      }
   }

   // turn any MIDI notes currently playing:
   midiOutReset(device);

   // Remove any data in MIDI device and close the MIDI Output port
   midiOutClose(device);

   return 0;
}


Advertisement
If you only care about one note, or want the effect for all notes, you can simulate panning by independently adjusting the left/right audio volumes. But don't expect that to be very reliable. Some midi devices only apply changed volumes to new notes -- notes in the midst of playing stay at the same volume. There can be perceptible jumps in the volume, and you won't be able to get a smooth pan effect. Also, some midi devices won't respond to the volume functions (midiOutSetVolume) -- the only way to modify the volume is to manually change that through midi control messages.

The painful approach is to modify the notes themselves during playback. Some notes have alternate left/right values -- not all do. If you want to change a note to be from the left, you have to remap the note when doing the midi-out call. Not all notes have this, and a left or right note will only be on the left or right. You still cannot achieve a pan effect from individual notes.

The best choice is to get a midi editor, change the whole midi track to contain the pan effect you desire, then store multiple midi tracks, one for each variation of pan-left-to-right, pan-right-to-left, centered, always-left, always-right, etc. Then test the tracks out on multiple devices to make certain they sound acceptable.

Fortuntately, midi tracks are small (although if you're doing midi, I'd assume its for an embedded device, where memory limitations are likely).
Actualy my objective to play the midisound is want to track the object on the screen, when the object at the top , i will play the more heavy note,

// message.data[1] = first data byte of the MIDI message, for example: 60 (60 = middle c)

message.data[1] = 60; <-- this value will change base on the y value of duck

and the value will change base on the object y position

but i think i will use the left and right channel to let the player know the object move from left to right, i think i will use the x value, but i just don't know how to do that, still looking for some other example on internet.

I didn't play any outside midi file, because i will code the midi file in the code, I think i will use more than 1 note, but the note just changing base on the y value
Has nothing to do with DirectX. Kicking this over to General.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

This topic is closed to new replies.

Advertisement