I'm trying to dynamically generate a small MP4 audio+video file directly from my Android app.
My original plan of attack:
The user enters some basic song data (a chord progression, etc) and the app builds a MIDI file.
The system builds chord diagrams for each chord, and using a MIDI reader it generates the animations frames array that is timed to the MIDI
Convert the MIDI into a raw PCM audio data <-- this S.O. question is specific to this point
Apply the raw audio to the animation frames - and encode the audio and video frames into an MP4
Provide the resulting MP4 video to the user with standard playback controls.
The App already builds the MIDI file based on user inputs including tempo, instrument, notes, etc. This part is done easily and the MIDI file is being generated correctly. This MIDI plays fine from Android's MediaPlayer. (step 1)
The animation frames are also being created correctly by reading back the MIDI file and cross referencing a list of static bitmaps for each chord in the sequence. These frames will become the video... but will be without audio at first. (step 2)
As you can see, the problems with Android MIDI latency is not so much a problem for me because I'm not creating a real-time synthesizer App... I just want to convert the MIDI to some audio format that can then be mixed into a video that is already timed to original the MIDI. (step 3)
The problem I'm running into is Step 3.
I understand that I need to use a software MIDI synthesizer to obtain the actual audio output that would be produced from a sequence of MIDI events. However, getting this to work correctly has become a major hurdle. I do not care about the precise quality of the resulting audio, just that it matches closely to what someone would expect if they where using General MIDI samples from a generic device (ala Gravis soundfonts or bulit-in Sovinox sounds, etc).
So...
My first attempt was with the above two projects... mash them up in such a way that a MIDI file could be converted into a raw PCM data buffer.... it hasn't gone so well yet.
The midi library (1) reads a MIDI file with a real-time listener and sends the events to the Midi Driver (2) which plays the raw PCM data generated by the onboard synthesizer.
(NOTE: A few tweaks were made to the driver so that the entire buffer was stored and only returned once the MIDI reader was finished. This also means that the entire process takes an amount of time equal to length of the song just to convert it because we are "listening" in real-time.)
I have yet to get this to work as I hoped. I wanted to keep this as simple as possible and prefer to use open source projects if at all possible. It would be better if it could do this without relying on real-time listeners.
Some other libraries and tools that I have been considering (but may be overkill):
EVEN MORE CONTENDERS (not much research done yet):
jFugue/timidity/audacity/fluidSynth/cSound/jMusic/JSyn/Gervill/Softonic/Caustic/LibGDX/JetPlayer/OpenSL-ES
My questions are:
Am I working down the correct path with the above projects? I'm relatively new to MIDI->PCM conversion so I want to make sure I'm not completely missing something.
If not, how should I go about converting a MIDI file into some sort of audio format that can then be used in the creation of an MP4 (or any video playback format)?
Are there other open source projects that may be helpful in this task of converting MIDI 2 raw audio waveforms using Android?
And are there any examples of such a task already written for use on Android? (i.e. already ported for use with Android JNI, etc)
My hope is that I completely missed something that will make this a trivial task... my assumption is that this is going to take some serious hacking and JNI kung-fu.
I am open to taking the hard road if that's what it takes. Any and all advice would be appreciated.
I'm not an Android user, but I tried many ways to generate WAV files from MIDI, and I'm the more happy about this task, with FluidSynth, which seems to be available as a library for Android, and is the point of this other StackOverflow question: Using Fluidsynth to play notes from SoundFonts on Android.
You just need to know about sound‑fonts (searching the web will easily tell you) and choose a good one which is not too big (otherwise, you may have lack of memory issue).
Also check the sound‑font covers all the instruments you want to be playable.