From 277a6781b8c2ff980167bb52ee128e3a8092aeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Sch=C3=A4fer?= Date: Thu, 4 Apr 2019 14:22:06 +0200 Subject: [PATCH] =?UTF-8?q?removed=20application/Numeric/SH=20-seem=20to?= =?UTF-8?q?=20be=20unused=20files=20originating=20from=20Kunkem=C3=B6ller'?= =?UTF-8?q?s=20Diplomarbeit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Numeric/SH/@itaAudioMIMO/itaAudioMIMO.m | 87 ---- .../@itaSphSynthDirectivity/SHfilter2SHrir.m | 101 ----- .../convolve_itaBalloon_and_SH_RIR.m | 84 ---- .../evaluate_synthesisError.m | 33 -- .../@itaSphSynthDirectivity/extendFreqRange.m | 90 ----- .../SH/@itaSphSynthDirectivity/getPositions.m | 98 ----- .../itaSphSynthDirectivity.m | 378 ------------------ .../ita_test_itaSphSynthDirectivity.m | 82 ---- .../makeArraySampling.m | 33 -- .../SH/@itaSphSynthDirectivity/makeSHfilter.m | 83 ---- .../@itaSphSynthDirectivity/makeSynthArray.m | 119 ------ .../convolve_filter_and_measurement.m | 83 ---- .../convolve_itaBalloon_and_sphRIR.m | 63 --- ...ion_of_ideal_and_synthesised_directivity.m | 62 --- .../@itaSyntheticDir/freqData2synthesisRule.m | 272 ------------- .../SH/@itaSyntheticDir/getPositions.m | 77 ---- .../@itaSyntheticDir/itaBalloon2synthFilter.m | 86 ---- .../SH/@itaSyntheticDir/itaSyntheticDir.m | 194 --------- .../ita_test_itaSyntheticDir.m | 94 ----- .../SH/@itaSyntheticDir/makeSpeakerSampling.m | 27 -- .../Numeric/SH/@itaSyntheticDir/makeSphRIR.m | 223 ----------- .../SH/@itaSyntheticDir/makeSynthSpeaker.m | 160 -------- .../maku_SYNTH_penalty_condition_rotError.m | 61 --- .../maku_SYNTH_penalty_num_IR.m | 60 --- .../maku_SYNTH_penalty_num_IRII.m | 63 --- .../maku_SYNTH_penalty_num_rot.m | 72 ---- .../maku_SYNTH_penalty_rot_error.m | 35 -- .../maku_SYNTH_penalty_rot_error_2_max_cond.m | 35 -- .../@itaSyntheticDir/synthesisRule2filter.m | 207 ---------- .../synthesisRule2filter_back_2010-11-20.m | 142 ------- .../@itaSyntheticDir/test_steepest_descend.m | 31 -- .../test_synthesize_yourself.m | 19 - 32 files changed, 3254 deletions(-) delete mode 100644 applications/Numeric/SH/@itaAudioMIMO/itaAudioMIMO.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/SHfilter2SHrir.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/convolve_itaBalloon_and_SH_RIR.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/evaluate_synthesisError.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/extendFreqRange.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/getPositions.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/itaSphSynthDirectivity.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/ita_test_itaSphSynthDirectivity.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/makeArraySampling.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/makeSHfilter.m delete mode 100644 applications/Numeric/SH/@itaSphSynthDirectivity/makeSynthArray.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/convolve_filter_and_measurement.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/convolve_itaBalloon_and_sphRIR.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/correlation_of_ideal_and_synthesised_directivity.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/freqData2synthesisRule.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/getPositions.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/itaBalloon2synthFilter.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/itaSyntheticDir.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/ita_test_itaSyntheticDir.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/makeSpeakerSampling.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/makeSphRIR.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/makeSynthSpeaker.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_condition_rotError.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IR.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IRII.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_rot.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error_2_max_cond.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter_back_2010-11-20.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/test_steepest_descend.m delete mode 100644 applications/Numeric/SH/@itaSyntheticDir/test_synthesize_yourself.m diff --git a/applications/Numeric/SH/@itaAudioMIMO/itaAudioMIMO.m b/applications/Numeric/SH/@itaAudioMIMO/itaAudioMIMO.m deleted file mode 100644 index e509f08..0000000 --- a/applications/Numeric/SH/@itaAudioMIMO/itaAudioMIMO.m +++ /dev/null @@ -1,87 +0,0 @@ -classdef itaAudioMIMO < itaAudio - - - % - % This file is part of the ITA-Toolbox. Some rights reserved. - % You can find the license for this m-file in the license.txt file in the ITA-Toolbox folder. - % - properties(Access = private, Hidden = true) - - mReceiverPosition = itaCoordinates(); - mReceiverUpVector = itaCoordinates(); - mReceiverViewVector = itaCoordinates(); - mSourcePosition = itaCoordinates(); - mSourceUpVector = itaCoordinates(); - mSourceViewVector = itaCoordinates(); - end - - properties(Dependent = true, Hidden = false) - nSources - nReceivers - - end - properties(Dependent = true, Hidden = true) - - end - methods - - - function this = itaAudioMIMO(varargin) - this = this@itaAudio(varargin{1}(1)); - - [nReceivers, nSources] = size(varargin{1}); - nSamplesOrBins = size(this.data, 1); - - - this.(this.domain) = zeros(nSamplesOrBins, nReceivers, nSources); - channelNames = cell(nReceivers, nSources); - for iReceiver = 1:nReceivers - for iSource = 1:nSources - if varargin{1}(iReceiver, iSource).nChannels > 1 - error('nur ein channel pro itaAudio. muss man anpassen wenn man was anderes will') - end - this.(this.domain)(:, iReceiver, iSource) = varargin{1}(iReceiver, iSource).(this.domain); - channelNames(iReceiver, iSource) = varargin{1}(iReceiver, iSource).channelNames; - end - end - - this.channelNames = channelNames; - end - - - function res = source(this, iSource) - res = this; - - dataSize = [this.nReceivers this.nSources]; - - % use linear index because channelNames is always 1-D and data 2-D - linearIndex = sub2ind(dataSize, 1:dataSize(1), iSource*ones(1,dataSize(1))); - - res.data = this.data(:, linearIndex); - res.channelNames = this.channelNames(linearIndex); - end - - - function res = receiver(this, iReceiver) - res = this; - - dataSize = [this.nReceivers this.nSources]; - - % use linear index because channelNames is always 1-D and data 2-D - linearIndex = sub2ind(dataSize, iReceiver*ones(1,dataSize(2)), 1:dataSize(2)); - - res.data = this.data(:, linearIndex); - res.channelNames = this.channelNames(linearIndex); - end - - - function nSources = get.nSources(this) - nSources = size(this.(this.domain), 3); - end - - function nReceivers = get.nReceivers(this) - nReceivers = size(this.(this.domain), 2); - end - - end -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/SHfilter2SHrir.m b/applications/Numeric/SH/@itaSphSynthDirectivity/SHfilter2SHrir.m deleted file mode 100644 index ba16d26..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/SHfilter2SHrir.m +++ /dev/null @@ -1,101 +0,0 @@ -function SHfilter2SHrir(this) -% This function extends the frequency range of the filters, calculated by -% itaSphSynthDirectivity.makeSHfilter, and convolve them with the -% measurement. -% -% The result is first saved in a big matrix 'rirData' and then exportet in -% itaAudio-format into the directory this.folder/SH_RIR -% -% see also: itaSphSynthDirectivity, makeSynthArray, makeSHfilter, convolve_itaBalloon_and_SHfilter - -if ~strcmpi(this.outputFormat, 'itaAudio') - error(' '); -end - -%check measurement data files -for idxD = 1:length(this.measurementDataFolder) - testFile = [this.measurementDataFolder{idxD} filesep this.filemask '1.ita']; - if ~exist(testFile,'file'); - error(['There is no such file: "' testFile '.ita"']); - end -end - -nmax_l = (this.nmax+1)^2; - -actFF = [0 0]; %index Folder and File of the current measurementdata in the memory -freqOffset = length(this.array.freqVector(this.array.freqVector < this.freqVector(1))); - -this.myWaitbar(this.nSpeakers+1, 'SHfilter2SHrir'); - -for idxS = 1:this.nSpeakers - this.myWaitbar(idxS); - - % parse filter data 2 itaAudio - filter = itaAudio('samplingRate',this.array.samplingRate, 'signalType','energy',... - 'dataType', this.precision); - filter.freqData = zeros(this.array.nBins, nmax_l, this.precision); - filter.freqData(freqOffset+(1:this.nBins),:) = ... - permute(this.mFilterData.get_data(1:this.nBins, idxS, 1:nmax_l), [1 3 2]); - - filter = this.extendFreqRange(filter); - - %read measurement data - TRC = this.speaker2idxTiltRotCh(idxS,:); %tilt & rotation angle, channel - FF = this.idxTiltRot2idxFolderFile{TRC(1),TRC(2)}; %folder file - if sum(actFF == FF) ~= 2 - % only load if neccessary - data = ita_read([this.measurementDataFolder{FF(1)} filesep this.filemask int2str(FF(2)) '.ita']); - actFF = FF; - end - - % initialize output's freqData - if idxS == 1 - rirData = zeros(data(1).nBins, nmax_l, data(1).nChannels, this.precision); - nMic = data(1).nChannels; - end - - %adapt length of filter and data - if data(1).nSamples ~= filter.nSamples - if data(1).nSamples < filter.nSamples - % that should never happen - error('sorry, I did not expect that, maybe you could code that?'); - else - filter = filter.'; - filter = ita_time_window(filter, round(filter.nSamples/2+[-0.005*filter.samplingRate 0]),'samples','symmetric'); - filter = ita_extend_dat(filter, data(1).nSamples,'symmetric'); - filter = filter'; - end - end - - % convolve - for idxM = 1:nMic - rirData(:,:,idxM) = rirData(:,:,idxM) + bsxfun(@times, cast(data(TRC(3)).freqData(:,idxM), this.precision), filter.freqData); - end - clear filter; -end - -this.myWaitbar(this.nSpeakers+1); - -% initialize output objects -if ~isdir([this.folder filesep 'SH_RIR']), - mkdir([this.folder filesep 'SH_RIR']); -end - - -for idxD = 1:nMic - out = itaAudio; - out.samplingRate = this.array.samplingRate; - out.signalType = 'energy'; - out.dataType = this.precision; - out.freqData = rirData(:,:,idxD); - - out.comment = ['SH - RIR (' data(1).channelNames{idxD} ')']; - out.userData = struct('freqRange', this.freqRange); - for idxC = 1:out.nChannels - [n m] = ita_sph_linear2degreeorder(idxC); - out.channelNames{idxC} = ['sph ' int2str(n) ', ' int2str(m)]; - end - ita_write(out, [this.folder filesep 'SH_RIR' filesep 'SH_RIR_Mic' int2str(idxD) '.ita']); -end - -this.myWaitbar([]); diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/convolve_itaBalloon_and_SH_RIR.m b/applications/Numeric/SH/@itaSphSynthDirectivity/convolve_itaBalloon_and_SH_RIR.m deleted file mode 100644 index 61c04a4..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/convolve_itaBalloon_and_SH_RIR.m +++ /dev/null @@ -1,84 +0,0 @@ -function out_m = convolve_itaBalloon_and_SH_RIR(this, balloon, varargin) -% -% Convolves a target-directivity (an itaBalloon-object) and the impulse -% responses of abstract directivities with the form of spherical harmonic -% basefunctions. -% see also: makeSHfilter and SHfilter2SHrir -% -% input: -% - balloon : target - directivity - function -% -% options: -% 'channels' you can choose one ore multiple channels (directivity of a -% multichannel itaBalloon will be sumed up). -% 'mpb_filter' result will be band widhth filtered by ita_mpb_filter -% 'rotate' here you can give a set of euler rotation angles to rotate the input balloon. -% The output will be an array of filters- one for each -% position -% 'rotate', {[orientation 1], [orientation 2], ... } -sArgs = struct('channels',1:balloon.nChannels,'rotate',zeros(1,3)); -if nargin > 2 - sArgs = ita_parse_arguments(sArgs, varargin); -end - -if ~isdir([this.folder filesep 'SH_RIR']) || ~numel(dir([this.folder filesep 'SH_RIR' filesep '*.ita'])) - error('First proceed itaSphSyntDirectivity.SHfilter2SHrir'); -end - -if ~iscell(sArgs.rotate), sArgs.rotate = {sArgs.rotate}; end -for idxR = 1:length(sArgs.rotate) - if size(sArgs.rotate{idxR},2)~=3, error('size(rotatate,2) != 3 (euler angle)'); end -end - -% target's directivity -ao = balloon.idxCoefSH2itaAudio(1:this.mFilterData.dimension(3),'channels',sArgs.channels,'sum_channels', true); -ao.dataType = this.precision; - -if balloon.fftDegree ~= this.array.fftDegree - error('I can not handle different fftDegrees. Please use itaBalloon.convert_fftDegree as work arround.'); -end - -% synthesised abstract room impulse responses -nMic = numel(dir([this.folder filesep 'SH_RIR' filesep 'SH_RIR_Mic*.ita'])); - -out = itaAudio(length(sArgs.rotate),nMic); -for idxM = 1:nMic - RIR = ita_read([this.folder filesep 'SH_RIR' filesep 'SH_RIR_Mic' int2str(idxM) '.ita']); - for idxR = 1:length(sArgs.rotate) - out(idxR, idxM) = itaAudio('dataType', this.precision, 'signalType', 'energy','samplingRate', this.array.samplingRate); - ao2 = ao; - if strcmpi(this.SHType, 'complex') - ao2.freqData = ita_sph_rotate_complex_valued_spherical_harmonics(ao.freqData.',sArgs.rotate{idxR}).'; - elseif strcmpi(this.SHType, 'real') - ao2.freqData = ita_sph_rotate_real_valued_spherical_harmonics(ao.freqData.',sArgs.rotate{idxR}).'; - else - error('unknown SHType'); - end - - % adapt data - if ao2.nSamples < RIR.nSamples - ao2 = ita_time_window(ao2, round(ao2.nSamples/2+[-0.005*ao2.samplingRate 0]),'samples','symmetric'); - ao2 = ita_extend_dat(ao2, RIR.nSamples,'symmetric'); - else - ao2 = ita_extract_dat(ao2, RIR.nSamples,'symmetric'); - ao2 = ita_time_window(ao2, round(ao2.nSamples/2+[-0.005*ao2.samplingRate 0]),'samples','symmetric'); - end - - %convolve and add - out(idxR, idxM) = sum(ita_multiply_spk(ao2,RIR)); - - %adapt latency samples - if balloon.latencySamples ~= this.array.latencySamples - out(idxR, idxM) = ita_time_shift(out(idxR, idxM), balloon.latencySamples - this.array.latencySamples, 'samples'); - end - - out(idxR, idxM).channelNames{1} = ''; - out(idxR, idxM).comment = ['synthesized RIR of ' balloon.name ' (mic: ' int2str(idxM) ')']; - end -end - -out_m = itaAudio(length(sArgs.rotate),1); -for idxR = 1:length(sArgs.rotate) - out_m(idxR) = merge(out(idxR,:)); - out_m(idxR).history = {' '}; -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/evaluate_synthesisError.m b/applications/Numeric/SH/@itaSphSynthDirectivity/evaluate_synthesisError.m deleted file mode 100644 index de31f8f..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/evaluate_synthesisError.m +++ /dev/null @@ -1,33 +0,0 @@ -function varargout = evaluate_synthesisError(this, varargin) -% returns and plots the relative root mean square error of the synthesis of -% abstract directivities with the surface of spherical harmonics. -% -% options: freq: vector of frequencies beeing evaluated -% degault : this.freqRange in 1/3-octave steps -% namx: maximum degree of evaluation -% -sArgs = struct('freq', [], 'nmax', this.nmax); -if nargin > 1 - sArgs = ita_parse_arguments(sArgs, varargin); -end -if isempty(sArgs.freq) - sArgs.freq = ita_ANSI_center_frequencies(this.freqRange, 3); -end - -RMS = zeros((sArgs.nmax+1)^2, length(sArgs.freq), this.precision); - -filter = this.mFilterData.get_data(this.freq2idxFreq(sArgs.freq), 1:this.nSpeakers, 1:(sArgs.nmax+1)^2); - -for idxF = 1:length(sArgs.freq) - RMS(:,idxF) = sum(abs(eye((sArgs.nmax+1)^2) - this.freq2coefSH_synthArray(sArgs.freq(idxF), 'nmax', sArgs.nmax)... - * permute(filter(idxF,:,:), [2 3 1])).^2,2); -end - -RMS = sqrt(RMS); -ita_sph_plot_coefs_over_freq(RMS, sArgs.freq, 'type','max'); - -if nargout - varargout = {RMS}; -else - varargout = {}; -end diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/extendFreqRange.m b/applications/Numeric/SH/@itaSphSynthDirectivity/extendFreqRange.m deleted file mode 100644 index 55ea79c..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/extendFreqRange.m +++ /dev/null @@ -1,90 +0,0 @@ -function ao = extendFreqRange(this, ao) -% -% this function smoothes and extends the a calculated frequency response -% using rational fit (must be improoved) or polynomes -% - - - -overlap = 1/3; % overlap of sections -fitSecDegree = [3 18]; - -%% initialize -freqData = ao.freqData; -outData = zeros(size(freqData), this.precision); - -% estimate frequency range -channel = 1; -while ~sum(abs(freqData(:,channel))) && channel < ao.nChannels - channel = channel + 1; -end -idx_FR = [find(abs(freqData(:,channel))>0, 1, 'first'),... - find(abs(freqData(:,channel))>0, 1, 'last')]; - -% mean amplitude -meanAmp = mean(abs(freqData(idx_FR(1):idx_FR(2),:)), 1); - -if idx_FR(1) > 1 - % indicees to extend the first part of the frequency range ... - ids_fit = ao.freq2index(ao.freqVector(idx_FR(1)*[1 2^overlap])); - nAddPs = floor(min(length(ids_fit), ids_fit(1)/2)/2)*2; - ids_all = [(1:nAddPs).'; ids_fit]; - newIds = ids_all(1):ids_all(end); - extend_low = true; - fitSecDegree(1) = min(fitSecDegree(1), length(ids_all)-1); -else - extend_low = false; - ids_fit = [1 1]; -end -if idx_FR(2) < ao.nBins - % indicees to extend the end of the frequency range - ide_fit = ao.freq2index(ao.freqVector(idx_FR(2)*[2^(-overlap) 1])); - nAddPe = length(ide_fit); - p1 = 0.25*ide_fit(end) + 0.75*ao.nBins; pe = ao.nBins; - addPe = (round(p1) : round((pe-p1)/(nAddPe)) : round(pe)).'; - addPe(end) = ao.nBins; - ide_all = [ide_fit; addPe]; - newIde = ide_all(1):ide_all(end); - extend_high = true; - fitSecDegree(2) = min(fitSecDegree(2), length(ide_all)-5); -else - extend_high = false; - ide_fit = [1 1]*ao.nBins; -end -%% xover -xover = zeros(size(freqData,1),2, this.precision); -xover(1:ids_fit(1) ,1) = 1; -xover(ids_fit(2):ide_fit(1),2) = 1; -xover(ide_fit(2):end, 3) = 1; - -if extend_low - % first X - lX = ids_fit(2)-ids_fit(1); - xover(ids_fit(1):ids_fit(2),1) = 1 - (0:lX)/lX; - xover(ids_fit(1):ids_fit(2),2) = (0:lX)/lX; -end -if extend_high - % second X - lX = ide_fit(2)-ide_fit(1); - xover(ide_fit(1):ide_fit(2),2) = 1 - (0:lX)/lX; - xover(ide_fit(1):ide_fit(2),3) = (0:lX)/lX; -end -nBins = ao.nBins; -for idxC = 1:ao.nChannels - newStuff = zeros(nBins,2, this.precision); - if extend_low - % extend the first part of the frequency range ... - datas = freqData(ids_fit, idxC); - [P S muX] = polyfit(ids_all, [repmat(meanAmp(idxC), nAddPs, 1); datas] , fitSecDegree(1)); %#ok - newStuff(newIds,1) = polyval(P, (newIds-muX(1))/muX(2)); - end - if extend_high - % extend the second part of the frequency range ... - datae = freqData(ide_fit, idxC); - [P S muX] = polyfit(ide_all, [datae; repmat(meanAmp(idxC), length(addPe), 1)], fitSecDegree(2)); %#ok - newStuff(newIde,2) = polyval(P, (newIde-muX(1))/muX(2)); - end - %% xover über Abschnitte - outData(:,idxC) = sum([newStuff(:,1) freqData(:,idxC) newStuff(:,2)] .* xover, 2); -end -ao.freqData = outData; diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/getPositions.m b/applications/Numeric/SH/@itaSphSynthDirectivity/getPositions.m deleted file mode 100644 index 8e5799d..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/getPositions.m +++ /dev/null @@ -1,98 +0,0 @@ -function this = getPositions(this, varargin) -% reads rotationAngle out of a set of measurement data set by -% measurementDataFolder = {'folder1', 'folder2',...} -% -% you can use 'ita_roomacoustics_correlation_coefficient_longtime to select good -% speaker positions -% -% settings: -% 'nPos' : maximum number of rotations per folder to build a synthSuperSpeaker -% 'corcoef' : the result of -% "ita_roomacoustics_correlation_coefficient_longtime", that -% determines the best correlating measurement positions - -sArgs = struct('corcoef',[], 'nPos',[]); - -%% init -check_empty(this) - -if nargin > 1 - sArgs = ita_parse_arguments(sArgs,varargin); -end - -if isempty(this.measurementDataFolder) - error('give me some "measurementDataFolder"'); -end - -if ~isempty(sArgs.corcoef) - % select speaker positions via correlation analyis - [dummy idxPositions] = sort(sArgs.corcoef.timeData,'descend'); %#ok - if ~isempty(sArgs.nPos) - idxPositions = idxPositions(1:sArgs.nPos); - end -else - idxPositions = []; lastIndex = 0; - for idxF = 1:length(this.measurementDataFolder) - nFiles = numel(dir([this.measurementDataFolder{idxF} filesep this.filemask '*.ita'])); - if ~nFiles, error(['can not find no file "' this.measurementDataFolder{idxF} filesep this.filemask '*.ita"']); end - - % select speaker positions via a maximum number of positions - if ~isempty(sArgs.nPos) - - idxPositions = [idxPositions, lastIndex + (1:floor(nFiles/sArgs.nPos):nFiles)]; %#ok - if length(idxPositions) > sArgs.nPos - idxPositions = idxPositions(1:sArgs.nPos); - end - - if length(idxPositions) ~= sArgs.nPos - disp('check'); - end - - % take all measured data - else - idxPositions = [idxPositions, lastIndex + (1:nFiles)]; %#ok - end - lastIndex = lastIndex + nFiles; - end -end - -% routing : position 2 folder/file -idxPos2idxFolderFile = zeros(0,2); -for idxF = 1:length(this.measurementDataFolder) - nFiles = numel(dir([this.measurementDataFolder{idxF} filesep this.filemask '*.ita'])); - if ~nFiles, error(['can not find no file "' this.measurementDataFolder{idxF} filesep this.filemask '*.ita"']); end - idxPos2idxFolderFile = [idxPos2idxFolderFile; ones(nFiles,1)*idxF (1:nFiles).']; %#ok -end - -idxPos2idxFolderFile = idxPos2idxFolderFile(idxPositions,:); - -%% read rotation angle out of measurement data - -% (*) Im Moment gilt noch: idxTilt = idxFolder. -% Später sollte / könnte man auch idxTilt mal aus den Messdaten auslesen (?) -nTilt = length(this.measurementDataFolder); -nRotMax = 0; -for idxT = 1:nTilt - nRotMax = max(nRotMax, length(idxPos2idxFolderFile(idxPos2idxFolderFile(:,1) == idxT, 2))); -end - -this.idxTiltRot2idxFolderFile = cell(nTilt, nRotMax); -this.rotationAngle = cell(nTilt,1); - -%get rotation angles from channel data.coordinates -for idxP = 1:length(idxPositions) - idxFolder = idxPos2idxFolderFile(idxP,1); - idxFile = idxPos2idxFolderFile(idxP,2); - data = ita_read([this.measurementDataFolder{idxFolder} filesep this.filemask int2str(idxFile) '.ita']); - - if ~this.rotationAngle_counterClockWise - phi = mod(10*pi - data(1).channelCoordinates.phi(1), 2*pi); - else - phi = mod(data(1).channelCoordinates.phi(1), 2*pi); - end - - % (*) - idxTilt = idxFolder; - this.rotationAngle{idxTilt} = [this.rotationAngle{idxTilt} phi]; - this.idxTiltRot2idxFolderFile{idxTilt, length(this.rotationAngle{idxTilt})} = [idxFolder idxFile]; -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/itaSphSynthDirectivity.m b/applications/Numeric/SH/@itaSphSynthDirectivity/itaSphSynthDirectivity.m deleted file mode 100644 index 8e631df..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/itaSphSynthDirectivity.m +++ /dev/null @@ -1,378 +0,0 @@ -classdef itaSphSynthDirectivity < handle - % see also itaSphSynthSirectivity.tutorial - - % TO DO - % - makeArraySampling(this), dann funktioniert erst die kodierte - % Ansteuerung (Ansteuerung nach sphärischen Harmonischen) - properties (Dependent = true) - folder % object's home directory - array % an itaSphericalLoudspeaker or an itaBalloonSH - arrayChannels % indices of the array's speaker that shall be involved - arrayNmax % maximim degree for the synthesis of the super-array - tiltAngle % euler angle (see tutorial) - rotationAngle % vector of rotation angles (see tutorial) - measurementDataFolder % directories of your measurements - freqRange - precision - MBytesPerSegment - end - properties(Access = private) - mFolder = []; - mArray = itaBalloon; - mArrayChannels = []; - mArrayNmax = nan; - mTiltAngle = {[0 0 0]}; - mRotationAngle = 0; - mMeasurementDataFolder = {}; - mFreqRange = []; - end - properties (Access = public) - name = 'this'; - comment = ' '; - regularization = 1e-4; - rotationAngle_counterClockWise = true; %if measurements stem from itaItalian this must be set false! - encodeNmax = 20; - nmax = nan; - filemask = ''; - end - properties(GetAccess = public, SetAccess = private) - freqVector = []; - nSpeakers = []; % set in makeSynthSpeaker - nBins = []; - idxTiltRot2idxFolderFile = {}; % set in getPositions - speaker2idxTiltRotCh = []; % set in makeSynthSpeaker - SHType = []; - - arraySampling = itaCoordinates; % set in makeSpeakerSampling - end - properties(Access = private) - internalFreqRange = []; - mDataSH = itaFatSplitMatrix; - mFilterData = itaFatSplitMatrix; - outputFormat = []; - end - methods - % constructor - function this = itaSphSynthDirectivity(varargin) - if ~nargin - % initialize some stuff - this.MBytesPerSegment = 200; - this.precision = 'single'; - else - if isa(varargin{1}, 'itaSphSynthDirectivity') - prop = this.propertiesSaved; - for idx = 1:length(prop) - this.(prop{idx}) = varargin{1}.(prop{idx}); - end - % call class's copy constructor - this.mDataSH = itaFatSplitMatrix(varargin{1}.mDataSH); - this.mFilterData = itaFatSplitMatrix(varargin{1}.mFilterData); - - % load actual data - if ~isempty(varargin{1}.array) - this.mArray = ita_read_itaBalloon([varargin{1}.array.balloonFolder filesep varargin{1}.array.name]); - end - end - end - end - - - % data administration - function idxFreq = freq2idxFreq(this,freq) - % frequency 2 index of freqVector - idxFreq = zeros(size(freq)); - for idx = 1:numel(freq) - [dist idxFreq(idx)] = min(abs(this.freqVector-freq(idx))); %#ok - end - end - function value = freq2coefSH_synthArray(this, freq, varargin) - % returns the spherical harmonic coefficients at given - % frequencies - % output-size: [coefficients(linear numbered); array-speaker; frequency] - % options : nmax: maximum degree of coefficient - % : channels: index of array-speaker - sArgs = struct('nmax',this.arrayNmax,'channels',1:this.nSpeakers); - if nargin > 2 - sArgs = ita_parse_arguments(sArgs,varargin); - end - - %read data - value = this.mDataSH.get_data(1:(sArgs.nmax+1)^2, sArgs.channels, this.freq2idxFreq(freq)); - end - function filter = idxSH2filter(this, idxSH, varargin) - % returns a filter that weights all the synthArrays speakers, - % so that their superposition yields a directivity with the - % surface of the spherical base function with the linear index - % idxSH. - % - % the filter's frequency range can be extended using - % this.extendFreqRange - % - % if this.SHtype == 'complex', this function is a complex - % valued spherical harmominc, if == 'real', ... - % - % if your array was an itaBalloon with a continuous - % frequencyResponse, output will be an itaAudio, otherwise an - % itaResult. - % - % otopn : 'speakers' default : 1:this.nSpeakers - % - % see also: tutorial, ita_sph_degreeorder2linear, ita_sph_base, - % ita_sph_realvalued_basefunction, itaSamplingSph, - % itaSamplingSphReal, extendFreqRange - sArgs = struct('speakers',1:this.nSpeakers); - if nargin > 2 - sArgs = ita_parse_arguments(sArgs, varargin); - end - if strcmpi(this.outputFormat, 'itaResult') - filter = itaResult(length(idxSH),1); - for idx = 1:length(idxSH) - filter(idx).freqVector = this.freqVector; - end - elseif strcmpi(this.outputFormat, 'itaAudio') - filter = itaAudio(length(idxSH),1); - for idx = 1:length(idxSH) - filter(idx).samplingRate = this.speaker.samplingRate; - filter(idx).signalType = 'energy'; - end - else - error(' unknown format'); - end - - for idx = 1:length(idxSH) - filter(idx).dataType = this.precision; - - idxOffset = length(this.speaker.freqVector(this.speaker.freqVector < this.freqVector)); - filter(idx).freqData(idxOffset+(1:this.nBins),:) = this.mFilterData.get_data(1:this.nBins,sArgs.speakers,idxSH(idx)); - - filter(idx).channelUserData{1} = sArgs.speakers; - [n m] = ita_sph_linear2degreeorder(idxSH(idx)); - filter(idx).comment = ['filter for the synthesis of SH ' int2str(n) ', ' int2str(m) ' (not smoothed)']; - end - end - function out = encodeCoefSH(this, in) - % in : [idxCoefSH idxRealChannel idxFreq] - % out: [idxCoefSH idxEncodedChannel idxFreq] - - % check if encoding must be initialized - if ~isa(this.arraySampling, 'itaSamplingSph')... - || this.arraySampling.nPoints ~= this.nSpeakers - this.makeArraySampling; - end - - if this.encodeNmax ~= this.arraySampling.nmax - if strcmpi(this.SHType, 'complex') - this.arraySampling = itaSamplingSph(this.arraySampling); - elseif strcmpi(this.SHType, 'real') - this.arraySampling = itaSamplingSphReal(this.arraySampling); - else - error('unknown SH-type'); - end - this.arraySampling.nmax = this.encodeNmax; - save(this); - end - - % encoding - out = zeros(size(in,1), (this.encodeNmax+1)^2, size(in,3)); - for idxF = 1:size(in,3) - out(:,:,idxF) = in(:,:,idxF)*this.arraySamplingY(:,1:(this.encodeNmax+1)^2); - end - end - function out = decodeCoefSH(this, in, maintainedFunctions) - % in : [idxEncodedChannel idxFreq] - % out: [idxRealChannel idxFreq] - - out = zeros(size(this.arraySamplingY,1), size(in,2), size(in,3)); - for idxN = 1:size(in,3) - out(:,:,idxN) = this.arraySamplingY(:,maintainedFunctions)*in(:,:,idxN); - end - end - - % set / get methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - function set.folder(this, dir) - this.mDataSH.folder = dir; - this.mFilterData.folder = dir; - this.mFolder = dir; - end - function value = get.folder(this) - value = this.mFolder; - end - function set.MBytesPerSegment(this, value) - this.mDataSH.MBytesPerSegment = value; - this.mFilterData.MBytesPerSegment = value; - end - function value = get.MBytesPerSegment(this) - value = this.mDataSH.MBytesPerSegment; - end - function set.array(this, value) - check_empty(this); - if isa(value, 'itaBalloonSH') - if ~value.existSH - error('You must proceed a spherical harmonic transform of your array first!'); - end - this.SHType = value.SHType; - this.arrayNmax = min(this.arrayNmax, value.nmax); - nChannels = value.nChannels; - elseif isa(value, 'itaSphSphericalLoudspeaker'); - this.SHType = 'complex'; - nChannels = value.nApertures; - - else - error('"this.array" must be either an itaBalloonSH or an itaSphericalLoudspeaker - object!!"'); - end - this.mArray = value; - - if isempty(this.arrayChannels) - this.arrayChannels = 1:nChannels; - else - this.arrayChannels = this.arrayChannels(this.arrayChannels<=nChannels); - end - - %reset - this.arraySampling = itaCoordinates; - end - function value = get.array(this) - value = this.mArray; - end - function set.arrayChannels(this, value) - check_empty(this); - this.mArrayChannels = value; - end - function value = get.arrayChannels(this) - value = this.mArrayChannels; - end - function set.arrayNmax(this, value) - check_empty(this); - if isa(this.array, 'itaBalloonSH') - value = min(value, this.array.nmax); - end - this.mArrayNmax = value; - end - function value = get.arrayNmax(this) - value = this.mArrayNmax; - end - function set.tiltAngle(this, value) - check_empty(this); - if ~iscell(value) - value = {value}; - end - for idx = 1:length(value) - if size(value{idx},2) ~= 3 - error('input data size mismatch'); - end - end - this.mTiltAngle = value; - end - function value = get.tiltAngle(this) - value = this.mTiltAngle; - end - function set.rotationAngle(this, value) - check_empty(this); - if ~iscell(value) - value= {value}; - end - this.mRotationAngle = value; - end - function value = get.rotationAngle(this) - value = this.mRotationAngle; - end - function set.measurementDataFolder(this, value) - check_empty(this); - if ~iscell(value) - value = {value}; - end - this.mMeasurementDataFolder = value; - end - function value = get.measurementDataFolder(this) - value = this.mMeasurementDataFolder; - end - function set.freqRange(this, value) - check_empty(this); - if length(value) ~= 2 - error('input data size mismatch'); - end - this.mFreqRange = value; - this.internalFreqRange = value .* [1/sqrt(2) sqrt(2)]; - end - function value = get.freqRange(this) - value = this.mFreqRange; - end - function set.precision(this, value) - this.mDataSH.precision = value; - end - function value = get.precision(this) - value = this.mDataSH.precision; - end - - % administration - function value = read(this,file) - value = this.mDataSH.read(file); - end - function save(this) - if ~isdir(this.folder) - ita_verbose_info('Making folder for you...',1); - mkdir(this.folder) - end - - if ~isempty(this.mDataSH) - this.mDataSH.save_currentData; - end - if ~isempty(this.mFilterData) - this.mFilterData.save_currentData; - end - s = struct(this.name, itaSphSynthDirectivity(this)); %#ok - save([this.folder filesep this.name],'-struct','s',this.name); - end - - %% error messages - function check_empty(this) - if ~this.mDataSH.isempty - error('itaSphSyntDirectivity::you can not set this property, because object is not empty'); - end - end - end - methods(Hidden = true) - % this ist just to hide all the handle functions... - function varargout = addlistener(this, varargin), varargout = this.addlistener@handle(varargin); end - function varargout = eq(this, varargin), varargout = this.eq@handle(varargin); end - function varargout = findobj(this, varargin), varargout = this.findobj@handle(varargin); end - function varargout = findprop(this, varargin), varargout = this.findprop@handle(varargin); end - function varargout = ge(this, varargin), varargout = this.ge@handle(varargin); end - function varargout = gt(this, varargin), varargout = this.gt@handle(varargin); end - function varargout = le(this, varargin), varargout = this.le@handle(varargin); end - function varargout = lt(this, varargin), varargout = this.lt@handle(varargin); end - function varargout = ne(this, varargin), varargout = this.ne@handle(varargin); end - function varargout = notify(this, varargin), varargout = this.notify@handle(varargin); end - function varargout = delete(this, varargin), varargout = this.delete@handle(varargin); end - end - methods(Static, Hidden = true) - function myWaitbar(in, text) - persistent WB maxN string; - - if exist('text','var') % if there's a string, initialize - maxN = in; - string = text; - WB = waitbar(0, [string ' (initialize)']); - - elseif in < maxN - waitbar(in/maxN, WB, [string ' (proceed ' int2str(in) ' / ' int2str(maxN-1) ')']); - - else - waitbar(1, WB, [string ' (finish)']); - end - - if isempty(in) - close(WB); - end - end - function prop = propertiesSaved - prop = {'mFolder','mArrayChannels',... - 'mArrayNmax','mTiltAngle','mRotationAngle','mMeasurementDataFolder','mFreqRange',... - 'name','comment','regularization','rotationAngle_counterClockWise','encodeNmax','nmax',... - 'freqVector','nSpeakers','nBins','idxTiltRot2idxFolderFile','speaker2idxTiltRotCh'... - ,'SHType','arraySampling', 'internalFreqRange','filemask', 'outputFormat'}; - % mDataSH and mArray get an extra treatment ...(see - % constructor) - end - end -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/ita_test_itaSphSynthDirectivity.m b/applications/Numeric/SH/@itaSphSynthDirectivity/ita_test_itaSphSynthDirectivity.m deleted file mode 100644 index 08ea0e1..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/ita_test_itaSphSynthDirectivity.m +++ /dev/null @@ -1,82 +0,0 @@ -%% Short demo for itaSphSynthDirectivity class -% -% -% Das hier dient vorläufig auch als Demo für diese Klasse. Ist im Prinzip -% bisschen wir itaBalloon: Einen Haufen settings geeignet setzen, play -% drücken, warten, warten und dann ein paar Auswertungsroutinen genießen -% -% -% -%% settings -this = itaSphSynthDirectivity; -this.folder = [homeFolder '\evaluation\superDode']; -this.name = 'superDode'; -this.array = ita_read_itaBalloon([balloonHomeFolder '\Dode_Mid2_c\DODE_MID']); - -% basic settings -this.freqRange = [100 16000]; -this.arrayNmax = 30; % maximale Ordnung, bis zu der das synthetisch erweiterete Array berechnet wird -this.arrayChannels = 1:12; % die Channels des itaBalloons, die in der Messung angewendet wurden -this.nmax = 30; % maximale Ordnung, bis zu der alles andere Berechnet wird -this.precision = 'single'; - -% important stuff: -this.measurementDataFolder = ... % Pade der Messdaten - {[homeFolder filesep measurementFolder{1} '\data_p'], ... - [homeFolder filesep measurementFolder{2} '\data_p'], ... - [homeFolder filesep measurementFolder{3} '\data_p']}; -this.tiltAngle = ... % zugeordnete Euler - Kippwinkel - {[0 180 0; 38.5+80 16.2 0]* pi/180, ... - [0 180 0; 38.5+0 16.2 0] * pi/180, ... - [0 180 0; 38.5+40 16.2 0]* pi/180}; - -this.filemask = 'dode'; % filemask -this.rotationAngle_counterClockWise = false; % angles by itaItalian : dreht im Urzeigersinn !! -this.getPositions('nPos',20); % liest this.rotationAngle aus Messdaten, setzt rooting channel2 -save(this); - - -%% --- Der Abschnitt dauert bisschen (trotz intensiven Gebrauchs des profilers...)!! -% engster Flaschenhals : fft in 'SHfilter2SHrir' -% -% Für diese Funktionen gibt es jeweils aufschlussreiche Dokumentation -% -disp('makin awesome enlarged array'); -this.makeSynthArray; % die SH-Koeffizienten des synthetischen Arrays werden berechnet (Die große D-Matrix) -disp('makin awesome synthesis filter'); -this.makeSHfilter; % Invertierung der D-Matrix, regularisiert. + Umsortieren der Vorzugsrichtung: - % Bislang waren die Daten nach Frequenzen - % unterteilt, jetzt nach Einzellautsprechern -disp('makin awesome synthesized room impulse responses'); -this.SHfilter2SHrir; % Die Filter werden mit da Messung gefaltet - -% Quelle synthetisieren -target = ita_read_itaBalloon([balloonHomeFolder '\CUBEd\CUBE']); -ao = this.convolve_itaBalloon_and_SH_RIR(target); - -%% --- Auswertung ----------------- - -% coeffizienten des erweiterten Arrays: -coef = this.freq2coefSH_synthArray(2000); % -> see doc - -% 'mein' graph -RMS = this.evaluate_synthesisError; % -> see doc - -% filter anschauen (index von zu synthetisierender sphericsal harmonic 2 -% filter) -ao = this.idxSH2filter(1); - - - -%% Vergleich mit Messung; - -target = ita_read_itaBalloon([balloonHomeFolder '\CUBEd\CUBE']); -orgFiles = [homeFolder filesep measurementFolder{7} '\data_p\cube']; -org = itaAudio(numel(dir([orgFiles '*'])),1); -rot = {}; -for idx = 1:length(org) - org(idx)= ita_read([orgFiles int2str(idx) '.ita']); - rot = [rot, {[0 0 2*pi - org(idx).channelCoordinates.phi(1)]}]; %#ok %CUBE's rotation angles (euler format) -end - -synth = this.convolve_itaBalloon_and_SH_RIR(target, 'rotate',rot); % synth: an array of itaAudios: length(synth) == length(rot) \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/makeArraySampling.m b/applications/Numeric/SH/@itaSphSynthDirectivity/makeArraySampling.m deleted file mode 100644 index e7dfa48..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/makeArraySampling.m +++ /dev/null @@ -1,33 +0,0 @@ -function makeArraySampling(this, varargin) -% This function trys to get the center-points of the apertures of the -% synthSpeaker. It works on the assumption, that each chassis' pressure has a -% distinctive major lobe in the center of the chassis -% at the given frequency 'freq' - -if isa(varargin{1}, 'itaCoordinates') -elseif isnumeric(varargin{1}) - %freq choose a high frequency - sampling = ita_sph_sampling_gaussian(80,'noSH',true); - if strcmpi(this.SHType, 'complex') - sampling = itaSamplingSph(sampling); - else - sampling = itaSamplingSphReal(sampling); - end - sampling.nmax = this.arrayNmax; - - % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - coef = this.freq2coefSH_synthSpeaker(sArgs.freq, 'nmax', this.speaker_nmax,'normalized'); - this.speakerSampling = itaCoordinates(this.nApertures); - - for idxC = 1:this.nApertures - [dummy idxMax] = max(abs(SH*coef(:,idxC))); %#ok - this.speakerSampling.sph(idxC,:) = sampling.sph(idxMax,:); - end - - this.speakerSampling_basefunctions = ita_sph_realvalued_basefunctions(this.speakerSampling, this.encode_nmax); - save(this); -else - error('I don not understand your input'); -end - -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/makeSHfilter.m b/applications/Numeric/SH/@itaSphSynthDirectivity/makeSHfilter.m deleted file mode 100644 index c055224..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/makeSHfilter.m +++ /dev/null @@ -1,83 +0,0 @@ -function makeSHfilter(this,varargin) -% calculates filter for the synthesis of the single spherical harmonics and -% convolves it with the measured data -% -% input: -% - encoded : false/(true) encoded controling of the chassis -% - muteChannels : mute single speaker -% -% output: -% The RIRs and the filters will also be saved in "this.folder" -% -% see also: itaSyntheticDir, itaSyntheticDir.getPositions, -% itaSyntheticDir.makeSynthSpeaker itaSyntheticDir.convolve_itaBalloon_and_sphRIR - -% Author: Martin Kunkemoeller, 13.12.2010 - -% initialize %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -sArgs = struct('encoded', false, 'muteChannels', []); -if nargin > 1 - sArgs = ita_parse_arguments(sArgs, varargin); -end - -if isnan(this.nmax), error('You must set a maximum order for this synthesis'); end - -% maximum order (linear) -nmax_l = (this.nmax+1)^2; - -% the big filter matrix (tmp): format like itaAudio.freqData - -this.myWaitbar(this.nBins+1, 'makeSHfilter : calculate filter'); - -filterData_tmp = itaFatSplitMatrix([this.nBins, this.nSpeakers, nmax_l], 1, this.precision); -filterData_tmp.folder = this.folder; -filterData_tmp.dataFolderName = 'filterData_tmp'; -filterData_tmp.MBytesPerSegment = this.MBytesPerSegment; - - - -for idxF = 1:this.nBins - this.myWaitbar(idxF); - - D = cast(this.freq2coefSH_synthArray(this.freqVector(idxF), 'nmax', this.nmax), this.precision); - D(:,sArgs.muteChannels) = 0; - if sArgs.encoded - D = this.encodeCoefSH(D); - end - - % matrix invertation, Tikhonov regularization - invD = (D'*D + this.regularization*eye(size(D,2)))\D'; - - if sArgs.encoded - data = permute(this.decodeCoefSH(invD, 1:(this.encode_nmax+1)^2), [3 1 2]); - else - data = permute(invD, [3 1 2]); - end - filterData_tmp.set_data(idxF, 1:this.nSpeakers, 1:nmax_l, data); -end - -this.myWaitbar([]); - -%% copy to other split dimension (-> speaker) -this.mFilterData = itaFatSplitMatrix([this.nBins, this.nSpeakers, nmax_l], 2, this.precision); -this.mFilterData.dataFolderName = 'filterData'; -this.mFilterData.MBytesPerSegment = this.MBytesPerSegment; -this.mFilterData.folder = this.folder; - -maxBlockSize_MB = max(400, this.MBytesPerSegment); % if there are problems with "out of memory", decrease this number!! - -nBlock = round(maxBlockSize_MB*2^20 / this.nBins / nmax_l / 2); - -this.myWaitbar(length(1:nBlock:this.nBins)+1, 'makeSHfilter : sort your data') -for idxF = 1:nBlock:this.nSpeakers - this.myWaitbar(idxF); - - indicees = idxF : idxF+nBlock-1; - indicees = indicees(indicees <= this.nSpeakers); - this.mFilterData.set_data(1:this.nBins, indicees, 1:nmax_l, ... - filterData_tmp.get_data(1:this.nBins, indicees, 1:nmax_l)); -end - -remove(filterData_tmp); -save(this); -this.myWaitbar([]); diff --git a/applications/Numeric/SH/@itaSphSynthDirectivity/makeSynthArray.m b/applications/Numeric/SH/@itaSphSynthDirectivity/makeSynthArray.m deleted file mode 100644 index c433e15..0000000 --- a/applications/Numeric/SH/@itaSphSynthDirectivity/makeSynthArray.m +++ /dev/null @@ -1,119 +0,0 @@ -function makeSynthArray(this,freq) -% After you've done all the important settings, proceed this function and -% the spherical harmonic coefficients of your array's speakers will be -% calculated. -% -% input: freq (optional, if your array is an itaBalloonSH) -% frequency bins for which the synthetic array will be calculated -% default : this.array.freqVector in the frequency range -% this.freqRange -% -% -% see also: tutorial, makeSHfilter - -if isempty(this.folder) || isempty(this.array) || isempty(this.arrayNmax) || isempty(this.nmax)... - || isempty(this.arrayChannels) || isempty(this.freqRange) && isa(this.array,'itaBalloon') - error('first you must set stuff like "folder", "array", "arrayNmax", "freqRange" and "arrayChannels"'); -end - -if length(this.tiltAngle) ~= length(this.rotationAngle) || ... - (~isempty(this.measurementDataFolder) && length(this.tiltAngle) ~= length(this.measurementDataFolder)) - error('size of "tiltAngle", "rotationAngle" and "measurementDataFolder" must be equal!!'); -end - -if this.mArrayNmax < this.nmax - error('"this.nmax" must be smaller than "this.mArrayNmax"'); -end - -%% initialize -if isa(this.array,'itaBalloonSH') - if ~exist('freq','var') - this.freqVector = this.array.freqVector; - this.freqVector = this.freqVector(this.freqVector >= this.internalFreqRange(1)); - this.freqVector = this.freqVector(this.freqVector <= this.internalFreqRange(2)); - this.outputFormat = 'itaAudio'; - else - this.freqVector = freq; - this.outputFormat = 'itaResult'; - end - -elseif isa(this.array,'itaSphericalLoudspeaker') - if ~exist('freq','var') - error('Hep, give me a "frequencyVector" !!') - end - this.freqVector = freq; - this.freqRange = [min(freq) max(freq)]; - this.outputFormat = 'itaResult'; -end -this.nBins = length(this.freqVector); - -this.myWaitbar(this.nBins+1, 'makeSynthArray'); - -nChannels = length(this.arrayChannels); -nTilt = length(this.tiltAngle); - -%% set rooting: channel of synthetic array -> array orientation, array channel ... -this.speaker2idxTiltRotCh = zeros(0,3); -for idxT = 1:nTilt - newPart = zeros(length(this.rotationAngle{idxT})*nChannels, 3); - for idxR = 1:length(this.rotationAngle{idxT}) - newPart((idxR-1)*nChannels + (1:nChannels), :) = ... - [ones(nChannels, 1)*[idxT idxR] (1:nChannels).']; - end - this.speaker2idxTiltRotCh = [this.speaker2idxTiltRotCh; newPart]; -end -this.nSpeakers = size(this.speaker2idxTiltRotCh,1); - - -%% matrices to tilt the array -tiltMatrix = cell(nTilt,1); -for idxT = 1:nTilt - if size(this.tiltAngle{idxT},2) ~= 3, error('All tilt angles must have size [x 3] !'); end - if strcmpi(this.SHType, 'complex') - tiltMatrix{idxT} = ita_sph_rotate_complex_valued_spherical_harmonics(this.mArrayNmax, this.tiltAngle{idxT}); - elseif strcmpi(this.SHType, 'real') - tiltMatrix{idxT} = ita_sph_rotate_real_valued_spherical_harmonics(this.mArrayNmax, this.tiltAngle{idxT}); - else - error(' '); - end -end - -%% Synthesise the super array -this.mDataSH.dimension = [(this.arrayNmax+1)^2, this.nSpeakers, this.nBins]; -this.mDataSH.splitDimension = 3; -this.mDataSH.dataFolderName = 'dataSH'; -for idxF = 1:length(this.freqVector) - this.myWaitbar(idxF); - - if isa(this.array,'itaBalloonSH') - %read spherical coefs (from a measured array) - singleArray = this.array.freq2coefSH(this.freqVector(idxF), 'nmax',this.arrayNmax,... - 'channels',this.arrayChannels); - - elseif isa(this.array,'itaSphericalLoudspeaker') - pressureFactor = this.array.pressureFactor(2*pi/344*this.freqVector(idxF)); - if size(pressureFactor,1) == 1, pressureFactor = pressureFactor.'; end - singleArray = ... - this.array.apertureSH(1:(this.arrayNmax+1)^2,this.arrayChannels) .*... - pressureFactor(1:(this.mArrayNmax+1)^2,:); - end - - for idxA = 1:nChannels:this.nSpeakers - idT = this.speaker2idxTiltRotCh(idxA,1); - idR = this.speaker2idxTiltRotCh(idxA,2); - - if strcmpi(this.SHType, 'complex') - this.mDataSH.set_data(1:(this.arrayNmax+1)^2, idxA-1+(1:nChannels), idxF, ... - ita_sph_rotate_complex_valued_spherical_harmonics(tiltMatrix{idT}*singleArray, [this.rotationAngle{idT}(idR) 0 0])); - else - this.mDataSH.set_data(1:(this.arrayNmax+1)^2, idxA-1+(1:nChannels), idxF, ... - ita_sph_rotate_real_valued_spherical_harmonics(tiltMatrix{idT}*singleArray, [this.rotationAngle{idT}(idR) 0 0])); - end - end -end - -%conclude -this.myWaitbar(this.nBins+1); -save(this); -this.myWaitbar([]); -end diff --git a/applications/Numeric/SH/@itaSyntheticDir/convolve_filter_and_measurement.m b/applications/Numeric/SH/@itaSyntheticDir/convolve_filter_and_measurement.m deleted file mode 100644 index c51339b..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/convolve_filter_and_measurement.m +++ /dev/null @@ -1,83 +0,0 @@ -function out = convolve_filter_and_measurement(this, filter, filemask) - -apertures = filter.channelUserData; -if isempty(apertures) - error('I got no channelUserData, now I have a problem'); -end - -myWaitbar(filter.nChannels+1); - -for idxF = 1:length(this.measurementDataFolder) - if ~numel(dir([this.measurementDataFolder{idxF} filesep filemask '*'])) - error('you filemask does not seem to work'); - end -end - -for idxC = 1:filter.nChannels - myWaitbar(idxC); - - TRC = this.aperture2idxTiltRotCh(apertures{idxC},:); %tilt rotation angle - FF = this.idxTiltRot2idxFolderFile{TRC(1),TRC(2)}; %folder file - - data = ita_read([this.measurementDataFolder{FF(1)} filesep filemask int2str(FF(2)) '.ita']); - data = data.ch(TRC(3)); - - if idxC == 1 %only the first time - if data.nSamples < filter.nSamples - nSamples_original = data.nSamples; - else - nSamples_original = 0; - filter = ita_time_window(filter, round(filter.nSamples/2+[-0.005*filter.samplingRate 0]),'samples','symmetric'); - filter = ita_extend_dat(filter, data.nSamples,'symmetric'); - filter = filter'; - end - - outData = zeros(data.nBins,1); - end - if nSamples_original, %only if filter is longer than the data - data = ita_extend_dat(data, filter.nSamples); - end - - outData = outData + data.freqData .* filter.ch(idxC).freqData; -end - -% conclude -myWaitbar(filter.nChannels+1); - -out = data; -out.freqData = outData; - -if nSamples_original - out = ita_time_crop(out,[1 nSamples_original]); -end - -out.channelNames = {' '}; -out.channelCoordinates.cart = nan(1,3); -% out = ita_time_window(out, out.nSamples + [-300 0],'samples'); - -if ~isempty(filter.userData) -out = ita_time_shift(out, filter.userData{1}.timeShift, 'samples'); -end -% - -myWaitbar([]); -end - -function myWaitbar(in) -persistent WB maxN; - -if ~exist('maxN','var') || isempty(maxN)... - || exist('WB','var') && ~ishandle(WB); - maxN = in; - WB = waitbar(0, 'convolve (initialize)'); - -elseif in < maxN - waitbar(in/maxN, WB, ['convolve (proceed channel ' int2str(in) ' / ' int2str(maxN-1) ')']); -else - waitbar(1, WB, ['convolve (finish)']); -end - -if isempty(in) - close(WB); -end -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/convolve_itaBalloon_and_sphRIR.m b/applications/Numeric/SH/@itaSyntheticDir/convolve_itaBalloon_and_sphRIR.m deleted file mode 100644 index 8ce3e71..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/convolve_itaBalloon_and_sphRIR.m +++ /dev/null @@ -1,63 +0,0 @@ -function out = convolve_itaBalloon_and_sphRIR(this, balloon, filemask, varargin) - -% options: -% 'channels' you can choose one ore multiple channels (directivity of a -% multichannel itaBalloon will be sumed up). -% 'mpb_filter' result will be band widhth filtered by ita_mpb_filter -% 'rotate' here you can give a set of euler rotation angles to rotate the input balloon. -% The output will be an array of filters- one for each -% position -% 'rotate', {[orientation 1], [orientation 2], ... } -sArgs = struct('channels',1:balloon.nChannels, 'mpb_filter',[], 'rotate',zeros(1,3)); -if nargin > 3 - sArgs = ita_parse_arguments(sArgs, varargin); -end -if ~iscell(sArgs.rotate), sArgs.rotate = {sArgs.rotate}; end -for idxR = 1:length(sArgs.rotate) - if size(sArgs.rotate{idxR},2)~=3, error('size(rotatate,2) != 3 (euler angle)'); end -end - - -RIR = ita_read([this.folder filesep 'sphRIR' filesep filemask 'sphRIR.ita']); -ao = balloon.idxCoefSH2itaAudio(1:RIR.nChannels,'channels',sArgs.channels,'sum_channels', true); -ao.dataType = 'single'; - -% kill silent sph -maxValue = max(max(abs(ao.freqData))); -ao.freqData(:, max(abs(ao.freqData),[],1) < maxValue*1e-3) = 0; - -if balloon.samplingRate ~= this.speaker.samplingRate - error('help me, I can not handle different samplingRates. maybe you could code that'); -end - -out = itaAudio(length(sArgs.rotate),1); -for idxR = 1:size(sArgs.rotate,1) - out(idxR).signalType = 'energy'; - out(idxR).dataType = 'single'; - ao2 = ao; - if sum(sum(abs(sArgs.rotate{idxR}))) - ao2.freqData = ita_sph_rotate_realvalued_basefunc(ao.freqData.',sArgs.rotate{idxR}).'; - end - % adapt data - if ao2.nSamples < RIR.nSamples - ao2 = ita_time_window(ao2, round(ao2.nSamples/2+[-0.005*ao2.samplingRate 0]),'samples','symmetric'); - ao2 = ita_extend_dat(ao2, RIR.nSamples,'symmetric'); - else - ao2 = ita_extract_dat(ao2, RIR.nSamples,'symmetric'); - ao2 = ita_time_window(ao2, round(ao2.nSamples/2+[-0.005*ao2.samplingRate 0]),'samples','symmetric'); - end - - %convolve and add - out(idxR) = sum(ita_multiply_spk(ao2,RIR)); - %adapt latency samples - if balloon.latencySamples ~= this.speaker.latencySamples - out(idxR) = ita_time_shift(out(idxR), balloon.latencySamples - this.speaker.latencySamples, 'samples'); - end - - - out(idxR).channelNames{1} = ''; - out(idxR).comment = ['synthesized RIR of ' balloon.name ' (mic: ' filemask ')']; - out(idxR).history = {' '}; - - -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/correlation_of_ideal_and_synthesised_directivity.m b/applications/Numeric/SH/@itaSyntheticDir/correlation_of_ideal_and_synthesised_directivity.m deleted file mode 100644 index 0bbbcc3..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/correlation_of_ideal_and_synthesised_directivity.m +++ /dev/null @@ -1,62 +0,0 @@ -function out = correlation_of_ideal_and_synthesised_directivity(this,in,varargin) - -sArgs = struct('channels',[],'freq',this.freqVector,'nmax',this.nmax); - -if nargin > 2 - sArgs = ita_parse_arguments(sArgs, varargin); -end - -nCoef = (sArgs.nmax+1)^2; -freq = sArgs.freq; freq = sort(freq); -bla_e = 'What do you want?'; - -out = itaResult; -out.freqVector = freq; -out.freqData = zeros(length(freq),1); - -if isa(in,'itaBalloon') - v_cf = false; %gibbet nich, musste laden... -elseif length(in) == 1 - if mod(in,1), error(bla_e); end - if in > nCoef, error(bla_e); end - v_cf = zeros(1,nCoef); - v_cf(in) = 1; -elseif length(in) == 2; - in = ita_sph_degreeorder2linear(in(1),in(2)); - if mod(in,1), error(bla_e); end - if in > nCoef, error(bla_e); end - v_cf = zeros(1,nCoef); - v_cf(in) = 1; -elseif length(in) == nCoef; - if size(in,2) ~= nCoef - v_cf = in.'; - else - v_cf = in; - end - if size(v_cf > 1) - error(bla_e); - end -else - error(bla_e); -end - -idc = 1:(sArgs.nmax+1)^2; -for idxF = 1:length(freq) - if ~v_cf - coef = (in.freq2coefSH(freq(idxF),'nmax',sArgs.nmax)).'; - else - coef = v_cf; - end - freq2block = this.idxFreq2block(this.freq2idxFreq(freq(idxF))); - if ~exist('actBlock','var') || freq2block(1) ~= actBlock - actBlock = freq2block(1); - synthMatrix = this.read([this.folder filesep 'synthData' filesep 'freqDataSY_' int2str(actBlock)]); - synthSpeaker = this.read([this.folder filesep 'synthSuperSpeaker' filesep 'freqDataSH_' int2str(actBlock)]); - end - res_cf = coef * squeeze(synthMatrix(idc,:,freq2block(2))) * squeeze(synthSpeaker(:,idc,freq2block(2))); - out.freqData(idxF) = sum(abs(res_cf.*conj(coef))) / sum(abs(coef).^2); -end -%% -plotOut = out; -plotOut.freqData = sqrt(plotOut.freqData); -plotOut.plot_spk('ylim',[-3 0.1]); \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/freqData2synthesisRule.m b/applications/Numeric/SH/@itaSyntheticDir/freqData2synthesisRule.m deleted file mode 100644 index c17c294..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/freqData2synthesisRule.m +++ /dev/null @@ -1,272 +0,0 @@ -function [out maintainedChannels] = freqData2synthesisRule(this, inputData, idxFreqMinMax, varargin) - -% inputData : like itaAudio or itaResult... -% idxFreqMinMax : minimal and maximal frequency index of the given input -% data. The index refers to "this.freqVector", -% not to "this.speaker.freqVector" !! - -sArgs = struct('muteChannels',[], 'nmax', this.nmax, ... - 'optimize_freq_range',[], 'freqRange', this.freqRange,'encoded',false); -if nargin > 3 - sArgs = ita_parse_arguments(sArgs, varargin); -end - -%init, check input -if size(inputData,2) ~=(sArgs.nmax+1)^2 - error(['size(inputData,2) must be equal to the number of basefunctions : (nmax+1)^2']); -end - -if size(inputData,1) == 1 - freqDependendInput = false; - idxFreqMinMax = this.freq2idxFreq(sArgs.freqRange .*2.^[-0.5 0.5]); - -elseif size(inputData,1) == length(idxFreqMinMax(1):idxFreqMinMax(2)) - freqDependendInput = true; -else - error(['Dimension of input data mismatch']); -end - -idFreqOffSet = length(this.speaker.freqVector(this.speaker.freqVector < this.freqVector(1))); - - -%kill silent input data -maxValue = max(max(abs(inputData))); -inputData(:, mean(abs(inputData),1) < maxValue*1e-6) = 0; - -inputData = inputData.'; % switch dimensionality [coef frequency] %%% - -% kill redundant apertures %%%% -if this.target_tolerance - - % estimate frequency bins for optimization - nOptimisationFreq = 10; - if isempty(sArgs.optimize_freq_range) - %default optimization range: last half octave of frequency range - idMin = this.freq2idxFreq(this.freqVector(idxFreqMinMax(2))/sqrt(2)); - idMax = idxFreqMinMax(2); - - else - idMin = max(this.freq2idxFreq(sArgs.optimize_freq_range(1)), idxFreqMinMax(1)); - idMax = min(this.freq2idxFreq(sArgs.optimize_freq_range(2)), idxFreqMinMax(2)); - end - idxOptFreq = idMin : round((idMax-idMin)/(nOptimisationFreq-1)) : idMax; - - % get data for optimization - firstBlock = this.freq2coefSH_synthSpeaker(this.freqVector(idxOptFreq), 'nmax',sArgs.nmax, 'normalized'); - firstBlock(:,sArgs.muteChannels,:) = 0; - if sArgs.encoded - firstBlock = this.encodeCoefSH(firstBlock); - end - - % kill - if ~freqDependendInput, idxOptFreq = 1; end - maintainedChannels = killApertures(this, firstBlock, inputData(:,idxOptFreq)); - -else - if sArgs.encoded - maintainedChannels = 1:(this.encode_nmax+1)^2; - else - maintainedChannels = 1:this.nApertures; - end -end - -% initialize outputData %% -% can refer to both, an not encoded or encoded synthSpeaker -outputData = zeros(length(this.speaker.freqVector), length(maintainedChannels)); - -% proceed all data %%%%% -for idxB = 1:this.nDataBlock - %indices for synthSpeaker, input and output - actIdFreq = this.block2idxFreq(idxB); - actIdFreq = actIdFreq(actIdFreq >= idxFreqMinMax(1) & actIdFreq <= idxFreqMinMax(2)); - actIdInput = actIdFreq - idxFreqMinMax(1) + 1; - actIdOutput = actIdFreq + idFreqOffSet; - - if ~isempty(actIdFreq) - id_blockFreq = this.idxFreq2block(actIdFreq); - id_blockFreq = id_blockFreq(:,2); - - block = this.read([this.folder filesep 'synthSuperSpeaker' filesep 'freqDataSH_' int2str(idxB)]); - block = block(1:(sArgs.nmax+1)^2,:,id_blockFreq); - block(:,sArgs.muteChannels,:) = 0; - if sArgs.encoded - block = this.encodeCoefSH(block); - end - block = block(:,maintainedChannels,:); - - outputData(actIdOutput,:) = ... - synthFilter(this, block, inputData(:,actIdInput), this.nIterations); - end -end - -% if speaker was encoded, now decode :-) -if sArgs.encoded - outputData = (this.decodeCoefSH(outputData.', maintainedChannels)).'; - % from now on, "maintainedChannels" refers again to real and not to encoded channels - maintainedChannels = 1:this.nApertures; -end - -% deEqualize synthSpeaker -if ~isempty(this.speaker.sensitivity) - realChannels = this.aperture2idxTiltRotCh(maintainedChannels,3); - outputData = bsxfun(@rdivide, outputData, this.speaker.sensitivity.value(realChannels)); -end - -% if ~isempty(sArgs.response) %vielleicht mal wo anders unterbringen... -% outputData(idFreqOffSet+(1:length(this.freqVector)),:) = ... -% bsxfun(@times, outputData(idxOffset+(1:length(this.freqVector)),:), ... -% sArgs.response.freqData(sArgs.response.freq2index(this.freqVector))); -% end - -out = itaAudio; -out.samplingRate = this.speaker.samplingRate; -out.signalType = 'energy'; -out.dataType = 'single'; -out.freqData = outputData; -for idxC = 1:out.nChannels - % set channelUserData so itaSyntheticDir.convolve will find the proper RIR - out.channelUserData{idxC} = maintainedChannels(idxC); - out.channelNames{idxC} = ['aperture ' int2str(maintainedChannels(idxC))]; -end -end - -%% -function out = synthFilter(this, speaker, inputData, nIterations) -out = zeros(size(speaker,3), size(speaker,2)); % nFreq, nChannels - -input = inputData(:,1); - -% solve the invertation problem for every frequency -for idxF = 1:min(size(speaker,3),size(inputData,2)) - - %choose proper input data - if size(inputData,2) > 1 - input = inputData(:,idxF); - end - - % invert the speaker (tikhonov) - A = squeeze(speaker(:,:,idxF)); - invSpeaker = pinv(A'*A + this.regularization*eye(size(A,2)), 1e-8)* A'; - - % if condition was too bad... (is this still necessary ???) - if ~isempty(find(isnan(invSpeaker),1)) - disp(['sorry, had to kill a frequency due to a miserable condition']) - invSpeaker = 0; - end - - - if ~nIterations - out(idxF,:) = (invSpeaker * input).'; - else - % if the invertation was ambiguous, get the solution which is close - % to only half of the speakers switched on. - dum = zeros(size(speaker,2),1); - thresh = 1e-6; - - vector_1 = invSpeaker*input; - matrix_2 = eye(size(speaker,2)) - invSpeaker*speaker(:,:,idxF); - - for idxI = 1:this.nIterations - dum = vector_1 + matrix_2*dum; - meanAmplitude = mean(abs(dum).^2,2); - while(1) - if length(meanAmplitude/max(meanAmplitude) < thresh) < 0.5*size(dum,2) - thresh = thresh*increase_threshold(1); - else - dum(meanAmplitude/max(meanAmplitude) < thresh,:) = 0; - break; - end - end - end - out(idxF,:) = (vector_1 + matrix_2*dum).'; - end -end -end - -%% -function switchedOn = killApertures(this, speaker, inputData) -%% -switchedOn = 1:size(speaker,2); %indicees of the apertures that are not muted -nFreq = size(speaker,3); - -% theoretically achievable result (no aperture muted) -actFilter = synthFilter(this, speaker, inputData, 0).'; -idealResult = zeros(nFreq,1); -for idxF = 1:nFreq - idealResult(idxF) = inner_product(speaker(:,:,idxF)*actFilter(:,idxF), inputData(:,idxF)); -end - -%% -could_kill = [1 1]; -method = 0; - -%iterative killing redundant apertures -while(1) - - %kill under two assumptions - method = mod(method,2)+1; - could_kill(2) = could_kill(1); %short fifo-buffer - switch method - case 1 % method 1: kill silent speaker - meanP = mean(abs(actFilter).^2, 2); - thres = 10^(-60/10); %start at -60 dB - maybeSwitchedOn = switchedOn(meanP/max(meanP) > thres); - while length(maybeSwitchedOn) > 0.8* length(switchedOn) - thres = thres*10^0.5; - maybeSwitchedOn = switchedOn(meanP/max(meanP) > thres); - end - - case 2 % method 2: kill speaker which are similar to the loudest one - if length(switchedOn) > 1 - [dum idxMax] = max(sum(abs(actFilter).^2, 2)); %#ok - correlation = zeros(1,length(switchedOn)); - for idxA = 1:length(switchedOn) - correlation(idxA) = inner_product(squeeze(speaker(:, switchedOn(idxA), :)), squeeze(speaker(:,switchedOn(idxMax),:))); - end - [dum idxMaintain] = sort(correlation, 'ascend'); %#ok - idxMaintain = idxMaintain(idxMaintain ~= idxMax); %don't kill the loudest one itself :-) - idxMaintain = [idxMaintain(1:round(0.8*length(idxMaintain))) idxMax]; - maybeSwitchedOn = switchedOn(sort(idxMaintain)); - else - maybeSwitchedOn = []; - end - end - - %check if the result is still better than the given tolerance, if so - %accept the elemination - if ~isempty(maybeSwitchedOn) - maybeFilter = synthFilter(this, speaker(:, maybeSwitchedOn, :), inputData, 0).'; - maybeResult = zeros(nFreq,1); - for idxF = 1:nFreq - maybeResult(idxF) = inner_product(speaker(:,maybeSwitchedOn,idxF)*maybeFilter(:,idxF), inputData(:,idxF)); - end - - % 90% of the synthesized frequencies must be better than given - % tolerance - if sum(maybeResult/mean(idealResult) > 10^(this.target_tolerance/10))/length(idealResult) > 0.9 - switchedOn = maybeSwitchedOn; - actFilter = maybeFilter; - could_kill(1) = 1; - - disp(['method ' int2str(method) ' : number of apertures reduced to ' int2str(length(switchedOn))]); - if length(switchedOn) < 6 - disp([' speaker : ' int2str(switchedOn)]); - end - else - could_kill(1) = 0; - end - else - could_kill(1) = 0; - end - - if ~sum(could_kill) % test case || length(switchedOn) < 80 - break; - end -end -end - -function coef = inner_product(A,B) - %returns the mean normalized inner product of the columns of A and B - coef = mean(abs(sum(conj(A) .* B, 1))./sqrt(sum(abs(A).^2, 1).*sum(abs(B).^2, 1))); -end - diff --git a/applications/Numeric/SH/@itaSyntheticDir/getPositions.m b/applications/Numeric/SH/@itaSyntheticDir/getPositions.m deleted file mode 100644 index c5fc92d..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/getPositions.m +++ /dev/null @@ -1,77 +0,0 @@ -function this = getPositions(this, varargin) -% uses 'ita_roomacoustics_correlation_coefficient_longtime to select good -% speaker positions out of the data in 'this.measurementDataFolder' -% -% settings: -% 'nPos' : number of rotations to build a synthSuperSpeaker -% 'filemask', 'sd_' : filemasking the data of your reference speaker -% -% I promise, in january there will be a documentaion ! - -sArgs = struct('corcoef',[], 'nPos',[], 'filemask', 'sd_'); - -%% init -this.stillempty; % check -if nargin > 1 - sArgs = ita_parse_arguments(sArgs,varargin); -end - -if isempty(this.measurementDataFolder) - error('give me some "measurementDataFolder"'); -end - -idxPos2idxFile = zeros(0,2); -for idxF = 1:length(this.measurementDataFolder) - nFiles = numel(dir([this.measurementDataFolder{idxF} filesep sArgs.filemask '*.ita'])); - if ~nFiles, error(['can not find no file "' this.measurementDataFolder{idxF} filesep sArgs.filemask '1.ita"']); end - idxPos2idxFile = [idxPos2idxFile; ones(nFiles,1)*idxF (1:nFiles).']; %#ok -end - -% %% calculate correlation coefficient -% if isempty(sArgs.corcoef) || ~isa(sArgs.corcoef, 'itaResult') || sArgs.corcoef.nSamples ~= nAllFiles -% cc_filemask = cell(length(this.measurementDataFolder),1); -% for idxF = 1:length(this.measurementDataFolder) -% cc_filemask{idxF} = [this.measurementDataFolder{idxF} filesep sArgs.filemask]; -% end -% -% sArgs.corcoef = ita_roomacoustics_correlation_coefficient_longtime('filemask', cc_filemask, ... -% 'refPos', 'last_1', 'nRef', 5, 'freqRange', this.freqRange_intern); -% end -% -% %% get positions -% [dummy idxPositions] = sort(sArgs.corcoef.timeData,'descend'); %#ok -idxPositions = 174:188; -if ~isempty(sArgs.nPos), - nPos = min(sArgs.nPos, length(idxPositions)); - idxPositions = idxPositions(1:nPos); -end -idxApplied2idxFile = idxPos2idxFile(idxPositions,:); - -% (*) Im Moment gilt noch: idxTilt = idxFolder. -% Später sollte man auch idxTilt mal aus den Messdaten auslesen (?) -nTilt = length(this.measurementDataFolder); -nRotMax = 0; -for idxT = 1:nTilt - nRotMax = max(nRotMax, length(idxApplied2idxFile(idxApplied2idxFile(:,1) == idxT, 2))); -end -this.idxTiltRot2idxFolderFile = cell(nTilt, nRotMax); -this.angle_rot = cell(nTilt,1); - -%get rotation angles from channel data.coordinates -for idxP = 1:length(idxPositions) - idxFolder = idxPos2idxFile(idxPositions(idxP),1); - idxFile = idxPos2idxFile(idxPositions(idxP),2); - data = ita_read([this.measurementDataFolder{idxFolder} filesep sArgs.filemask int2str(idxFile) '.ita']); - - if this.measurementCoordinates_are_itaItalian - phi = mod(10*pi - data(1).channelCoordinates.phi(1), 2*pi); - else - phi = mod(data(1).channelCoordinates.phi(1), 2*pi); - end - - % (*) - idxTilt = idxFolder; - this.angle_rot{idxTilt} = [this.angle_rot{idxTilt} phi]; - this.idxTiltRot2idxFolderFile{idxTilt, length(this.angle_rot{idxTilt})} = [idxFolder idxFile]; -end - diff --git a/applications/Numeric/SH/@itaSyntheticDir/itaBalloon2synthFilter.m b/applications/Numeric/SH/@itaSyntheticDir/itaBalloon2synthFilter.m deleted file mode 100644 index 5d7e9f8..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/itaBalloon2synthFilter.m +++ /dev/null @@ -1,86 +0,0 @@ -function out = itaBalloon2synthFilter(this,balloon,varargin) -% function out = itaBalloon2synthFilter(this,balloon,varargin) -% -% returns a filter that synthesises a directivity, specified by an -% itaBalloon object 'balloon' -% after that, just use "itaSyntheticDir.convolve_filter_and_measurement" to -% get wonderful results -% -% options: -% 'channels' you can choose one ore multiple channels (directivity of a -% multichannel itaBalloon wil be sumed up). -% 'freqRange', frequency range of synthesis (will be extended internally -% to have space for some filters) -% 'mpb_filter' result will be band widhth filtered by ita_mpb_filter -% 'optimize_freq_range' choose a not to big range for optimization steps -% (better choose some high frequencies) -% 'encoded' use spherical encoding of the speaker array -% 'nmax' maximum order of synthesis -% -% 'rotate' here you can give a set of euler rotation angles to rotate the input balloon. -% The output will be an array of filters- one for each -% position -% 'rotate', {[orientation 1], [orientation 2], ... } -sArgs = struct('channels',1:balloon.nChannels, 'nmax', this.nmax, 'optimize_freq_range', [],... - 'freqRange', this.freqRange, 'encoded', false, 'rotate',[]); - -if ~isa(balloon,'itaBalloon') - error('Please give me an itaBalloon!'); -end - -if nargin > 2 - sArgs = ita_parse_arguments(sArgs,varargin); -end - -% adapt balloon's fftdegree -if balloon.fftDegree ~= this.speaker.fftDegree - convertBalloon = true; - if exist([balloon.balloonFolder '_d' filesep balloon.name '.mat'],'file') - son = balloon.read([balloon.balloonFolder '_d' filesep balloon.name]); - if son.fftDegree == this.speaker.fftDegree; - convertBalloon = false; - balloon = son; - end - end - - if convertBalloon - balloon = balloon.convert_fftDegree(this.speaker.fftDegree, [balloon.balloonFolder '_d']); - end -end - -% indicees of frequency range (do a bit more, to have space for windowing) -idFreqMinMax = this.freq2idxFreq(sArgs.freqRange .* [1/sqrt(2) sqrt(2)]); -inputData = balloon.freq2coefSH(this.freqVector(idFreqMinMax(1):idFreqMinMax(2)), 'nmax', sArgs.nmax, 'normalized'); -inputData = squeeze(sum(inputData,2)).'; - -if isempty(sArgs.rotate), sArgs.rotate = {zeros(1,3)}; end -out = itaAudio(length(sArgs.rotate),1); - -for idxR = 1:length(sArgs.rotate) - - % eventually rotate the target function - if sum(sArgs.rotate{idxR}) - actInputData = ita_sph_rotate_realvalued_basefunc(inputData.', sArgs.rotate{idxR}).'; - else - actInputData = inputData; - end - - % calculate frequency dependent weights for all speakers - out(idxR) = this.freqData2synthesisRule(actInputData, idFreqMinMax,... - 'optimize_freq_range',sArgs.optimize_freq_range, 'encoded',sArgs.encoded, 'nmax', sArgs.nmax); - - % deEqualize input data - if ~isempty(balloon.sensitivity) - out(idxR).freqData = out(idxR).freqData * balloon.sensitivity.value; - end - - % timeShift: prepare compensation of difference of latencysamples - % (will be done in the convolve function) - arg = struct('timeShift', balloon.latencySamples - this.speaker.latencySamples, 'euler_angle', sArgs.rotate{idxR}); - out(idxR).userData = {arg}; - - % weights -> filter (via polynomial smoothing) - out(idxR) = this.synthesisRule2filter(out(idxR), 'method','polyfit','waitbar',false,'extend_only',true); %achtung: normalerweise glätten! - -end -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/itaSyntheticDir.m b/applications/Numeric/SH/@itaSyntheticDir/itaSyntheticDir.m deleted file mode 100644 index 6bcc61b..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/itaSyntheticDir.m +++ /dev/null @@ -1,194 +0,0 @@ -classdef itaSyntheticDir < itaMotherBalloonSynth - % I promise, in january there will be a documentaion ! - properties(Access = public) - speaker = []; - speaker_channels = []; - speaker_nmax = 20; - encode_nmax = 15; - freq_range = []; - - nmax = 20; - - regularization = 1e-5; - target_tolerance = -0.1; - nIterations = 3; - - euler_tilt = {[0 180 0; 38.5 16.2 0]}; %euler_angle - angle_rot = {}; % set in getPositions, or by user - - measurementDataFolder = {}; - - % italian turntable moves clockwise for a positive phi-angle... - measurementCoordinates_are_itaItalian = true; - end - properties(SetAccess = private, GetAccess = public) - nApertures = []; % set in makeSynthSpeaker - idxTiltRot2idxFolderFile = cell(0); % set in getPositions - aperture2idxTiltRotCh = []; % set in makeSynthSpeaker - speakerSampling = []; % set in makeSpeakerSampling - speakerSampling_basefunctions = []; - spherical_harmonics_type = []; % set in makeSynthSpeaker - end - properties(Access = private) - end - methods - function this = itaSyntheticDir - end - function set.speaker(this,speak) - if this.stillempty - this.speaker = speak; - - if isa(this.speaker, 'itaBalloon') && isempty(this.freqRange) %#ok - this.freqRange = [min(speak.freqVector)*sqrt(2) max(speak.freqVector)/sqrt(2)]; %#ok - end - this.speaker_nmax = min(this.speaker_nmax, speak.nmax); %#ok - end - end - function set.freqRange(this, value) - if this.stillempty, this.freqRange = value; end - end - function set.nmax(this, value) - if this.stillempty, this.nmax = value; end - end - function set.euler_tilt(this, value) - if this.stillempty, - if ~iscell(value) - this.euler_tilt = {value}; - else - this.euler_tilt = value; - end - end - end - function set.angle_rot(this, value) - if this.stillempty, - if ~iscell(value) - this.angle_rot = {value}; - else - this.angle_rot = value; - end - end - end - function set.measurementDataFolder(this, value) - if this.stillempty, - if ~iscell(value) - this.measurementDataFolder = {value}; - else - this.measurementDataFolder = value; - end - end - end - - function set.speaker_channels(this, value) - if this.stillempty, this.speaker_channels = value; end - end - function set.target_tolerance(this, value) - this.target_tolerance = -abs(value); - end - - function value = freq2coefSH_synthSpeaker(this, freq, varargin) - sArgs = struct('nmax',this.speaker_nmax,'channels',1:this.nApertures); - if nargin > 2 - for idx = 3:nargin - if strcmpi(varargin{idx-2},'normalized') - outputEqualized = true; - varargin = varargin((1:end) ~= idx-2); - break; - else - outputEqualized = false; - end - end - sArgs = ita_parse_arguments(sArgs,varargin); - else - outputEqualized = false; - end - - nC = (sArgs.nmax+1)^2; - nFreq = numel(freq); - - if nFreq > this.nMaxPerCalculation - disp('Warning: This is a big matrix, better split the frequency-Vektor'); - end - - idxBlock = this.mux_idxFreq2block(this.freq2idxFreq(freq),:); - value = zeros(nC, length(sArgs.channels), nFreq); - - actBlock = []; - for idxF = 1:nFreq - if isempty(actBlock) || idxBlock(idxF,1) ~= actBlock - actBlock = idxBlock(idxF,1); - data = this.read([this.folder filesep 'synthSuperSpeaker' filesep 'freqDataSH_' int2str(actBlock)]); - end - value(:,:,idxF) = data(1:nC, sArgs.channels, idxBlock(idxF,2)); - end - - if ~outputEqualized - if isa(this.speaker, 'itaBalloon') && ~isempty(this.speaker.sensitivity) - realChannels = this.aperture2idxTiltRotCh(sArgs.channels,3); - value = bsxfun(@times, value, this.speaker.sensitivity.value(realChannels)); - end - end - end - - function out = coefSH2synthFilter(this,input, varargin) - sArgs = struct('nmax', this.nmax, 'optimize_freq_range', [], 'freqRange', this.freqRange, 'encoded', false); - if nargin > 2 - sArgs = ita_parse_arguments(sARgs, varargin); - end - - if length(input) <= 2 - if length(input) == 2 - input = ita_sph_degreeorder2linear(input(1), input(2)); - end - coefSH = zeros((this.nmax+1)^2,1); - coefSH(input) = 1; - elseif length(input) == (this.nmax+1)^2; - coefSH = input; - else - error(['I need a vector "coefSH" which weights all the ' int2str((this.nmax+1)^2) ' base functions']); - end - - if size(coefSH,1) > size(coefSH,2) - coefSH = coefSH.'; - end - if size(coefSH,1) ~= 1 - error('I need a vector, not a matrix'); - end - - out = this.freqData2synthesisRule(coefSH, 1, 'optimize_freq_range', sArgs.optimize_freq_range, 'freqRange', sArgs.freqRange, 'encoded',sArgs.encoded); - end - end - methods (Access = private) - function out = stillempty(this) - if numel(dir([this.folder filesep 'synthSpeaker' filesep 'freqDataSH_*'])) - error('I can not set this value any more since this object is not empty!!'); - else - out = true; - end - end - function out = freq_range_intern(this) - out = this.freqRange.*[1/sqrt(2) sqrt(2)]; - end - - function out = encodeCoefSH(this, in) - % in : [idxCoefSH idxRealChannel idxFreq] - % out: [idxCoefSH idxEncodedChannel idxFreq] - if sqrt(size(this.speakerSampling_basefunctions,2))-1 < this.encode_nmax - disp('must calculate new basefunctions'); - this.makeSpeakerSampling; - end - out = zeros(size(in,1), (this.encode_nmax+1)^2, size(in,3)); - for idxF = 1:size(in,3) - out(:,:,idxF) = in(:,:,idxF)*this.speakerSampling_basefunctions(:,1:(this.encode_nmax+1)^2); - end - end - function out = decodeCoefSH(this, in, maintainedFunctions) - % in : [idxEncodedChannel idxFreq] - % out: [idxRealChannel idxFreq] - - out = zeros(size(this.speakerSampling_basefunctions,1), size(in,2), size(in,3)); - for idxN = 1:size(in,3) - out(:,:,idxN) = this.speakerSampling_basefunctions(:,maintainedFunctions)*in(:,:,idxN); - end - end - end -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/ita_test_itaSyntheticDir.m b/applications/Numeric/SH/@itaSyntheticDir/ita_test_itaSyntheticDir.m deleted file mode 100644 index 6f9dc25..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/ita_test_itaSyntheticDir.m +++ /dev/null @@ -1,94 +0,0 @@ -%% Short tutorial about data structure and methods in itaSyntheticDir -%Kurze Zusammenstellung der Datenstruktur und der Funktionen von -%itaSyntheticDir, sowie der Ergebnisse der Messungen im Seminarraum -% -% -% Ordnerstruktur : -% - sem_1tilt und sem_2tilt (itaSyntheticDir Objekte) -% - this.mat : Zeiger auf itaSyntheticDir-Objekt -% - synthSuperSpeaker : sphärische Koeffizienten des synthetisierten -% Lautsprecherarrays, in Frequenzblöcke zusammengefasst, über -% this.freq2coefSH_synthSpeaker abrufbar -% - sphRIR : Impulsantworten der sphärischen Harmonischen -% z.B. : md_M1_sphRIR.ita: itaAudio mit allen Impulsantworten, gemessen -% an Mic 1 -% - sphFilter : Filter zur Erzeugung der sphRIR (nicht geglättet) -% dienen nur zur Evaluation -% - filterData : (eigentlich nur) temporäre Zwischenspeicherung des invertierten -% synthSuperSpeakers, Frequenzblöcke -% -% - Messdaten: -% - Nur ein Kippwinkel (für sem_1tilt) : Ordner 'DODE_I\data_csII' -% - 'md_M1_6.ita' : "multi channel dode, Mic 1, turntableposition 6" -% enthält die RIRs aller 12 Treiber, channelCoordinates = -% Rotationswinkel (ACHTUNG : im Uhrzeigersinn : phi = 2l*pi - channelChoordinates.phi) -% - 'sd_6.ita' : "single channel dode, turntableposition 6" -% enthält RIR des Referenzdodekaeders an allen 5 Mikrofonen -% -% - zwei Kippwinkel (für sem_2tilt) (Daten wie oben) -% Ordner 'DODE_IIa\data_csII' und 'DODE_IIb\data_csII' -% -% - Vergleichsmessung mit der Zielquelle: Ordner: 'CUBE_I\data_cs', 'CUBE_II\data_cs' -% - sd_1.ita : Referenzdodekaeder (siehe oben) -% - cu_2.ita : RIR des Würfellautsprechers an turntableposition 2, -% alle 5 Mics -% -% - Fotos : Mikrofone : 1+2 = inkes & rechtes Ohr des Kunstkopfes, -% 3,4,5 : Ke4-Kapseln, von der rednerposition zum Fenster hin -% durchnumeriert (3, ca. 2 m vom Dode weg, 4 mitten im Raum, 5 weit hinten) -% -% - -%% Beispiel für die Funktionen der itaSyntheticDir an Hand von 'sem_2tilt' - -%% initialize: - % basic settings - this = itaSyntheticDir; - this.folder = 'sem_2tilt'; % object's homedirectory - this.measurementDataFolder = {'...\DODE_IIa\data_csII', '...\DODE_IIb\data_csII'}; - this.euler_tilt = {[tilt_angles_I], [tilt_angles_II]}; - this.speaker = dode; % theitaBalloon of your measurement speaker array - this.speaker_channels = 1:12; % the (measurement)-channels that refer to your used speakers - this.measurementCoordinates_are_itaItalian = true; %if the channelCoordinates in your measurement data are ste by itaItalian - - % set maximum order of spherical harmonic stuff - this.nmax = 25; % all the calculations are beeing done with this maximum order - this.speaker_nmax = 30; % if you want to, you can synthesize the synthSpeaker up to an higher order (evaluation purposes only) - this.encode_nmax = 15; % if encoded - - % set regarization - this.regularization = 1e-5; % tikhonov regularization parameter - this.target_tolerance = -0.0100; %[dB] if single speakers are excluded, the inner product theoretical achieved directivity result must not get worse than ths tolerance - -%% synthezise an awesome array - this.getPositions('nPos', 100); % selects the 100 'best' rotated measurements to build a synthSuperSpeaker - this.makeSynthSpeaker; % virtual synthesis of a speaker array - - %% synthesis of RIRs method I - - filter = this.itaBalloon2synthFilter(target_balloon); % see documentation!!!! - % give it directivity via an itaBalloon and it will return nice filters to - % weight your measurements - %uses the following functions: - targets_coeficients = ita_sph_rotate_realvalued_basefunc(targets_coeficients, [your rotation angles]); - weights = this.freqData2synthesisRule; - filter = this.synthesisRule2filter(weights,'method','polynomial'); - - RIR = this.convolve_filter_and_measurement(filter, filemask); - % filemask : z.B. 'md_M4_' - -%% synthesis of RIRs method II -%to proceed only once -this.makeSphRIR; % see documentation!!!! -this.convolve_itaBalloon_and_sphRIR(target_balloon); % see documentation!!!! - - -%% evaluation tools -% compare an original an a synthesized RIR: -test_maku_compare; % see documentation!!!! - -% compare an original an a synthesized directivity: -test_maku_plot_synthresult; % see documentation!!!! - - - \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/makeSpeakerSampling.m b/applications/Numeric/SH/@itaSyntheticDir/makeSpeakerSampling.m deleted file mode 100644 index 5b52a6e..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/makeSpeakerSampling.m +++ /dev/null @@ -1,27 +0,0 @@ -function this = makeSpeakerSampling(this,varargin) -% This function trys to get the center-points of the apertures of the -% synthSpeaker. It works on the assumption, that each chassis' pressure has a -% distinctive major lobe in the center of the chassis -% at the given frequency 'freq' - - -sArgs = struct('freq', 3500); -if nargin > 1 - sArgs = ita_parse_arguments(sArgs, varargin); -end - -%freq choose a high frequency -sampling = ita_sph_sampling_gaussian(80,'noSH',true); - -SH = ita_sph_realvalued_basefunctions(sampling, this.speaker_nmax); -coef = this.freq2coefSH_synthSpeaker(sArgs.freq, 'nmax', this.speaker_nmax,'normalized'); -this.speakerSampling = itaCoordinates(this.nApertures); - -for idxC = 1:this.nApertures - [dummy idxMax] = max(abs(SH*coef(:,idxC))); %#ok - this.speakerSampling.sph(idxC,:) = sampling.sph(idxMax,:); -end - -this.speakerSampling_basefunctions = ita_sph_realvalued_basefunctions(this.speakerSampling, this.encode_nmax); -save(this); -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/makeSphRIR.m b/applications/Numeric/SH/@itaSyntheticDir/makeSphRIR.m deleted file mode 100644 index d368489..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/makeSphRIR.m +++ /dev/null @@ -1,223 +0,0 @@ -function out = makeSphRIR(this,varargin) -% calculates filter for the synthesis of the single spherical harmonics and -% convolves it with the measured data -% -% input: -% - filemask : name-extention of the measurement data (for best, give it -% all the extentions off all data at a time, that saves time, for example: -% {'md_M1_', 'md_M2_', 'md_M3_'} -% (optional) -% - nmax : maximum order of synthesized function -% -% - freq_range : the range in in which you want to use the array (the -% function will extend it a bit, so you have space for filtering -% - encoded : false/(true) encoded controling of the chassis -% - muteChannels : mute single speaker -% -% output: -% - out(idx) : an itaAudio with the RIRs of all the estimated -% basefunctions, measured by the mic specified by the filemask{idx} -% The RIRs and the filters will also be saved in "this.folder" -% -% see also: itaSyntheticDir, itaSyntheticDir.getPositions, -% itaSyntheticDir.makeSynthSpeaker itaSyntheticDir.convolve_itaBalloon_and_sphRIR - -% Author: Martin Kunkemoeller, 13.12.2010 - -% initialize %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -sArgs = struct('nmax', this.nmax,'filemask', {''}, ... - 'freqRange', this.freqRange, 'encoded', false, 'muteChannels', []); - -if nargin > 1 - sArgs = ita_parse_arguments(sArgs, varargin); -end - -if isempty(sArgs.filemask), error('I need filemasks'); end - -% make directories -if ~isdir([this.folder filesep 'sphRIR']) - mkdir([this.folder filesep 'sphRIR']); -end -if ~isdir([this.folder filesep 'sphFilter']) - mkdir([this.folder filesep 'sphFilter']) -end -if ~isdir([this.folder filesep 'filterData']) - mkdir([this.folder filesep 'filterData']); %temporary directory -end - -%check measurement data files -if ~iscell(sArgs.filemask), sArgs.filemask = {sArgs.filemask}; end -FF = this.idxTiltRot2idxFolderFile{1,1}; -for idxD = 1:length(sArgs.filemask) - if ~exist([this.measurementDataFolder{FF(1)} filesep sArgs.filemask{idxD} int2str(FF(2)) '.ita'],'file'); - error(['There is no such file: "' this.measurementDataFolder{FF(1)} filesep sArgs.filemask{idxD} int2str(FF(2)) '.ita"']); - end -end - -% maximum order (linear) -nmax_l = (this.nmax+1)^2; -nmax_rir = (sArgs.nmax+1)^2; - -%indicees of frequencies (refered to the data in the synth object) -idxFreqMinMax = this.freq2idxFreq(sArgs.freqRange .* [1/sqrt(2) sqrt(2)]); -%when mapping indicees to itaAudios, this.speaker etc. always add this -idxFreqOffset = length(this.speaker.freqVector(this.speaker.freqVector < this.freqVector(1))); - - -% invert the speaker (tikhonov) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -ita_verbose_info('itaSyntheticDir:makeSphRIR:Calculate frequency dependent weights for each speaker',1); - -% the big filter matrix: -filterData = single(zeros(idxFreqMinMax(2)-idxFreqMinMax(1)+1, this.nApertures, nmax_rir)); - -for idxB = 1:this.nDataBlock - - %indices for synthSpeaker - actIdFreq = this.block2idxFreq(idxB); - actIdFreq = actIdFreq(actIdFreq >= idxFreqMinMax(1) & actIdFreq <= idxFreqMinMax(2)); - %indices for filterData - actIdOut = actIdFreq-idxFreqMinMax(1)+1; - if ~isempty(actIdFreq) - id_blockFreq = this.idxFreq2block(actIdFreq); - id_blockFreq = id_blockFreq(:,2); - - block = this.read([this.folder filesep 'synthSuperSpeaker' filesep 'freqDataSH_' int2str(idxB)]); - block = block(1:nmax_l,:,id_blockFreq); - block(:,sArgs.muteChannels,:) = 0; - if sArgs.encoded - block = this.encodeCoefSH(block); - end - - for idxF = 1:size(block,3) - % the invertation itself (tikhonov) - A = squeeze(block(:,:,idxF)); - invSpeaker = pinv(A'*A + this.regularization*eye(size(A,2)), 1e-8)* A'; - - if sArgs.encoded - filterData(actIdOut(idxF),:,:) = single(permute(this.decodeCoefSH(invSpeaker(:,1:nmax_rir,:), 1:(this.encode_nmax+1)^2), [3 1 2])); - else - filterData(actIdOut(idxF),:,:) = single(permute(invSpeaker(:,1:nmax_rir,:), [3 1 2])); - end - end - end -end - -% unnormalize synthSpeaker -if ~isempty(this.speaker.sensitivity) - realChannels = this.aperture2idxTiltRotCh(:,3); - filterData = bsxfun(@rdivide, filterData, this.speaker.sensitivity.value(realChannels)); -end - -% make sphFilter (serves only for evaluation purposes) %%%%%%%%%%%%%% -for idxC = 1:nmax_rir - filter = itaAudio; - filter.samplingRate = this.speaker.samplingRate; - filter.signalType = 'energy'; - filter.dataType = 'single'; - freqData = zeros(length(this.speaker.freqVector), this.nApertures); - freqData(idxFreqOffset+(idxFreqMinMax(1):idxFreqMinMax(2)),:) = filterData(:,:,idxC); - filter.freqData = freqData; - filter.channelUserData{1} = 1:this.nApertures; - - [n m] = ita_sph_linear2degreeorder(idxC); - filter.comment = ['filter for synthesis of sph ' int2str(n) ', ' int2str(m) ' (not smoothed)']; - ita_write(filter, [this.folder filesep 'sphFilter' filesep 'filter_' int2str(idxC) '.ita' ]) -end - - - -% If you have a computer with fantastic much memory, you can set 'nInBlock' to a -% fantastic big number (won't give you a big speedup, bottle neck is somewhere else) -nInBlock = 100; -for idxB = 1:ceil(this.nApertures/nInBlock) - data = filterData(:,(idxB-1)*nInBlock+1 : min(idxB*nInBlock, this.nApertures),:); %#ok - save([this.folder filesep 'filterData' filesep 'filterData_' int2str(idxB)],'data'); -end -clear('invSpeaker','block','A','data','filterData'); - -% proceed all measurement data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% - make filters -% - convolve these filters and the data and add it to the final result 'rirData' -% nomenclature : filter.ch(idxN) weights speaker idxA when -% basefunction idxN is beeing synthesized -ita_verbose_info('itaSyntheticDir:makeSphRIR:extend filters frequency range and convolve it with the measurements',1); - -data = itaAudio(length(sArgs.filemask),1); - -actFF = [0 0]; %index Folder and File of the current measurementdata in the memory -actIdxFilter = 0; -for idxA = 1:this.nApertures - ita_verbose_info([' proceed measurement ' int2str(idxA) ' / ' int2str(this.nApertures)],1); - - %read measurement data - TRC = this.aperture2idxTiltRotCh(idxA,:); %tilt & rotation angle, channel - FF = this.idxTiltRot2idxFolderFile{TRC(1),TRC(2)}; %folder file - if sum(actFF == FF) < 2 - clear data; - data = itaAudio(length(sArgs.filemask),1); - for idxD = 1:length(sArgs.filemask)% proceed all microphone channels at a time - data(idxD) = ita_read([this.measurementDataFolder{FF(1)} filesep sArgs.filemask{idxD} int2str(FF(2)) '.ita']); - actFF = FF; - end - end - - % read filter data and smooth it - if actIdxFilter ~= ceil(idxA/nInBlock) - actIdxFilter = ceil(idxA/nInBlock); - filterData = this.read([this.folder filesep 'filterData' filesep 'filterData_' int2str(actIdxFilter)]); - end - - % (initialize this object always new due to speedup reasons) - filter = itaAudio; - filter.samplingRate = this.speaker.samplingRate; - filter.signalType = 'energy'; - filter.dataType = 'single'; - freqData = zeros(length(this.speaker.freqVector), nmax_rir); - freqData(idxFreqOffset+(idxFreqMinMax(1):idxFreqMinMax(2)),:) = ... - squeeze(filterData(:,mod(idxA-1,nInBlock)+1,:)); - filter.freqData = freqData; - % extend frequency range, no polymomial smoothing - filter = this.synthesisRule2filter(filter, 'method', 'polyfit','waitbar',false,'extend_only',true); - - % initialize output's freqData - if idxA == 1 - rirData = single(zeros(data(1).nBins, nmax_rir, length(sArgs.filemask))); - end - - %adapt length of filter and data - if data(1).nSamples ~= filter.nSamples - if data(1).nSamples < filter.nSamples, error('sorry, I did not expect that, maybe you could code that?'); end; - filter = ita_time_window(filter, round(filter.nSamples/2+[-0.005*filter.samplingRate 0]),'samples','symmetric'); - filter = ita_extend_dat(filter, data(1).nSamples,'symmetric'); - end - - % convolve - for idxD = 1:length(sArgs.filemask) - rirData(:,:,idxD) = rirData(:,:,idxD) + single(bsxfun(@times, data(idxD).freqData(:,TRC(3)), filter.freqData)); - end - - clear filter; -end - -% rmdir([this.folder filesep 'filterData']); -save([this.folder filesep 'rirData'],'rirData'); %developer stuff -%% - - -% set output object -out = itaAudio(length(sArgs.filemask),1); -for idxD = 1:length(sArgs.filemask) - out(idxD).samplingRate = this.speaker.samplingRate; - out(idxD).signalType = 'energy'; - out(idxD).dataType = 'single'; - out(idxD).freqData = rirData(:,:,idxD); - - out(idxD).comment = 'RIR of all the basefunctions'; - out(idxD).userData = struct('freqRange', sArgs.freqRange); - for idxC = 1:out(idxD).nChannels - [n m] = ita_sph_linear2degreeorder(idxC); - out(idxD).channelNames{idxC} = ['sph ' int2str(n) ', ' int2str(m)]; - end - ita_write(out(idxD), [this.folder filesep 'sphRIR' filesep sArgs.filemask{idxD} 'sphRIR.ita']); -end diff --git a/applications/Numeric/SH/@itaSyntheticDir/makeSynthSpeaker.m b/applications/Numeric/SH/@itaSyntheticDir/makeSynthSpeaker.m deleted file mode 100644 index b23fb6d..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/makeSynthSpeaker.m +++ /dev/null @@ -1,160 +0,0 @@ -function makeSynthSpeaker(this,freq) -% I promise, in january there will be a documentaion! -% have a look on itaSyntheticDir.tutorial - -if ~isdir([this.folder filesep 'synthSuperSpeaker']), - mkdir([this.folder filesep 'synthSuperSpeaker']); -end - -if length(this.euler_tilt) ~= length(this.angle_rot) || ... - (~isempty(this.measurementDataFolder) && length(this.euler_tilt) ~= length(this.measurementDataFolder)) - error('size of "euler_tilt", "angle_rot" and "measurementDataFolder" must be equal!!'); -end - -if isempty(this.speaker_channels) || isempty(this.freqRange) && isa(this.speaker,'itaBalloon') - error('first you must set stuff like "speaker_nmax", "freq_range" and "speaker_channels"'); -end - -%% initialize, set data structure -if isa(this.speaker,'itaBalloon') - if ~exist('freq','var') - idxFreq = this.speaker.freq2idxFreq(min(this.freqRange_intern)) : this.speaker.freq2idxFreq(max(this.freqRange_intern)); - this.freqVector = this.speaker.freqVector(idxFreq); - this.spherical_harmonics_type = this.speaker.SHType; - else - this.freqVector = freq; - this.spherical_harmonics_type = this.speaker.spherical_harmonics_type; - end - -elseif isa(this.speaker,'itaSphericalLoudspeaker') - if ~exist('freq','var') - error('Help, give me a "frequencyVector" !!') - end - this.freqVector = freq; - this.freqRange = [min(freq) max(freq)]; - this.spherical_harmonics_type = 'complex'; %itaSphericalLaudspeaker deals only with complex valued stuff - -else - error('"this.speaker" must be either an itaBalloon or an itaSphericalLoudspeaker - object!!"'); -end - -if this.speaker_nmax < this.nmax - error('"this.nmax" must be smaller than "this.speaker_nmax"'); -end - -myWaitbar(length(this.freqVector)+1); -this.setDataStructure; - -nChannels = length(this.speaker_channels); -nTilt = length(this.euler_tilt); - -%% set rooting: channel of synthetic speaker -> speaker orientation, speaker channel ... -this.aperture2idxTiltRotCh = zeros(0,3); -for idxT = 1:nTilt - newPart = zeros(length(this.angle_rot{idxT})*nChannels, 3); - for idxR = 1:length(this.angle_rot{idxT}) - newPart((idxR-1)*nChannels + (1:nChannels), :) = ... - [ones(nChannels, 2)*diag([idxT idxR]) (1:nChannels).']; - end - this.aperture2idxTiltRotCh = [this.aperture2idxTiltRotCh; newPart]; -end -this.nApertures = size(this.aperture2idxTiltRotCh,1); - - -%% matrices to tilt the speaker -tiltMatrix = cell(nTilt,1); -for idxT = 1:nTilt - if size(this.euler_tilt{idxT},2) ~= 3, error('All tilt and rotation angles must have size [x 3] !'); end - if strcmpi(this.spherical_harmonics_type, 'complex') - tiltMatrix{idxT} = ita_sph_rotate_complex_valued_spherical_harmonics(this.speaker_nmax, this.euler_tilt{idxT}); - else - tiltMatrix{idxT} = ita_sph_rotate_real_valued_spherical_harmonics(this.speaker_nmax, this.euler_tilt{idxT}); - end -end - -%% Synthesise the super speaker -for idxB = 1:this.nDataBlock - nFreq = length(this.block2idxFreq(idxB)); - if isa(this.speaker,'itaBalloon') - %read spherical coefs (from a measured speaker) - single_sp = this.speaker.freq2coefSH(... - this.freqVector(this.block2idxFreq(idxB)), 'nmax',this.speaker_nmax,'channels',this.speaker_channels, 'normalized'); - - elseif isa(this.speaker,'itaSphericalLoudspeaker') - pressureFactor = this.speaker.pressureFactor(2*pi/344*this.freqVector(this.block2idxFreq(idxB))); - single_sp = ... - repmat(this.speaker.apertureSH(1:(this.speaker_nmax+1)^2,this.speaker_channels), [1 1 nFreq]) .*... - repmat(permute(pressureFactor(1:(this.speaker_nmax+1)^2,:), [1 3 2]), [1 nChannels 1]); - - end - - - %superspeaker's frequencyBlock - super_sp = zeros((this.speaker_nmax+1)^2, this.nApertures, nFreq); - for idxF = 1:nFreq - myWaitbar(this.block2idxFreq(idxB,idxF)); - - for idxA = 1:nChannels:this.nApertures - idT = this.aperture2idxTiltRotCh(idxA,1); - idR = this.aperture2idxTiltRotCh(idxA,2); - - if strcmpi(this.spherical_harmonics_type, 'complex') - super_sp(:, idxA-1+(1:nChannels), idxF) = ... - ita_sph_rotate_complex_valued_spherical_harmonics(tiltMatrix{idT}*single_sp(:,:,idxF), [this.angle_rot{idT}(idR) 0 0]); - else - super_sp(:, idxA-1+(1:nChannels), idxF) = ... - ita_sph_rotate_real_valued_spherical_harmonics(tiltMatrix{idT}*single_sp(:,:,idxF), [this.angle_rot{idT}(idR) 0 0]); - end - end - end - save([this.folder filesep 'synthSuperSpeaker' filesep 'freqDataSH_' int2str(idxB)], 'super_sp'); -end - -%conclude -myWaitbar(length(this.freqVector)+1); -save(this); -myWaitbar([]); -end - -function myWaitbar(in) -persistent WB maxN; - -if ~exist('maxN','var') || isempty(maxN)... - || exist('WB','var') && ~ishandle(WB); - maxN = in; - WB = waitbar(0, 'makeSynthSpeaker (initialize)'); - -elseif in < maxN - waitbar(in/maxN, WB, ['makeSynthSpeaker (proceed frequency ' int2str(in) ' / ' int2str(maxN-1) ')']); - -else - waitbar(1, WB, ['makeSynthSpeaker (finish)']); -end - -if isempty(in) - close(WB); -end -end - -% function lin = nm2N(n,m) -% if length(n) > 1, error(' '); end -% lin = n^2+n+1+m; -% end - -% function value = rotate_z(value, nmax, phi) -% % according to Dis Zotter, chapter 3.1.4 -% % compare: ita_sph_rotate_real_valued_spherical_harmonics -% % (there it is a bit different because there (first) the coordinate system -% % and not the spherical function is rotated -% % -% %Idea: Fs,m = [cos(m phi) -sin(m phi)] * [Fs,mo ; Fc,mo] -% % Fc,m = [sin(m phi) cos(m phi)] * [Fs,mo ; Fc,mo] -% -% % value(nm2N(n,0),nm2N(n,0)) does not change -% for n = 0:nmax -% for m = 1:n -% value(nm2N(n,-m),:) = [cos(m*phi) -sin(m*phi)] * value(nm2N(n,[-m m]),:); -% value(nm2N(n, m),:) = [sin(m*phi) cos(m*phi)] * value(nm2N(n,[-m m]),:); -% end -% end -% end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_condition_rotError.m b/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_condition_rotError.m deleted file mode 100644 index bf04168..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_condition_rotError.m +++ /dev/null @@ -1,61 +0,0 @@ -function [diagSE] = maku_SYNTH_penalty_condition_rotError(this) - -maxCond = 100; -rot_error = [0 0.5 1 2 4 8 16]*pi/180; - -% freq = ita_ANSI_center_frequencies(this.freqRange,3); -freq = [250 500 1000 2000 4000 6000]; - -diagSE = zeros((this.nmax+1)^2, length(rot_error), length(freq)); - -for idxF = 1:length(freq) - speaker = this.freq2coefSH_synthesisedSpeaker(freq(idxF),'nmax',this.speaker_nmax); - - for idxE = 1:length(rot_error) - WD_error = ita_sph_wignerD(this.speaker_nmax, -repmat(rot_error(idxE),1,3)); - disp([int2str(idxF) ', ' int2str(idxE)]); - - sE = abs(maku_SYNTH_make_SynthMatrix(speaker(:,1:(this.nmax+1)^2), maxCond, 0)... - *(speaker * WD_error)).^2; - - - divisor = sum(sE,2); - idxKill = (1:length(divisor)).' .* (divisor < 1e-5); - idxKill = idxKill(idxKill~=0); - divisor(idxKill) = 1e5; - diagSE(:,idxE,idxF) = diag(sE) ./ divisor; - end -end -%% - -for idxF = 1:length(freq) - % ggf Diagonaleinträge von sE über der Anzahl der Lautsprecherpositionen graphisch darstellen - val = zeros(this.nmax+1,size(diagSE,2)); - for idxO = 0:this.nmax - val(idxO+1,:) = min(diagSE(idxO^2+1:(idxO+1)^2,:,idxF),[],1); - end - - %% - val_cut = 0.8; - idxKill = (1:size(val,1)).' .* (val(:,1) < val_cut); - idxKill = idxKill(idxKill~=0); - val(idxKill,1) = 1e6; - val = val ./ repmat(val(:,1),1,size(val,2)); - val(idxKill,1) = 0; - - subplot(3,ceil(length(freq)/3),idxF), - h = pcolor(rot_error*180/pi, 0:this.nmax, max(val,val_cut)); - set(h,'linestyle','none'); -% set(gca,'xscale','log', 'xtick',rot_error*180/pi);%,'xTickLabel',rot_error); - xlabel('rotation error') - title(int2str(freq(idxF))); colorbar; -end - -%% -for idxE = 1:length(rot_error) -subplot(2,ceil(length(rot_error)/2),idxE) -pcolor(squeeze(diagSE(:,idxE,:))); - - -end - diff --git a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IR.m b/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IR.m deleted file mode 100644 index 4e21442..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IR.m +++ /dev/null @@ -1,60 +0,0 @@ -function out = maku_SYNTH_penalty_num_IR(filemask,refPos,nRef,channel) - -% filemask: [path filesep nameextension] - -nIr = numel(dir([filemask '*'])); -freq_range = [400 6000]; - -%% init reference and time constances -idInitFiles = refPos + (0:nRef-1); -if max(idInitFiles) > nIr - idInitFiles = idInitFiles - max(idInitFiles) + nIr; -end - -[mean_data, crop] = initialize_filtering(filemask, idInitFiles ,freq_range, channel); -norm_factor = sum(mean_data.timeData.^2); - -%% proceed all data -out = itaResult; -out.timeVector = 1:nIr; - -for idxIR = 1:nIr - if ~mod(idxIR,5) - disp([int2str(idxIR) ' / ' int2str(nIr) ' done']); - end - data = ita_read([filemask int2str(idxIR) '.ita']); - data = ita_mpb_filter(data.ch(channel),freq_range); - data = ita_time_crop(data,[0 crop],'time'); - out.timeData(idxIR) = sum(data.timeData.*mean_data.timeData) / norm_factor; -end -%% -% plotOut = out; plotOut.timeData = sqrt(out.timeData); -% plotOut.plot_dat_dB('ylim',[-3 0.1]); xlabel('Idx Impulsantwort'); -end - - -function [mean_data, crop] = initialize_filtering(filemask, idInitFiles ,freq_range, channel) - -% mean_data : Referenzimpulsantwort, berechnet aus den -% 'idInitFiles'-Impulsantworten -%crop : ungefähr der Anteil ('time') der frühen Reflexionen -% crop = I_time/2 (I_time: Übergang Signal -> Rauschen, über -% ita_roomacoustics_detectionSNR_room; -all_data = itaAudio(length(idInitFiles),1); -for idx = 1:length(idInitFiles) - data = ita_read([filemask int2str(idInitFiles(idx)) '.ita']); - all_data(idx) = data.ch(channel); -end - -crop = zeros(length(idInitFiles),1); -for idxA = 1:length(all_data) - all_data(idxA) = ita_mpb_filter(all_data(idxA),freq_range); - res = ita_roomacoustics_detectionSNR(all_data(idxA)); - crop(idxA,:) = res(2).freqData; -end - -crop = mean(crop)/2; % Frühe Reflexionen sind hauptsächlich relevant -mean_data = mean(all_data); -mean_data = ita_time_crop(mean_data,[0 crop],'time'); - -end diff --git a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IRII.m b/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IRII.m deleted file mode 100644 index 399aa63..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_IRII.m +++ /dev/null @@ -1,63 +0,0 @@ -function out = maku_SYNTH_penalty_num_IRII(filemask,refPos,nRef,oct) -%% angefangen: Auswertung in mehreren Frequenzbändern.... -% filemask: [path filesep nameextension] - -nIr = numel(dir([filemask '*'])); -freq_range = [400 6000]; - -%% init reference and time constances -idInitFiles = refPos + (0:nRef-1); -if max(idInitFiles) > nIr - idInitFiles = idInitFiles - max(idInitFiles) + nIr; -end - -[mean_data, crop] = initialize_filtering(filemask, idInitFiles ,freq_range, oct); -norm_factor = sum(mean_data.timeData.^2); - -%% proceed all data -out = itaResult; -out.timeVector = 1:nIr; - -for idxIR = 1:nIr - if ~mod(idxIR,5) - disp([int2str(idxIR) ' / ' int2str(nIr) ' done']); - end - data = ita_read([filemask int2str(idxIR) '.ita']); - data = ita_mpb_filter(data,freq_range); - data = ita_time_crop(data,[0 crop],'time'); - out.timeData(idxIR) = sum(data.timeData.*mean_data.timeData) / norm_factor; -end -%% -plotOut = out; plotOut.timeData = sqrt(out.timeData); -plotOut.plot_dat_dB('ylim',[-3 0.1]); xlabel('Idx Impulsantwort'); -end - - -function [mean_data, crop] = initialize_filtering(filemask, idInitFiles ,freq_range, oct) - -% mean_data : Referenzimpulsantwort, berechnet aus den -% 'idInitFiles'-Impulsantworten -%crop : ungefähr der Anteil ('time') der frühen Reflexionen -% crop = I_time/2 (I_time: Übergang Signal -> Rauschen, über -% ita_roomacoustics_detectionSNR_room; -all_data = itaAudio(length(idInitFiles),1); -for idx = 1:length(idInitFiles) - all_data(idx) = ita_read([filemask int2str(idInitFiles(idx)) '.ita']); -end - -idxF = ita_ANSI_center_frequencies([25 22000],oct); -[dum idMin] = min(abs(idxF - min(freq_range))); -[dum idMax] = min(abs(idxF - max(freq_range))); clear dum; -crop = zeros(length(idInitFiles),1); -for idxA = 1:length(all_data) -% all_data(idxA) = ita_mpb_filter(all_data(idxA),freq_range); - test = ita_mpb_filter(all_data(idxA),'oct',oct); - res = ita_roomacoustics_detectionSNR(all_data(idxA)); - crop(idxA,:) = res(2).freqData; -end - -crop = mean(crop)/2; % Frühe Reflexionen sind hauptsächlich relevant -mean_data = mean(all_data); -mean_data = ita_time_crop(mean_data,[0 crop],'time'); - -end diff --git a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_rot.m b/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_rot.m deleted file mode 100644 index 2fa8116..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_num_rot.m +++ /dev/null @@ -1,72 +0,0 @@ -function result = maku_SYNTH_penalty_num_rot(this, indexPositions) - -freq = ita_ANSI_center_frequencies(this.freqRange,1); -nRot = length(this.angle_rot_I) + length(this.angle_rot_II); - -nCh_s = length(this.speaker_channels); -diagSE = zeros((this.nmax+1)^2,nRot/16,length(freq)); - - -idxWB = 0; -maxWB = length(freq)*nRot-1; -WB = waitbar(idxWB/maxWB,['maku\_SYNTH\_penalty\_num\_rot (progress : ' int2str(0) ' %)']); -for idxF = 1:length(freq) - speaker = this.freq2coefSH_synthesisedSpeaker(freq(idxF),'nmax',this.nmax); - for idxD = 1:nRot - waitbar(idxWB/maxWB, WB, ['maku\_SYNTH\_penalty\_num\_rot (progress : ' num2str(idxWB/maxWB*100,2) ' %)']); - idxWB = idxWB+1; - - sE = abs(... - maku_SYNTH_make_SynthMatrix(speaker(1:idxD*nCh_s, :), this.condmax, 0) ... - * speaker(1:idxD*nCh_s, :)).^2; - - %avoid division by zero - divisor = sum(sE,2); - idxKill = (1:length(divisor)).' .* (divisor < 1e-5); - idxKill = idxKill(idxKill~=0); - divisor(idxKill) = 1e5; - diagSE(:,idxD,idxF) = diag(sE) ./ divisor; - end -end - -result = itaResult; -result.timeVector = (1:nRot); -result.timeData = zeros(nRot,length(freq)); - -waitbar(idxWB/maxWB, WB, ['maku\_SYNTH\_penalty\_num\_rot (concluding ... )']); -for idxF = 1:length(freq) - val = zeros(this.nmax+1,size(diagSE,2)); - - %Basis soll mit maximal 1.5 dB Fehler synthetisiert werden, - %schlechter interresiert nicht, da sie eh rausfliegt... - val_cut = 10^(-1.5/10); - - % val(idxO,:) : die am schlechtesten synthetisierte Basisfunktion - for idxO = 0:this.nmax - val(idxO+1,:) = min(diagSE(idxO^2+1:(idxO+1)^2,:,idxF),[],1); - end - - %optimum: alle Lautsprecherpositionenverwenden: val(:,end) - optimum = val(:,end); - idxKillNot = (1:this.nmax+1).' .* (optimum > val_cut); - idxKillNot = idxKillNot(idxKillNot~=0); - val(idxKillNot,:) = val(idxKillNot,:) ./ repmat(optimum(idxKillNot),1,size(val,2)); - - result.timeData(:,idxF) = sqrt(mean(val(idxKillNot,:),1)) .'; - - %% ggf Diagonaleinträge von sE über der ANzahl der Lautsprecherpositionen graphisch darstellen - % idxKill = (1:size(val,1)).'; - % for idx = 1:length(idxKillNot) - % idxKill = idxKill(idxKill ~= idxKillNot(idx)); - % end - % subplot(3,ceil(length(freq)/3),idxF), - % h = pcolor(max(val,val_cut)); - % set(h,'linestyle','none'); - % xlabel('number of rotations') - % title(int2str(freq(idxF))); colorbar; - - -end -close(WB) -% result.plot_dat_dB('ylim',[-5 0.1]); xlabel('number of rotations') -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error.m b/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error.m deleted file mode 100644 index a455288..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error.m +++ /dev/null @@ -1,35 +0,0 @@ -function [result con] = maku_SYNTH_penalty_rot_error(this) -%% -nSteps = 5; -maxVal = 6; - -maxCond = 10.^(1: maxVal/(nSteps) :maxVal); - -rot_error = 0*pi/180; -WD_error = ita_sph_wignerD(this.nmax, -repmat(rot_error,1,3)); - -% freq = ita_ANSI_center_frequencies(this.freqRange,3); -freq = [250 500 1000 2000 4000 6000]; - -result = itaResult; -result.timeVector = maxCond; -result.timeData = zeros(length(maxCond),length(freq)); - -con = itaResult; -con.freqVector = freq; -con.freqData = zeros(length(freq),1); - -for idxF = 1:length(freq) - result.channelNames{idxF} = [int2str(freq(idxF)) ' Hz']; - speaker = this.freq2coefSH_synthesisedSpeaker(freq(idxF),'nmax',this.nmax); - - con.freqData(idxF) = cond(speaker); - for idx = 1:length(maxCond) - disp([int2str(idxF) ', ' int2str(idx)]); - - sE = abs(maku_SYNTH_make_SynthMatrix(speaker, maxCond(idx), 0)... - *(speaker * WD_error)).^2; - divisor = sum(sE,2); divisor(~divisor) = 1; - result.timeData(idx, idxF) = sqrt(mean(diag(sE) ./ divisor)); - end -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error_2_max_cond.m b/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error_2_max_cond.m deleted file mode 100644 index ef17f05..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/penaltyFunctions/maku_SYNTH_penalty_rot_error_2_max_cond.m +++ /dev/null @@ -1,35 +0,0 @@ -function [result con] = maku_SYNTH_penalty_rot_error_2_max_cond(this) -%% -nSteps = 5; -maxVal = 6; - -maxCond = 10.^(1: maxVal/(nSteps) :maxVal); - -rot_error = 0*pi/180; -WD_error = ita_sph_wignerD(this.nmax, -repmat(rot_error,1,3)); - -% freq = ita_ANSI_center_frequencies(this.freqRange,3); -freq = [250 500 1000 2000 4000 6000]; - -result = itaResult; -result.timeVector = maxCond; -result.timeData = zeros(length(maxCond),length(freq)); - -con = itaResult; -con.freqVector = freq; -con.freqData = zeros(length(freq),1); - -for idxF = 1:length(freq) - result.channelNames{idxF} = [int2str(freq(idxF)) ' Hz']; - speaker = this.freq2coefSH_synthesisedSpeaker(freq(idxF),'nmax',this.nmax); - - con.freqData(idxF) = cond(speaker); - for idx = 1:length(maxCond) - disp([int2str(idxF) ', ' int2str(idx)]); - - sE = abs(maku_SYNTH_make_SynthMatrix(speaker, maxCond(idx), 0)... - *(speaker * WD_error)).^2; - divisor = sum(sE,2); divisor(~divisor) = 1; - result.timeData(idx, idxF) = sqrt(mean(diag(sE) ./ divisor)); - end -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter.m b/applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter.m deleted file mode 100644 index 16936ed..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter.m +++ /dev/null @@ -1,207 +0,0 @@ -function varargout = synthesisRule2filter(this, ao, varargin) -sArgs = struct('outputType','ita','bandwidth_filter',[], 'method', 'rationalfit','waitbar',true,'extend_only',false); -if nargin > 2 - sArgs = ita_parse_arguments(sArgs,varargin); -end - -if ~isempty(sArgs.bandwidth_filter) && sArgs.bandwidth_filter.nSamples ~= a.nSamples; - erros('signal an bandwidth filter must have equal number of samples'); -end - -if ao.nChannels > 1 - % recursive, call function again for each channel - %% split channels - freqData = zeros(size(ao.freqData)); - if sArgs.waitbar, WB = waitbar(0,' '); end - - % change 'outputType' - idxMethod = find(strcmpi(varargin,'outputType')); - if isempty(idxMethod) - varargin = [varargin {'outputType','matrix'}]; - else - varargin{idxMethod+1} = 'matrix'; - end - - for idxC = 1:ao.nChannels - if idxC == 1 || ~mod(idxC,10) - if sArgs.waitbar, waitbar(idxC/ao.nChannels, WB, ['approximate synthesis using polynomes (' num2str(idxC/ao.nChannels*100, 2) '% )']); end - end - freqData(:,idxC) = this.synthesisRule2filter(ao.ch(idxC),varargin{:}); - end - - if sArgs.waitbar, close(WB); end - - - -else % the function - if strcmpi(sArgs.method, 'rationalfit') - - dum = ao; - dum.freqData = zeros(size(dum.freqData)); - - %% rational fit - find(abs(ao.freqData) > 0, 1, 'first') - f_low = ao.freqVector(find(abs(ao.freqData) > 0, 1, 'first')+1); - f_high = ao.freqVector(find(abs(ao.freqData) > 0, 1, 'last')-1); - - % low extension of the (intern) frequency range - [ext_low] = ita_audio2zpk_rationalfit(ao,'degree',7,'mode','log', 'freqRange', f_low*[1 2]); - out = ext_low'; -% a = out; - - %% main_part - % cut in to peaces - oct = 1; - if f_high/f_low < 2^(1/oct) - freq = [f_low f_high]; - else - freq = []; - for idx = 0:log2(f_high/f_low)*oct - freq = [freq; f_low*2^(idx/oct)]; %#ok - end - freq = [freq(1:end-1)*2^(-1/3) freq(2:end)*2^(1/3)]; - freq(1) = f_low; freq(end) = f_high; - end - idxFreq = [ao.freq2index(freq(:,1)) ao.freq2index(freq(:,2))]; - - % fit with common polynomes - part = itaAudio; - for idx = 1:length(idxFreq) - part.freqData = zeros(ao.nBins,1); - ind = (idxFreq(idx,1):idxFreq(idx,2)).'; - projInd = (ind - mean(ind))/ std(ind); - [P S muX] = polyfit(projInd, ao.freqData(ind), min(ceil(length(ind)*0.3), 15)); %#ok - part.freqData(ind) = polyval(P, (projInd-muX(1))/muX(2)); - - - if idx == 1 - out = ita_xfade_spk(out, part, [f_low f_low*sqrt(2)]); - else - out = ita_xfade_spk(out, part, [freq(idx,1) freq(idx-1,2)]); - end - end - - % high extension of the (intern) frequency range - [ext_high] = ita_audio2zpk_rationalfit(ao,'degree',30,'mode','log', 'freqRange', f_high*[0.5 1]); - out = ita_xfade_spk(out, ext_high', f_high*[1/sqrt(2) 1]); - - out.freqData(1) = 0; - - - - else - %% polynomial approximation (part wise) - - oct = 2; % sections per octave - overlap = 1/3; % overlap of sections - - idx_FR = [find(abs(ao.freqData)>0, 1, 'first') find(abs(ao.freqData)>0, 1, 'last')]; - f_low = ao.freqVector(idx_FR(1)); - f_high = ao.freqVector(idx_FR(2)); - freqData = ao.freqData; - - if ~isempty(sArgs.bandwidth_filter) - id = idx_FR(1):idx_FR(2); - freqData(id) = freqData(id)./sArgs.bandwidth_filter.freqData(id); - end - - % edge frequencies of the sections - idx = 0:log2(f_high/max(f_low,1))*oct; - fitSecF = f_low*2.^(idx/oct); - if f_high/fitSecF(end) < 2^(1/oct) - fitSecF = [fitSecF(1:end-1) f_high]; - else - fitSecF = [fitSecF f_high]; - end - - % indices of the sections's first and last frequency bin, including overlaping - idxFitSec = [[1; max(ao.freq2index(fitSecF*2^(-overlap/2)), idx_FR(1))], [min(ao.freq2index(fitSecF*2^(overlap/2)), idx_FR(2)); ao.nBins]]; - - % default polynome degrees - fitSecDegree = min([3; round(0.3*(idxFitSec(:,2) - idxFitSec(:,1))); 3],18); - - % first smooth calculatet parts ... - newStuff = zeros(ao.nBins, size(idxFitSec,1)); - - for idxS = 2:size(idxFitSec,1)-1 - if ~sArgs.extend_only - ind = (idxFitSec(idxS,1):idxFitSec(idxS,2)).'; - [P S muX] = polyfit(ind, freqData(ind), fitSecDegree(idxS)); %#ok - - newStuff(ind,idxS) = polyval(P, (ind-muX(1))/muX(2)); - else - ind = (idxFitSec(idxS,1):idxFitSec(idxS,2)).'; - newStuff(ind,idxS) = freqData(ind); - end - end - - meanAmp = mean(abs(freqData(idx_FR(1):idx_FR(2)))); - - % ... then extend the first part of the frequency range ... - ind = (idxFitSec(2,1):idxFitSec(1,2)).'; - - nAddPoints = floor(min(length(ind), ind(1)/2)/2)*2; - data = freqData(ind); - - ind = [(1:nAddPoints).'; ind]; - data = [repmat(meanAmp, nAddPoints, 1); data]; - - [P S muX] = polyfit(ind, data , fitSecDegree(1)); %#ok - newInd = ind(1):ind(end); - newStuff(newInd,1) = polyval(P, (newInd-muX(1))/muX(2)); - - % ... and extend the end of the frequency range - ind = (idxFitSec(end,1):idxFitSec(end-1,2)).'; - nAddPoints = length(ind); - p1 = 0.25*ind(end) + 0.75*ao.nBins; pe = ao.nBins; - addPoints = (round(p1) : round((pe-p1)/(nAddPoints)) : round(pe)).'; - addPoints(end) = ao.nBins; - - data = freqData(ind); - - ind = [ind; addPoints]; - data = [data; repmat(meanAmp, length(addPoints), 1)]; - - [P S muX] = polyfit(ind, data , fitSecDegree(end)); %#ok - newInd = ind(1):ind(end); - newStuff(newInd,end) = polyval(P, (newInd-muX(1))/muX(2)); - - - %% xover über Abschnitte - freqData = newStuff(:,1); - for idxS = 1:size(newStuff,2)-1 - xover = ones(size(newStuff,1),2); - xover(idxFitSec(idxS,2)+1:end,1) = 0; - xover(1:idxFitSec(idxS+1,1)-1,2) = 0; - - lX = idxFitSec(idxS,2)-idxFitSec(idxS+1,1); - xover(idxFitSec(idxS+1,1):idxFitSec(idxS,2),2) = (0:lX)/lX; - xover(idxFitSec(idxS+1,1):idxFitSec(idxS,2),1) = 1-xover(idxFitSec(idxS+1,1):idxFitSec(idxS,2),2); - - freqData = sum(xover .* [freqData newStuff(:,idxS+1)],2); - end - - freqData(1) = 0; %no DC - - end -end - -% select output type -if strcmpi(sArgs.outputType, 'matrix') - if strcmpi(sArgs.method, 'rationalfit') - varargout{1} = out.freqData; - else - varargout{1} = freqData; - end -else - varargout{1} = ao; - if strcmpi(sArgs.method, 'rationalfit') - varargout{1}.freqData = out.freqData; - else - varargout{1}.freqData = freqData; - end - -end - - - diff --git a/applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter_back_2010-11-20.m b/applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter_back_2010-11-20.m deleted file mode 100644 index 2e3ac59..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/synthesisRule2filter_back_2010-11-20.m +++ /dev/null @@ -1,142 +0,0 @@ -function varargout = synthesisRule2filter(this, a, varargin) -sArgs = struct('format','ita','method','rationalfit','bandwidth_filter',[]); -if nargin > 2 - sArgs = ita_parse_arguments(sArgs,varargin); -end - -if ~isempty(sArgs.bandwidth_filter) && sArgs.bandwidth_filter.nSamples ~= a.nSamples; - erros('signal an bandwidth filter must have equal number of samples'); -end - -if a.nChannels > 1 - %% split channels - freqData = zeros(size(a.freqData)); - WB = waitbar(0,' '); - for idxC = 1:a.nChannels - if idxC == 1 || ~mod(idxC,10) - waitbar(idxC/a.nChannels, WB, ['smooth filter using polynomes (' num2str(idxC/a.nChannels*100, 2) '% )']); - end - if sum(abs(a.ch(idxC).freqData)); - freqData(:,idxC) = this.polynomial_smoothing(a.ch(idxC), 'format', 'matrix', 'method', sArgs.method, 'bandwidth_filter', sArgs.bandwidth_filter); - end - end - close(WB); -else - if strcmpi(sArgs.method,'rationalfit') - freq_range = a.freqVector([find(abs(a.freqData), 1, 'first') find(abs(a.freqData), 1, 'last')]); - dum = ita_audio2zpk_rationalfit(a, 'degree',20,'mode','lin','freqRange',freq_range); - freqData = dum.freqData; - else - %% Abschnittsweises Polynomfitten - - overlap = 1/3; - oct = 1.5; - - freq_range = a.freqVector([find(a.freqData ~=0, 1, 'first') find(a.freqData ~=0, 1, 'last')]); - idx_FR = a.freq2index(freq_range); - - if ~isempty(sArgs.bandwidth_filter) - id = idx_FR(1):idx_FR(2); - a.freqData(id) = a.freqData(id)./sArgs.bandwidth_filter.freqData(id); - end - - fitSecF = []; - for idx = 0:log2(max(freq_range)/min(freq_range))*oct - fitSecF = [fitSecF min(freq_range)*2^(idx/oct)]; %#ok - end - if max(freq_range)/max(fitSecF) < 2^(1/oct) - fitSecF = [fitSecF(1:end-1) max(freq_range)]; - else - fitSecF = [fitSecF max(freq_range)]; - end - - fitSecN = [3 15*ones(1,ceil(length(fitSecF)/2))... - 19*ones(1,floor(length(fitSecF)/2)) 4]; - - idxFitSec = zeros(length(fitSecF)+1,2); - - for idx = 1:length(fitSecF)+1 - if idx == 1 - idxFitSec(idx,:) = [1 a.freq2index(fitSecF(idx)*2^overlap)]; - elseif idx <= length(fitSecF) - idxFitSec(idx,:) = [a.freq2index(max(min(freq_range), fitSecF(idx-1)*2^(-overlap)))... - a.freq2index(min(max(freq_range), fitSecF(idx)*2^overlap))]; - else - idxFitSec(idx,:) = [a.freq2index(fitSecF(idx-1)*2^(-overlap)) a.nBins]; - end - end - - %% Zuerst die Abschnitte glätten, die berechnet wurden ... - newStuff = zeros(a.nBins, size(idxFitSec,1)); - - for idxS = 2:size(idxFitSec,1)-1 - indices = (idxFitSec(idxS,1):idxFitSec(idxS,2)).'; - projIndices = (indices - mean(indices))/ std(indices); - [P S muX] = polyfit(projIndices, a.freqData(indices), fitSecN(idxS)); %#ok - - newStuff(indices,idxS) = polyval(P, (projIndices-muX(1))/muX(2)); - end - - - %% ...dann Anfang ... - - idxCut = a.freq2index(60); - nAddPoints = 4; %even number - indices = (idxFitSec(2,1):idxFitSec(1,2)).'; - addPoints = [1:nAddPoints/2 idxCut+(1:nAddPoints/2-1)].'; - addPoints = addPoints(addPoints < indices(1)); - data = a.freqData(indices); - indices = [addPoints; indices]; - - data = [ repmat(mean(abs(a.freqData(idx_FR(1):idx_FR(2)))), length(addPoints), 1); data]; - - [P S muX] = polyfit(indices,data , fitSecN(1)); - indices = min(indices):max(indices); - newStuff(indices,1) = polyval(P, (indices-muX(1))/muX(2)); - - %% ... und Ende des Frequenzbereichs ergänzen - indices = (idxFitSec(end,1):idxFitSec(end-1,2)).'; - data = a.freqData(indices); - - p1 = 0.25*max(indices)+0.75*a.nBins; pe = a.nBins; - addPoints = (round(p1) : round((pe-p1)/(nAddPoints)) : round(pe)).'; - addPoints(end) = a.nBins; - indices = [indices; addPoints]; - data = [data; repmat(mean(abs(a.freqData(idx_FR(1):idx_FR(2)))), length(addPoints), 1)]; - - [P S muX] = polyfit(indices,data , fitSecN(end)); - indices = min(indices):max(indices); - newStuff(indices,end) = polyval(P, (indices-muX(1))/muX(2)); - - %% xover über Abschnitte - freqData = newStuff(:,1); - for idxS = 1:size(newStuff,2)-1 - xover = ones(size(newStuff,1),2); - xover(idxFitSec(idxS,2)+1:end,1) = 0; - xover(1:idxFitSec(idxS+1,1)-1,2) = 0; - - lX = idxFitSec(idxS,2)-idxFitSec(idxS+1,1); - xover(idxFitSec(idxS+1,1):idxFitSec(idxS,2),2) = (0:lX)/lX; - xover(idxFitSec(idxS+1,1):idxFitSec(idxS,2),1) = 1-xover(idxFitSec(idxS+1,1):idxFitSec(idxS,2),2); - - freqData = sum(xover .* [freqData newStuff(:,idxS+1)],2); - end - - - freqData(1) = 0; - freqData(end) = freqData(end)/2; - freqData = freqData*sqrt(2)/a.nSamples; - - if ~isempty(sArgs.bandwidth_filter) - freqData = freqData .* sArgs.bandwidth_filter.freqData; - end - - end -end - -if strfind(sArgs.format,'it') - varargout{1} = a; - varargout{1}.freqData = freqData; -else - varargout{1} = freqData; -end diff --git a/applications/Numeric/SH/@itaSyntheticDir/test_steepest_descend.m b/applications/Numeric/SH/@itaSyntheticDir/test_steepest_descend.m deleted file mode 100644 index a49f96b..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/test_steepest_descend.m +++ /dev/null @@ -1,31 +0,0 @@ -function x = test_steepest_descend(this, SYNTH, SPEAK, input) - -j = sqrt(-1); -nIt = 10; -x = SYNTH*input; -dA = mean(abs(x))*0.1; -mu = 1e-4; - -pen = zeros(nIt+1,1); - -A = SYNTH*input; -B = (eye(this.nApertures) - SYNTH*SPEAK); -for idxI = 1:nIt - pen(idxI) = penalty(x); - - dPen = zeros(length(x),1); - for idxX = 1:length(x) - dX = zeros(length(x),1); dX(idxX) = dA; - testX = A + B * (abs(x) + dX) * exp(j*mean(angle(x))); - dPen(idxX) = (penalty(testX) - pen(idxI))/dA; - end - x = A + B * (abs(x) - mu*dPen) * exp(j*mean(angle(x))); - plot(pen); pause(0.05); -end - - - -end -function pen = penalty(x) -pen = std(angle(x)); -end \ No newline at end of file diff --git a/applications/Numeric/SH/@itaSyntheticDir/test_synthesize_yourself.m b/applications/Numeric/SH/@itaSyntheticDir/test_synthesize_yourself.m deleted file mode 100644 index 86a10f5..0000000 --- a/applications/Numeric/SH/@itaSyntheticDir/test_synthesize_yourself.m +++ /dev/null @@ -1,19 +0,0 @@ - -function filter = test_synthesize_yourself(this, aperture) - -freq = this.speaker.freqVector; -coef = this.freq2coefSH_synthSpeaker(freq, 'channels', 4, 'nmax',this.nmax); - -disp(['try to synthesise aperture ' int2str(aperture)]); -TRC = this.aperture2idxTiltRotCh(aperture,:); -FF = this.idxTiltRot2idxFolderFile{TRC(1), TRC(2)}; - -disp([' id tilt / rotation angle \channel : ' int2str(TRC)]); -disp([' id folder / file : ' int2str(FF)]); - -if isempty(this.speaker.sensitivity) - filter = this.freqData2synthFilter(squeeze(coef).', freq, 'muteChannels', aperture); - -else - filter = this.freqData2synthFilter(squeeze(coef).', freq, 'sensitivity',this.speaker.sensitivity(TRC(3)), 'muteChannels', aperture); -end \ No newline at end of file -- GitLab