フィルターのクリア

BPM analysis in a song

9 ビュー (過去 30 日間)
amjad hammad
amjad hammad 2022 年 3 月 11 日
編集済み: Rik 2022 年 3 月 17 日
hi i am working in code to calculate in a Musical composition but i have o
[queen,fs] = audioread('Test_sound.mp3');
vyrez=queen(1:fs*30);
trhold= 0.01; % / 0.2
x = length(vyrez);
cas = round(x/fs);
nfft2=2.^nextpow2(x);
otoc=vyrez';
fy=fft(otoc,nfft2);
fy=fy(1:nfft2/2);
fy=fy';
xfft=fs.*(0:nfft2/2-1)/nfft2;
figure
subplot(2,1,1);
plot(vyrez);
title('Original snippet signal from the song ');
cut_off=1.5e3/fs/2;
order=32;
h=fir1(order,cut_off,'low');
fh=fft(h,nfft2);
fh=fh(1:nfft2/2);
mul=fh.*fy;
% subplot(2,1,2);
% plot(abs(mul));
sig=abs(ifft(mul));
subplot(2,1,2);
plot(sig);
title('Track snippet signal after filters ');
brk=size(fh); % condition of a break in the loop to bypass the error
bps=0;
peak=0;
temp=0;
but i have problem in two condition
1- condition to prevent multiple beats
2- condition for beat insertion (0.4 optimal threshold)
and any new idea for code or make it shorter or more simplely
  2 件のコメント
Walter Roberson
Walter Roberson 2022 年 3 月 15 日
What difficulty are you observing? We do not have your file and you did not say what is wrong.
Rik
Rik 2022 年 3 月 17 日
編集済み: Rik 2022 年 3 月 17 日
I recovered the removed content from the Google cache (something which anyone can do). Editing away your question is very rude. Someone spent time reading your question, understanding your issue, figuring out the solution, and writing an answer. Now you repay that kindness by ensuring that the next person with a similar question can't benefit from this answer.
This page is now archived.

サインインしてコメントする。

回答 (1 件)

Walter Roberson
Walter Roberson 2022 年 3 月 15 日
partial correction.
[queen,fs] = audioread('Test_sound.mp3');
if size(queen,1) > fs*30
vyrez = queen(1:fs*30,1); % setting of snippet length (do not set many)
else
vyrez = queen(:,1);
end
Your old code was assuming that you had at least 30 seconds worth of sound, and was doing linear indexing. However what you really had was about 15 3/4 seconds of sound on each of two channels.
trhold= 0.01; % / 0.2
x = length(vyrez);
cas = round(x/fs);
% sound(vyrez,fs);
nfft2=2.^nextpow2(x);
otoc=vyrez';
fy=fft(otoc,nfft2);
fy=fy(1:nfft2/2);
fy=fy';
xfft=fs.*(0:nfft2/2-1)/nfft2;
figure
subplot(2,1,1);
plot(vyrez);
title('Original snippet signal from the song');
% subplot(2,1,1);
% plot(xfft,abs(fy/max(fy)));
cut_off=1.5e3/fs/2;
order=32;
h=fir1(order,cut_off,'low');
fh=fft(h,nfft2);
fh=fh(1:nfft2/2);
fh = reshape(fh, size(fy));
Your fh was coming out as a row vector, but fy is a column vector, and that was a problem.
mul=fh.*fy;
% subplot(2,1,2);
% plot(abs(mul));
sig=abs(ifft(mul));
subplot(2,1,2);
plot(sig);
title('Track snippet signal after filters');
brk=length(fh); % break condition in loop to bypass error
You were using size() with a single input parameter, but you were dealing with a row vector, so you were getting a vector [1 something] . That wasn't good for testing.
bps=0;
peak=0;
temp=0;
for k=2:length(sig)-1
% condition for preventing multiple bit insertion
if(sig(k)<trhold && trhold<sig(k-1))
You were using sig(k)<trhold<sig(k-1) which means something completely different to MATLAB
p=0;
j=k;
for j= k:k+100
p=p+real(sig(j));
end
if(p+5<peak)
temp=0;
end
end
% condition for beat inclusion (0.4 optimal threshold)
if(sig(k)>0.4)
bps=bps+1;
j=k;
for j= k+100
if(j>=brk)
break;
end
end
end
end
fprintf('There was %d beats in the song snippet %f seconds long \n', bps, cas);
You had the variables reversed for the message.
min=cas/60;
bpm=bps/min;
fprintf('BPM = %f [beat/min]\n',bpm);
figure
subplot(2,1,1);
plot(xfft,abs(fy/max(fy)));
subplot(2,1,2);
plot(abs(mul));
  3 件のコメント
Walter Roberson
Walter Roberson 2022 年 3 月 15 日
Consider for example
j = k : min(k+100, brk);
peak = sum(real(sig(j)));
Replaces your for j loop.
Walter Roberson
Walter Roberson 2022 年 3 月 15 日
Replace
if(sig(k)>0.4&&temp==0) %sig(k)>sig(k-1)&& sig(k)>sig(k+1)&&
bps=bps+1;
temp=1;
peak=0;
j=k;
for j= k:k+100
if(j>=brk)
break;
end
peak=peak+real(sig(j));
end
end
with
if(sig(k)>0.4&&temp==0) %sig(k)>sig(k-1)&& sig(k)>sig(k+1)&&
bps=bps+1;
temp=1;
j = k : min(k+100, brk);
peak = sum(real(sig(j)));
end
Recall that earlier I gave code and said that it replaces your for loop.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeFilter Analysis についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by