Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Access to the 127 midi voices... Updated With Sound Function
#1
This is just a quick knock together example of how to access individual midi commands in FB under windows. Perhaps a better Play command?

I will post a more complete example later (hide the messy midi commands and all).

Edit: The example here has been removed. See the full version below.
Reply
#2
Here is a little cleaned up version. The first is the bi file with all of the messy stuff.

Code:
'Midi_Acc
'A collection of tools to play midi notes on a Windows box
'Hopefully this will someday include code for *nix systems as well
'
'Not every possible function is included here, but there are enough
'to send your own custom commands to the Midi Device
'
'R Keeling 25 March 2005
'randy@keeling.com


'$include once: 'win/mmsystem.bi'

'the ratio between notes... 2 ^ (1 / 12)
const RBN = 1.0594630943592952646

'the log(RBN)
const LRBN = 0.057762265046662109118

'RBN squared minus 1
const SRBNM = 0.1224620483093729814

'the Hertz Frequency of the lowest Midi Note  
const MidiNoteZeroFreq = 8.1757989156437073336

'Highest Octave in Midi
Const MaxOctave = 10

'MIDI Mapper
Const MIDI_MAPPER = -1

'midi message constants
    ' MIDI Controller Numbers Constants
Const midiMOD_WHEEL            = 1
Const midiBREATH_CONTROLLER    = 2
Const midiFOOT_CONTROLLER      = 4
Const midiPORTAMENTO_TIME      = 5
Const midiMAIN_VOLUME          = 7
Const midiBALANCE              = 8
Const midiPAN                  = 10
Const midiEXPRESS_CONTROLLER   = 11
Const midiDAMPER_PEDAL         = 64
Const midiPORTAMENTO           = 65
Const midiSOSTENUTO            = 66
Const midiSOFT_PEDAL           = 67
Const midiHOLD_2               = 69
Const midiEXTERNAL_FX_DEPTH    = 91
Const midiTREMELO_DEPTH        = 92
Const midiCHORUS_DEPTH         = 93
Const midiDETUNE_DEPTH         = 94
Const midiPHASER_DEPTH         = 95
Const midiDATA_INCREMENT       = 96
Const midiDATA_DECREMENT       = 97

    ' MIDI status messages
Const midiNOTE_OFF             = &H80
Const midiNOTE_ON              = &H90
Const midiKEY_PRESSURE         = &HA0
Const midiCONTROLLER_CHANGE    = &HB0
Const midiPROGRAM_CHANGE       = &HC0
Const midiCHANNEL_PRESSURE     = &HD0
Const midiPITCH_BEND           = &HE0


'midi note constants
   'for different octaves
   'use Octave*12+note
   'Octaves run from 0 to 10
const midiC       = 0  

const midiCs      = 1  
const midiDb      = 1  

const midiD       = 2  

const midiDs      = 3  
const midiEb      = 3  

const midiE       = 4  
const midiFb      = 4  

const midiF       = 5  
const midiEs      = 5  

const midiFs      = 6  
const midiGb      = 6  

const midiG       = 7  

const midiGs      = 8  
const midiAb      = 8  

const midiA       = 9  

const midiAs      = 10
const midiBb      = 10

const midiB       = 11
const midiCb      = 11

'instruments
const midiAcoustic_Grand_Piano  =  0
const midiBright_Piano          =  1
const midiElectric_Grand_Piano  =  2
const midiHonky_Tonk_Piano      =  3
const midiElectric_piano_1      =  4
const midiElectric_Piano_2      =  5
const midiHarpsichord           =  6
const midiClavinet              =  7
const midiCelesta               =  8
const midiGlockenspiel          =  9
const midimusic_Box             =  10
const midiVibraphone            =  11
const midiMarimba               =  12
const midiXylophone             =  13
const midiTubular_bells         =  14
const midiDulcimer              =  15
const midiDrawbar_Organ         =  16
const midiPercussive_Organ      =  17
const midiRock_Organ            =  18
const midiChurch_Organ          =  19
const midiReed_Organ            =  20
const midiAccordion             =  21
const midiHarmonica             =  22
const midiTango_Accordion       =  23
const midiNylon_String_Guitar   =  24
const midiSteel_String_Guitar   =  25
const midiJazz_Guitar           =  26
const midiClean_Electric_Guitar =  27
const midiMuted_Electric_Guitar =  28
const midiOverdrive_Guitar      =  29
const midiDistortion_Guitar     =  30
const midiGuitar_Harmonics      =  31
const midiAccoustic_Bass        =  32
const midiFingered_Bass         =  33
const midiPicked_Bass           =  34
const midiFretless_Bass         =  35
const midiSlap_Bass_1           =  36
const midiSlap_Bass_2           =  37
const midiSynth_Bass_1          =  38
const midiSynth_Bass_2          =  39
const midiViolin                =  40
const midiViola                 =  41
const midiCello                 =  42
const midiContrabass            =  43
const midiTremolo_Strings       =  44
const midiPizzicato_Strings     =  45
const midiOrchestral_Harp       =  46
const midiTimpani               =  47
const midiString_Ensemble_1     =  48
const midiString_Ensemble_2     =  49
const midiSynth_Strings_1       =  50
const midiSynth_Strings_2       =  51
const midiChoir_ahh             =  52
const midiChoir_oohh            =  53
const midiSynth_Voice           =  54
const midiOrchestral_Hit        =  55
const midiTrumpet               =  56
const midiTrombone              =  57
const midiTuba                  =  58
const midiMuted_Trumpet         =  59
const midiFrench_Horn           =  60
const midiBrass_Section         =  61
const midiSynth_Brass_1         =  62
const midiSynth_Brass_2         =  63
const midiSoprano_Sax           =  64
const midiAlto_Sax              =  65
const midiTenor_Sax             =  66
const midiBaritone_Sax          =  67
const midiOboe                  =  68
const midiEnglish_Horn          =  69
const midiBassoon               =  70
const midiClarinet              =  71
const midiPiccolo               =  72
const midiFlute                 =  73
const midiRecorder              =  74
const midiPan_flute             =  75
const midiBlown_Bottle          =  76
const midiShakuhachi            =  77
const midiWhistle               =  78
const midiOcarina               =  79
const midiSquare_Wave           =  80
const midiSawtooth_Wave         =  81
const midiCaliope               =  82
const midiChiff                 =  83
const midiCharang               =  84
const midiVoice                 =  85
const midiFifths                =  86
const midiBass_Lead             =  87
const midiNew_Age               =  88
const midiWarm                  =  89
const midiPolySynth             =  90
const midiChoir                 =  91
const midiBowed                 =  92
const midiMetallic              =  93
const midiHalo                  =  94
const midiSweep                 =  95
const midiFX_Rain               =  96
const midiFX_Soundtrack         =  97
const midiFX_Crystal            =  98
const midiFX_Atmosphere         =  99
const midiFX_Brightness         =  100
const midiFX_Goblins            =  101
const midiFX_Echo_Drops         =  102
const midiFX_Star_Theme         =  103
const midiSitar                 =  104
const midiBanjo                 =  105
const midiShamisen              =  106
const midiKoto                  =  107
const midiKalimba               =  108
const midiBagpipe               =  109
const midiFiddle                =  110
const midiShanai                =  111
const midiTinkle_bell           =  112
const midiAgogo                 =  113
const midiSteel_Drums           =  114
const midiWoodblock             =  115
const midiTaiko_Drum            =  116
const midiMelodic_Tom           =  117
const midiSynth_Drum            =  118
const midiReverse_Cymbal        =  119
const midiGuitar_Fret_Noise     =  120
const midiBreath_Noise          =  121
const midiSeashore              =  122
const midiBird_Tweet            =  123
const midiTelephone_Ring        =  124
const midiHelicopter            =  125
const midiApplause              =  126
const midiGunshot               =  127

dim shared MidiError as string

function MidiGetError() as string
   MidiGetError = MidiError
end function
sub MidiSend(ByVal hMidiOut as integer, ByVal statusmsg As integer,_
   ByVal data1msg As integer, ByVal data2msg As integer = 0)

  Dim midiMessage As integer
  dim lowint As integer
  dim highint As integer

  lowint = (data1msg * &H100) + statusmsg
  highint = (data2msg * &H100) * &H100
  midiMessage = lowint + highint
  midiOutShortMsg hMidiOut, midiMessage
End sub
function MidiOpen (ByVal MidiDevice as integer = MIDI_MAPPER ) as integer
  
   dim hMidiDevice as integer
   dim nMidiDevices as integer
   MidiError = ""
  
   nMidiDevices = midiOutGetNumDevs()
  
   if nMidiDevices <=0 then
      MidiError = "No Midi Devices Found!"
      MidiOpen = -1
      exit function
   end if
  
   midiOutOpen hMidiDevice, MidiDevice, 0, 0, CALLBACK_NULL
   MidiOpen = hMidiDevice
end function
sub MidiClose (ByVal hMidiOut as integer)
   midiOutClose hmidiOut
   MidiError = ""
end sub
sub MidiSetInstrument (ByVal hMidiOut as integer, _
   ByVal Instrument as integer = 0, ByVal Channel as integer = 0)
  
   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if instrument < 0 or instrument > 127 then
      MidiError = "Instrument Out Of Range: " + STR$(instrument)
      exit sub
   end if
  
   MidiSend hmidiOut, midiPROGRAM_CHANGE + Channel , Instrument
end sub
sub MidiSetMainVolume (ByVal hMidiOut as integer, _
   ByVal Volume as integer = 127, ByVal Channel as integer = 0)
  
   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if Volume < 0 or Volume > 127 then
      MidiError = "Volume Out Of Range: " + STR$(Volume)
      exit sub
   end if
  
   MidiSend hMidiOut, midiCONTROLLER_CHANGE + Channel, midiMAIN_VOLUME, Volume
end sub
sub MidiNoteOn (Byval hMidiOut as integer, ByVal Note as integer, _
   Octave as integer = 4, Velocity as integer = 127, Channel as integer = 0)

   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if Velocity < 0 or Velocity > 127 then
      MidiError = "Velocity Out Of Range: " + STR$(Velocity)
      exit sub
   end if
  
   if Note < 0 or Note > 11 then
      MidiError = "Note Out Of Range: " + STR$(Note)
      exit sub
   end if

   if Octave < 0 or Octave > MaxOctave then
      MidiError = "Octave Out Of Range: " + STR$(Octave)
      exit sub
   end if  
  
   if Octave = 9 and Note > midiG then
      MidiError = "Notes above G (7) in " + str$(MaxOctave) + "th Octave are not allowed in MIDI"
      exit sub
   end if
  
   MidiSend hmidiOut, midiNOTE_ON + Channel, Octave * 12 + Note, Velocity
end sub
sub MidiNoteOff (Byval hMidiOut as integer, ByVal Note as integer, _
   Octave as integer = 4, Channel as integer = 0)

   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if Note < 0 or Note > 11 then
      MidiError = "Note Out Of Range: " + STR$(Note)
      exit sub
   end if

   if Octave < 0 or Octave > MaxOctave then
      MidiError = "Octave Out Of Range: " + STR$(Octave)
      exit sub
   end if  
  
   if Octave = 9 and Note > midiG then
      MidiError = "Notes above G (7) in " + str$(MaxOctave) + "th Octave are not allowed in MIDI"
      exit sub
   end if
  
   MidiSend hmidiOut, midiNOTE_OFF + Channel, Octave * 12 + Note
end sub
sub MidiSetKeyPressure (ByVal hMidiOut as integer, ByVal Note as Integer, _
   ByVal Octave as integer = 4, ByVal Value as integer = 127, ByVal Channel as integer = 0)
  
   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if Value < 0 or Value > 127 then
      MidiError = "Value in Set Key Pressure Out Of Range: " + STR$(Value)
      exit sub
   end if

   if Note < 0 or Note > 11 then
      MidiError = "Note Out Of Range: " + STR$(Note)
      exit sub
   end if

   if Octave < 0 or Octave > MaxOctave then
      MidiError = "Octave Out Of Range: " + STR$(Octave)
      exit sub
   end if  
  
   if Octave = 9 and Note > midiG then
      MidiError = "Notes above G (7) in " + str$(MaxOctave) + "th Octave are not allowed in MIDI"
      exit sub
   end if
  
   MidiSend hMidiOut, midiKEY_PRESSURE + Channel, Octave * 12 + Note, Value
end sub
sub MidiSetControlChange (ByVal hMidiOut as integer, _
   ByVal ControlNumber as integer, _
   ByVal Value as integer = 127, _
   ByVal Channel as integer = 0)
  
   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if Value < 0 or Value > 127 then
      MidiError = "Value in Set Key Pressure Out Of Range: " + STR$(Value)
      exit sub
   end if

   if ControlNumber < 0 or ControlNumber > 127 then
      MidiError = "Control Number Out Of Range: " + STR$(ControlNumber)
      exit sub
   end if

  
   MidiSend hMidiOut, midiCONTROLLER_CHANGE + Channel, ControlNumber, Value
end sub
sub MidiSetProgramChange (ByVal hMidiOut as integer, _
   ByVal ProgramNumber as integer, _
   ByVal Channel as integer = 0)
  
   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if ProgramNumber < 0 or ProgramNumber > 127 then
      MidiError = "Program Number Out Of Range: " + STR$(ProgramNumber)
      exit sub
   end if
  
   MidiSend hMidiOut, midiPROGRAM_CHANGE + Channel, ProgramNumber
end sub
sub MidiSetPitchBend (ByVal hMidiOut as integer, _
   ByVal Value1 as integer = 0, _
   ByVal Value2 as integer = 64, _
   ByVal Channel as integer = 0)
  
   'Value1 is the LSB
   'Value2 is the MSB
   'a value of 0h00 0h40 (LSB first) means no pitch shift
   'a value of 0h00 0h00 (LSB first) means to shift as low as possible
   'a value of 0h7f 0h7f (LSB first) means to shift as high as possible
  
   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if Value1 < 0 or Value1 > 127 then
      MidiError = "Value1 in Set Pitch Bend Out Of Range: " + STR$(Value1)
      exit sub
   end if

   if Value2 < 0 or Value2 > 127 then
      MidiError = "Value2 in Set Pitch Bend Out Of Range: " + STR$(Value2)
      exit sub
   end if

   MidiSend hMidiOut, midiPITCH_BEND + Channel, Value1, Value2
end sub
sub MidiSetChannelPressure (ByVal hMidiOut as integer, _
   ByVal ChannelPressure as integer, _
   ByVal Channel as integer = 0)
  
   MidiError = ""
   if channel < 0 or channel > 15 then
      MidiError = "Channel Out Of Range: " + STR$(Channel)
      exit sub
   end if
  
   if ChannelPressure < 0 or ChannelPressure > 127 then
      MidiError = "Channel Pressure Out Of Range: " + STR$(ChannelPressure)
      exit sub
   end if
  
   MidiSend hMidiOut, midiCHANNEL_PRESSURE + Channel, ChannelPressure
end sub
sub PlayNote (ByVal Note as integer, ByVal Octave as integer, _
   ByVal Duration as single, ByVal Instrument as integer = 0, _
   ByVal Volume as integer = 127)
  
   dim tMidi as integer
   dim t as single
   tMidi = MidiOpen
   MidiSetInstrument tMidi, Instrument
   MidiNoteOn tMidi,Note,Octave, Volume
  
   t = timer + Duration
   do while t > timer
      sleep 10
   loop
  
   MidiNoteOff tMidi, Note, Octave
   MidiClose tMidi
end sub

function MidiSound (ByVal frequency as single, ByVal Duration as single, _
   ByVal Voice as integer = midiTrumpet) as integer
  
   'This routine uses midi to generate a frequency
   'to do this, we must find a midi note below the
   'requested frequency (f) and pitch bend up from
   'that note (x).
   '
   'A basic equation for the frequency of a midi note
   'is b*n^x = frequency. This comes from the fact
   'that is western music (and thus MIDI) the distance
   'between two semi-tones is the 12th root of 2 (lets call it n).
   'And this comes from the fact that there are tweleve
   'in the western scale (C, C#, D, D#, E, F, F#, G, G#, A, A#, B)
   'and that when you go up an octave, the frequency of the note
   'doubles. So if you start from some base note and keep multiplying
   'by n you will get each successive note. The base note that we
   'will start with is note 0 in midi (midi notes run from 0 - 127).
   'But we are now forced to know what the frequency of note zero is.
   'In MIDI standard, note 69 is 440 exactly (A above middle C on a piano).
   'We can now solve for b.
   '
   'b*n^x = Frequency
   'b*(2^(1/12))^69 = 440
   'b = 8.1757989156437073336
   '
   'so Midi note zero (C in the lowest octave) has a
   'frequency of approx. 8.1758 hertz
   '
   'We can now the frequency of any midi note. We can also find the
   'midi note with a given frequency. I will call these notes Virtual Notes
   'because they will often be fractional notes (9.34 or 143.1234 for example)
   'that aren't really midi notes (midi notes are integers only). However,
   'we can use these notes to find where we start for a given frequency and
   'pitch bend up to that note.
   '
   'To find a base note (x) we can solve our first equation for x.
   'b*n^x = f
   'x = (log(f/b))/(log(n))
   '
   'this is a virtual note, what we want is the first real note before this
   'so we can bend from that real note to our desired virtual note. This is
   'done with the int function.
   'x = int((log(f/b))/(log(n)))
   '
   'Now that we have a note to bend from we must learn how to bend.
   'The GM MIDI standard states that a pitch bend should range from two
   'semi-tones (notes) below the note, to two semi-tones above the note. This
   'means that if our note was G, we could bend from F below it, to A above it).
   'The command for pitch bend is set up so that it takes 2 bytes, a msb (most
   'sign. byte) and a lsb (least sign. byte). Think of msb as the main bend,
   'and the lsb as fine tuning. The values each range from 0 to 127. A value
   'of msb = 64, lsb = 0 means no bending at all, msb = 127, lsb = 127 is a full
   '2 semi-tone bend up, and msb = 0, lsb = 0 is 2 full semi-tones down. To make
   'it easier think of it as pitch bending running from 0 to 128
   'with 64 in the middle. And since we are only bending up, we just have to
   'go from (0 to 64). We will add 64 to this to get the right bend. To start,
   'we will set our frequency between the base note value and 2 semi-tones up
   'then scale this between 0 and 64.
   '
   'lf (lower frequency) = b*n^x
   'hf (higher frequency) = b*n^(x+2)
   '
   'if let k be our ratio we get
   '
   'k = 64 * ((f - lf)/(hf-lf))
   '
   'the msb would be the integer part of k + 64, while the lsb would be fractional
   'part of k scaled from 0 to 127. Even though the range of msb could run
   'from 64 to 128 (which is outside of the max value of 127) it won't because
   'we are only bending at most 1 semi-tone.
   '
   'msb = int(k) + 64
   'lsb = int((k - int(k)) * 127)
   '
   'At this point we could be done, but if we look at the equations, they
   'could be cleaned up a bit.
   '
   'k, when we write it all out is
   '
   'k = 64 * ((f - b*n^x)/(b*n^(x+2) - b*n^x))
   '
   'that's three multiplications of b alone. If we factor out b and
   'cancel it we get
   'k = 64 * ((f/b - n^x)/(n^(x+2) - n^x))
   'one division for 3 multiplications isn't bad but we can
   'also clean up the denominator a little.
   'n^(x+2) - n^x = n^x*n^2 - n^x = n^x(n^2 -1)
   '
   'since n is a constant, why solve n^2-1 each time, make it a const
   'n^2 - 1 is approx. 0.1224620483093729814, so if we call this z we have
   '
   'k = 64 * ((f/b - n^x)/(n^x*z))
   '
   'and we can save another power evaluation buy setting w = n^x
   '
   'k = 64 * ((f/b - w)/(w*z))

   dim f as single
   dim x as integer
   dim w as single
   dim k as single
   dim s as single
   dim msb as integer
   dim lsb as integer
  
   f = frequency
   'we are only going to allow sound frequency between 10 and 14000 hertz
   'the average human with GOOD hearing can hear between 20-20000 hertz
   'so this isn't too bad
   '
   'besides, after 5000 its almost all the same :-) annoying
   if f < 10 then f = 10
   if f > 14000 then f = 14000
  
   'we use this a couple of times, so lets save it
   'b = MidiNoteZeroFreq
  
   s = f / MidiNoteZeroFreq
  
   'LRBN is the Log of the Ration Between Two Notes, i.e. the Log(n)
   x = int(log(s)/LRBN)
   w = RBN^x
   k = 64 * ((s - w)/(w*SRBNM))
  
   msb = int(k) + 64
   lsb = int((k - int(k)) * 127)
  
   'do the midi stuff
   dim hMidi as integer
   'the channel, I used 15, because the default play note is on 0
   dim o as integer
   dim n as integer
   dim t as single
   n = x mod 12
   o = (x-n)/12
   const c = 15
   hMidi = MidiOpen
   MidiSetMainVolume hMidi, 127, c
   MidiSetInstrument hMidi, Voice, c
   MidiSetPitchBend hMidi, lsb, msb, c
   MidiNoteOn hMidi, n, o, 127, c
   t = timer + duration
   do while t > timer
      sleep 10
   loop
   MidiNoteOff hMidi, n, o, c
   MidiSetPitchBend hMidi, 0, 64, c
   MidiClose hMidi
end function

And a small driver program might be:
Code:
'$include: 'midi_acc.bi'
option explicit

'Do it the hard way
dim hMidi as integer

hMidi = MidiOpen
MidiSetMainVolume hMidi, 127
MidiSetInstrument hMidi, midiCello
MidiNoteOn hMidi, midiC,3
sleep
MidiNoteOff hMidi, midiC,3
MidiClose hMidi

do while inkey$<>"":loop

'Play a single note the easy way
PlayNote midiG, 5, 1.5, midiChurch_Organ

'Play An F# Major scale in the 6th octave on flute
PlayNote midiFs, 6, .5, midiFlute
PlayNote midiGs, 6, .5, midiFlute
PlayNote midiAs, 6, .5, midiFlute
PlayNote midiB,  6, .5, midiFlute
PlayNote midiCs, 7, .5, midiFlute
PlayNote midiDs, 7, .5, midiFlute
PlayNote midiF,  7, .5, midiFlute
PlayNote midiFs, 7, .5, midiFlute


dim i as integer
for i = 0 to 5000 step 1000
   midisound i,.1
next i

? "Done"
sleep

EDITED: Added MidiSound Function
Reply
#3
Nifty. Nice work.
Reply
#4
To Keeling:

I have just this afternoon tested your little FB MIDI-based proggie out, and I dare believe that it is an EXCELLENT QB-like “Sound” command that FreeBASIC 100% needs (and deserves, as well!)!!! d=Big Grin=b You know why? Because during that test there, the MIDI-based notes came out *so* clearly on the computer that I use! Perfect, I must say, my man!!

I must personally congratulate you on a spectactular job well done here, Keeling, from the very bottom of my heart!!! :king: Hey, I mean it now.

Talk to you later, and God BLESS you this coming weekend!! Wink !



SUCH A REAL PLEASURE MEETING YOU HANDSOMELY,

[Image: file.php?id=32]
Adigun Azikiwe Polack
One of the Founders of “Aura Flow” ::: Continuing Developer of “Frantic Journey”
Current Developer of “Star Angelic Slugger” ::: Webmaster of the “AAP Official Projects Squad”
Original Creator of the “The New FreeBASIC 8-Bit Palette Machine”
url=http://dhost.hopto.org/aapproj/][Image: file.php?id=194][/url]
Your *official* home of the FreeBasic GFX Demo Central, now holding over 150 FB graphics demos so far!!! Big Grin !
Reply
#5
:oops: What more can I say but thanks.

I am currently working on making a FB Sound command to mimmic QB's using the Midi pitch shift to match the input hertz. The range will only be from around 5 - 14,000 due to the limits of Midi but that should do for most applications.

Again, thanks for the kind words.

Randy
Reply
#6
Are you able to put that in a downloadable ZIP please?
atos-Software
http://www.datacentertalk.com - interested in how web hosting works? Here the place to go to find out.
[Image: 42-r]
Reply
#7
I guess so. But it is really just one file to cut and paste. :-)



Here it is. In the file is the bi file, a driver program and a compiled exe. A whole 9k. :-)

EDIT: The zip file here has also been updated.
Reply
#8
Great work.
Reply
#9
The only problem that I have with it is that the PlayNote function opens and closes the midi device every time it runs, so it makes all the notes staccato. Also, the PlayNote has no support for Channels!

Perhaps I'll modify it so that PlayNote takes the midi device as well as the channel, and maybe make it so that its a state machine, like OpenGL, so you can play multiple notes on the same channel at the same time with PlayNote.
.14159265358979323846264338327950288419716939937510582709445
Glarplesnarkleflibbertygibbertygarbethparkentalelelangathaffendoinkadonkeydingdonkaspamahedron.
Reply
#10
That's why there is the 'hard method', so that you can keep the midi device open, set the channel, whatever you want. The play note is there just for a quick one off note.

Look at the driver program I posted and in the .bi file at the functions:

MidiOpen
MidiClose
MidiNoteOn
MidiNoteOff

There are also functions in there for more advanced midi messages.

I am open to all ideas for the tool. If there is anything I can do to help or if you have some ideas for functions to add, let me know.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)