Dear Josh,
When using BpodWavePlayer, we notice that when a wave is playing in loop mode (in one channel) and we try to update the waveform of another wave (to be played on a different channel) it starts producing distorted signals on all channels.
Here is a test protocol for this issue:
%% Create an instance of the wavePlayer module
W = BpodWavePlayer(WavePlayerUSB);
SF=50000;
sig_T = 4;
Wave_Mask = randn(1, SF*sig_T);
Wave_Mask = 4.9*Wave_Mask/(max(abs(Wave_Mask)));
Level_A = -2*ones(1, 100);
Fstim = 40;
Tstim = 1;
timeSig = 0:1/SF:Tstim;
Wave_LaserPowerSig = 4*sin(2*pi*Fstim*timeSig);
% Program wave server
W.LoopDuration = [300 0 0 0]; % in seconds
W.LoopMode={'On', 'Off', 'Off', 'Off'};
W.SamplingRate = SF;
W.TriggerMode = 'Master'; % triggers can force-start a new wave during playback
W.TriggerProfileEnable = 'On';
W.OutputRange = '-5V:5V';
W.setupSDCard();
W.loadWaveform(1, Level_A);
W.loadWaveform(2, Wave_Mask);
W.loadWaveform(3, Wave_LaserPowerSig);
W.TriggerProfiles = zeros(64,4);
W.TriggerProfiles(1,:) = [2 3 0 0];
W.TriggerProfiles(2,:) = [1 0 0 0];
%% Set Bpod serial message library with correct codes to trigger waves X on analog output channels X
analogPortIndex = find(strcmp(BpodSystem.Modules.Name, 'WavePlayer1'));
if isempty(analogPortIndex)
error('Error: Bpod WavePlayer module not found. If you just plugged it in, please restart Bpod.')
end
ResetSerialMessages;
LoadSerialMessages('WavePlayer1', ['P' 0], 99);
LoadSerialMessages('WavePlayer1', ['P' 1], 98);
%% Main loop (runs once per trial)
for currentTrial = 1:MaxTrials
S = BpodParameterGUI('sync', S); % Sync parameters with BpodParameterGUI plugin
%--- Typically, a block of code here will compute variables for assembling this trial's state machine
if currentTrial>1
Wave_LaserPowerSig = randi(4)*sin(2*pi*Fstim*timeSig);
W.loadWaveform(3, Wave_LaserPowerSig);
end
%--- Assemble state machine
sma = NewStateMachine();
sma = AddState(sma, 'Name', 'FirstState', ... % This example state does nothing, and ends after 0 seconds
'Timer', 1,...
'StateChangeConditions', {'Tup', 'SecondState'},...
'OutputActions', {'WavePlayer1' 99});
sma = AddState(sma, 'Name', 'SecondState', ... % This example state does nothing, and ends after 0 seconds
'Timer', 1,...
'StateChangeConditions', {'Tup', 'LastState'},...
'OutputActions', {'WavePlayer1' 98});
sma = AddState(sma, 'Name', 'LastState', ... % This example state does nothing, and ends after 0 seconds
'Timer', 1,...
'StateChangeConditions', {'Tup', 'exit'},...
'OutputActions', {});
SendStateMatrix(sma); % Send state machine to the Bpod state machine device
RawEvents = RunStateMatrix; % Run the trial and return events
%--- Package and save the trial's data, update plots
if ~isempty(fieldnames(RawEvents)) % If you didn't stop the session manually mid-trial
BpodSystem.Data = AddTrialEvents(BpodSystem.Data,RawEvents); % Adds raw events to a human-readable data struct
BpodSystem.Data.TrialSettings(currentTrial) = S; % Adds the settings used for the current trial to the Data struct (to be saved after the trial ends)
SaveBpodSessionData; % Saves the field BpodSystem.Data to the current data file
%--- Typically a block of code here will update online plots using the newly updated BpodSystem.Data
end
%--- This final block of code is necessary for the Bpod console's pause and stop buttons to work
HandlePauseCondition; % Checks to see if the protocol is paused. If so, waits until user resumes.
if BpodSystem.Status.BeingUsed == 0
W.stop();
return
end
end
The Level_A wave is playing in loop mode on channel 1 at the start of each trial. At that time we need to update the waveform Wave_LaserPowerSig.
If the protocol runs like this for a few trials, the played output signals eventually become distorted. Often the BpodWavePlayer needs to be powered off/on to recover the integrity of the signals.
This however does not occur if we set Loop Mode to Off and use very long signals instead.
Is there a solution for this?