Find all datapoints in an audio file where a tone was recorded and snip them out.
3 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Lutz
am 17 Mär. 2022
Kommentiert: Mathieu NOE
am 25 Mär. 2022
Hello guys,
i record audio data and to prepare the raw data for later stuff, i have to snip a long recording into smaller pieces. so, I try to find all "tones" in one recording. That means in the end i need a tool that gives me the time stamps to snip the places or sounds out of the data. for a better understanding see the screenshot:
every red dot is a sound. My Idea was to find the highest pich inside the data and cut it with a littlebit buffer time in the front and after out.
At this point my Problem is to find these peaks.
At this point i tryed it with a threshold
th = mean(y2) +3*std(y2);
ind = find(y2>th);
y2Snip = {};
indDiff = find(diff(ind)>5);
for i=1:length(indDiff)+1
if i==1
y2Snip{i} = y2(ind(1)-1:ind(indDiff(1))+1);
elseif i==length(indDiff)+1
y2Snip{i} = y2(ind(indDiff(i-1)+1)-1:ind(end)+1);
else
y2Snip{i} = y2(ind(indDiff(i-1)+1)-1:ind(indDiff(i))+1);
end
end
This works, but it finds much more data points than i need and i cant cut the "one tone" out becaus it finds in "one tone" alot of more data points.
Thanks for Help.
0 Kommentare
Akzeptierte Antwort
Mathieu NOE
am 18 Mär. 2022
hello
this would be my suggestion.
the individual segments are selected based on the signal rms value and their length. here you can choose to store the segements that are above a given threshold (here 10% of the max rms value) and longer than min_contiguous_samples samples
the results (time , signal) are stored in a cell array (data_store)
hope it helps !
% load audio data
[data, Fs] = audioread('test_voice_mono.wav');
samples = length(data);
dt = 1/Fs;
time =(0:samples-1)*dt;
%% parameters
min_contiguous_samples = 1000; % store "red" segments only if they are at least this length
threshold = 0.1; % 1 = max (100%) of rms value
samples_befor = 100; % add some samples before the "start" point detected by code below
samples_after = 100; % add some samples after the "end" point detected by code below
%% main loop %%%%
% running rms (buffered) parameters :
rms_buffer = 500; % nb of samples in one buffer (buffer size)
shift = 1; % = rms_buffer-overlap; % nb of samples between 2 contiguous buffers
for ci=1:fix((samples-rms_buffer)/shift +1)
start_index = 1+(ci-1)*shift;
stop_index = min(start_index+ rms_buffer-1,samples);
time_index(ci) = round((start_index+stop_index)/2); % time index expressed as sample unit (dt = 1 in this simulation)
rms_data(ci) = my_rms(data(start_index:stop_index)); %
end
time_rms = time(time_index);
ind = (rms_data>threshold*max(rms_data));
% now define start en end point of "red" segments
[begin,ends] = find_start_end_group(ind);
length_ind = ends - begin;
ind2= length_ind>min_contiguous_samples; % check if their length is valid (above min_contiguous_samples value)
begin = begin(ind2); % selected points
ends = ends(ind2); % selected points
% define for plot the red rms data
time2 = time_rms(ind);
rms_data2 = rms_data(ind);
% define the begin / ending x, y values of raw data
time2_begin = time_rms(begin);
data_begin = interp1(time,data,time2_begin);
time2_ends = time_rms(ends);
data_ends = interp1(time,data,time2_ends);
figure(1),
plot(time,data,'k',time2,rms_data2,'r.',time2_begin,data_begin,'*c',time2_ends,data_ends,'*m','MarkerSize',12);
legend('signal',['rms above ' num2str(threshold*100) ' %'] ,'begin points','end points');
% store each "red" segment separately (in cell array)
figure(2), hold on
for ci = 1:length(begin)
ind = (time>=time2_begin(ci)-samples_befor*dt & time<=time2_ends(ci)+samples_after*dt);
xx = time(ind);
yy = data(ind);
data_store{ci} = [xx(:) yy(:)]; % 2 columns : time / data
plot(xx,yy);
end
hold off
%%%% end of main file %%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [begin,ends] = find_start_end_group(ind)
% This locates the beginning /ending points of data groups
D = diff([0,ind,0]);
begin = find(D == 1);
ends = find(D == -1) - 1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function x_rms = my_rms(x)
x_rms = sqrt(mean(x.^2));
end
2 Kommentare
Mathieu NOE
am 25 Mär. 2022
hello
as you can see this is part of the code (functions are at the end of the code)
my code works on my release R2020b - what are you running ?
function x_rms = my_rms(x)
x_rms = sqrt(mean(x.^2));
end
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Audio I/O and Waveform Generation finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!