Mid Life Crisis - Midi Thread

BlitzMax Forums/BlitzMax Programming/Mid Life Crisis - Midi Thread

dw817(Posted 2016) [#1]
I was looking over the code archives but did not see an example program for BlitzMAX which would play a single MID instrument. For instance, piano, MIDI instrument #1.

Here is some code I wrote in GFA if it helps. Forgive me if today I don't know how it works or can be applied to BlitzMAX:




skidracer(Posted 2016) [#2]
Porbably best to start with some C and port from there.

https://msdn.microsoft.com/en-us/library/windows/desktop/dd798495(v=vs.85).aspx

Brucey may already have a portmidi module which would be a lot simpler.


Casaber(Posted 2016) [#3]
Donīt have a mid life crisis now do you hear.

Here you go.


Extern "win32"
Function midiOutOpen(lphMidiOut:Int ,uDeviceID:Int,dwCallback:Int,dwInstance:Int,dwFlags:Int)
Function midiOutClose(hMidiOut:Int)
Function midiOutShortMsg(hMidiOut:Int,dwMsg:Int)
End Extern

Const NoteOn = $9 , NoteOff = $8 , ProgramChange = $C , CC = $B

' Make a more practical version of midioutshortmsg
Function SendMidi(Handle,Channel,Status,Data1=0,Data2=0)
	midiOutShortMsg(Handle,(Data2 Shl 16) | (Data1 Shl 8 ) | (Status Shl 4) | Channel)
End Function

' Open
Local MidiOut:Int , handle:Int Ptr
Handle = Varptr MidiOut ; MidiOutOpen Int(Handle),-1,0,0,0 ' -1 is always MIDI MAPPER

' Set Grand Piano
Channel = 1 ; Instrument = 1 ; SendMidi MidiOut,Channel,ProgramChange,Instrument

Repeat
	Note = Rand(64,127) ; Vel = Rand(64,127)
	SendMidi MidiOut,Channel,NoteOn,Note,Vel ' Note on
	Delay 64 ' Pause some length
	SendMidi MidiOut,Channel,NoteOff,Note ' Note off
Until KeyDown(KEY_ESCAPE)

' Close
midiOutClose MidiOut



Casaber(Posted 2016) [#4]
I had to try and see how well Bmax syncs,

beercuase we all we know.. that's what matters in life.




Midimaster(Posted 2016) [#5]
here is a (running) code sample for MIDI using Brucey RtMidi.Mod:

http://www.blitzbasic.com/Account/showuser.php?id=10365

I use this functions very reliable in all my commercial music education software


Here is a tool with source code, that converts MIDI into OGG. It shows also how to call MIDI on low level:

http://www.blitzforum.de/forum/viewtopic.php?t=37210

By the way... Your code is written by "Engelbert van Loock". Are you Engelbert?


dw817(Posted 2016) [#6]
Casaber nailed it. And in very small code too ! Outstanding ! I already have you down for being the first to play, seek, and read MIDI and now here you have the ability to effectively send MIDI notes.

Nicely done !! I like your beat box too. Catchy rhythm. :)

I'll take a look it over, make some functions out of it, and then anyone can have real sound effects and musical notes directly in their code without requiring a Mod or DLL.
. . .

Simon Armstrong: Thanks but fortunately I won't have to mess with C.

Midimaster: Won't need to use it. Thanks though. Interesting bit about MIDI into OGG. Do you mean *.MID to *.OGG, the media file ?

And no, I am not Engelbert. He was one of many GFA programmers from Germany when I was using the language. I told him I didn't want to use the PC speaker for sound effects for this one game I was working on and was there a way to create sound without using WAV files ?

He said I could play some of the high percussion instruments by opening MIDI drivers to accomplish this - and then he sent me some code to show playing the piano.

And yes, I did make use of this. I wrote a quick game Dungeon that used only plotting MIDI sounds throughout and it worked quite well. I should totally rewrite that game sometime.




Brucey(Posted 2016) [#7]
and then anyone can have real sound effects and musical notes directly in their code without requiring a Mod or DLL

Indeed, and for everyone else who doesn't use Windows, or wants more control, there's always the well supported open-source libraries/modules.


Casaber(Posted 2016) [#8]
Dw817 watch out though, WinRT / "Metro" still lacks MIDI completely. I guess that will change. Same with iOS they too had no MIDI support at all before version 3.

Remember it's only Windows and not ASIO (only MME). RTMIDI uses MME same for Win32 underneath so no changes there, but you could have Apple support if you used it I guess.
We could try to do the same as with Windows above but with OSX. It could be fun to see how small Mac version would be, we can talk more about that later if you want.

I also have few ideas how to search for a softsynth on the device e.g for applying Soundfonts later.


dw817(Posted 2016) [#9]
Okay, here is a sample game demo to see how playing MIDI notes can be used for sound effects.



Yes ! I was just going to mention SoundFonts, Casaber. My favorite is "Chaos_V20."

Brucey, as for more control. Nope, I'm good. I just wanted to have the ability to sound out MIDI notes.

As for system compatibility, yes, I suspect when I finish Carryall 750k it will only run in Windows.


Casaber(Posted 2016) [#10]
Iīm not getting any sounds in that game? I quickly tried debugged what it could be, it so far I think it must be the single playmidievent routine if anything. Everything else is perfect condition. I can't understand why it's quiet.

So I tried my code again on the same system, and out flows all kinds of notes. So something is different.

I saw some notes in there by the way, do you mean volume to be velocity? Your thoughts about echo imply that you want to use velocity to fake echo aswell?
You could do that with either MIDI channel volume, or with velocity with Note on's. I guess the most "correct way"
would be to use MIDI channel volume as velocity might be used for many things, it should be best only used for expression. In my humble opionion.

With shitty GM it would make no difference though in most cases if you use vel or volume.

Chaos is a good bank. Very expressive one.

But David oh David Why do you have have sound and not me? :s Maybe my volume is too low, Iīm getting deaf. I experienced very low MIDI earlier
today before posting when I tried some ryhthms, I have no idea yet why, I know it has a working MIDI system, well you can play Macgyver.mid on it, that's class.
A GM is GM right. I had very odd flutes and low volume, so it might be just my shitty system..


*EDIT SOLVED, how could I miss that, it's MIDIOFF, it should not be called to turn off sounds. Just need a small recode to use noteoff instead.
I guess some systems are more forgiving than others.

EDIT2* no false alarm, you implemented a allnoteoff, but taking it away made me hear sounds at least. We'll it's just some detail then to work out later I guess. I think you just switch off sounds too fast, it just that simple. But I could be wrong. But I donīt think so. Some systems allow percussion especially to cling off, mine doesn't. If you tell it to stop, it stops right away. Or it could be a polyphony problem.


dw817(Posted 2016) [#11]
Glad you got it working, Casaber ! I would think that the sound I'm using for the player hitting a wall would not be heard it all, but I get a slight metallic tap - so that does work here.

At one point I couldn't hear any MIDI at all and panicked. Then I clicked the speaker icon in the bottom-right-hand corner of the taskbar, then click MIXER. And see that the program I was running had volume set to zero.

I never could get MIDI to work in DOS BOX, which is a shame as I now have GFA working in it, I wrote this lovely Wind Chime program that also has a button for generating random music with backup synthesizer chords and everything.

Just doesn't work in DOS BOX. :/

And yes, I don't know the difference between velocity or volume - they may be one and the same in MIDI ?


Casaber(Posted 2016) [#12]
In MIDI Velocity is reserved for the strength of something e.g. the plucked string, the blown sax, or the hit percussion/fx.

Low velocity are often programed to also sound more mellow and more you know.. everything that you naturally can relate to soft sounds. A good flute for example can become more breathy at low vel. Lower volume is one of those properties of course, but its a package deal in velocity. It might be anything.

Another thing is that volume can be changed wheneever, velocity is only given at the strike of the sound, at the start. Once you've said a velocity,
you can't change it while it's playing, that would be to strike the drum again.

MIDI volume is pure pure volume and you can change it whenever, and it affects everything on that one channel that you send it to.
Velocity happens only once and "per key" and is meant to be a package deal. Vel may filter sounds, it could change EG's it could do alot of things.
It's not just volume. Execept in shitty GM's then it's pretty much just volume and that's part of why we hate it. No expressiveness.


Casaber(Posted 2016) [#13]
Would love to hear those chimes and music generations sometime, maybe it's possible to convert it to Bmax?
I remember that it was a real struggle to try get things working sometimes with DOS and sound, haha I guess DOSBOX emulates things TOO WELL ;)


Casaber(Posted 2016) [#14]
This technique should suffice for syncing with frames at least, it keeps 2-3msec average on an old XP couple of years ago, and Windows7 and newer improved alot.

There's no timetagging here in te output, but you can stream with some effort if you want (that would be to setup a buffer upto 64k in size instead of just ONE MIDI event),
and then you trigger the whole buffer as you do here all in one go. That would make things "atomic", all events in the buffer would have perfect integrity.
But I think that's overkill to stream if you only need framed synced effects.

With all good tools you could do most things with just careful timing and perhaps using things like threads and
learn all kinds of nice mechanisms that makes OS behave nice, which are good also for graphics and everything.

BMax is powerful enough to do close acccurate sample creation realtime with OpenAL so it could definitley time complex MIDI on its fingertips ;)

So I say, use the simple route when you can. It's a win win.


Casaber(Posted 2016) [#15]
I had a look in your original sourcecode about that echo and I think I know what it's meant to do. You set Echo on/off in the
source and you do that using SystemEx msg, you're programming the synth to a particular reverb/echo, and instead of using streaming / long midi
msg API to send any length MIDI message (which this needs) you're reusing (cleverly) the shortmsg routine.

So Echo is a flag telling if your're doing that trick or not. Does that ring a bell?
I might be wrong because Iīm not sure why there's a zero sent when your'e not doing that. It might be a filler for Windows API?
If so I donīt think itīs needed.

PROCEDURE PlayNote(Instr,Pitch,Volume,Echo,Channel)
IF Echo
~@@MIDIOUTSHORTMSG(MIDI,(255 << 8) + &00)
ELSE
~@@MIDIOUTSHORTMSG(MIDI,0)
ENDIF
~@@MIDIOUTSHORTMSG(MIDI,(Instr << 8) + &CA) ' This is a hardcoded PROGRAMCHANGE for CHANNEL 10 (DRUM CHANNEL)
~@@MIDIOUTSHORTMSG(MIDI,(Volume << 16) + (Pitch << 8) + &9A) ' This is a HARDCODED NOTE ON for CHANNEL 10 (DRUM CHANNEL)
' Pitch = 0-127

This was just an idea I had when I glanced at the code. It's a clever way to send any MIDI msg using the short API if it's true.

EDIT
No I changed my mind it seems to be a MIDI msg template with something else not a Sysex?
Will check more closely when I get the time because that zero still aludes me.


Midimaster(Posted 2016) [#16]
@dw817
Ah... I know Engelbert as a musician collge since 1980. In 2005 Engelbert worked with me on some projects. Now he is a web developer in south bavaria and I lost the contact....


@all
Once sent a PROGRAM CHANCE on a channel the sound (one of 127) remains the same. So there is no need for sending PGC again. Better to use another channel (0,9,11-15) if you need another instrument.

Channel 10 is always the DRUM CHANNEL. The message part you called "pitch" is normally called NOTE. It will play 127 chromatic notes from deep C to high C. But in DRUM CHANNEL this results in one of 127 different Drum Sounds.

There is also a CHANNEL PITCH message 1110nnnn, which manipulates the following NOTE messages.

My MIDI-TO-OGG converter plays the scale (all 128 notes) of a sound and saves 128 audio-files, which can be used afterwards in BlitzMax games like normal TSound-samples.

Also important to know. MIDI uses the sound device of the user to play the events. So you never know, whether the user has only poor (incomplete) GM-Library, good libraries like Roland Sound Canvas or a extern high quality music instrument like the Yamaha Tyros.


skidracer(Posted 2016) [#17]
Thread moved to BlitzMax Programming due to quality of content.


angros47(Posted 2016) [#18]
BlitzMax is multi-platform; midi programming is easy on windows, but not on linux, because many linux distros by default don't provide a software midi synthesizer, so midi is available only on system with midi hardware (you can install a midi soft synth, but the download is usually about 50 mb or more)


Casaber(Posted 2016) [#19]
@Midimaster You could ask the OS and look for known softsynths / drivers. It's a unusual thing to do but if you have reason to
believe that there might be a common softsynth onboard then it's no problem to direct everything there (and skip midi mapper).

The absolute standard ones that comes with Windows (Microsoft GS Wavetable) & Apple OSX (Quicktime synth) both uses
Rolands SoundCanvas so I guess they bought the cheapest version, and did something terrible with it.

Just curious, have you developed alot for Bars&Pipes ? Or I might misstake you for someone else. If you donīt mind me asking.


skidracer(Posted 2016) [#20]
@angros47 after reading up on RTMidi it seems that some midi programming tasks such as virtual soft synths and VJ visualiser apps that both need to provide a midi endpoint for other applications is actually easier for MacOS and Linux.


angros47(Posted 2016) [#21]
Midi programming in linux is actually easy, but after you wrote your program, it just won't work on most linux systems, because it won't find a midi port available.


skidracer(Posted 2016) [#22]
Most linux systems don't have displays let alone speakers :)


dw817(Posted 2016) [#23]
My goodness you guys are busy here. I guess I do ask the right questions. :)

I have looked at the code that generates raw sound (generated AudioSample) in general for BlitzMAX and I can't seem to generate any without a harsh click before it starts and a harsh click as it stops.

Casaber's MIDI routine however does a nice job. No click before or after a sound, and doesn't require creation of a sound file or anything - and I suspect I could port over my Wind Chimes routine.

I'm still messing with straight audio though, the one that uses the CreateAudioSample(). Trying to develop a routine where 0 is silent, 1 is very low pitch and 255 is very high pitch. It's the clicking in-between that's the problem.


Casaber(Posted 2016) [#24]
I looked into what new things Windows has to offer on the MIDI front. When you want more sample like control.
DirectMusic being from 1996, MME from 1991 and they've grown old without improving themselves. MIDI itself should have a midlife crisis.

Wondering if anyone has already have had experience with the new Windows API? I myself havn't had the time too look into it,
it seem to cover all new Windows including ARM/"Metro". Which is nice.

Seemingly it's about MIDI and nothing else, no standard softsynths distributed with Windows, and no way to play for instance a .mid with a single command.
Everything is instead pure MIDI and meant to be about hand-made quality connections between apps if I understood things right.

A very Ipad-like thing to do, I have the feeling. I would like that, so that would be very welcome.

https://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.midi.aspx

http://video.namm.org/general/A3E_Microsoft_Keynote.mp4


Midimaster(Posted 2016) [#25]
Casaber, I know all these things... The portability to Windows and OS and the possibility of selecting the devices is the reason why I use Bruceys RtMidi.Mod. It's not "unusual" to select drivers, but a "must have". My customers always have 3 to 4 differnet midi devices and want to switch the target. The source code of my MIDI-TO-OGG converter shows how to code a complete MIDI implementation in a BlitzMax program.

The biggest problem is the latency (60-200msec) of the software based wave-tables. So most of my customers use extern midi instrument (10msec) for realtime MIDI. You can feel this in my rhythm-trainer, where it is important to interact with the sounds coming out of the speakers.
If you need a real-time music instrument, you need to convert the tones into audio with MIDI-TO-OGG converter.

@dw817
In my former post ( http://www.blitzbasic.com/Community/post.php?topic=105879&post=1297182 ) I descriped the 3 reasons for your audio problems. A combination of your code and these three rules should bring the solution. As you can hear in the LISTEN&HEAR-MACHINE complex manipultations on audio are possible.

@casaber
No, I did not work for "Bars Pipes". I started developing MIDI -Software on Atari in 1985. But always with the target "music education". As my name says I'm "Midimaster" and thats also my company's name www.midimaster.de. We offer 20 programs for music education on Windows and Mac. And there is a cooperation with WIDI-Soft, who hold the still best Audio-To-Note recognition algorithm. So... a big experience in audio related algorithms


MIDI is the standard language for music instruments. No midlife crisis... Musicians need it also to communicate between instruments (without computers) and it is the base for DMX light commands on all stages of the world. Musicians never needed the build in windows MIDI wave table. They always connect a USB device, which is self installing. The USB device has a low latency sound generator or is a driver to connect music instruments or lasers etc....


dw817(Posted 2016) [#26]
MidiMaster, your link shows a profile.

Casaber, keep up the great work ! Your code submits are incredibly helpful AND useful !


Casaber(Posted 2016) [#27]
MidiMaster, sounds like we have alot in common, nice. Me, I started with music back in 1982,
and then I begun learning programmming abit later with the Atari (C64 first) not much though but I got the taste for it.

Iīve treid WIDIsoft many years ago their audio2mid, I used it for Gitarr lead and Cello tracking. I remember many of those audio2mid at that time did not track volume
and I think that one was the only one that did both pitch and volume? Not many ppl care about those details. I loved that they thought of it.

I should present myself later aswell. Everyone has profiles but me haha but I just need some time I think. I'll get to that.


Casaber(Posted 2016) [#28]
Dw817 Thanks, and same to you. Your posts engage alot of ppl and thoughts, and makes things very enjoyable :)


Midimaster(Posted 2016) [#29]
@dw817... upps.. corrected


dw817(Posted 2016) [#30]
Midimaster, the code you listed does not run by itself. Could you please post it in its entirety so it "runs out of the box ?" Thanks.