- BPM: If not specified, the assumed BPM of 120 may differ from the track's actual tempo. With MIDI clicks at 0.1250s and assuming there are two notes played for each click, the resulting tempo is 240 BPM.
- Sampling rate: The sampling rate used in the code can be different from the original sampling rate.
How to convert MIDI file into audio file and preserve tempo?
8 ビュー (過去 30 日間)
古いコメントを表示
This is a bit of a musical question.
First, I generate a click track in MIDI at 1/8 = .1250 and save the data in a MAT file. I don't need the whole MIDI header etc. since I just need to use the data to create an audio file. Since I don't specify a tempo in BPM, I assume it is 120.
Next I attempt to convert the MIDI info into an audio file, using Sine waves as the clicks. When I do this, the track is not at the same tempo as the MIDI file. Why is this?
(Excuse my clumsy programming.)
Fs = 96000; % SAMPLE RATE OF AUDIO FILE
% CREATE SINE WAVE PULSE
sine1 = dsp.SineWave();
sine1.SamplesPerFrame = Fs;
sine1.Frequency = 5;
fSine = sine1();
% CREATE AN EMPTY 1-SEC WAVE FILE TO HOLD OUTPUT
zOUT = zeros(Fs*1,1); % NUMBER OF SECONDS
% LOAD MIDI FILE INFO AND PUT IT INTO SEPARATE ARRAYS
zF = load("Click Track TEST.mat"); % LOAD MIDI FILE INFO
cMALL = zF.cZ;
cMTRACK = cMALL(:,1);
cMPITCH = cMALL(:,3);
cMVEL = cMALL(:,4);
cMDb = cMALL(:,5); % BEGIN DURATION FOR EACH PULSE
cMDe = cMALL(:,6); % END DURATION
cMsiz = size(cMTRACK,1);
aa = 0;
zz = 0;
cc = 1;
for ii = 1:cMsiz
% MIDI DURATION CALCULATE
bD = cMDb(ii); % MIDI DURATION BEGIN
eD = cMDe(ii); % MIDI DURATION END
cMDz = eD - bD; % DURATION OF THE PULSE
% CONVERT MIDI DURATION TO AUDIO FRAME # DURATION
cMDFsz = round(cMDz * Fs); % CONVERT MIDI TO SAMPLE DURATION
zzend = cMDFsz;
% ALTERNATE BETWEEN SINE WAVE AND SILENCE TO HEAR PULSE
if mod(ii,2) == 1
cMP = fSine(1:cMDFsz);
else
cMP = 0;
end
zOUT(zz+1:zz+zzend,1) = cMP;
zz = zz + zzend;
end
% WRITE FILE AS WAVE AUDIO
fileOUT = ' Click Test 96K 2023.wav';
audiowrite(fileOUT,zOUT, Fs);
0 件のコメント
回答 (2 件)
Binaya
2024 年 1 月 14 日
Hi Mark
I understand that you would like to know why the audio file generated from MIDI file is not playing at the same tempo as the original MIDI track.
The main reason of the tempo mismatch can be:
I hope this helps.
Regards
Binaya
0 件のコメント
Voss
2024 年 1 月 14 日
編集済み: Voss
2024 年 1 月 14 日
zF = load('Click Track TEST.mat'); % LOAD MIDI FILE INFO
cMALL = zF.cZ;
disp(cMALL)
Assuming 120 BPM (i.e., 1 beat every 0.5 seconds), then each 4 rows is one beat.
A guess: You shouldn't be turning on the sine wave every alternate row:
if mod(ii,2) == 1
cMP = fSine(1:cMDFsz);
else
cMP = 0;
end
but every fourth row, based on where the 75's are in the third column
if cMPITCH(ii) == 75
cMP = fSine(1:cMDFsz);
else
cMP = 0;
end
Here's your code, incorporating that change (and re-written in a more concise style), including a plot that shows you get one duration-0.125-second click each 0.5 seconds (= 8 clicks in 4 seconds = 120 BPM).
Fs = 96000; % SAMPLE RATE OF AUDIO FILE
% CREATE SINE WAVE PULSE
sine1 = dsp.SineWave();
sine1.SamplesPerFrame = Fs;
sine1.Frequency = 5;
fSine = sine1();
zF = load('Click Track TEST.mat');
zOUT = zeros(Fs*zF.cZ(end,6),1);
zz = 0;
for ii = 1:size(zF.cZ,1)
N = round((zF.cZ(ii,6) - zF.cZ(ii,5)) * Fs);
if zF.cZ(ii,3) == 75
zOUT(zz+1:zz+N,1) = fSine(1:N);
end
zz = zz + N;
end
% WRITE FILE AS WAVE AUDIO
fileOUT = ' Click Test 96K 2023.wav';
audiowrite(fileOUT,zOUT, Fs);
plot((1:zz)/Fs,zOUT)
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Simulation, Tuning, and Visualization についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!