HUGE thing to know: In the MIDI header is a value that gives you 'ticks per quarter note' and 'milliseconds per quarter note'. This is what you use to draw out MIDI note events visually. You also use 'Tempo' which is in microseconds, there are 60 million microseconds in a minute so you do 60 million / tempo = BPM and thats how you get the BPM of a song. You can then use ticks per quarter, bpm, milliseconds per quarter and get all the values you need to visualize from these.
@@cube2fox Not really an advantage but I do prefer when the box-sizing prop. of parent elements is inherited by child elements (same with other properties like font-family)
Yes. I just completed a project using a Teensy 4.1 MCU + 3 audio shields to become a laser image synth, with 14 waveform generators, 4-1 X/Y mixers, 2 AM LFOs feeding multiplexers and RGB color modulation. IOW, it's a Laserium synth the size of a fist. Everything is controllable via usbMIDI with an custom mapped Akai ACP40 controller, Cakewalk's DAW, a 15" touchscreen, and/or Surface Pro tablet GUIs, created with Pure Data. Each Teensy Laser Synth is set to a unique MIDI channel, one for each projector. The DAW handles the outputs via Bus mixdowns. I'm no electronics engineer, software developer, nor musician. But, Laserium taught me all about working with cycloid imagery. Our pal, Dave, from Notes and Volts taught me everything I needed to know to transform my 30 year old dreams into modern reality.😎 🤯 Lasers have ILDA files, but since my laser synth is MIDI controlled, I can also record live laser shows onto MIDI files, as well! That's a game changer. Thanks! 🙏
You are doing an AMAZING job and i cant stress that enough. Trust me not everyone has the ability to teach sophisticated things that well. You are blessed sir. Thank you.
Being a bit of a masochist I decided to write my own DAW but realised I only have an understanding of sending and receiving Midi messages and not so much the file structure of a typical midi file. This is great, the clearest explanation I've seen so far.
After spending months working on exactly this same code, I would like to note that none of the timing information (the delta time between events) is actually sent to the midi device. It is only stored in the midi file, and used by the sequencer to calculate “when” to send the event to the device. Just wanted to clarify. :)
There's a pervasive misconception in this video that took me a minute to understand. The delta time information is part of the event in the midi file, but it is not part of the midi message that is sent out. The time stamp tells the midi file player (or sequencer) when to send the message, but the midi protocol is fully asynchronous, messages can be sent any time and they are processed as they are received. This also relates to why midi bytes are mostly 7 bit values. It's not to conserve bandwidth, all 8 bits are sent, but the first byte of a message will have the high bit set to 1 so the receiving device knows this is the start of a midi message. The rest of the bytes in the message must have the high bit set to 0. Midi devices process midi messages as they are received, and they do not know or care who sent them or when. Imagine multiple midi instruments all receiving event messages and trying to comply with delta time stamps. They would need to all be in sync somehow. The midi protocol is designed specifically to avoid this problem.
Hi javidx! I want to thank you for your work, and congratulate you on your skills. I started my adventure with game development when I was a kid, but over time I appreciated software engineering too. This and the synthesizer videos are currently queued to be seen, as generation and modeling of the wave for sound fascinates me. I hope you can grow on the Internet, you deserve much more.
Great video, yet again. I'd just like to add that the reason for treating a Note-On event with a value of 0 as if it were a Note-Off event was to take full advantage of the running status. This way, most of the messages in normal midi tracks would not need the status byte.
The first file format that I learned was the interlaced bitmap (ilbm) that was output by Deluxe Paint. I was still so new to programming that learning how to read and write to this file format made me feel empowered in my new skill and profession. It was a blast! I also remember when Deluxe Paint created a new format, the packed bitmap (pbm), for 8-bit-per-pixel graphics. What an improvement!
Another fab video! I enjoyed playing with MIDI in my own audio projects, and this provides a great reference for me or anyone else interested in digital music.
Great video, javid! It's been a very handy reference for a project I'm working on with midi files at the moment. During it I've actually ran into a small bug cause by some unhandled events in your code. There's a few extra meta events that you'll want to handle in certain midi files: metaProgramName (0x8), metaDevicePort (0x9), and metaMidiPort (0x21). For the first 2 you'll want to do a standard readString() with the length read in prior, but the midi port meta event you'd read in a single byte. I believe some meta events can also have delta time associated with them, meaning after we handle meta events, we need to pass in the delta time for these "other" events, and furthermore, the algorithm to convert the midi events into a series of notes needs to be tweaked to account for non-note events that have a time delta. An easy solution would be to check if an "other" event type has a time delta, and if it does, pass it onto the next event in sequence so this time isn't lost if any real note on/off events come in later.
Hey javidx9. After couple of weeks it's great to see the new MIDI video. I almost finished my project that i asked your advice. Unfortunately i couldn't find any good tutorial about understanding the structure of the MIDI files and now i'm a native Hexadecimal/Binary Reader( Sort of :) ). Looks like i achieved to the point you've shown in this video. Only with couple of differences( Which are totally normal ). I just wanted to thank you again. Your answer helped me believe in myself. SO THANK YOU!
Loved this 🙂 I’ve made my own web audio music sequencer using text files and have been wondering how I can hook my guitar up to compose tunes rather than typing notes in, so this was very helpful!
Lol, like most programming topics, understanding something complex actually takes time. Would you prefer a 3 minute video with little usable information? If so, im sure there are plenty of alternatives more suitable.
@@SealedKiller He over reacted to something i said once too, comedy often goes over his head, lol i said something similar, basically was told to go elsewhere. hes good.. but a clown.
Yeah, this video is about 1 year too late for me. I had to figure all of this out myself. Next time, try to get these videos out BEFORE I need them. :)
Hello Javidx9, Yet again you have blown my mind with what is possible in programming. With just a few lines of code, you can create anything I enjoy the music you played in the video WELLDONE until next time... All the best from Speedy C
The only time I've ever done anything with MIDI was when doing a DOOM port, and having to convert the internal not quite midi to something that could be properly played. Was a fun experience, actually that was true for the whole project as I was using it an excuse to learn some new stuff.
Eh personally I would prefer a .mod/.xm based sequence format for modern standalone homebrew synths that aren't meant to be used in normal daws as vst like the terminal synthesizer he made, obviously in a vst environment you would want to use midi because I'm pretty sure that's the protocol most daws use internally but for your own programs you obviously have many more potential options
javidx9. I have a topic request. You seem familiar with this. Where a specification for a binary file format exists, partial or full documented, you seem experienced with how to write programming code that opens and interprets and works with that binary data. You seem to have been doing this for quite some time now. And it may not be especially difficult. But I am unknowledgeable with this. I wanted to work with PCX image files in the mid-2000s and failed to do so. Can you do an educational video on working with binary file formats? Opening them, moving through the bits and bytes and all of the techno mumbo jumbo? And I'd like if you can make this one of your more elementary videos. A basics video. :) Like talking points and things I feel you'd cover in such a video. "MSB" or "most significant byte." All of the hexadecimal codes you employ in the video when moving byte-by-byte through the file. Seeking through the file, like moving to a specific referenced area by a table in the header of the file. Many file formats employ that method. Can you discuss outputting or writing such a file? I don't know how to do that either. What is the means of outputting a binary file format, like an image format, for instance? And so all of that is working with the binary file formats, but if you felt to do this separately or in the same episode, I'd think simply covering computer data and file formats, like the ideas of "binary" and "plain text" and the little encoding schemes and "Little Endian" and things... :( You'd do so well to please adolescent me fifteen years ago. I had been trying to do all of these things and I only ever produced results using existing code shared by others. I never wrote my own code to do these things because, despite all my Google searching in the mid-2000s, I was unable to find the methods to work with binary data like this. :(
You need some sort of specification/guide to know how to interpret the bytes in a binary file. Popular formats have their layout available online, like how to interpret bytes of a wav file for instance. But just a random binary file with no specification is just a sequence of bytes... you can interpret those sequences many different ways, and 99% of those will spit out garbage. Even if you get valid data out (sheer luck) you still won't know what that data represents in the sequence. That's why reversing binary files with no specification is *near* impossible
I think what you're asking is "How do I parse binary files?" I'd start with the data structures (structs or classes), and try to read it as sequentially as possible (sometimes the table of contents of binary files are at the end of a file, like .zip files and .pdf files), and read each field into the data structure that you've made. This process of parsing and reading (restoring) into your data structure is called "deserialization", and writing (saving) to a file from your data structures is called "serialization". For MSB and LSB handling, most processors can reverse the "endian" (byte order) in a single instruction, but you can do it in C or C++ using a union containing the sized type (sint32_t for example), and a byte (uint8_t) array with the same size. Use the same sort of algorithm that you would use to reverse a string. (The asm single instruction is obviously much faster.) Hopefully, if he doesn't make a video, that info (paired with a search engine) will get you started.
holy shit taco sauce batman. just when i feel like im watching some ancient amazing knowledge UA-cam video. i peek at the date and its fucking two days ago. google... google.. you're getting a lot faster at finding relevant shit that i may want to view. i indeed enjoyed this video.
I migrated from hoarding MIDI to XM/MOD/SM etc files because instead of playing synthesized music, they played snippets of wave files (I think?). Obviously this was before MP3.
After seeing just the title I was wondering if you were going to use ff7 music as an example and I wasn't disappointed :) In fact I could recognize it just by looking at the track you highlighted
There's a horrible noise at 3:21, headphone users turn down your volume. Idk if it's possible but if the creator reads this, muting the content for about .1 seconds would make a world of difference to this.
switch (nStatus >> 4) { case EventName::VoiceNoteOff: break; case EventName::VoiceNoteOn: break; case EventName::VoiceAftertouch: break; case EventName::VoiceControlChange: break; case EventName::VoiceProgramChange: break; case EventName::VoiceChannelPressure: break; case EventName::VoicePitchBend: break; case EventName::SystemExclusive: break; }
Hi Bruno and Thanks, though aim a bit higher! I've been programming for almost 30 years now, that's a lot of time to practice - the key is to never stop learning. But one trick I suggest, is use programming to learn about other things, that way you get a 2 for 1 deal XD
What a lovely coincidence... I’m working with NIMEs and a friend showed me your video. I just commented with him that my former advisor used exactly this strategy when learning anything: code it. :) Congratulations for the amazing content, btw!
I personally would recommend sekaiju for midi editing, especially if you are writing for an old game that uses modis and GM soundfont compatibility is a necessity
If you want to browse a sample library by playing a song that you know, then in what format do you store the song? Even in the DAW spicific file formats, probably MIDI.
@@jaysistar2711 When I get a new sample library, I just start composing something with it. Whether it sees the light of day or not is a completely different question
Dear sir, can you create a video about what kinds of tools do you recommend for programmers to use and how to use them? Git, GDB, and Valgrind are very well known by many. But what about any more obscure tools that you can recommend? For example, I use Microsoft Programmer Calculator, and Meld for comparing source code files and entire directories, but I haven't heard about anyone using them. What about other useful tools like WinSCP? I have used it but I only know the bare minimum.
I have two questions regarding the code, first I don’t understand why you couldn’t have used a switch for the nStatus upper nibble, which also would’ve compacted some of the code using multiple case statements for the unimplemented cases. Second couldn’t the ReadValue lambda could have just been written with the inner loop, removing the special case if at the beginning. I was just wondering if you had a reason for doing these things this way, or just if it just doesn’t seem better to you to do it the way that I mentioned.
Your MIDI-Event to Visualize-Notes translation is actually an emulator. Or how we pesky musicians say: A virtual instrument. The silent version was great:P Naaah, I like it:)
Man, you gotta be young indeed (or in the opposite end of the age spectrum, in which case, respect) to not to know what midi is, ha ha. Banter aside, thank you very much for this, as someone who grew up with many older computer games playing midi (well, really even the NES and other such retro consoles used midi), it's interesting for me to finally look into what the code actually looks like. Ik ik, even games nowadays use midi format, only the quality of the instruments have changed. I'd imagine at least the code of midi nowadays compared to an NES game's midi timing would be different, in much the way versions of C++ are different (but somewhat compatible) from each other, is that correct or is that wrong? Anyways, I always love your videos, even though I barely ever dabble in programming (because I just can't wrap my head around it xP)
Would you also make a mod/xm player or a video series about it? It'a a music format with real audio data, pitching the samples tbo play the notes and some effects.
Yeah. The battle theme (and all SNES and PS1 music) is actually closer to a MOD file than a midi file. The SNES has an 8 channel DSP, and no synthesizer at all.
Trying to make my own midi visualization and this is super helpful to get me going with the midifileformat. Thank You :). I was wondering, having trouble working with binaryfileformats is often something that gets my project to a screeching halt, and I usually end up moving on to other things thinking I have to get better to crack this. Any suggestion on how to learn, get better at reverse engineering fileformats ? It seems even for the more common ones, finding good or any documentation is near impossible. Now, I get this is not a trivial thing to do ,so I'm not looking for an easy and quick solution rather some pointers on where to start and what to play around with or read up on. Thanks for all your hard work and those insightful and motivating videos :) Cheers,
Thanks for Your Great Work. A question: I want to change the midi protocol and add a key among the 12 stantard keys. That is: 13 semitones. How can I add this using writing software to tell the "machine" to play a 13th clef? The musical scale of 13 semitones would be composed as follows: C - C # - D - D # - E - E # - F - F # - G - G # - A - A # - B. Thanks
Recently I've been working on the topic of midi in C#. I'm wondering how to create a TICK generator ? When PPQN=480, tempo=240, 1 tick = 521 microseconds. How to program such a decision? Thank you !
I'm not so sure about the whole seeking back thing to determine the duration of the note. At least not for playback. I guess you only need this to render out the piano roll?
Not really related but I wondered how you managed to get the console buffer to have a character height of 1, giving you a pixel aspect ratio of 1:1. (11:28) The best I can do with my own engine is 1:2. When I set it to 1:1 it just defaults to 1:2 and I end up with a vertically stretched image.
He recently made a new game engine actually, which uses opengl instead of console buffers, so (in this video at least) he’s not doing that with the console. You can look for the olc pixel game engine video for more details.
@@veda-powered Yes, you're right. I didn't notice it was olcPixelGameEngine.h and not olcConsoleGameEngine.h. I was worried there was a way to do 1:1 PAR since I designed the whole engine around the fact that it couldn't go below 1:2 (1:1 would have been workable but not as neat looking as 1:2). Thanks.
One funny note for you all, heh. In 80s russians were using the same MIDI interface which was registered in Germany first together with various forms of DIN-ports and cables, but we used simplified version of analog MIDI to satisfy the needs of music industry. For now, MIDI is the most popular and safe format to store a data with notes and to play them from keyboard. You can even import MIDI-files into the sequencer, for example, into FL Studio MIDI, and then attach proper digital instruments and play them in real-time. I am sure that MIDI standards will stay alive until the next revolution in storing of sampled data.
HUGE thing to know: In the MIDI header is a value that gives you 'ticks per quarter note' and 'milliseconds per quarter note'. This is what you use to draw out MIDI note events visually. You also use 'Tempo' which is in microseconds, there are 60 million microseconds in a minute so you do 60 million / tempo = BPM and thats how you get the BPM of a song. You can then use ticks per quarter, bpm, milliseconds per quarter and get all the values you need to visualize from these.
This channel is a gold mine. Thank you for sharing!
This video made me as happy as when I discovered:
* { box-sizing: border-box }
Ah, good old CSS
html { box-sizing: border-box }
html * { box-sizing: inherit }
@@_lapys Which is the advantage over the above?
@@cube2fox Not really an advantage but I do prefer when the box-sizing prop. of parent elements is inherited by child elements (same with other properties like font-family)
@@_lapys Makes sense if you need to disable border-box for a piece of included foreign code because it assumes normal box-sizing. E.g. a date picker.
Yes. I just completed a project using a Teensy 4.1 MCU + 3 audio shields to become a laser image synth, with 14 waveform generators, 4-1 X/Y mixers, 2 AM LFOs feeding multiplexers and RGB color modulation.
IOW, it's a Laserium synth the size of a fist.
Everything is controllable via usbMIDI with an custom mapped Akai ACP40 controller, Cakewalk's DAW, a 15" touchscreen, and/or Surface Pro tablet GUIs, created with Pure Data.
Each Teensy Laser Synth is set to a unique MIDI channel, one for each projector. The DAW handles the outputs via Bus mixdowns.
I'm no electronics engineer, software developer, nor musician. But, Laserium taught me all about working with cycloid imagery. Our pal, Dave, from Notes and Volts taught me everything I needed to know to transform my 30 year old dreams into modern reality.😎
🤯 Lasers have ILDA files, but since my laser synth is MIDI controlled, I can also record live laser shows onto MIDI files, as well! That's a game changer.
Thanks! 🙏
You are doing an AMAZING job and i cant stress that enough. Trust me not everyone has the ability to teach sophisticated things that well. You are blessed sir. Thank you.
This is now number one, of my top chanels of all youtube for programing. Thanks for sharing your knowledge!!!
Being a bit of a masochist I decided to write my own DAW but realised I only have an understanding of sending and receiving Midi messages and not so much the file structure of a typical midi file. This is great, the clearest explanation I've seen so far.
After spending months working on exactly this same code, I would like to note that none of the timing information (the delta time between events) is actually sent to the midi device. It is only stored in the midi file, and used by the sequencer to calculate “when” to send the event to the device. Just wanted to clarify. :)
So why are DELTATIME intervals retained in this example?
There's a pervasive misconception in this video that took me a minute to understand. The delta time information is part of the event in the midi file, but it is not part of the midi message that is sent out. The time stamp tells the midi file player (or sequencer) when to send the message, but the midi protocol is fully asynchronous, messages can be sent any time and they are processed as they are received. This also relates to why midi bytes are mostly 7 bit values. It's not to conserve bandwidth, all 8 bits are sent, but the first byte of a message will have the high bit set to 1 so the receiving device knows this is the start of a midi message. The rest of the bytes in the message must have the high bit set to 0. Midi devices process midi messages as they are received, and they do not know or care who sent them or when. Imagine multiple midi instruments all receiving event messages and trying to comply with delta time stamps. They would need to all be in sync somehow. The midi protocol is designed specifically to avoid this problem.
Hi javidx!
I want to thank you for your work, and congratulate you on your skills.
I started my adventure with game development when I was a kid, but over time I appreciated software engineering too.
This and the synthesizer videos are currently queued to be seen, as generation and modeling of the wave for sound fascinates me.
I hope you can grow on the Internet, you deserve much more.
I'm not even 1/10th through the video and you've already earned my like, comment, and subscription!
Thanks Ron, that's very kind of you to say so, I hope the remaining 90% was satisfactory too :D
Some days ago I was looking some stuffs on MIDI and this came up today, pretty cool!
PixelGameEngine surveillance software working perfectly. Good Stuff!
Great video, yet again. I'd just like to add that the reason for treating a Note-On event with a value of 0 as if it were a Note-Off event was to take full advantage of the running status. This way, most of the messages in normal midi tracks would not need the status byte.
The first file format that I learned was the interlaced bitmap (ilbm) that was output by Deluxe Paint. I was still so new to programming that learning how to read and write to this file format made me feel empowered in my new skill and profession. It was a blast! I also remember when Deluxe Paint created a new format, the packed bitmap (pbm), for 8-bit-per-pixel graphics. What an improvement!
Haha, how I already knew the song @9:48 :D That "wait a moment..." feeling... and then seeing I was right. Nice selection! And nice video, as always!
Tbh I wanted to train a neural network to make music for my game as Im not that good and you've came up with this, perfect timing :)
Another fab video! I enjoyed playing with MIDI in my own audio projects, and this provides a great reference for me or anyone else interested in digital music.
Wow, just wow! I need to implement midi in my project and this has been a huge help. Thanks mate!
Great video, javid! It's been a very handy reference for a project I'm working on with midi files at the moment. During it I've actually ran into a small bug cause by some unhandled events in your code.
There's a few extra meta events that you'll want to handle in certain midi files: metaProgramName (0x8), metaDevicePort (0x9), and metaMidiPort (0x21). For the first 2 you'll want to do a standard readString() with the length read in prior, but the midi port meta event you'd read in a single byte.
I believe some meta events can also have delta time associated with them, meaning after we handle meta events, we need to pass in the delta time for these "other" events, and furthermore, the algorithm to convert the midi events into a series of notes needs to be tweaked to account for non-note events that have a time delta. An easy solution would be to check if an "other" event type has a time delta, and if it does, pass it onto the next event in sequence so this time isn't lost if any real note on/off events come in later.
Hey javidx9.
After couple of weeks it's great to see the new MIDI video. I almost finished my project that i asked your advice.
Unfortunately i couldn't find any good tutorial about understanding the structure of the MIDI files and now i'm a native Hexadecimal/Binary Reader( Sort of :) ).
Looks like i achieved to the point you've shown in this video. Only with couple of differences( Which are totally normal ).
I just wanted to thank you again. Your answer helped me believe in myself.
SO THANK YOU!
Fantastic! I've worked with MIDI before but never from a coding perspective, love it.
Best explanation of MIDI I've ever seen. Thanks.
Loved this 🙂 I’ve made my own web audio music sequencer using text files and have been wondering how I can hook my guitar up to compose tunes rather than typing notes in, so this was very helpful!
JavidX9 humble-bragging about his guitar skills while he's teaching me c++ is what I'm here for
Inspired by this !! great channel !!
I've just downloaded MIDI specs to give it a try !!!
thanks for you work !!
I could add this code to the synthesizer code of your previous videos so a keyboard connected via midi to the sound card could work!
I’m so glad you made this video, Javidx9. MIDI is fascinating. Cheers!
Man I love midi sounds, such nostalgia
"A Quick look into the MIDI file format"
47 minutes okay
Lol, like most programming topics, understanding something complex actually takes time. Would you prefer a 3 minute video with little usable information? If so, im sure there are plenty of alternatives more suitable.
@@javidx9 I watched the whole video, I was trying to make a joke 😂
@@SealedKiller He over reacted to something i said once too, comedy often goes over his head, lol i said something similar, basically was told to go elsewhere.
hes good.. but a clown.
@@samljer I like his channel. He's not a clown.
It's a bad joke?
You have a lot of sneaky little edits in this video that I love.
What a great video! Thanks @javidx9 for keep making this content.
been waiting 15 years for this video XD
9:46 "Yoo I know this song idk why"
10:41 "SHIEEET"
Final Fantasy?
@@francescoesco123 Yes, specifically the Final Fantasy 7 track Let the Battles Begin!
Oh that's perfect!
I've been struggling with this recently but you came at the perfect time!
Keep it up! 👍
Nice one EspriTox!
Yeah, this video is about 1 year too late for me. I had to figure all of this out myself. Next time, try to get these videos out BEFORE I need them. :)
Hello Javidx9, Yet again you have blown my mind with what is possible in programming. With just a few lines of code, you can create anything I enjoy the music you played in the video WELLDONE until next time... All the best from Speedy C
Finally a good MIDI tutorial. Thanks javidx9
The only time I've ever done anything with MIDI was when doing a DOOM port, and having to convert the internal not quite midi to something that could be properly played. Was a fun experience, actually that was true for the whole project as I was using it an excuse to learn some new stuff.
I'm working on optimizing a dsp library right now, this is perfect to listen to :) Thanks so much! I'd love to work on MIDI one day
Wow! Looking forward to implementing this in Java.
That audio glitch at 3:21 really jumped me.
Nonetheless, this helps me on creating MIDI based script for animation.
very very helpful for a project I am working on. Thank you
Fantastic !!! please go ahead with midiplayer adding some more functions, or a song cursor, makers and midilooper !!!
Thanks a lot for the video! Incredible! Really fun to mix art, electronics and computer science
I just got promoted as Senior dev (C#) but compared to your skills and knowledge I feel like intern.
Its just practice and lots of failure...
YES! FF7 Battle! That's how I usually decided if the midi synth were good on my win 98 PC :p
lol, it never, ever gets old. I hope it isnt ruined in the remake XD
I'm actually using this to turn my piano into a badass 8bit synthesizer machine
This would be good if you could mix this into your earlier synth tutorial series and perhaps cover how to write that to midi
Eh personally I would prefer a .mod/.xm based sequence format for modern standalone homebrew synths that aren't meant to be used in normal daws as vst like the terminal synthesizer he made, obviously in a vst environment you would want to use midi because I'm pretty sure that's the protocol most daws use internally but for your own programs you obviously have many more potential options
Yes! FFVII battle theme. Excellent choice.
javidx9. I have a topic request.
You seem familiar with this. Where a specification for a binary file format exists, partial or full documented, you seem experienced with how to write programming code that opens and interprets and works with that binary data. You seem to have been doing this for quite some time now. And it may not be especially difficult. But I am unknowledgeable with this. I wanted to work with PCX image files in the mid-2000s and failed to do so.
Can you do an educational video on working with binary file formats? Opening them, moving through the bits and bytes and all of the techno mumbo jumbo? And I'd like if you can make this one of your more elementary videos. A basics video. :)
Like talking points and things I feel you'd cover in such a video. "MSB" or "most significant byte." All of the hexadecimal codes you employ in the video when moving byte-by-byte through the file. Seeking through the file, like moving to a specific referenced area by a table in the header of the file. Many file formats employ that method. Can you discuss outputting or writing such a file? I don't know how to do that either. What is the means of outputting a binary file format, like an image format, for instance?
And so all of that is working with the binary file formats, but if you felt to do this separately or in the same episode, I'd think simply covering computer data and file formats, like the ideas of "binary" and "plain text" and the little encoding schemes and "Little Endian" and things... :( You'd do so well to please adolescent me fifteen years ago. I had been trying to do all of these things and I only ever produced results using existing code shared by others. I never wrote my own code to do these things because, despite all my Google searching in the mid-2000s, I was unable to find the methods to work with binary data like this. :(
You need some sort of specification/guide to know how to interpret the bytes in a binary file. Popular formats have their layout available online, like how to interpret bytes of a wav file for instance. But just a random binary file with no specification is just a sequence of bytes... you can interpret those sequences many different ways, and 99% of those will spit out garbage. Even if you get valid data out (sheer luck) you still won't know what that data represents in the sequence. That's why reversing binary files with no specification is *near* impossible
I think what you're asking is "How do I parse binary files?" I'd start with the data structures (structs or classes), and try to read it as sequentially as possible (sometimes the table of contents of binary files are at the end of a file, like .zip files and .pdf files), and read each field into the data structure that you've made. This process of parsing and reading (restoring) into your data structure is called "deserialization", and writing (saving) to a file from your data structures is called "serialization". For MSB and LSB handling, most processors can reverse the "endian" (byte order) in a single instruction, but you can do it in C or C++ using a union containing the sized type (sint32_t for example), and a byte (uint8_t) array with the same size. Use the same sort of algorithm that you would use to reverse a string. (The asm single instruction is obviously much faster.)
Hopefully, if he doesn't make a video, that info (paired with a search engine) will get you started.
At 12:14
MIDI files are like a box of chocolates, you never know what you gonna get... *//insert Forrest Gump theme here*
Even though I am not that much interested in the video contents, I like your videos as they are done very well!
That has to be one of the most useless comments I have ever read on UA-cam. I don’t even think that ChatGPT could’ve come up with that.
Fantastic video
yay. new vid
3:21 damaged my ears
Yeah I dunno what that is, its not on my master, I double checked - some youtube wierdness
lmao
music to my ears.
@@javidx9 youtube being youtube
"bust out our bags full of cables" ...too true
Good topic.
I was thinking of some sort of timeline for a SHMUP quite early into the video. You could basically use a midi-editor to place your enemies :D
Dang, I was working on my kalimba player when I saw this vid! definitely gonna try this project after finished
holy shit taco sauce batman.
just when i feel like im watching some ancient amazing knowledge UA-cam video.
i peek at the date and its fucking two days ago.
google...
google..
you're getting a lot faster at finding relevant shit that i may want to view.
i indeed enjoyed this video.
I migrated from hoarding MIDI to XM/MOD/SM etc files because instead of playing synthesized music, they played snippets of wave files (I think?). Obviously this was before MP3.
Somebody is going to create Synthesizer-Hero or hopefully even a game playable with a midi keyboard. Great idea!
You’re welcome. :)
Oh, it's the Final Fantasy 7 battle song!
After seeing just the title I was wondering if you were going to use ff7 music as an example and I wasn't disappointed :) In fact I could recognize it just by looking at the track you highlighted
Thank you so much for this video !
Can you please tell when does it know the track ends? I mean when does the for loop stop running? Thank you :)
MIDI 1.1: Making music for over 40 years and people like Chic Corea don't complain!
yeah... i'll come back to this later. this is a little too advanced for me. looks interesting though!
O/T - The MiniNova is an incredible synth for not much money.
There's a horrible noise at 3:21, headphone users turn down your volume. Idk if it's possible but if the creator reads this, muting the content for about .1 seconds would make a world of difference to this.
What a great video. Thank you very much.
Awesome Video! Thank you, already subscribed!
switch (nStatus >> 4)
{
case EventName::VoiceNoteOff: break;
case EventName::VoiceNoteOn: break;
case EventName::VoiceAftertouch: break;
case EventName::VoiceControlChange: break;
case EventName::VoiceProgramChange: break;
case EventName::VoiceChannelPressure: break;
case EventName::VoicePitchBend: break;
case EventName::SystemExclusive: break;
}
HELL YES!
😂
what material did you use to study and reach the level you are today?
I want to program just like you.
I think you are an excellent programmer.
Hi Bruno and Thanks, though aim a bit higher! I've been programming for almost 30 years now, that's a lot of time to practice - the key is to never stop learning. But one trick I suggest, is use programming to learn about other things, that way you get a 2 for 1 deal XD
@@javidx9 thanks for the tip
I Love your videos..
I started studying C++
What a lovely coincidence... I’m working with NIMEs and a friend showed me your video. I just commented with him that my former advisor used exactly this strategy when learning anything: code it. :) Congratulations for the amazing content, btw!
I personally would recommend sekaiju for midi editing, especially if you are writing for an old game that uses modis and GM soundfont compatibility is a necessity
"It produces something rather special"
Sample Libraries: "Am I a joke to you??"
If you want to browse a sample library by playing a song that you know, then in what format do you store the song? Even in the DAW spicific file formats, probably MIDI.
@@jaysistar2711 When I get a new sample library, I just start composing something with it. Whether it sees the light of day or not is a completely different question
Dear sir, can you create a video about what kinds of tools do you recommend for programmers to use and how to use them? Git, GDB, and Valgrind are very well known by many. But what about any more obscure tools that you can recommend? For example, I use Microsoft Programmer Calculator, and Meld for comparing source code files and entire directories, but I haven't heard about anyone using them. What about other useful tools like WinSCP? I have used it but I only know the bare minimum.
Bravvo this was very informative many thanks
I have two questions regarding the code, first I don’t understand why you couldn’t have used a switch for the nStatus upper nibble, which also would’ve compacted some of the code using multiple case statements for the unimplemented cases. Second couldn’t the ReadValue lambda could have just been written with the inner loop, removing the special case if at the beginning. I was just wondering if you had a reason for doing these things this way, or just if it just doesn’t seem better to you to do it the way that I mentioned.
Your MIDI-Event to Visualize-Notes translation is actually an emulator.
Or how we pesky musicians say: A virtual instrument.
The silent version was great:P Naaah, I like it:)
Man, you gotta be young indeed (or in the opposite end of the age spectrum, in which case, respect) to not to know what midi is, ha ha.
Banter aside, thank you very much for this, as someone who grew up with many older computer games playing midi (well, really even the NES and other such retro consoles used midi),
it's interesting for me to finally look into what the code actually looks like.
Ik ik, even games nowadays use midi format, only the quality of the instruments have changed. I'd imagine at least the code of midi nowadays compared to an NES game's midi timing would be different, in much the way versions of C++ are different (but somewhat compatible) from each other, is that correct or is that wrong? Anyways, I always love your videos, even though I barely ever dabble in programming (because I just can't wrap my head around it xP)
Would you also make a mod/xm player or a video series about it? It'a a music format with real audio data, pitching the samples tbo play the notes and some effects.
Yeah. The battle theme (and all SNES and PS1 music) is actually closer to a MOD file than a midi file. The SNES has an 8 channel DSP, and no synthesizer at all.
Trying to make my own midi visualization and this is super helpful to get me going with the midifileformat. Thank You :).
I was wondering, having trouble working with binaryfileformats is often something that gets my project to a screeching halt, and I usually end up moving on to other things thinking I have to get better to crack this. Any suggestion on how to learn, get better at reverse engineering fileformats ? It seems even for the more common ones, finding good or any documentation is near impossible.
Now, I get this is not a trivial thing to do ,so I'm not looking for an easy and quick solution rather some pointers on where to start and what to play around with or read up on.
Thanks for all your hard work and those insightful and motivating videos :)
Cheers,
NMS Awesome Thank you for Tutorials series
Almost didn’t watch this one because it is music. So glad I did though. Wonderful video. Thank you for making it.
Do you not like music?
Thanks for Your Great Work. A question: I want to change the midi protocol and add a key among the 12 stantard keys. That is: 13 semitones. How can I add this using writing software to tell the "machine" to play a 13th clef? The musical scale of 13 semitones would be composed as follows: C - C # - D - D # - E - E # - F - F # - G - G # - A - A # - B. Thanks
thanks man, very helpful tutorial!
Recently I've been working on the topic of midi in C#. I'm wondering how to create a TICK generator ? When PPQN=480, tempo=240, 1 tick = 521 microseconds. How to program such a decision?
Thank you !
I would love to see a 127 key keyboard lol
Great video as always
Oh my! For geek's sske! This is my phone ring tone hahaha... And the battle tune for waking up.
I'm not so sure about the whole seeking back thing to determine the duration of the note. At least not for playback. I guess you only need this to render out the piano roll?
AMAZING!
Cool, thanks. : )
I am looking to program a midi chord analyzer in C++ in JUCE. Do you have any ideas on how to get started?
Not really related but I wondered how you managed to get the console buffer to have a character height of 1, giving you a pixel aspect ratio of 1:1. (11:28)
The best I can do with my own engine is 1:2. When I set it to 1:1 it just defaults to 1:2 and I end up with a vertically stretched image.
He recently made a new game engine actually, which uses opengl instead of console buffers, so (in this video at least) he’s not doing that with the console. You can look for the olc pixel game engine video for more details.
@@veda-powered Yes, you're right. I didn't notice it was olcPixelGameEngine.h and not olcConsoleGameEngine.h.
I was worried there was a way to do 1:1 PAR since I designed the whole engine around the fact that it couldn't go below 1:2 (1:1 would have been workable but not as neat looking as 1:2).
Thanks.
Why not use peek instead of get to read the status byte?
Thank you so much, this is great
3:21 ahhhhh, my ears
Excellent
omg... where was this video in 1997 !?!?!?!
Lol indeed... The curse of the modern age of information tsunamis, is that they've come a bit late for some of us!
@@IrizarryBrandon Right ?!?!?!
So well explained I thought you were german
One funny note for you all, heh. In 80s russians were using the same MIDI interface which was registered in Germany first together with various forms of DIN-ports and cables, but we used simplified version of analog MIDI to satisfy the needs of music industry. For now, MIDI is the most popular and safe format to store a data with notes and to play them from keyboard. You can even import MIDI-files into the sequencer, for example, into FL Studio MIDI, and then attach proper digital instruments and play them in real-time. I am sure that MIDI standards will stay alive until the next revolution in storing of sampled data.