138 lines
4.1 KiB
Matlab
138 lines
4.1 KiB
Matlab
function showEQNoisePSD(eq_noise, options)
|
|
arguments
|
|
eq_noise
|
|
options.postfilter_taps = NaN
|
|
options.fignum (1,1) double = NaN % Default to NaN if not provided
|
|
options.displayname (1,:) char = '' % Default to an empty string if not provided
|
|
options.color = [];
|
|
options.colormode (1,1) string {mustBeMember(options.colormode, ["diverging", "qualitative", "paired"])} = "diverging";
|
|
end
|
|
|
|
persistent nextGroupIdx
|
|
if isempty(nextGroupIdx)
|
|
nextGroupIdx = 0;
|
|
end
|
|
|
|
% Determine the figure number to use or create a new figure
|
|
if isnan(options.fignum)
|
|
fig = figure; % Create a new figure and get its handle
|
|
else
|
|
fig = figure(options.fignum); % Use the specified figure number
|
|
end
|
|
hold on
|
|
ax = gca;
|
|
linesBefore = findall(ax, 'Type', 'Line');
|
|
|
|
useAutomaticColor = isempty(options.color);
|
|
if useAutomaticColor
|
|
options.color = selectEQNoisePSDColor(ax, options.colormode);
|
|
end
|
|
|
|
% Ensure the figure is ready before calling spectrum
|
|
eq_noise = eq_noise - mean(eq_noise.signal);
|
|
eq_noise.spectrum("displayname", options.displayname, "fignum", fig.Number, "normalizeTo0dB", 0,"color",options.color,"fft_length",4096);
|
|
|
|
if ~isnan(options.postfilter_taps)
|
|
% Hold on to the figure for further plotting
|
|
hold on;
|
|
|
|
% Compute the frequency response of the postfilter
|
|
[h, w] = freqz(1, options.postfilter_taps, length(eq_noise), "whole", eq_noise.fs);
|
|
h = h / max(abs(h)); % Normalize the filter response
|
|
|
|
% Adjust frequency axis to center at 0
|
|
w_ = (w - eq_noise.fs / 2);
|
|
|
|
% Plot the inverted postfilter response
|
|
plot(w_ * 1e-9, 20 * log10(fftshift(abs(h))), 'DisplayName', ['Burg Coeffs: ', num2str(round(options.postfilter_taps, 2)), ' '], 'LineWidth', 1,'Color',options.color,'LineStyle','--');
|
|
|
|
% Ensure a legend is displayed
|
|
legend('show');
|
|
end
|
|
|
|
if useAutomaticColor
|
|
nextGroupIdx = nextGroupIdx + 1;
|
|
newLines = getNewLines(ax, linesBefore);
|
|
tagEQNoisePSDLines(newLines, nextGroupIdx);
|
|
recolorEQNoisePSDLines(ax, options.colormode);
|
|
end
|
|
|
|
xlim([-eq_noise.fs/2* 1e-9 eq_noise.fs/2* 1e-9]);
|
|
% ylim([-15, 0]);
|
|
|
|
end
|
|
|
|
function color = selectEQNoisePSDColor(ax, colormode)
|
|
if colormode == "qualitative"
|
|
N = sum(arrayfun(@(x) strcmp(x.LineStyle, '-'), ax.Children));
|
|
cmap = linspecer(8);
|
|
color = cmap(mod(N, size(cmap, 1)) + 1, :);
|
|
else
|
|
color = [0 0 0];
|
|
end
|
|
end
|
|
|
|
function newLines = getNewLines(ax, linesBefore)
|
|
linesAfter = findall(ax, 'Type', 'Line');
|
|
newLines = linesAfter(~ismember(linesAfter, linesBefore));
|
|
end
|
|
|
|
function tagEQNoisePSDLines(lines, groupIdx)
|
|
for lineIdx = 1:numel(lines)
|
|
setappdata(lines(lineIdx), 'showEQNoisePSDGroupIdx', groupIdx);
|
|
end
|
|
end
|
|
|
|
function recolorEQNoisePSDLines(ax, colormode)
|
|
if colormode == "qualitative"
|
|
return
|
|
end
|
|
|
|
lines = findall(ax, 'Type', 'Line');
|
|
groupIdx = NaN(size(lines));
|
|
|
|
for lineIdx = 1:numel(lines)
|
|
if isappdata(lines(lineIdx), 'showEQNoisePSDGroupIdx')
|
|
groupIdx(lineIdx) = getappdata(lines(lineIdx), 'showEQNoisePSDGroupIdx');
|
|
end
|
|
end
|
|
|
|
lines = lines(~isnan(groupIdx));
|
|
groupIdx = groupIdx(~isnan(groupIdx));
|
|
|
|
if isempty(lines)
|
|
return
|
|
end
|
|
|
|
groups = unique(groupIdx, 'stable');
|
|
groups = sort(groups);
|
|
cols = getEQNoisePSDColormap(colormode, numel(groups));
|
|
|
|
for groupColorIdx = 1:numel(groups)
|
|
sameGroup = groupIdx == groups(groupColorIdx);
|
|
set(lines(sameGroup), 'Color', cols(groupColorIdx, :));
|
|
end
|
|
end
|
|
|
|
function cols = getEQNoisePSDColormap(colormode, numColors)
|
|
switch colormode
|
|
case "paired"
|
|
cols = cbrewer2('paired', numColors);
|
|
otherwise
|
|
cols = getDivergingWithoutBrightCenter(numColors);
|
|
end
|
|
end
|
|
|
|
function cols = getDivergingWithoutBrightCenter(numColors)
|
|
numBaseColors = max(6, numColors);
|
|
centerExcludeFraction = 0.3;
|
|
|
|
baseCols = cbrewer2('RdYlBu', numBaseColors);
|
|
centerIdx = (numBaseColors + 1) / 2;
|
|
excludeHalfWidth = centerExcludeFraction * numBaseColors / 2;
|
|
keepIdx = find(abs((1:numBaseColors) - centerIdx) > excludeHalfWidth);
|
|
sampleIdx = round(linspace(1, numel(keepIdx), numColors));
|
|
|
|
cols = baseCols(keepIdx(sampleIdx), :);
|
|
end
|