Align two signals using cross correlation
6 views (last 30 days)
Show older comments
I have two four channel recorders and a total of six microphones. Since the time lag between the two recorders is ~5 seconds, I need to align the signals on each. I have previously had success doing this using code from the function AlignWave in the file exchange, in the code below I align the two channels on the second recorder with the first channel on the first recorder. However in my dataset of 47 recordings, there is one file for which this doesn't work, and I can't figure out why. In this case, only one of the two files on the second recorder is correctly aligned.
I will be happy to share the data but the file is larger than 5MB in zip format.
%% Align .wavs from second recorder with those on the first recorder
for i=1:height(uPa_out.recorder_671105061)
wav1=uPa_out.recorder_671105061.pos1{i,1}; %get datetime of file on first recorder
wav1_dt=strsplit(uPa_out.recorder_671105061.wavFile{i,1},'.');
wav1_dt=datetime(wav1_dt(2),'InputFormat','yyMMddHHmmss');
start_range=wav1_dt-seconds(5);
rec2_files={uPa_out.recorder_335577141.pos5{i,1},uPa_out.recorder_335577141.pos2{i,1}}; %datetime of file on second recorder
rec2_files_dt=strsplit(uPa_out.recorder_335577141.wavFile{i,1},'.');
rec2_files_dt=datetime(rec2_files_dt(2),'InputFormat','yyMMddHHmmss');
%only align channels from different recorders if there is <= 5 seconds
%between them
if(rec2_files_dt>=start_range)&(rec2_files_dt<=wav1_dt)
for b=1:length(rec2_files)
wav2=rec2_files{1,b};
x=xcorr(wav1,wav2); %use cross correlation to align the data
[~,d]=max(x); %d is index for maximum value of x
delay=d-max(length(wav1),length(wav2));
if delay>0
yfrag=[zeros(delay,1); wav2];
else
yfrag=wav2(-delay+1:end);
end
wav2_files_new{1,b}=yfrag;
wav2_files_new{2,b}=-delay+1;
end
Data.five_new=wav2_files_new{1,1};
Data.two_new=wav2_files_new{1,2};
%Correct length of channels so they are all the same length
if delay>0
else %if data on second recorder is moved left to align with data on
%first recorder, then you need to delete 'extra' data at end of
%channels on first recorder
lengths(1,1)=length(wav2_files_new{1,1}); %the length of each newly adjusted channel will be different
lengths(2,1)=length(wav2_files_new{1,2});
min_length=min(lengths); %find shortest re-aligned channel, cut all channels to that length
uPa_out.recorder_671105061.pos1{i,1}=uPa_out.recorder_671105061.pos1{i,1}(1:min_length);
uPa_out.recorder_671105061.pos6{i,1}=uPa_out.recorder_671105061.pos6{i,1}(1:min_length);
uPa_out.recorder_671105061.pos3{i,1}=uPa_out.recorder_671105061.pos3{i,1}(1:min_length);
uPa_out.recorder_671105061.pos4{i,1}=uPa_out.recorder_671105061.pos4{i,1}(1:min_length);
%also need to cut longer channel on second recorder
%just cut both, one will remain the same and one will change
%depending on which channel was the longer one
uPa_out.recorder_335577141.pos5_new{i,1}=Data.five_new(1:min_length);
uPa_out.recorder_335577141.pos2_new{i,1}=Data.two_new(1:min_length);
end
else
%do not align files if they have different start times
warning('Files from different recorders have different start times');
end
end
%Take a look at the signal on each channel
figure(i);
subplot(611);plot(uPa_out.recorder_671105061.pos1{i,1})
subplot(612);plot(uPa_out.recorder_671105061.pos6{i,1})
subplot(613);plot(uPa_out.recorder_671105061.pos3{i,1})
subplot(614);plot(uPa_out.recorder_671105061.pos4{i,1});
subplot(615);plot(uPa_out.recorder_335577141.pos5{i,1})
subplot(616);plot(uPa_out.recorder_335577141.pos2{i,1});
subplot(615);plot(Data.five_new);
subplot(616);plot(Data.two_new);
subplot(615);plot(uPa_out.recorder_335577141.pos5_new{i,1});
subplot(616);plot(uPa_out.recorder_335577141.pos2_new{i,1});
0 Comments
Answers (1)
Image Analyst
on 12 Aug 2021
You can zip them up and put them on your MATLAB drive or Google drive.
Cross correlation does not always find where one signal is inside another. That's a myth. Sometimes it's true and sometimes not. Maybe you're having a case where it's not true. What it does is find where the product of the two signals is maximum, which may not occur where you think the signal best overlap - especially if the signals are different like where one has greater or varying amplitude compared to the other. See attached demo.
2 Comments
Image Analyst
on 12 Aug 2021
Edited: Image Analyst
on 12 Aug 2021
Personally I haven't done it yet, but here is the documentation. Looks like you also need an email address but you might be able to pick a instant/disposable one like answers@malinator.com or something like that.
Share Folders in MATLAB
Starting in R2019b, if you want other people to be able to view or edit your files, you can share the folder in MATLAB and control the file permissions. You can share a folder by inviting individual members to have access to the folder or by sharing a link to the folder.
To share a folder from MATLAB®, MATLAB Drive Connector must be running and the folder you choose to share must be in your MATLAB Drive™. If you are working in MATLAB Online™, you do not need MATLAB Drive Connector to share folders since sharing is always enabled.
For more information about sharing with MATLAB Drive, including limitations, see the MATLAB Drive documentation.Share a Folder
To share a folder by invitation, in the Current Folder browser, right-click the folder and select Share > Manage Members. You can select to share with view-only or can-edit permission for each person individually. To enter several addresses at one time, use a semi-colon or comma separator. You can only do this if they all have the same access level.
People you invite to a shared folder in this way will receive an email invitation. They must accept the invitation to have access to the shared folder. When inviting individual participants, you can make changes to each member's access at any time after the initial invite.
To share a folder with a view-only link, in the Current Folder browser, right-click the folder and select Share > Manage Link. Click Copy Link to copy the link to the clipboard.
In MATLAB Online, to share a folder that you have not shared before by invitation, right-click the folder and select Share > Invite Members. To share a folder by link, right-click the folder and select Share > Create Link.
Also see this posting from tech support
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!