Create new .wav files around findpeak outputs
4 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Charlotte Findlay
il 8 Ott 2019
Commentato: Charlotte Findlay
il 9 Ott 2019
Hi everyone,
I would like to create short .wav files containing the audio data of each detected peak (see plot below as example). I would like the data in each .wav file to include the peak and a buffer on either side of roughly 0.02 s (e.g. black boxes around peaks would each be seperate .wav files). I have include my code so far and added a zip file with a short sample of the data to run code below.
% Read in audio file
[y,Fs] = audioread('test_MATLABAsk.wav');
info = audioinfo('test_MATLABAsk.wav');
sound(y,Fs) % Play the sound
% plot the data
% Create a time component using info
t = 0:seconds(1/Fs):seconds(info.Duration);
t = t(1:end-1);
figure(1)
plot(t,y)
xlabel('Time (s)')
ylabel('Audio Signal')
% Detect peaks from y
[pk_Fs, locs_Fs] = findpeaks(y,Fs, 'MinPeakDistance',0.03, 'MinPeakHeight',0.01); % See plot example below
0 Commenti
Risposta accettata
Guillaume
il 8 Ott 2019
Here's how I'd do it:
infile = 'C:\somewhere\somefolder\test_100m.wav'; %I'd recommend you use full path instead of relying on the current directory
outfolder = 'C:\somewhere\someotherfolder';
outformat = 'split%03d.wav'; %using sprintf format to insert peak number
halfwidth = seconds(0.02); %half width of signal to keep around peak
%read file, convert to timetable, find peak locations
[samples, Fs] = audioread(infile);
audiotable = timetable(samples, 'SampleRate', Fs);
[~, peaklocs] = findpeaks(samples, Fs, 'MinPeakDistance', 0.03, 'MinPeakHeight', 0.01);
%iterate over peaks, extract signal and save to file
for peakidx = 1:numel(peaklocs)
peaktime = audiotable.Time(peakloc(peakidx));
tokeep = isbetween(audiotable.Time, peaktime - halfwidth, peaktime + halfwidth);
audiowrite(fullfile(outfolder, sprintf(outformat, peakidx)), audiotable.samples(tokeep), Fs);
end
19 Commenti
Guillaume
il 9 Ott 2019
Ok, so peaktime makes sense, you're using a wav file much longer than the one you originally posted. The duration of that file is at least 110 seconds.
peaktime is simply (peaklocs-1) ./ Fs
and peaktime is a plain vector. I did write in a comment that if it's a plain vector you needed to convert that to a duration vector with seconds. Otherwise, it's interpreted as days when you subtract audiotable.Time. So, correct code using Fs for findpeaks:
infile = 'C:\somewhere\somefolder\test_100m.wav'; %I'd recommend you use full path instead of relying on the current directory
outfolder = 'C:\somewhere\somefolder\OutWav';
outformat = 'split%03d.wav'; %using sprintf format to insert peak number
halfwidth = seconds(0.02); % half width of signal to keep around peak
%read file, convert to timetable, find peak locations
[samples, Fs] = audioread(infile);
audiotable = timetable(samples, 'SampleRate', Fs);
[~, peaktimes] = findpeaks(samples, Fs, 'MinPeakDistance', 0.03, 'MinPeakHeight', 0.01);
peaktimes = seconds(peaktimes);
%iterate over peaks, extract signal and save to file
for peakidx = 1:numel(peaktimes)
tokeep = abs(audiotable.Time - peaktimes(peakidx)) <= halfwidth;
audiowrite(fullfile(outfolder, sprintf(outformat, peakidx)), audiotable.samples(tokeep), Fs);
end
For what it's worth, I've raise a service request with Mathworks to get them to improve the documentation of findpeaks.
Più risposte (0)
Vedere anche
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!