Académique Documents
Professionnel Documents
Culture Documents
Included are some very basic synthesis functions, which can easily be replaced by your own code. MIDI
can be also be generated from note information you create within matlab: perhaps useful for audio
transcription or algorithmic composition.
Contents
Here's an example of reading in the included file, jesu.mid. First, readmidi.m parses the file into messages
and stores them in a matlab struct.
midi =
format: 0
ticks_per_quarter_note: 384
track: [1x1 struct]
midi2audio will synthesize this midi information to a waveform. The default uses a simple FM synthesis
technique. This can then be written to a file, etc.
%% listen in matlab:
soundsc(y, Fs); % FM-synth
% save to file:
% (normalize so as not clipped in writing to wav)
y = .95.*y./max(abs(y));
wavwrite(y, Fs, 'out.wav');
To add or modify synthesis algorithms, you can change or replace the 'synth.m' file.
Internally, midi2audio uses the midiInfo function to generate start and end times of all notes in the file.
midiInfo will display a list of the midi messages in the file:
midiInfo also returns a matrix of size Nx8, where N is the number of notes in the file. The 8 colunms
indicate:
1. track number
2. channel number
3. note number (midi encoding of pitch)
4. velocity
5. start time (seconds)
6. end time (seconds)
7. message number of note_on
8. message number of note_off
>> Notes(1:5,:)
ans =
Piano Roll
This "Notes" matrix can easily be used to create a "piano-roll" display. I've included a script for this:
%% compute piano-roll:
[PR,t,nn] = piano_roll(Notes);
%% display piano-roll:
figure;
imagesc(t,nn,PR);
axis xy;
xlabel('time (sec)');
ylabel('note number');
figure;
imagesc(t,nn,PR);
axis xy;
xlabel('time (sec)');
ylabel('note number');
Writing MIDI
Simple scale
writemidi.m and matrix2midi.m allow you generate some notes somehow in Matlab, and write them out to
a MIDI file. Here's a simple example of creating a chromatic scale:
% initialize matrix:
N = 13; % number of notes
M = zeros(N,6);
midi_new = matrix2midi(M);
writemidi(midi_new, 'testout.mid');
Note, you only have to specify the first 6 columns of the note matrix (7 and 8 hold the index of MIDI
messages). Now, you should have a valid MIDI file to open elsewhere. If you're on Linux, you might have
timidity installed,
$ timidity testout.mid
# hopefully you hear something...
Random Notes
Now, let's try creating some random music: let's say 200 random notes with random start times and
volumes, etc...
% initialize matrix:
N = 200;
M = zeros(N,6);
midi_new = matrix2midi(M);
writemidi(midi_new, 'testout2.mid');
$ timidity testout2.mid
Notes
readmidi should be able to read any MIDI file - it does little parsing except breaking up into individual messages (handles deltatimes, running-mode, and determines the message type).
In synthesis, many message types are ignored (for example, it doesn't handle controller messages, e.g. pitch-wheel bends, etc.).
Using readmidi and writemidi with no modifications can be used to test behavior. For example, run something like,
>> writemidi(readmidi('orig.mid'),'new.mid');
and check that 'orig.mid' and 'new.mid' are identical binary files. If you find this doesn't create an identical file, please let me know (but make sure it's a valid MIDI file). Or, you can do the check entire in Matlab, (since writemidi returns a byte string)
I would be happy to hear about about any bugs and keep this up to date.
However, I don't plan on making any major improvements to this. I no longer use Matlab at all. I've
transitioned to Python (numpy, scipy, ipython, matplotlib) and will never look back!
Files
The files are hosted on github. The project includes these files:
There is more documentation within each m-file. For example type, help midi2audio in MATLAB.