Learn how to convert easily a MIDI file to MP3 using Timidity and FFmpeg in Ubuntu 20.04

How to convert a MIDI file to MP3 using TiMidity and FFmpeg in Ubuntu 20.04

As I mentioned in previous posts on how to convert MIDI files to WAV in Windows using VLC, I had to find a way to convert them as well in Ubuntu. After some research, I ended up using timidity to play the MIDI file and FFmpeg to store the output stream into an MP3 file using the command line.

In this article, I will explain to you how to easily convert MIDI files to MP3 in your Ubuntu 20.04 desktop and server using Timidity to play the midi files and FFMPEG to pipe it into an MP3 file.

1. Install timidity

TiMidity++ is a CLI utility that converts some of MIDI files (supported formats: Standard MIDI files (*.mid), Recomposer  files  (*.rcp,  *.r36,  *.g18,  *.g36)  and  Module  files (*.mod)) into formatted audio files (e.g.  RIFF  WAVE).   TiMidity++  uses  Gravis Ultrasound-compatible patch files or Soundfonts (*.sfx, *.sf2) to generate  digital  audio data  from  MIDI files.  The digital audio data generated by TiMidity++ can be stored in a file for processing, or played in real-time through an audio device. In real-time playing, TiMidity++ can show the lyrics contained in KAR or WRD files. So as you can see, it cannot export to our desired format MP3, however, we can manipulate the real-time playing to store it into an MP3 file using FFMPEG.

Before continuing with the installation, update the apt repositories:

sudo apt-get update

And then install Timidity with the following command:

sudo apt-get install timidity

The installation of this package will take about 150MB of space on your disk. Once it finishes you should be able to use timidity from the command line.

2. Install FFmpeg

As next, install FFmpeg, the suite of libraries and programs for handling video, audio, and other multimedia files and streams. The following command should do the trick if you don't have it installed already:

sudo apt-get install ffmpeg

The installation of this package will take about 260MB of space on your disk. For more information and steps to install in other operative systems, please visit the official downloads page of the FFmpeg website here.

3. Converting MIDI to MP3

Finally, now that you have the 2 required libraries to make this work, proceed with the conversion using the following command. It works like this, timidity will play the provided MIDI file as the first positional argument and the -Ow option will generate a RIFF WAVE format output. Then, we will pipe the output to FFMPEG that will handle the stream, and store it into an MP3 file:

timidity input_file.mid -Ow -o - | ffmpeg -i - -acodec libmp3lame -ab 64k output_file.mp3

Replace input_file.mid with the absolute or relative path to the MIDI file in your system that you want to convert to MP3 and replace output_file.mp3 with the absolute or relative path to the MP3 file that will contain the converted audio.

This would generate an output similar to the following one in the terminal:

Playing ./acdc-backinblack.mid
MIDI file: ./acdc-backinblack.mid
Format: 1  Tracks: 5  Divisions: 960
ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
  configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
[wav @ 0x557e8f53c700] Ignoring maximum wav data size, file may be invalid
Warning: -: Illegal seek: Can't make valid header
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from 'pipe:':
  Duration: N/A, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> mp3 (libmp3lame))
Output #0, mp3, to 'output_file.mp3':
    TSSE            : Lavf58.29.100
    Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, s16p, 64 kb/s
      encoder         : Lavc58.54.100 libmp3lame
Playing time: ~257 seconds:48.52 bitrate=  55.1kbits/s speed=76.2x    
Notes cut: 0
Notes lost totally: 0
pipe:: corrupt input packet in stream 0
size=    1993kB time=00:04:15.00 bitrate=  64.0kbits/s speed=75.8x    
video:0kB audio:1992kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.012400%

And of course, would generate a new MP3 file in the desired destination with the specified filename that you can now play on any device that supports this format.

Happy coding ❤️!

Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.