Code covered by the BSD License  

Highlights from
Impulsive Noise Meter

image thumbnail
from Impulsive Noise Meter by Edward Zechmann
Calculates Impulsive noise metrics for hazardous acoustic noise assessent

[pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value)
function [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value)
% % find_previous_crossing: finds previous crossing above or below p_value
% %
% % Syntax:
% %
% % [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value);
% %
% % **********************************************************************
% %
% % Description
% %
% % The program "find_previous_crossing" will find the index of the data
% % point preceeding the data point wher the data array crosses p_value.
% %
% % Finds the previous crossing above or below p_value given a
% % multichannel input data time series p and a starting index p_index.
% %
% % The time record p has size [num_samples, num_channels].  The p_index is
% % the starting point
% %
% %
% %
% %
% % **********************************************************************
% %
% % Input variables
% %
% % p=randn(100000, 10);	% time record of data samples
% %                         % default value is p=randn(100000, 1);
% %
% % p_index                 % index of starting point for
% %                         % finding previous crossing of p_value.
% %                         %
% %                         % default value is [maxy, p_index]=max(y, [], 1);
% %
% % p_value=0;              % Threshold value for the crossing.
% %                         % default value is p_value=0;
% %
% %
% % **********************************************************************
% %
% % Output variables
% %
% % pc_ix is the index of the data sample before the previous crossing.
% %
% % pc_int is the interpolated fractional index of the previous crossing.
% %
% %
% % **********************************************************************
%
% Example='1';
%
% p=[1:0.1:10];     % time record of data samples
%
% p_index=5;        % index of starting point for
%                   % finding previous crossing of p_value.
%
% p_value=2.01;     % Threshold value for the crossing.
%                   % default value is p_value=0;
%
% [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value);
%
%
%
% Example='2';
%
% p=[10:-0.1:-100]; % time record of data samples
%
% p_index=80;       % index of starting point for
%                   % finding previous crossing of p_value.
%
% p_value=2.56;     % Threshold value for the crossing.
%                   % default value is p_value=0;
%
% [pc_ix, pc_int]=find_previous_crossing(p, p_index, p_value);
%
%
%
% % **********************************************************************
% %
% % find_previous_crossing was written by Edward L. Zechmann.
% %
% %     date  6 August      2010
% %
% % modified  9 August      2010    Made program work with multiple 
% %                                 channels.  Updated Comments
% %
% %
% %
% % **********************************************************************
% %
% % Please feel free to modify this code.
% %
% % See also: rise_time, find_previous_crossing, find_previous_ncrossings,
% %                      find_next_crossing, find_next_ncrossings
% %                      A_duration, B_mil_1474D_duration, B_Duration,
% %                      C_Duration, D_Duration
% %



if (nargin < 1 || isempty(p)) || ~isnumeric(p)
    warning('need at least 1 input: using random numbers as input data');
    p=randn(100000, 1);
end


% Make the data have the correct data type and size
[p]=convert_double(p);

% Make sure the matrix y is oriented correctly.
% Transpose if necessary.
[num_samples, num_channels]=size(p);

if num_samples < num_channels
    p=p';
    [num_samples, num_channels]=size(p);
end

if (nargin < 2 || isempty(p_index)) || any(~isnumeric(p_index))
    [maxy, p_index]=max(y, [], 1);
end

p_index(p_index > num_samples)=num_samples;
p_index(p_index < 1)=1;


if (nargin < 3 || isempty(p_value)) || ~isnumeric(p_value)
    p_value=0;
end

pc_ix=zeros(num_channels, 1);
pc_int=zeros(num_channels, 1);


for e1=1:num_channels;

    % Set value of p2 for channel e1
    p2=p(:, e1);

    % Select p_value for channel e1
    if length(p_value) >= e1
        p_value_buf=p_value(e1);
    else
        p_value_buf=p_value(end);
    end
    
    % Shift p2 for channel e1
    if p2(p_index) < p_value_buf
        p2=-p2+p_value_buf;
    else
        p2=p2-p_value_buf;
    end

    % Select p_index for channel e1
    if length(p_index) >= e1
        pc_ix_buf=p_index(e1);
    else
        pc_ix_buf=p_index(end);
    end
    
    
    % make sure that p_index_buf is in range
    if pc_ix_buf > length(p2)
        pc_ix_buf=length(p2);
    end
    
    if pc_ix_buf < 1
        pc_ix_buf=1;
    end

    
    % find start time for A-duration, which is the first zero-crossing before
    % the peak pressure
    flag1=0;
    while (flag1 == 0) && (pc_ix_buf > 1)
        pc_ix_buf = pc_ix_buf-1;
        if p2(pc_ix_buf) <= 0
            flag1=1;
        end
    end

    % interpolate to find better begin time
    if isequal(flag1, 0)
        pc_ix_buf=[];
        pc_int_buf=[];
    else
        if abs(p2(pc_ix_buf)-p2(pc_ix_buf+1)) >= 10^-12
            pc_int_buf = (0-p2(pc_ix_buf))/(p2(pc_ix_buf+1)-p2(pc_ix_buf))+pc_ix_buf;
        else
            pc_int_buf=pc_ix_buf;
        end
    end

    
    if ~isempty(pc_ix_buf)
        pc_ix(e1)=pc_ix_buf;
        pc_int(e1)=pc_int_buf;
    end
    
end

Contact us at files@mathworks.com