From 77f29d61ed5a0c91467615a425b63d88a4ddbbdb Mon Sep 17 00:00:00 2001 From: "fritzPC2\\Adam" Date: Sat, 7 Apr 2018 17:16:40 -0400 Subject: [PATCH 1/4] Version of TrialTypeOutcome Plot that handles having trial types and outcomes built on the fly starting from an empty array Also added *.asv to gitignore --- .gitignore | 3 +- .../Plugins/Plots/TrialTypeOutcomePlot.asv | 156 ++++++++++++++++++ .../Plugins/Plots/TrialTypeOutcomePlot.m | 19 ++- 3 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 Functions/Plugins/Plots/TrialTypeOutcomePlot.asv diff --git a/.gitignore b/.gitignore index 41d8c63..1d82b50 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ Calibration Files/** Data/** Protocols/** .gitmodules -*BpodUserPath.txt \ No newline at end of file +*BpodUserPath.txt +*.asv \ No newline at end of file diff --git a/Functions/Plugins/Plots/TrialTypeOutcomePlot.asv b/Functions/Plugins/Plots/TrialTypeOutcomePlot.asv new file mode 100644 index 0000000..3542572 --- /dev/null +++ b/Functions/Plugins/Plots/TrialTypeOutcomePlot.asv @@ -0,0 +1,156 @@ +%{ +---------------------------------------------------------------------------- + +This file is part of the Bpod Project +Copyright (C) 2015 Joshua I. Sanders, Cold Spring Harbor Laboratory, NY, USA + +---------------------------------------------------------------------------- + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3. + +This program is distributed WITHOUT ANY WARRANTY and without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +%} +% function OutcomePlot(AxesHandle,TrialTypeSides, OutcomeRecord, CurrentTrial) +function TrialTypeOutcomePlot(AxesHandle, Action, varargin) +%% +% Plug in to Plot trial type and trial outcome. +% AxesHandle = handle of axes to plot on +% Action = specific action for plot, "init" - initialize OR "update" - update plot + +%Example usage: +% TrialTypeOutcomePlot(AxesHandle,'init',TrialTypes) +% TrialTypeOutcomePlot(AxesHandle,'init',TrialTypes,'ntrials',90) +% TrialTypeOutcomePlot(AxesHandle,'update',CurrentTrial,TrialTypes,OutcomeRecord) + +% varargins: +% TrialTypes: Vector of trial types (integers) +% OutcomeRecord: Vector of trial outcomes +% Simplest case: +% 1: correct trial (green) +% 0: incorrect trial (red) +% Advanced case: +% NaN: future trial (blue) +% -1: withdrawal (red circle) +% 0: incorrect choice (red dot) +% 1: correct choice (green dot) +% 2: did not choose (green circle) +% OutcomeRecord can also be empty +% Current trial: the current trial number + +% Adapted from BControl (SidesPlotSection.m) +% Kachi O. 2014.Mar.17 +% J. Sanders. 2015.Jun.6 - adapted to display trial types instead of sides + +%% Code Starts Here +global nTrialsToShow %this is for convenience +global BpodSystem + +switch Action + case 'init' + %initialize pokes plot + TrialTypeList = varargin{1}; + + nTrialsToShow = 90; %default number of trials to display + + if nargin > 3 %custom number of trials + nTrialsToShow =varargin{3}; + end + axes(AxesHandle); + MaxTrialType = max(TrialTypeList); + + + % Fitz mod note- 2 ways to determine trial types on the fly, one is to preallocate + % trial types and outcomes with NaNs and then fill them in as you + % go, second is to build trial type and outcome lists by accretion + if isempty(MaxTrialType) || isnan(MaxTrialType) + MaxTrialType = 1; % for NaN filled TrialTypes, might occur if you determine trial type on the fly + end + %plot in specified axes + Xdata = 1:min(nTrialsToShow, length(TrialTypeList)); Ydata = -TrialTypeList(Xdata); + BpodSystem.GUIHandles.FutureTrialLine = line([Xdata,Xdata],[Ydata,Ydata],'LineStyle','none','Marker','o','MarkerEdge','b','MarkerFace','b', 'MarkerSize',6); + BpodSystem.GUIHandles.CurrentTrialCircle = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','k','MarkerFace',[1 1 1], 'MarkerSize',6); + BpodSystem.GUIHandles.CurrentTrialCross = line([0,0],[0,0], 'LineStyle','none','Marker','+','MarkerEdge','k','MarkerFace',[1 1 1], 'MarkerSize',6); + BpodSystem.GUIHandles.UnpunishedErrorLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','r','MarkerFace',[1 1 1], 'MarkerSize',6); + BpodSystem.GUIHandles.PunishedErrorLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','r','MarkerFace','r', 'MarkerSize',6); + BpodSystem.GUIHandles.RewardedCorrectLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','g','MarkerFace','g', 'MarkerSize',6); + BpodSystem.GUIHandles.UnrewardedCorrectLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','g','MarkerFace',[1 1 1], 'MarkerSize',6); + BpodSystem.GUIHandles.NoResponseLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','b','MarkerFace',[1 1 1], 'MarkerSize',6); + set(AxesHandle,'TickDir', 'out','YLim', [-MaxTrialType-.5, -.5], 'YTick', -MaxTrialType:1:-1,'YTickLabel', strsplit(num2str(MaxTrialType:-1:-1)), 'FontSize', 16); + xlabel(AxesHandle, 'Trial#', 'FontSize', 18); + ylabel(AxesHandle, 'Trial Type', 'FontSize', 16); + hold(AxesHandle, 'on'); + + case 'update' + CurrentTrial = varargin{1}; + TrialTypeList = varargin{2}; + OutcomeRecord = varargin{3}; + MaxTrialType = max(TrialTypeList); + if isnan(MaxTrialType) + MaxTrialType = 1; % for NaN filled TrialTypes, this if statement should nev + end + set(AxesHandle,'YLim',[-MaxTrialType-.5, -.5], 'YTick', -MaxTrialType:1:-1,'YTickLabel', strsplit(num2str(MaxTrialType:-1:-1))); + if CurrentTrial<1 + CurrentTrial = 1; + end + TrialTypeList = -TrialTypeList; + % recompute xlim + if length(TrialTypeList) > CurrentTrial % trial types are pre-determined + [mn, mx] = rescaleX(AxesHandle,CurrentTrial,nTrialsToShow); + else % if trial types are not predetermined, have graph end at current trial + mn = max(1, CurrentTrial - nTrialsToShow + 1); + mx = CurrentTrial; + end + + + %axes(AxesHandle); %cla; + %plot future trials + FutureTrialsIndx = CurrentTrial:mx; + Xdata = FutureTrialsIndx; Ydata = TrialTypeList(Xdata); + set(BpodSystem.GUIHandles.FutureTrialLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); + %Plot current trial + set(BpodSystem.GUIHandles.CurrentTrialCircle, 'xdata', [CurrentTrial,CurrentTrial], 'ydata', [TrialTypeList(CurrentTrial),TrialTypeList(CurrentTrial)]); + set(BpodSystem.GUIHandles.CurrentTrialCross, 'xdata', [CurrentTrial,CurrentTrial], 'ydata', [TrialTypeList(CurrentTrial),TrialTypeList(CurrentTrial)]); + + %Plot past trials + if ~isempty(OutcomeRecord) + indxToPlot = mn:CurrentTrial-1; + %Plot Error, unpunished + EarlyWithdrawalTrialsIndx =(OutcomeRecord(indxToPlot) == -1); + Xdata = indxToPlot(EarlyWithdrawalTrialsIndx); Ydata = TrialTypeList(Xdata); + set(BpodSystem.GUIHandles.UnpunishedErrorLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); + %Plot Error, punished + InCorrectTrialsIndx = (OutcomeRecord(indxToPlot) == 0); + Xdata = indxToPlot(InCorrectTrialsIndx); Ydata = TrialTypeList(Xdata); + set(BpodSystem.GUIHandles.PunishedErrorLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); + %Plot Correct, rewarded + CorrectTrialsIndx = (OutcomeRecord(indxToPlot) == 1); + Xdata = indxToPlot(CorrectTrialsIndx); Ydata = TrialTypeList(Xdata); + set(BpodSystem.GUIHandles.RewardedCorrectLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); + %Plot Correct, unrewarded + UnrewardedTrialsIndx = (OutcomeRecord(indxToPlot) == 2); + Xdata = indxToPlot(UnrewardedTrialsIndx); Ydata = TrialTypeList(Xdata); + set(BpodSystem.GUIHandles.UnrewardedCorrectLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); + %Plot DidNotChoose + DidNotChooseTrialsIndx = (OutcomeRecord(indxToPlot) == 3); + Xdata = indxToPlot(DidNotChooseTrialsIndx); Ydata = TrialTypeList(Xdata); + set(BpodSystem.GUIHandles.NoResponseLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); + end +end + +end + +function [mn,mx] = rescaleX(AxesHandle,CurrentTrial,nTrialsToShow) +FractionWindowStickpoint = .75; % After this fraction of visible trials, the trial position in the window "sticks" and the window begins to slide through trials. +mn = max(round(CurrentTrial - FractionWindowStickpoint*nTrialsToShow),1); +mx = mn + nTrialsToShow - 1; +set(AxesHandle,'XLim',[mn-1 mx+1]); +end + + diff --git a/Functions/Plugins/Plots/TrialTypeOutcomePlot.m b/Functions/Plugins/Plots/TrialTypeOutcomePlot.m index 729dc15..fae1e29 100644 --- a/Functions/Plugins/Plots/TrialTypeOutcomePlot.m +++ b/Functions/Plugins/Plots/TrialTypeOutcomePlot.m @@ -64,11 +64,16 @@ function TrialTypeOutcomePlot(AxesHandle, Action, varargin) end axes(AxesHandle); MaxTrialType = max(TrialTypeList); - if isnan(MaxTrialType) + + + % Fitz mod note- 2 ways to determine trial types on the fly, one is to preallocate + % trial types and outcomes with NaNs and then fill them in as you + % go, second is to build trial type and outcome lists by accretion + if isempty(MaxTrialType) || isnan(MaxTrialType) MaxTrialType = 1; % for NaN filled TrialTypes, might occur if you determine trial type on the fly end %plot in specified axes - Xdata = 1:nTrialsToShow; Ydata = -TrialTypeList(Xdata); + Xdata = 1:min(nTrialsToShow, length(TrialTypeList)); Ydata = -TrialTypeList(Xdata); BpodSystem.GUIHandles.FutureTrialLine = line([Xdata,Xdata],[Ydata,Ydata],'LineStyle','none','Marker','o','MarkerEdge','b','MarkerFace','b', 'MarkerSize',6); BpodSystem.GUIHandles.CurrentTrialCircle = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','k','MarkerFace',[1 1 1], 'MarkerSize',6); BpodSystem.GUIHandles.CurrentTrialCross = line([0,0],[0,0], 'LineStyle','none','Marker','+','MarkerEdge','k','MarkerFace',[1 1 1], 'MarkerSize',6); @@ -88,7 +93,7 @@ function TrialTypeOutcomePlot(AxesHandle, Action, varargin) OutcomeRecord = varargin{3}; MaxTrialType = max(TrialTypeList); if isnan(MaxTrialType) - MaxTrialType = 1; % for NaN filled TrialTypes, might occur if you determine trial type on the fly + MaxTrialType = 1; % for NaN filled TrialTypes, this if statement shouldn't in practice be reached when using 'update' as opposed to 'init' end set(AxesHandle,'YLim',[-MaxTrialType-.5, -.5], 'YTick', -MaxTrialType:1:-1,'YTickLabel', strsplit(num2str(MaxTrialType:-1:-1))); if CurrentTrial<1 @@ -96,7 +101,13 @@ function TrialTypeOutcomePlot(AxesHandle, Action, varargin) end TrialTypeList = -TrialTypeList; % recompute xlim - [mn, mx] = rescaleX(AxesHandle,CurrentTrial,nTrialsToShow); + if length(TrialTypeList) > CurrentTrial % trial types are pre-determined + [mn, mx] = rescaleX(AxesHandle,CurrentTrial,nTrialsToShow); + else % if trial types are not predetermined, have graph end at current trial + mn = max(1, CurrentTrial - nTrialsToShow + 1); + mx = CurrentTrial; + end + %axes(AxesHandle); %cla; %plot future trials From f55c43cefeaad44e7e0c7699ac6ba695538030a6 Mon Sep 17 00:00:00 2001 From: Fitz Sturgill Date: Mon, 9 Apr 2018 19:38:57 -0400 Subject: [PATCH 2/4] testing 'popupmenutext' : returns selected string rather than its numeric index --- .../Plugins/ParameterGUI/BpodParameterGUI.m | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Functions/Plugins/ParameterGUI/BpodParameterGUI.m b/Functions/Plugins/ParameterGUI/BpodParameterGUI.m index 2724d41..da161d4 100644 --- a/Functions/Plugins/ParameterGUI/BpodParameterGUI.m +++ b/Functions/Plugins/ParameterGUI/BpodParameterGUI.m @@ -167,6 +167,9 @@ ThisPanelHeight = ThisPanelHeight + (htable.Position(4)-25); BpodSystem.GUIHandles.ParameterGUI.Panels.(ThisTabPanelNames{p}).Position(4) = ThisPanelHeight; BpodSystem.GUIData.ParameterGUI.LastParamValues{ParamNum} = htable.Data; + case 'popupmenutext' % popupmenu, but returns string of menu item rather than its numeric index FS MOD 4/2018 + BpodSystem.GUIData.ParameterGUI.Styles(ParamNum) = 9; + BpodSystem.GUIHandles.ParameterGUI.Params{ParamNum} = uicontrol(htab,'Style', 'popupmenu', 'String', ThisParamString, 'Value', find(strcmp(ThisParam, ThisParamString)), 'Position', [HPos+220 VPos+InPanelPos+2 200 25], 'FontWeight', 'normal', 'FontSize', 12, 'BackgroundColor','white', 'FontName', 'Arial','HorizontalAlignment','Center'); otherwise error('Invalid parameter style specified. Valid parameters are: ''edit'', ''text'', ''checkbox'', ''popupmenu'', ''togglebutton'', ''pushbutton'''); end @@ -244,6 +247,15 @@ elseif Params.GUI.(ThisParamName) ~= ThisParamLastValue set(ThisParamHandle, 'Value', GUIParam); end + case 9 % popupmenu text, returns string FS MOD 4/2018 + GUIParam = get(ThisParamHandle, 'Value'); + GUIParamList = get(ThisParamHandle, 'String'); + GUIParamString = GUIParamList{GUIParam}; + if ~strcmpi(GUIParamString, ThisParamLastValue) + Params.GUI.(ThisParamName) = GUIParamString; + elseif ~strcmpi(Params.GUI.(ThisParamName), ThisParamLastValue) + set(ThisParamHandle, 'Value', find(strcmp(Params.GUI.(ThisParamName), ThisParamList))); + end case 6 %Pushbutton GUIParam = get(ThisParamHandle, 'Value'); if GUIParam ~= ThisParamLastValue @@ -301,6 +313,10 @@ for iColumn = 1:numel(columnNames) Params.GUI.(ThisParamName).(columnNames{iColumn}) = GUIParam(:,iColumn); end + case 9 % popupmenu text, returns string FS MOD 4/2018 + GUIParam = get(ThisParamHandle, 'Value'); + GUIParamList = get(ThisParamHandle, 'String'); + Params.GUI.(ThisParamName) = GUIParamList{GUIParam}; end end otherwise From 261854ccd42abac08949ccc1df3a776245b0a57e Mon Sep 17 00:00:00 2001 From: Fitz Sturgill Date: Mon, 9 Apr 2018 20:05:26 -0400 Subject: [PATCH 3/4] Succesfully tested popupmenutext GUI style, like popupmenu but returns string from menu list rather than its numeric index --- Functions/Plugins/ParameterGUI/BpodParameterGUI.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Functions/Plugins/ParameterGUI/BpodParameterGUI.m b/Functions/Plugins/ParameterGUI/BpodParameterGUI.m index da161d4..0c29cbb 100644 --- a/Functions/Plugins/ParameterGUI/BpodParameterGUI.m +++ b/Functions/Plugins/ParameterGUI/BpodParameterGUI.m @@ -251,10 +251,10 @@ GUIParam = get(ThisParamHandle, 'Value'); GUIParamList = get(ThisParamHandle, 'String'); GUIParamString = GUIParamList{GUIParam}; - if ~strcmpi(GUIParamString, ThisParamLastValue) + if GUIParam ~= ThisParamLastValue Params.GUI.(ThisParamName) = GUIParamString; - elseif ~strcmpi(Params.GUI.(ThisParamName), ThisParamLastValue) - set(ThisParamHandle, 'Value', find(strcmp(Params.GUI.(ThisParamName), ThisParamList))); + elseif find(strcmp(Params.GUI.(ThisParamName), GUIParamList)) ~= ThisParamLastValue + set(ThisParamHandle, 'Value', find(strcmp(Params.GUI.(ThisParamName), GUIParamList))); end case 6 %Pushbutton GUIParam = get(ThisParamHandle, 'Value'); From 965cad5366071229ec45deb7932e8e13152a6329 Mon Sep 17 00:00:00 2001 From: "fritzPC2\\Adam" Date: Sat, 25 Aug 2018 15:52:09 -0400 Subject: [PATCH 4/4] Shujing's commit involving sound calibration --- Calibration Files/SoundCalibration.mat | Bin 680 -> 0 bytes .../Plugins/Plots/TrialTypeOutcomePlot.asv | 156 -------- .../SoundCalibrator/SoundCalibrationManager.m | 21 +- Functions/SoundCalibrator/TestSoundManager.m | 13 +- .../old version/SoundCalibrationManager-.m | 353 ++++++++++++++++++ .../old version/TestSoundManager-.m | 209 +++++++++++ .../old version/response_one_sound-.m | 85 +++++ .../SoundCalibrator/response_one_sound.m | 10 +- 8 files changed, 675 insertions(+), 172 deletions(-) delete mode 100644 Calibration Files/SoundCalibration.mat delete mode 100644 Functions/Plugins/Plots/TrialTypeOutcomePlot.asv create mode 100644 Functions/SoundCalibrator/old version/SoundCalibrationManager-.m create mode 100644 Functions/SoundCalibrator/old version/TestSoundManager-.m create mode 100644 Functions/SoundCalibrator/old version/response_one_sound-.m diff --git a/Calibration Files/SoundCalibration.mat b/Calibration Files/SoundCalibration.mat deleted file mode 100644 index f179b639449b87ef325db04aed7c27126aeda86b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 680 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w>_Ia4t$sEJ;mK$j`G< z@XgOt@J%dIFfdmzG_f)@ure`HFfuSSQy>~JzyPDCFF%m2z{J2%G3Rk|LV`g;T0#Qz zB^ie^M;I8_1lTDHv3+d*?EN`tj&N~=WQ4?#g^!Lp$V{3sW%8*8#s)3p$z4L;MxQ@B z33Xoz_HGjTd?{E`;mrdE`H-u2okvymI#pNh`>8oIbLL7-1Lse{moFJjHV*#mWuWtb z`4N*_%kP^P?&vdp6;=+JBitd|Fz3I*g?%>_--oZAbbaMozSm#3n@|7wzMvv-TI4g0 z{kIdZKR@}<&hNKOmfGLcsg)H69=e(?{(V@xUFO@~FTY~Wlw4`d-yc<4e6X;++*|JU z_EmF>BJ?hV7e+l_<9svhxJCVTZoYd=U46Txrpu`4*J)cmt2nB-d};Wq@@J;);#r4Rp(w4n;>-;QECiS<;@y`rwOzd*<6(zs99jR@s zP2cms`f$AW+ok(;ZlBIHzy9yn%dhhH^<%T@*M4%`m3LIG`m51Fm4l(r-}HZzpS9~= zee>Vd8}y^YUaZ}4{$lRuKR+{?ZP$lRDtA6A^ZRJivU%xA{5Q{+?@7N=P`>r={ua&2 zYW}w}__@lN+3q|%*CF;!$Ki(J8-sR<+8&QzGa7WHGiRBxJDp>z{ZgP-L!tMQ5AIL3ZA?(r@00*uDtnjLYR`D7HJK3;-mzD<}W} diff --git a/Functions/Plugins/Plots/TrialTypeOutcomePlot.asv b/Functions/Plugins/Plots/TrialTypeOutcomePlot.asv deleted file mode 100644 index 3542572..0000000 --- a/Functions/Plugins/Plots/TrialTypeOutcomePlot.asv +++ /dev/null @@ -1,156 +0,0 @@ -%{ ----------------------------------------------------------------------------- - -This file is part of the Bpod Project -Copyright (C) 2015 Joshua I. Sanders, Cold Spring Harbor Laboratory, NY, USA - ----------------------------------------------------------------------------- - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, version 3. - -This program is distributed WITHOUT ANY WARRANTY and without even the -implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -%} -% function OutcomePlot(AxesHandle,TrialTypeSides, OutcomeRecord, CurrentTrial) -function TrialTypeOutcomePlot(AxesHandle, Action, varargin) -%% -% Plug in to Plot trial type and trial outcome. -% AxesHandle = handle of axes to plot on -% Action = specific action for plot, "init" - initialize OR "update" - update plot - -%Example usage: -% TrialTypeOutcomePlot(AxesHandle,'init',TrialTypes) -% TrialTypeOutcomePlot(AxesHandle,'init',TrialTypes,'ntrials',90) -% TrialTypeOutcomePlot(AxesHandle,'update',CurrentTrial,TrialTypes,OutcomeRecord) - -% varargins: -% TrialTypes: Vector of trial types (integers) -% OutcomeRecord: Vector of trial outcomes -% Simplest case: -% 1: correct trial (green) -% 0: incorrect trial (red) -% Advanced case: -% NaN: future trial (blue) -% -1: withdrawal (red circle) -% 0: incorrect choice (red dot) -% 1: correct choice (green dot) -% 2: did not choose (green circle) -% OutcomeRecord can also be empty -% Current trial: the current trial number - -% Adapted from BControl (SidesPlotSection.m) -% Kachi O. 2014.Mar.17 -% J. Sanders. 2015.Jun.6 - adapted to display trial types instead of sides - -%% Code Starts Here -global nTrialsToShow %this is for convenience -global BpodSystem - -switch Action - case 'init' - %initialize pokes plot - TrialTypeList = varargin{1}; - - nTrialsToShow = 90; %default number of trials to display - - if nargin > 3 %custom number of trials - nTrialsToShow =varargin{3}; - end - axes(AxesHandle); - MaxTrialType = max(TrialTypeList); - - - % Fitz mod note- 2 ways to determine trial types on the fly, one is to preallocate - % trial types and outcomes with NaNs and then fill them in as you - % go, second is to build trial type and outcome lists by accretion - if isempty(MaxTrialType) || isnan(MaxTrialType) - MaxTrialType = 1; % for NaN filled TrialTypes, might occur if you determine trial type on the fly - end - %plot in specified axes - Xdata = 1:min(nTrialsToShow, length(TrialTypeList)); Ydata = -TrialTypeList(Xdata); - BpodSystem.GUIHandles.FutureTrialLine = line([Xdata,Xdata],[Ydata,Ydata],'LineStyle','none','Marker','o','MarkerEdge','b','MarkerFace','b', 'MarkerSize',6); - BpodSystem.GUIHandles.CurrentTrialCircle = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','k','MarkerFace',[1 1 1], 'MarkerSize',6); - BpodSystem.GUIHandles.CurrentTrialCross = line([0,0],[0,0], 'LineStyle','none','Marker','+','MarkerEdge','k','MarkerFace',[1 1 1], 'MarkerSize',6); - BpodSystem.GUIHandles.UnpunishedErrorLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','r','MarkerFace',[1 1 1], 'MarkerSize',6); - BpodSystem.GUIHandles.PunishedErrorLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','r','MarkerFace','r', 'MarkerSize',6); - BpodSystem.GUIHandles.RewardedCorrectLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','g','MarkerFace','g', 'MarkerSize',6); - BpodSystem.GUIHandles.UnrewardedCorrectLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','g','MarkerFace',[1 1 1], 'MarkerSize',6); - BpodSystem.GUIHandles.NoResponseLine = line([0,0],[0,0], 'LineStyle','none','Marker','o','MarkerEdge','b','MarkerFace',[1 1 1], 'MarkerSize',6); - set(AxesHandle,'TickDir', 'out','YLim', [-MaxTrialType-.5, -.5], 'YTick', -MaxTrialType:1:-1,'YTickLabel', strsplit(num2str(MaxTrialType:-1:-1)), 'FontSize', 16); - xlabel(AxesHandle, 'Trial#', 'FontSize', 18); - ylabel(AxesHandle, 'Trial Type', 'FontSize', 16); - hold(AxesHandle, 'on'); - - case 'update' - CurrentTrial = varargin{1}; - TrialTypeList = varargin{2}; - OutcomeRecord = varargin{3}; - MaxTrialType = max(TrialTypeList); - if isnan(MaxTrialType) - MaxTrialType = 1; % for NaN filled TrialTypes, this if statement should nev - end - set(AxesHandle,'YLim',[-MaxTrialType-.5, -.5], 'YTick', -MaxTrialType:1:-1,'YTickLabel', strsplit(num2str(MaxTrialType:-1:-1))); - if CurrentTrial<1 - CurrentTrial = 1; - end - TrialTypeList = -TrialTypeList; - % recompute xlim - if length(TrialTypeList) > CurrentTrial % trial types are pre-determined - [mn, mx] = rescaleX(AxesHandle,CurrentTrial,nTrialsToShow); - else % if trial types are not predetermined, have graph end at current trial - mn = max(1, CurrentTrial - nTrialsToShow + 1); - mx = CurrentTrial; - end - - - %axes(AxesHandle); %cla; - %plot future trials - FutureTrialsIndx = CurrentTrial:mx; - Xdata = FutureTrialsIndx; Ydata = TrialTypeList(Xdata); - set(BpodSystem.GUIHandles.FutureTrialLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); - %Plot current trial - set(BpodSystem.GUIHandles.CurrentTrialCircle, 'xdata', [CurrentTrial,CurrentTrial], 'ydata', [TrialTypeList(CurrentTrial),TrialTypeList(CurrentTrial)]); - set(BpodSystem.GUIHandles.CurrentTrialCross, 'xdata', [CurrentTrial,CurrentTrial], 'ydata', [TrialTypeList(CurrentTrial),TrialTypeList(CurrentTrial)]); - - %Plot past trials - if ~isempty(OutcomeRecord) - indxToPlot = mn:CurrentTrial-1; - %Plot Error, unpunished - EarlyWithdrawalTrialsIndx =(OutcomeRecord(indxToPlot) == -1); - Xdata = indxToPlot(EarlyWithdrawalTrialsIndx); Ydata = TrialTypeList(Xdata); - set(BpodSystem.GUIHandles.UnpunishedErrorLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); - %Plot Error, punished - InCorrectTrialsIndx = (OutcomeRecord(indxToPlot) == 0); - Xdata = indxToPlot(InCorrectTrialsIndx); Ydata = TrialTypeList(Xdata); - set(BpodSystem.GUIHandles.PunishedErrorLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); - %Plot Correct, rewarded - CorrectTrialsIndx = (OutcomeRecord(indxToPlot) == 1); - Xdata = indxToPlot(CorrectTrialsIndx); Ydata = TrialTypeList(Xdata); - set(BpodSystem.GUIHandles.RewardedCorrectLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); - %Plot Correct, unrewarded - UnrewardedTrialsIndx = (OutcomeRecord(indxToPlot) == 2); - Xdata = indxToPlot(UnrewardedTrialsIndx); Ydata = TrialTypeList(Xdata); - set(BpodSystem.GUIHandles.UnrewardedCorrectLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); - %Plot DidNotChoose - DidNotChooseTrialsIndx = (OutcomeRecord(indxToPlot) == 3); - Xdata = indxToPlot(DidNotChooseTrialsIndx); Ydata = TrialTypeList(Xdata); - set(BpodSystem.GUIHandles.NoResponseLine, 'xdata', [Xdata,Xdata], 'ydata', [Ydata,Ydata]); - end -end - -end - -function [mn,mx] = rescaleX(AxesHandle,CurrentTrial,nTrialsToShow) -FractionWindowStickpoint = .75; % After this fraction of visible trials, the trial position in the window "sticks" and the window begins to slide through trials. -mn = max(round(CurrentTrial - FractionWindowStickpoint*nTrialsToShow),1); -mx = mn + nTrialsToShow - 1; -set(AxesHandle,'XLim',[mn-1 mx+1]); -end - - diff --git a/Functions/SoundCalibrator/SoundCalibrationManager.m b/Functions/SoundCalibrator/SoundCalibrationManager.m index 31b8b9a..c861cf3 100644 --- a/Functions/SoundCalibrator/SoundCalibrationManager.m +++ b/Functions/SoundCalibrator/SoundCalibrationManager.m @@ -55,11 +55,20 @@ function SoundCalibrationManager_OpeningFcn(hObject, eventdata, handles, varargi global BpodSystem if ispc % Start the MCC board with PsychToolbox BpodSystem.PluginObjects.USB1608G = struct; - warning off; BpodSystem.PluginObjects.USB1608G.Board = analoginput('mcc', 0); warning on; - BpodSystem.PluginObjects.USB1608G.Board.SampleRate = 200000; - BpodSystem.PluginObjects.USB1608G.Board.SamplesPerTrigger = 200000*.3; - BpodSystem.PluginObjects.USB1608G.Ch0 = addchannel(BpodSystem.PluginObjects.USB1608G.Board, 0); - BpodSystem.PluginObjects.USB1608G.Ch0.InputRange = [-10 10]; +% warning off; BpodSystem.PluginObjects.USB1608G.Board = analoginput('mcc', 0); warning on; + warning off; BpodSystem.PluginObjects.USB1608G.Board = daq.createSession('mcc'); warning on; + + % BpodSystem.PluginObjects.USB1608G.Board.SampleRate = 200000; + BpodSystem.PluginObjects.USB1608G.Board.Rate = 200000; + + %BpodSystem.PluginObjects.USB1608G.Board.SamplesPerTrigger = 200000*.3; + + % BpodSystem.PluginObjects.USB1608G.Ch0 = addchannel(BpodSystem.PluginObjects.USB1608G.Board, 0); + BpodSystem.PluginObjects.USB1608G.Ch0 = addAnalogInputChannel(BpodSystem.PluginObjects.USB1608G.Board,'Board0',0,'Voltage'); + + %BpodSystem.PluginObjects.USB1608G.Ch0.InputRange = [-10 10]; + BpodSystem.PluginObjects.USB1608G.Ch0.Range = [-10 10]; + end % Choose default command line output for SoundCalibrationManager handles.output = hObject; @@ -350,4 +359,4 @@ function edit11_CreateFcn(hObject, eventdata, handles) % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); -end +end \ No newline at end of file diff --git a/Functions/SoundCalibrator/TestSoundManager.m b/Functions/SoundCalibrator/TestSoundManager.m index c5aba15..fcf0a81 100644 --- a/Functions/SoundCalibrator/TestSoundManager.m +++ b/Functions/SoundCalibrator/TestSoundManager.m @@ -112,19 +112,20 @@ function play_Callback(hObject, eventdata, handles) CalFilePath = get(handles.filename_edit, 'String'); try - open(CalFilePath); % Creates local variable "SoundCal", a struct with the cal table and coefficients + load(CalFilePath); % Creates local variable "SoundCal", a struct with the cal table and coefficients catch error('Could not open calibration file'); end frequency = str2double(get(handles.frequency_edit, 'String')); -speaker = get(handles.speaker1, 'Value'); -if speaker == 0 % Other radio button is selected - speaker = 2; +handles.speaker = get(handles.speaker1, 'Value'); +if handles.speaker == 0 % Other radio button is selected + handles.speaker = 2; end % Attenuation for this frequency at Target SPL toneAtt = polyval(SoundCal(1,handles.speaker).Coefficient,frequency); -diffSPL = str2double(handles.volume_edit.String) - SoundCal(1,speaker).TargetSPL; + +diffSPL = str2double(handles.volume_edit.String) - SoundCal(1,handles.speaker).TargetSPL; attFactor = sqrt(10^(diffSPL/10)); amplitude = toneAtt*attFactor; @@ -206,4 +207,4 @@ function frequency_edit_Callback(hObject, eventdata, handles) % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of frequency_edit as text -% str2double(get(hObject,'String')) returns contents of frequency_edit as a double +% str2double(get(hObject,'String')) returns contents of frequency_edit as a double \ No newline at end of file diff --git a/Functions/SoundCalibrator/old version/SoundCalibrationManager-.m b/Functions/SoundCalibrator/old version/SoundCalibrationManager-.m new file mode 100644 index 0000000..31b8b9a --- /dev/null +++ b/Functions/SoundCalibrator/old version/SoundCalibrationManager-.m @@ -0,0 +1,353 @@ +function varargout = SoundCalibrationManager(varargin) + +% SOUNDCALIBRATIONMANAGER MATLAB code for SoundCalibrationManager.fig +% SOUNDCALIBRATIONMANAGER, by itself, creates a new SOUNDCALIBRATIONMANAGER or raises the existing +% singleton*. +% +% H = SOUNDCALIBRATIONMANAGER returns the handle to a new SOUNDCALIBRATIONMANAGER or the handle to +% the existing singleton*. +% +% SOUNDCALIBRATIONMANAGER('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in SOUNDCALIBRATIONMANAGER.M with the given input arguments. +% +% SOUNDCALIBRATIONMANAGER('Property','Value',...) creates a new SOUNDCALIBRATIONMANAGER or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before SoundCalibrationManager_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to SoundCalibrationManager_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help SoundCalibrationManager + +% Last Modified by GUIDE v2.5 18-Sep-2015 10:31:07 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @SoundCalibrationManager_OpeningFcn, ... + 'gui_OutputFcn', @SoundCalibrationManager_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before SoundCalibrationManager is made visible. +function SoundCalibrationManager_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to SoundCalibrationManager (see VARARGIN) +global BpodSystem +if ispc % Start the MCC board with PsychToolbox + BpodSystem.PluginObjects.USB1608G = struct; + warning off; BpodSystem.PluginObjects.USB1608G.Board = analoginput('mcc', 0); warning on; + BpodSystem.PluginObjects.USB1608G.Board.SampleRate = 200000; + BpodSystem.PluginObjects.USB1608G.Board.SamplesPerTrigger = 200000*.3; + BpodSystem.PluginObjects.USB1608G.Ch0 = addchannel(BpodSystem.PluginObjects.USB1608G.Board, 0); + BpodSystem.PluginObjects.USB1608G.Ch0.InputRange = [-10 10]; +end +% Choose default command line output for SoundCalibrationManager +handles.output = hObject; + +handles.filename = []; + +% Update handles structure +guidata(hObject, handles); + +% UIWAIT makes SoundCalibrationManager wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = SoundCalibrationManager_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; + +% --- Executes during object creation, after setting all properties. +function MaxFreq_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit10 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + + +% --- Executes during object creation, after setting all properties. +function SoundType_CreateFcn(hObject, eventdata, handles) +% hObject handle to SoundType (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function TargetSPL_CreateFcn(hObject, eventdata, handles) +% hObject handle to TargetSPL (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function MinBandLimit_CreateFcn(hObject, eventdata, handles) +% hObject handle to MinBandLimit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function MaxBandLimit_CreateFcn(hObject, eventdata, handles) +% hObject handle to MaxBandLimit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes on button press in calibrate. +function calibrate_Callback(hObject, eventdata, handles) +% hObject handle to calibrate (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% --- Initialize Sound Server --- +global BpodSystem +BpodSystem.PluginObjects.SoundCal = struct; +BpodSystem.PluginObjects.SoundCal.Abort = 0; +C = colormap; +%Get Calibration Parameters +TargetSPL = str2double(get(handles.TargetSPL,'String')); +MinFreq = str2double(get(handles.MinFreq,'String')); +MaxFreq = str2double(get(handles.MaxFreq,'String')); +nFreq = str2double(get(handles.nFreq,'String')); +nSpeakers = str2double(get(handles.nSpeakers,'String')); +nRepeats = str2double(get(handles.edit11,'String')); + +MinBandLimit = str2double(get(handles.MinBandLimit,'String')); +MaxBandLimit = str2double(get(handles.MaxBandLimit,'String')); + +FrequencyVector = logspace(log10(MinFreq),log10(MaxFreq),nFreq); + +PsychToolboxSoundServer('init') + +OutputFileName = ['SoundCalibration']; +[FileName,PathName] = uiputfile('.mat','Save Sound Calibration File',OutputFileName); + +handles.filename = fullfile(PathName,FileName); + +AttenuationVector = zeros(nFreq,nSpeakers,nRepeats); +SoundCal = struct; + +for inds=1:nSpeakers % -- Loop through speakers -- + + switch inds + case 1 + symb = 'o'; + case 2 + symb = 'x'; + end + + uiwait(msgbox({[' Calibrating speaker ' num2str(inds) '.'],' Position microphone and press OK to continue...'},'Sound Calibration','modal')); + + + Sound.Speaker = inds; + + for rep=1:nRepeats + + if rep>1 + uiwait(msgbox('Reposition mic for next repetition and press OK','Sound Calibration','modal')); + end + + for indf=1:nFreq % -- Loop through frequencies -- + + Sound.Frequency = FrequencyVector(indf); + BandLimits = Sound.Frequency * [MinBandLimit MaxBandLimit]; + + AttenuationVector(indf, inds,rep) = find_amplitude(Sound,TargetSPL,BandLimits,handles); + if AttenuationVector(indf, inds,rep) == 1 + errordlg('ERROR: The sound recorded was not loud enough to calibrate. Please manually increase the speaker volume and restart.'); + return; + end + axes(handles.attFig); + hold on + semilogx(FrequencyVector(1:indf)/1000,AttenuationVector(1:indf,inds,rep),[symb '-'],'Color',C(floor(64/nSpeakers/nRepeats)*(rep-1)+floor(64/nSpeakers)*(inds-1)+1,:)); + New_XTickLabel = get(gca,'xtick'); + set(gca,'XTickLabel',New_XTickLabel); + grid on; + ylabel('Attenuation (dB)'); + xlabel('Frequency (kHz)') + axis([MinFreq/1000 MaxFreq/1000 0 1]) + end + end + + semilogx(FrequencyVector(1:indf)/1000,mean(AttenuationVector(:,inds,:),3),'-','Color',C(floor(64/nSpeakers)*(inds-1)+1,:),'linewidth',1.5); + + SoundCal(1,inds).Table = [FrequencyVector' mean(AttenuationVector(:,inds,:),3)]; + SoundCal(1,inds).CalibrationTargetRange = [MinFreq MaxFreq]; + SoundCal(1,inds).TargetSPL = TargetSPL; + SoundCal(1,inds).LastDateModified = date; + SoundCal(1,inds).Coefficient = polyfit(FrequencyVector',mean(AttenuationVector(:,inds),3),1); + + drawnow; +end + +% -- Saving results -- +save(fullfile(PathName,FileName),'SoundCal'); + +uiwait(msgbox({'The Sound Calibration file has been saved in: ', fullfile(PathName,FileName)},'Sound Calibration','modal')); + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function MinFreq_CreateFcn(hObject, eventdata, handles) +% hObject handle to MinFreq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function nFreq_CreateFcn(hObject, eventdata, handles) +% hObject handle to nFreq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function nSpeakers_CreateFcn(hObject, eventdata, handles) +% hObject handle to nSpeakers (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function edit8_CreateFcn(hObject, eventdata, handles) +% hObject handle to MaxBandLimit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function edit9_CreateFcn(hObject, eventdata, handles) +% hObject handle to MinBandLimit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function edit10_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit10 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in test_btn. +function test_btn_Callback(hObject, eventdata, handles) +% hObject handle to test_btn (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +TestSoundManager(handles.filename) + +% --- Executes on button press in pause_btn. +function pause_btn_Callback(hObject, eventdata, handles) +% hObject handle to test_btn (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +global BpodSystem +BpodSystem.PluginObjects.SoundCal.Abort = 1; + +% --- Executes on button press in test_btn. +function nFreq_Callback(hObject, eventdata, handles) +% hObject handle to test_btn (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + + +function edit11_Callback(hObject, eventdata, handles) +% hObject handle to edit11 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of edit11 as text +% str2double(get(hObject,'String')) returns contents of edit11 as a double + + +% --- Executes during object creation, after setting all properties. +function edit11_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit11 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end diff --git a/Functions/SoundCalibrator/old version/TestSoundManager-.m b/Functions/SoundCalibrator/old version/TestSoundManager-.m new file mode 100644 index 0000000..c5aba15 --- /dev/null +++ b/Functions/SoundCalibrator/old version/TestSoundManager-.m @@ -0,0 +1,209 @@ +function varargout = TestSoundManager(varargin) +% TESTSOUNDMANAGER MATLAB code for TestSoundManager.fig +% TESTSOUNDMANAGER, by itself, creates a new TESTSOUNDMANAGER or raises the existing +% singleton*. +% +% H = TESTSOUNDMANAGER returns the handle to a new TESTSOUNDMANAGER or the handle to +% the existing singleton*. +% +% TESTSOUNDMANAGER('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in TESTSOUNDMANAGER.M with the given input arguments. +% +% TESTSOUNDMANAGER('Property','Value',...) creates a new TESTSOUNDMANAGER or raises +% the existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before TestSoundManager_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to TestSoundManager_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help TestSoundManager + +% Last Modified by GUIDE v2.5 18-Sep-2015 12:21:16 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @TestSoundManager_OpeningFcn, ... + 'gui_OutputFcn', @TestSoundManager_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + +% --- Executes just before TestSoundManager is made visible. +function TestSoundManager_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to TestSoundManager (see VARARGIN) + + + +% --- Outputs from this function are returned to the command line. +function varargout = TestSoundManager_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure + + + +% --- Executes during object creation, after setting all properties. +function frequency_edit_CreateFcn(hObject, eventdata, handles) +% hObject handle to frequency_edit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes during object creation, after setting all properties. +function volume_edit_CreateFcn(hObject, eventdata, handles) +% hObject handle to volume_edit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function volume_edit_Callback(hObject, eventdata, handles) +% hObject handle to volume_edit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of volume_edit as text +% str2double(get(hObject,'String')) returns contents of volume_edit as a double + + +% --- Executes on button press in play. +function play_Callback(hObject, eventdata, handles) +% hObject handle to play (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% --- Parameters of the test --- +toneDuration = 1; +fsOut = 192000; +tvec = 0:1/fsOut:toneDuration; + +CalFilePath = get(handles.filename_edit, 'String'); +try + open(CalFilePath); % Creates local variable "SoundCal", a struct with the cal table and coefficients +catch + error('Could not open calibration file'); +end +frequency = str2double(get(handles.frequency_edit, 'String')); +speaker = get(handles.speaker1, 'Value'); +if speaker == 0 % Other radio button is selected + speaker = 2; +end +% Attenuation for this frequency at Target SPL +toneAtt = polyval(SoundCal(1,handles.speaker).Coefficient,frequency); + +diffSPL = str2double(handles.volume_edit.String) - SoundCal(1,speaker).TargetSPL; +attFactor = sqrt(10^(diffSPL/10)); + +amplitude = toneAtt*attFactor; + +SoundVec = amplitude * sin(2*pi*frequency*tvec); + +if handles.speaker==1 + SoundVec = [ SoundVec; zeros(1,length(SoundVec)) ]; +end +if handles.speaker==2 + SoundVec = [ zeros(1,length(SoundVec)); SoundVec ]; +end + +% Load sound +PsychToolboxSoundServer('Load', 1, SoundVec); +% --- Play the sound --- +PsychToolboxSoundServer('Play', 1); + + +% --- Executes on button press in close. +function close_Callback(hObject, eventdata, handles) +% hObject handle to close (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +close(handles.gui) + +% --- Executes when selected object changed in unitgroup. +function unitgroup_SelectionChangedFcn(hObject, eventdata, handles) +% hObject handle to the selected object in unitgroup +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +if (hObject == handles.speaker1) + handles.speaker=1; +else + handles.speaker=2; +end +guidata(hObject,handles) + +function filename_edit_Callback(hObject, eventdata, handles) +% hObject handle to filename_edit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of filename_edit as text +% str2double(get(hObject,'String')) returns contents of filename_edit as a double + + +% --- Executes during object creation, after setting all properties. +function filename_edit_CreateFcn(hObject, eventdata, handles) +% hObject handle to filename_edit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in file. +function file_Callback(hObject, eventdata, handles) +% hObject handle to file (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +[FileName,PathName] = uigetfile; +handles.calfile = fullfile(PathName,FileName); +handles.filename_edit.String = handles.calfile; +load(handles.calfile) +handles.SoundCal = SoundCal; +guidata(hObject,handles) + + + +function frequency_edit_Callback(hObject, eventdata, handles) +% hObject handle to frequency_edit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of frequency_edit as text +% str2double(get(hObject,'String')) returns contents of frequency_edit as a double diff --git a/Functions/SoundCalibrator/old version/response_one_sound-.m b/Functions/SoundCalibrator/old version/response_one_sound-.m new file mode 100644 index 0000000..c21fcb0 --- /dev/null +++ b/Functions/SoundCalibrator/old version/response_one_sound-.m @@ -0,0 +1,85 @@ +% Get the sound intensity produced by a pure tone of a particular +% amplitude and frequency going into the speaker. +% +% Santiago Jaramillo - 2007.11.14 +% Uri - 2013.05.27 +% Fede - 2015.09.10 + +function [BandPower, signal_toplot, Parameters, ThisPSD] = response_one_sound(SoundParam,BandLimits) +global BpodSystem +% --- Parameters of the test --- +Parameters.ToneDuration = 1;%0.8; % sec +Parameters.TimeToRecord = 0.3; % sec +Parameters.FsOut = 192000; % Sampling frequency +tvec = 0:1/Parameters.FsOut:Parameters.ToneDuration; + +% --- Setting up PSD estimation --- +hPSD = spectrum.welch; +hPSD.SegmentLength=2048*8; + +% --- Set the acquisition card --- +channel = 1; +n_chan = 1; + +Parameters.FsIn = 200000; +n_data = Parameters.TimeToRecord*Parameters.FsIn; + +% --- Creating and loading sounds --- +SoundVec = SoundParam.Amplitude * sin(2*pi*SoundParam.Frequency*tvec); + +if SoundParam.Speaker==1 + SoundVec = [ SoundVec; zeros(1,length(SoundVec)) ]; +end +if SoundParam.Speaker==2 + SoundVec = [ zeros(1,length(SoundVec)); SoundVec ]; +end + +% Load sound +PsychToolboxSoundServer('Load', 1, SoundVec); + +% --- Play the sound --- +PsychToolboxSoundServer('Play', 1); + +pause(0.1); +if ispc + start(BpodSystem.PluginObjects.USB1608G.Board); + pause(.5); + RawSignal = getdata(BpodSystem.PluginObjects.USB1608G.Board)'; +else + data = mcc_daq('n_scan',n_data,'freq',Parameters.FsIn,'n_chan',n_chan); + RawSignal = data(channel,:); +end + +pause(Parameters.ToneDuration); + +signal_toplot = [0:1/Parameters.FsIn:(size(RawSignal,2)-1)/Parameters.FsIn; RawSignal]; + +PsychToolboxSoundServer('StopAll'); + +% --- Calculate power --- +ThisPSD = psd(hPSD,RawSignal,'Fs',Parameters.FsIn); +BandPower = band_power(ThisPSD.Data,ThisPSD.Frequencies,BandLimits); + + +function StimuliVec=SqCosBeeper(RR,SR,Freq,BeepDuration,CosRamp,MaxToneDuration) + +t1=0:1/SR:((BeepDuration/1000)-(1/SR)); +T=1/SR:1/SR:MaxToneDuration; +GetOnset=mod(T,(1/RR));%% find beep onset index +GetOnset=[1 find(diff(diff(GetOnset)>0)==-1)+3]; +CosRampLength=floor(CosRamp/1000*SR); +BeepLength=floor(BeepDuration/1000*SR); +ramp=(cos(t1(1:CosRampLength)*pi*2*1000/CosRamp)*-1+1)/2; +SpitRampInx=find(diff(ramp)<=0,1,'first'); +UpRamp=ramp(1:SpitRampInx); +DwRamp=ramp(SpitRampInx+1:end); +Ramp=[UpRamp ones(1,BeepLength-CosRampLength),DwRamp]; +FreqComponenmts=sum(sin(2*pi*T'*Freq+repmat(rand(1,length(Freq))*2*pi, length(T), 1)),2)'; + +% integrate beep into one long vec +BeepVec=zeros(size(T)); +for ii=GetOnset + BeepVec(ii:ii+length(t1)-1)=Ramp; +end +BeepVec(MaxToneDuration*SR+1:end)=[]; +StimuliVec=FreqComponenmts.*BeepVec; diff --git a/Functions/SoundCalibrator/response_one_sound.m b/Functions/SoundCalibrator/response_one_sound.m index c21fcb0..0c20f2c 100644 --- a/Functions/SoundCalibrator/response_one_sound.m +++ b/Functions/SoundCalibrator/response_one_sound.m @@ -42,9 +42,11 @@ pause(0.1); if ispc - start(BpodSystem.PluginObjects.USB1608G.Board); - pause(.5); - RawSignal = getdata(BpodSystem.PluginObjects.USB1608G.Board)'; + %start(BpodSystem.PluginObjects.USB1608G.Board); + %pause(.5); + %RawSignal = getdata(BpodSystem.PluginObjects.USB1608G.Board)'; + [RawSignal]=startForeground(BpodSystem.PluginObjects.USB1608G.Board); + else data = mcc_daq('n_scan',n_data,'freq',Parameters.FsIn,'n_chan',n_chan); RawSignal = data(channel,:); @@ -82,4 +84,4 @@ BeepVec(ii:ii+length(t1)-1)=Ramp; end BeepVec(MaxToneDuration*SR+1:end)=[]; -StimuliVec=FreqComponenmts.*BeepVec; +StimuliVec=FreqComponenmts.*BeepVec; \ No newline at end of file