[directmusic] Re: Introduction and question...

  • From: "Leo Newman" <leonewman@xxxxxxxxxxxxx>
  • To: <directmusic@xxxxxxxxxxxxx>
  • Date: Mon, 4 Nov 2002 12:19:46 -0800

Thank you for the help.  I appreciate it.   =]

A few more questions...

Do I need to make a tool that will process the MIDI messages that
SendMidiMsg() sends or is there a default tool that handles the message that
it sends to the performance?

Lets say I want to do a pitch-bend up one semitone.  If I set it to be plus
or minus 127 semitones for the range, do I pitch bend it 16384/255?  Then do
I convert this to a 14-bit number and split it into the high seven bits and
low seven bits?

I have spent most of the learning time with the DirectX SDK documentation.
It gets a little abstract for me at times.  Is there another source that
would help me with DirectMusic programming?  (Any books available?)

Since I am doing this as a hobby, I feel kind of guilty wasting your time
since this is what you do for a living.

Leo

-----Original Message-----
From: directmusic-bounce@xxxxxxxxxxxxx
[mailto:directmusic-bounce@xxxxxxxxxxxxx]On Behalf Of ThSteup@xxxxxxx
Sent: Monday, November 04, 2002 9:07 AM
To: directmusic@xxxxxxxxxxxxx
Subject: [directmusic] Re: Introduction and question...

Hello Leo,
Im working on a Phrase-Sampler Application that uses a similar approach.
Here  is some information we collected on this topic. Maby this will help
you.

The Pitch of a WaveSegment can be controlled by sending
MIDI-Pitch-Bend Messages to the Performance:

To make the code easier to read I suggest to use a function like this for
sending all midi messages :

bool SendMidiMsg(BYTE status, BYTE msb, BYTE lsb)
{
   DMUS_MIDI_PMSG* pMidi = NULL;

   if(FAILED(m_pPerf->AllocPMsg(sizeof(DMUS_MIDI_PMSG), (DMUS_PMSG**)&
pMidi)))
      return false;

   ZeroMemory(pMidi, sizeof(DMUS_MIDI_PMSG));

   pMidi->dwSize = sizeof(DMUS_MIDI_PMSG);
   pMidi->dwFlags = DMUS_PMSGF_TOOL_IMMEDIATE;
   pMidi->dwType = DMUS_PMSGT_MIDI;
   pMidi->dwGroupID = 0xFFFFFFFF;

   //if you want to send only to a specific audiopath : get its graph and
use
it here...
   //pMidi->pGraph = m_pGraph;

   pMidi->bStatus = status;
   pMidi->bByte1 = msb;
   pMidi->bByte2 = lsb;

   if(FAILED(m_pPerf->SendPMsg((DMUS_PMSG*)pMidi)))
   {
      m_pPerf->FreePMsg((DMUS_PMSG*)pMidi);
      return false;
   }

   return true;
}

You can send PitchBend Messages before or while you are Playing the Wave.
A Pitch Bend Message looks like :

 Status: 0xE0
 Byte1: lsb
 Byte2: msb


Example code :


 SendMidiMsg(0xE0, lsb , msb);


Pitch Bend is a High-Resoltion Midi Controller (Representing for example the
Bend-Wheel of MIDI Keyboards) The two Byte Value in this Messages represents
a 14 Bit pitchbend-amount.

The maximum shift amount depends on the Setting of the pitch-band range.
With the default Pitch-bend range you will ony be able to make small shifts.
If you set the Pitch bend Range (RPN-Controller 0) to the maximum, you are
able to do Pitch bends over +-127 semintones.


The bend-range you set is divided into 16384 Parts.
the lower seven Bits of the Pitch Bend Amount you like to set
go into the lsb,the higer seven Bits go into the msb.


the MIDI RPN Message-Sequence for Pitch Bend Range setting is

// Begin RPN
Status: 0xB0 (ControlChange)
Byte1 : 101, Byte2:0

Status: 0xB0 (ControlChange)
Byte1 : 100, Byte2 : 0

// Data Entry
Status: 0xB0 (ControlChange)
Byte1 : 6, Byte2 : YOUR_BEND_RANGE

// End-RPN
Status: 0xB0 (ControlChange)
Byte1 : 101, Byte2 : 127

Status: 0xB0 (ControlChange)
Byte1 : 100, Byte2 : 127


This RPN-Messages can be sent in a similar manner as the Pitch-bend
Messages.

For Example the code

  SendMidiMsg(0xB0, 101, 0);
  SendMidiMsg(0xB0, 100, 0);
  SendMidiMsg(0xB0, 6, x);
  SendMidiMsg(0xB0, 101, 127);
  SendMidiMsg(0xB0, 100, 127);


sets the maximum Pitch bend to the amount of up/down x Semitones.

This should be done initially, before you play the wave.

If you want to shift down, you also need a DirectMusicTool that changes the
duration
of the wave, because otherwise is would be cutt-off too early.


Todor Fay suggested in a posting on this topic :

<<<<<<<<<<<<<<

Create a tool (with an IDirectMusicTool interface) and stick it in the
performance or audiopath.
The tool should only process Wave PMSGs and
you should set it to DMUS_PMSGT_WAVE in the GetMediaTypes() method.
Also, have it process immediately by setting to return
DMUS_PMSGF_TOOL_IMMEDIATE in the GetMsgDeliveryType() method.

So, once the tool is running and intercepting all of the wave messages,
what does it do?

One line of code:

    pMsg->rtDuration = pMsg->rtDuration * 10;

This makes the duration ten times as long, which is plenty to handle a
serious pitch bend in the downward direction.

<<<<<<<<<<<<

We tried this and it worked fine.

If you want to use the maximum pitchbend Range you may need to multiply the
rtDuration by
2048 instead of 10

Since the application were working on requiers more complicated calculations
and settings in the tool it wouldn't make much sense to post more of its
code
here, but if you run into some trouble with the tool programming let me
know.

Thomas




Other related posts: