Cloned from Grissess on Github, Loose bundle of software to broadcast midi files to computers and make a computer organ

Grissess 33d49cd847 Fixed timing issues 9 жил өмнө
.gitignore 154526e1a5 Fixed annoying tempo bug 9 жил өмнө
README.md 6f83a0a49c The great README update 10 жил өмнө
broadcast.py 5a43b7b907 Minor PCM fixes 9 жил өмнө
client.c 3e7481519e Major functionality enhancements and bugfixes 10 жил өмнө
client.py 33d49cd847 Fixed timing issues 9 жил өмнө
mkarduino.py b1e54746e8 Partial commit (sorry :( ) 10 жил өмнө
mkiv.py 8028934567 Modwheel appears to work 9 жил өмнө
packet.py 40b1e56164 Experiment PCM ready 9 жил өмнө
piano.py da2a7795f5 Some pygame stuff 10 жил өмнө
shiv.py 0fc9516017 Pitch bend support 9 жил өмнө
voice.py bd176a81f6 Getting things clean again 10 жил өмнө

README.md

What this is

The ITL Chorus is a very simple, loosely bundled package for playing MIDI in real time over a network. Presently, it consists of three different frontends:

  • mkiv.py: Makes an *i*nter*v*al (.iv) file from a MIDI (usually .mid) file. The interval file is an XML document (easily compressed) consisting of the necessary information required to play back voices or streams such that no notes overlap (and duration information is available).
  • client.c: A bare-minimum C program designed to run on even the most spartan Linux systems; it basically implements beep over UDP.
  • client.py: A far-more-functional Python program with advanced options, using the pyaudio API.
  • broadcast.py: Accepts an interval file, assigns clients to streams, and plays a piece in real time.

In general, you would use the tooling in precisely this order; generate an interval file with mkiv.py from a good MIDI performance (of your own acquiry :), either compile and run ./client as root or run python client.py on all the machines on a LAN that you would like to beep along, and then run broadcast.py with the generated interval file on any machine also on that LAN (potentially also one of the clients).

Troubleshooting

In my experience, the most annoying errors come about as the following:

  • No PC speaker. Many modern computers/motherboards omit this ancient piece of IBM technology entirely. Presumably, emulation is available (especially in desktop environments), but this normally requires a kernel-mode driver (as it has to respond to the very low-level syscall that actually would beep the speaker). ALSA purportedly provides snd_pcsp, but I've not seen it work yet. It should be noted that the python client.py script uses regular PCM speakers to operate, and so can work under these conditions.
  • Network issues. client doesn't really check for any LAN, happily listening on whatever interfaces it can find at the time. Many very basic installations of Linux seem to not dhclient properly, even if the link is up, so you will want to make sure that your ip information is set up how you like it before running client.
  • Lack of a compiler. Again, some bare-bones distributions don't ship with a compiler by default (I don't even know how you can use Linux like that :). Many nonetheless have package managers that will get a compiler and build environment for you. (On Debian and derivatives, build-essential works.)

Please submit an issue if something else seems off!

Options

All the scripts here (except the C program) have a plethora of options, most of which are documented both at the beginning of the source and if you simply pass --help or -h to them. Feel free to experiment!

Hacking

The .iv file format that is used extensively in communicating information is certainly not any standard that I am aware of, but it seems like a rather convenient standard for simple authorship. While I have no plans to write an IV editor at the moment, that may change; in the meantime, whosoever would like to do so should know the following about the IV files:

  • They are in XML--go ahead and open them in your favorite XML browser!
  • Their root element is "iv" with no decided namespace yet.
  • Under the root, there is a "meta" element with metainformation about the compilation process--at present, this includes things like the "bpms" element which has a "bpm" for each time period parsed out of the original MIDI.
  • Also under the root, and arguably most importantly, is the "streams" element that possesses all the "stream" elements that correspond to playable voices.
  • Each stream has a "type" attribute which determines what it is ("ns" is a note stream--the ones that have playable notes, and "aux" is a stream of non-note MIDI events), and an optional "group" attribute which determines what group it belongs to (broadcast.py uses this for routing).
  • All note streams (type="ns") should contain non-overlapping notes, in the sense that any "note" element in there should have a time + dur not greater than its next note. Additionally, all notes in such a stream should be sorted by time. Breaking either of these standards is not an egregious violation, and may prove to be interesting, but (at the moment) it will prevent broadcast.py from working properly. In addition, it should be noted that the clients are designed to overwrite one incoming note with the next, regardless of whether or not this interrupts the duration of the previous one--this is how "live mode" and "silence" work.

Todo

  • Polyphony--have multiple voices on one machine
    • Mixed polyphony: the audio is the result of mixing (saturating addition, etc.)--only doable with PCM
    • LFO polyphony: tones are "rapidly" switched between (how old microcomputers used to accomplish this with one beep speaker)
  • Preloading--send events to clients early to avoid jitter problems with the network
    • Would require a network time synchronization to work effectively; makes the broadcaster have less control over nuanced timing
  • Other stream types--e.g., PCM streams for raw audio data
    • More clientside implementation work
    • Definitely a higher bandwidth--might interfere with critical timing, and would almost certainly need preloading
  • Percussion--implement percussive instruments
    • Requires an analysis of how current DAWs and MIDI editors mark "percussion" tracks--with a program change? GM specifies channel 10...
  • Soundfonts--have the ability to significantly affect the instrumentation of the clients
    • Would also be nice to do this from the broadcaster's end without introducing RCE
    • Might require integration of another large libary like fluidsynth--at which point this would just be "networked MIDI" :)
  • Code cleanup--make the entire project slightly more modular and palatable