Commit 3d635eb7 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen

Merge branch 'master' of https://git.rwth-aachen.de/ita/toolbox

parents f6a06115 ca88b2c5
......@@ -662,6 +662,10 @@ classdef itaHRTF < itaAudio
%HRTFout = this.direction(idxCoord);
end
function this = buildsearchdatabase(this)
this.dirCoord = this.dirCoord.build_search_database;
end
function obj = direction(this, idxCoord)
idxDir = zeros(numel(idxCoord)*2,1);
idxDir(1:2:numel(idxCoord)*2,:) = 2*idxCoord-1;
......@@ -706,11 +710,17 @@ classdef itaHRTF < itaAudio
if ~exactSearch
phiU = rad2deg(this.phi_Unique);
thetaU = rad2deg(this.theta_Unique);
switch dirID
case {'phi_deg', 'p'}
slice = this.findnearestHRTF(thetaU,dir_deg);
case {'theta_deg', 't'}
slice = this.findnearestHRTF(dir_deg,phiU);
end
else
earCoords = this.getEar('L').channelCoordinates;
switch dirID
case {'phi_deg', 'p'}
phiValues = unique(earCoords.phi_deg);
phiValues = uniquetol(earCoords.phi_deg);
[~,index] = min(abs(phiValues - dir_deg));
exactPhiValue = phiValues(index);
tmp = earCoords.n(earCoords.phi_deg == exactPhiValue);
......@@ -718,7 +728,7 @@ classdef itaHRTF < itaAudio
slice = this.findnearestHRTF(thetaU,dir_deg);
case {'theta_deg', 't'}
thetaValues = unique(earCoords.theta_deg);
thetaValues = uniquetol(earCoords.theta_deg);
[~,index] = min(abs(thetaValues - dir_deg));
exactThetaValue = thetaValues(index);
tmp = earCoords.n(earCoords.theta_deg == exactThetaValue);
......@@ -727,12 +737,7 @@ classdef itaHRTF < itaAudio
slice = this.findnearestHRTF(dir_deg,phiU);
end
end
switch dirID
case {'phi_deg', 'p'}
slice = this.findnearestHRTF(thetaU,dir_deg);
case {'theta_deg', 't'}
slice = this.findnearestHRTF(dir_deg,phiU);
end
end
function slice = ss(this,dirID,dir_deg)
......@@ -911,10 +916,12 @@ classdef itaHRTF < itaAudio
ITD = phasenDiff./(2*pi*repmat(thisC.freqVector,1,size(phase1,2)));
else % averaged
phase = unwrap(angle(thisC.freqData));
t0_freq = bsxfun(@rdivide, phase,2*pi*thisC.freqVector);
usedBins = thisC.freq2index(sArgs.filter(1)):thisC.freq2index(sArgs.filter(2));
phase = unwrap(angle(thisC.freqData(2:end,:)));
freqVector = thisC.freqVector;
t0_freq = bsxfun(@rdivide, phase,2*pi*freqVector(2:end));
t0_freq = t0_freq(~isnan(t0_freq(:,1)),:);
t0_mean = mean(t0_freq(unique(thisC.freq2index(sArgs.filter(1)):thisC.freq2index(sArgs.filter(2))),:)); %mean is smoother than max; lower freq smooths also the result
t0_mean = mean(t0_freq(usedBins,:)); %mean is smoother than max; lower freq smooths also the result
ITD = t0_mean(thisC.EarSide == 'L') - t0_mean(thisC.EarSide == 'R');
end
case 'xcorr'
......@@ -1312,10 +1319,10 @@ classdef itaHRTF < itaAudio
ita_verbose_info(' More than one elevation in this object!', 0);
if strcmp(sArgs.plane,'horizontal')
thetaC_deg = 90;
thisC = this.sphericalSlice('theta_deg', thetaC_deg);
thisC = this.sphericalSlice('theta_deg', thetaC_deg,1);
elseif strcmp(sArgs.plane,'median')
phiC_deg = 0;
thisC = this.sphericalSlice('phi_deg', phiC_deg);
thisC = this.sphericalSlice('phi_deg', phiC_deg,1);
end
else thisC = this;
end
......
This diff is collapsed.
Copyright (c) 2014, Oliver J. Woodford, Yair M. Altman
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the {organization} nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (c) 2017, Yair Altman
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
......@@ -95,7 +95,7 @@ lowerTolVal = sArgs.distortionLimit * (1-sArgs.tolerance);
%% go through the excitation frequencies, process measurement
ita_verbose_info('Measurement process',1);
wb = itaWaitbar([numel(excitationFreq),numel(sArgs.distortionLimit)],'maxSPL',{'Frequencies','Limits'});
% frequency band loop with freqIdx
for freqIdx = 1:numel(excitationFreq)
......@@ -108,7 +108,7 @@ for freqIdx = 1:numel(excitationFreq)
% distortion limit loop
for distIdx = 1:numel(sArgs.distortionLimit)
wb.inc
% Amplification and measurement
while outputVoltage >= (outputVoltageRange(1)/10) && outputVoltage <= outputVoltageRange(2)
......@@ -211,11 +211,10 @@ for freqIdx = 1:numel(excitationFreq)
if breakFlag
breakFlag = false;
break;
end
end
end
end
wb.close;
%% Post-processing and Results
......
......@@ -88,8 +88,8 @@ classdef itaMSTFni < itaMSTF
% Define listeners to automatically call the init function of
% this class in case of a change in the below specified
% properties.
addlistener(this,'inputChannels','PostSet',@this.init);
addlistener(this,'outputChannels','PostSet',@this.init);
addlistener(this,'inputChannels','PostSet',@this.init_ni);
addlistener(this,'outputChannels','PostSet',@this.init_ni);
end
function this = edit(this)
......@@ -100,11 +100,10 @@ classdef itaMSTFni < itaMSTF
this = ita_mstfni_gui(this);
end
function this = init(this,varargin)
function this = init_ni(this,varargin)
% init - Initialize the itaMSTFni class object.
init@itaMSTF(this);
% if this is an object loaded from disk (niSession is empty),
% we do not need to initialize the card
% we do not need to re-initialize the card
if ~isempty(this.niSession)
this.niSession = init_NI_card(this);
end
......@@ -281,9 +280,6 @@ classdef itaMSTFni < itaMSTF
niSession.Channels(end).Name = inputChannels.name{iChannel};
% set to AC coupling to get rid of large DC offset
niSession.Channels(end).Coupling = 'AC';
% if any(strcmpi(Channels.type{iDevice,iChannel},{'Accelerometer' 'Microphone'}))
% niSession.Channels(end).Sensitivity = Channels.sensitivity(iDevice,iChannel);
% end
end
end
......@@ -307,6 +303,46 @@ classdef itaMSTFni < itaMSTF
end % function
function this = set_IEPE_channels(this,channelIds)
if isempty(this.niSession)
this.niSession = this.init_NI_card();
end
% first get NI info
[inputChannels,~,niDevices,~] = ita_get_ni_deviceinfo();
% INPUT
% set channel data from MS
channelIds = intersect(channelIds,this.inputChannels);
if isempty(channelIds)
error('Nothing to do, maybe your channels are not active?');
end
inputChannels.mapping = inputChannels.mapping(channelIds);
inputChannels.name = inputChannels.name(channelIds);
inputChannels.type = inputChannels.type(channelIds);
inputChannels.sensitivity = inputChannels.sensitivity(channelIds);
inputChannels.isActive = inputChannels.isActive(channelIds);
% Add analog input channels with IEPE supply
for iChannel = 1:numel(channelIds)
devIdx = [];
for iCh = 1:numel(this.niSession.Channels)
if strcmpi(inputChannels.name{iChannel},this.niSession.Channels(iCh).Name)
devIdx = iCh;
end
end
if ~isempty(devIdx)
this.niSession.removeChannel(devIdx);
else
error('Could not find your channel');
end
% then add again
iDevice = inputChannels.mapping{iChannel}(1);
iDeviceChannel = inputChannels.mapping{iChannel}(2);
this.niSession.addAnalogInputChannel(get(niDevices(iDevice),'ID'),iDeviceChannel-1,'IEPE');
this.niSession.Channels(end).Name = inputChannels.name{iChannel};
end
end % function
function sObj = saveobj(this)
% saveobj - Saves the important properties of the current
% measurement setup to a struct.
......
......@@ -92,7 +92,7 @@ if playback
peak_value = max(max(abs(data.timeData)));
if (peak_value > outputClipping) || (normalize_output)
ita_verbose_info('Oh Lord! Levels too high for playback. Normalizing...',0)
data = ita_normalize_dat(data);
data = data/peak_value*outputClipping;
end
end
......
......@@ -414,6 +414,7 @@ function [] = daffv17_write( varargin )
% note: use round here to avoid errors if alphapoints are not exactly
% integers but within epsilon
x = cell( round( args.alphapoints ), round( args.betapoints ), args.channels );
args.userdata = args.userdata.buildsearchdatabase;
for b=1:args.betapoints
beta = betastart + (b-1)*args.betares;
......@@ -422,13 +423,11 @@ function [] = daffv17_write( varargin )
points = 1;
else
points = args.alphapoints;
end
end
for a=1:points
alpha = alphastart + (a-1)*args.alphares;
% --= Impulse responses =--
% --= Impulse responses =--
if strcmp( args.content, 'IR' )
% Get the data
[ data, samplerate, metadata ] = args.datafunc( alpha, beta, args.userdata );
......
......@@ -508,7 +508,7 @@ classdef itaSuper < itaMeta
function res = get_diag(this)
% use eye as mask for diagonal
res = this(eye(size(this,1)));
res = this(logical(eye(size(this,1))));
end
function this = diag(this,diagonalshift,blocksize)
......
......@@ -24,39 +24,35 @@ function varargout = ita_multiple_time_windows(varargin)
sArgs = struct('pos1_a','itaAudioTime','blocksize',1024,'window',@hann,'overlap',0.5);
[a,sArgs] = ita_parse_arguments(sArgs,varargin);
b = sArgs.blocksize;
nWindow = b;
nWindow = sArgs.blocksize;
if sArgs.overlap < 1
nOverlap = round(nWindow*sArgs.overlap);
else
nOverlap = round(sArgs.overlap);
end
nSegments = ceil(a.nSamples / nWindow * 2 + 1);
nNewLength = (nSegments -1) * nWindow / 2;
% half a window length at beginning and end
ext_zeros = zeros(nWindow/2,a.nChannels);
data = [ext_zeros; a.time; ext_zeros];
nSegments = ceil((size(data,1) - nWindow) / (nWindow - nOverlap)) + 1;
nNewLength = (nSegments - 1) * (nWindow - nOverlap) + nWindow;
if nNewLength > a.nSamples
a = ita_extend_dat(a,nNewLength,'forcesamples');
end
%% generate window
win_vec = window(sArgs.window,nWindow+1).';
win_vec = window(sArgs.window,nWindow+1);
win_vec(end) = [];
ext_zeros = zeros(a.nChannels,nWindow/2);
data = [ext_zeros a.dat(:,:) ext_zeros];
resultDummy = a;
resultDummy.data = zeros(1,a.nChannels);
result = repmat(resultDummy,nSegments,1);
for idx = 1:nSegments
iLow = (idx-1)*(nWindow-nOverlap)+1;
iHigh = iLow+nWindow-1;
slice = bsxfun(@times,data(:,iLow:iHigh),win_vec);
result(idx).time = slice.';
sliceIds = (idx-1)*(nWindow-nOverlap) + (1:nWindow);
result(idx).time = bsxfun(@times,data(sliceIds,:),win_vec);
end
%%
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment