MATLAB has encountered an internal error and needs to close - macos

I've just installed the new MATLAB R2013b for 64bit Mac, and my OS is OS X 10.8.4. I'm running into a consistent problem that I never had with R2013a. When I run one of my scripts (see below), the entire script goes through OK, but then I keep getting an error message "MATLAB has encountered an internal problem and needs to close." Then I have to shut MATLAB down.
I have a feeling that I've goofed somewhere on the installation since I'm new to MATLAB, but I'm not sure.
This exact same script still runs fine on R2013a, which I've yet to uninstall. The script (making use of Psychtoolbox) is an experiment which opens a screen, presents some text, presents an audio file, and requires the participant to respond with 6 keystrokes. This script only presents two audio files, since I'm just testing it.
All the loops seem to work on both versions of MATLAB, and the screen closes at the end (which only happens after 2 passes through the main loop). I take this to mean the script is working, but something in a post stage is causing issues.
Any and all ideas are much appreciated!
-Josh
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% SCREEN & AUDIO SETUP %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%
%% SCREEN %%
%%%%%%%%%%%%
% Set up a nice blank screen.
whichScreen = 0;
% Full Screen mode
%window = Screen(whichScreen, 'OpenWindow');
% Small screen mode used for code testing
window = Screen('OpenWindow',0, [450 450 500], [5,5, 550,550]);
white = WhiteIndex(window); % pixel value for white
Screen(window, 'FillRect', white);
Screen(window, 'Flip');
% Set global text size for the display.
Screen('TextSize', window, 15);
Screen(window,'TextFont','Arial');
Screen('TextStyle', window, 0)
%%%%%%%%%%%
%% AUDIO %%
%%%%%%%%%%%
% Set initial audio parameters:
nrchannels = 1; % All stimuli are mono-sounds.
freq = 44100;
% Initialize sound driver.
InitializePsychSound;
try
pahandle = PsychPortAudio('Open', [], [], 3, freq, nrchannels);
catch
% If the above fails, use the audio device's standard frequency.
psychlasterror('reset'); % I believe this some reseting of the error made in 'try'.
pahandle = PsychPortAudio('Open', [], [], 3, [], nrchannels);
end
%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%
%%%%% MAIN LOOP %%%%%
%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%
home = '/Users/josh/Dropbox/Beverlab/Fall_2013_Study/Design/Matlab/'
SampleExperiment = {strcat(home,'Stimuli/tokensA/gipa_mono.wav'),...
strcat(home,'Stimuli/tokensB/gabo_mono.wav')};
timeLimit = 10; % Set up the time limit.
ans = 0; % This is used to track whether or not the participant answered.
numStim = 2; % Just using 2 right now to test the code
ListenChar(0);
for i=1:numStim;
token = char(SampleExperiment(1,randi([1,2]))); % randomly select a wave file from 'SampleExperiment' and assign it to 'token'
[y,freq] = wavread(token); % Read the current wav file.
wavedata = y'; % Transpose wav data.
PsychPortAudio('FillBuffer', pahandle, wavedata); % fill the buffer, ready to play
t1 = PsychPortAudio('Start', pahandle, 1, 0, 1); % play the wave file and get timestamp in one go
while GetSecs<t1+timeLimit
if ans<6
[secs, keyCode, deltaSecs] = KbWait([],2,t1+timeLimit);
if isempty(find(keyCode,1))
break
end
if ~isempty(find(keyCode,1))
ans=ans+1;
end
end
if ans==6
WaitSecs(rand*3+1);
break
end
end
if ans<6
DrawFormattedText(window, 'Lets try that again...press 6 times', 'center', 'center');
Screen(window, 'Flip');
WaitSecs(1);
Screen(window, 'FillRect', white);
Screen(window, 'Flip');
[y,freq] = wavread(token); % Read the current wav file.
wavedata = y'; % Transpose wav data.
PsychPortAudio('FillBuffer', pahandle, wavedata); % fill the buffer, ready to play
t1 = PsychPortAudio('Start', pahandle, 1, 0, 1); % play the wave file and get timestamp in one go
while GetSecs<t1+timeLimit
if ans<6
[secs, keyCode, deltaSecs] = KbWait([],2,t1+timeLimit);
if isempty(find(keyCode,1))
break
end
if ~isempty(find(keyCode,1))
ans=ans+1;
end
end
if ans==6
WaitSecs(rand*3+1);
break
end
end
end
end
Screen('CloseAll')

This sort of error usually indicates something drastic and unrecoverable has happened. It appears that the Psychtoolbox contains MEX files, that is probably the most likely culprit. I would either attempt to rebuild those using R2013b, or contact the authors to see if they have a version compatible with R2013b.

This crashing is likely due to a new bug in OSX 10.8.4, causing PsychToolBox to crash on closing the connection to the display server (and apparently bringing MATLAB with it). See here for discussion and resolution.
Anybody still having this issue, please update to the latest version of PsychToolBox (which is always a good idea!)

Related

How can I make udate_idletasks work on Mac

I've written a tkinter script with animation, that works fine on Xubuntu, but when I run it on Mac, the animation doesn't work. Here's a little script that demonstrates the problem:
import tkinter as tk
from time import sleep
root = tk.Tk()
canvas = tk.Canvas(root, height=200, width = 200)
canvas.pack()
this = canvas.create_rectangle(25,25, 75, 75, fill='blue')
that = canvas.create_rectangle(125, 125, 175, 175, fill = 'red')
def blink(event):
global this, that
for _ in range(9):
canvas.itemconfigure(this, fill='red')
canvas.itemconfigure(that, fill = 'blue')
canvas.update_idletasks()
sleep(.4)
this, that = that, this
canvas.bind('<ButtonRelease-1>', blink)
root.mainloop()
This draws a red square and a blue square on a canvas. When the user clicks the canvas, the squares repeatedly switch colors. On Xubuntu, it works as intended.
On Mac, when I click the canvas, I get spinning beach ball, and after a few seconds, we see that squares have switched colors, because they switch colors an odd number of times in the code.
It seems to me that update_idletasks isn't working. Is there some way to fix this? I am running python 3.9.5 with Tk 8.6 on Big Sur.
I think what you can do is avoid tasks that will block the mainloop, in this case time.sleep(). So your code can be remade by emulating a for loop with after, and I see nothing that stops this general code from running OS independent:
count = 0 # Think of this as the `_` in for _ in range(9)
def blink(event=None):
global this, that, count
if count < 9: # Basically repeats everytime `count` is less than 9, like a for loop
canvas.itemconfigure(this, fill='red')
canvas.itemconfigure(that, fill='blue')
this, that = that, this
count += 1 # Increase count
root.after(400,blink) # Repeat this code block every 400 ms or 0.4 seconds
else:
count = 0 # After it is 9, set it to 0 for the next click to be processed
I found that using update instead of update_idletasks works on both platforms. It's my understanding though, that the latter is much preferred. See the accepted answer to this question for example. This solves my immediate problem, but does anyone know if update_idletasks ever works on the Mac?

FMOD Ex dropping sounds, eventually going silent

I'm attempting to port an old open-source FMOD 3 game (Candy Crisis) to the latest version of FMOD Ex 4 on OS X. Its sound needs are very simpleā€”it plays WAVs, sometimes changing their frequency or speaker mix, and also plays MOD tracker music, sometimes changing the speed. I'm finding that the game works fine at first, but over the course of a few minutes, it starts truncating sounds early, then the music loses channels and eventually stops, then over time all sound ceases. I can cause the problem to reproduce more quickly if I lower the number of channels available to FMOD.
I can get the truncated/missing sounds issue to occur even if I never play a music file, but music definitely seems to make things worse. I have also tried commenting out the code which adjusts the sound frequency and speaker mix, and that was not the issue.
I am calling update() every frame.
Here's the entirety of my interactions with FMOD to play WAVs:
void InitSound( void )
{
FMOD_RESULT result = FMOD::System_Create(&g_fmod);
FMOD_ERRCHECK(result);
unsigned int version;
result = g_fmod->getVersion(&version);
FMOD_ERRCHECK(result);
if (version < FMOD_VERSION)
{
printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION);
abort();
}
result = g_fmod->init(8 /* was originally 64, but 8 repros the issue faster */, FMOD_INIT_NORMAL, 0);
FMOD_ERRCHECK(result);
for (int index=0; index<kNumSounds; index++)
{
result = g_fmod->createSound(QuickResourceName("snd", index+128, ".wav"), FMOD_DEFAULT, 0, &s_sound[index]);
FMOD_ERRCHECK(result);
}
}
void PlayMono( short which )
{
if (soundOn)
{
FMOD_RESULT result = g_fmod->playSound(FMOD_CHANNEL_FREE, s_sound[which], false, NULL);
FMOD_ERRCHECK(result);
}
}
void PlayStereoFrequency( short player, short which, short freq )
{
if (soundOn)
{
FMOD::Channel* channel = NULL;
FMOD_RESULT result = g_fmod->playSound(FMOD_CHANNEL_FREE, s_sound[which], true, &channel);
FMOD_ERRCHECK(result);
result = channel->setSpeakerMix(player, 1.0f - player, 0, 0, 0, 0, 0, 0);
FMOD_ERRCHECK(result);
float channelFrequency;
result = s_sound[which]->getDefaults(&channelFrequency, NULL, NULL, NULL);
FMOD_ERRCHECK(result);
result = channel->setFrequency((channelFrequency * (16 + freq)) / 16);
FMOD_ERRCHECK(result);
result = channel->setPaused(false);
FMOD_ERRCHECK(result);
}
}
void UpdateSound()
{
g_fmod->update();
}
And here's how I play MODs.
void ChooseMusic( short which )
{
if( musicSelection >= 0 && musicSelection <= k_songs )
{
s_musicChannel->stop();
s_musicChannel = NULL;
s_musicModule->release();
s_musicModule = NULL;
musicSelection = -1;
}
if (which >= 0 && which <= k_songs)
{
FMOD_RESULT result = g_fmod->createSound(QuickResourceName("mod", which+128, ""), FMOD_DEFAULT, 0, &s_musicModule);
FMOD_ERRCHECK(result);
result = g_fmod->playSound(FMOD_CHANNEL_FREE, s_musicModule, true, &s_musicChannel);
FMOD_ERRCHECK(result);
EnableMusic(musicOn);
s_musicModule->setLoopCount(-1);
s_musicChannel->setPaused(false);
musicSelection = which;
s_musicPaused = 0;
}
}
If someone wants to experiment with this, let me know and I'll upload the project somewhere. My gut feeling is that FMOD is busted but I'd love to be proven wrong.
Sounds like your music needs to be set as higher priority than your other sounds. Remember, lower numbers are more important. I think you can just set the priority on the channel.
Every time I play the following WAV, FMOD loses one channel permanently. I am able to reproduce this channel-losing behavior in the "playsound" example if I replace the existing jaguar.wav with my file.
https://drive.google.com/file/d/0B1eDRY8sV_a9SXMyNktXbWZOYWs/view?usp=sharing
I contacted Firelight and got this response. Apparently WAVs can include a looping command! I had no idea.
Hello John,
I've taken a look at the two files you have provided. Both files end
with a 2 sample infinite loop region.
FMOD 4 (and FMOD 5 for that matter) will see the loop region in the
file and automatically enable FMOD_LOOP_NORMAL if you haven't
specified any loop mode. Assuming you want one-shot behavior just pass
in FMOD_LOOP_OFF when you create the sound.
Kind regards, Mathew Block | Senior Platform Engineer
Technically this behavior contradicts the documented behavior of FMOD_DEFAULT (which is specified to imply FMOD_LOOP_OFF) so they are planning to improve the documentation here.
Based on the wave sample you supplied, FMOD is behaving correctly as it appears you've figured out. The sample has a loop that is honored by FMOD and the last samples are simply repeated forever. While useless, this is correct and the variance in the samples is so slight as to not be audible. While not part of the original spec for wave format, extended information was added later to support meta data such as author, title, comments and multiple loop points.
Your best bet is to examine all your source assets for those that contain loop information. Simply playing all sounds without loop information is probably not the best workaround. Some loops may be intentional. Those that are will have code that stops them. Typically, in a game, the entire waveform is looped when looping is desired. You can then write or use a tool that will strip the loop information. If you do write your own tool, I'd recommend resampling the audio to the native output sampling rate of the hardware. You'd need to insure your resampler was sample accurate (no time shift) and did not introduce noise.
Historically, some game systems had a section at the end of the sound with silence and a loop point set on this region. The short reason for this was to reduce popping that might occur at the end of a sound in a hardware audio channel.
Curiosly, the last 16 samples of your .wav look like garbage and I'm wondering if the .wav assets you're using were converted from a source meant for a game console and that's where the bogus loop information came from as well.
This would have been a comment but my lowly rep does not allow it.

How to extract frames at particular intervals from video using matlab

I am using matlab 2013a software for my project.
I face a problem while splitting video into individual frames.
I want to know how to get frames at a specific intervals from video.. i.e., i want to grab frames at the rate of one frame per second(frame/sec) .My input video has 50 frames/sec. In the code I have used step() to slice the video into frames.
The following is my code , basically a face detection code(detects multiple faces in a video) . This code captures every frame in the video(i.e 50fp approx) and processes it. I want to process frames at the rate of 1 fps. Please help me.
clear classes;
videoFileReader = vision.VideoFileReader('C:\Users\Desktop\project\05.mp4');
**videoFrame = step(videoFileReader);**
faceDetector = vision.CascadeObjectDetector(); % Finds faces by default
tracker = MultiObjectTrackerKLT;
videoPlayer = vision.VideoPlayer('Position',[200 100 fliplr(frameSize(1:2)+30)]);
bboxes = [];
while isempty(bboxes)
**framergb = step(videoFileReader);**
frame = rgb2gray(framergb);
bboxes = faceDetector.step(frame);
end
tracker.addDetections(frame, bboxes);
frameNumber = 0;
keepRunning = true;
while keepRunning
**framergb = step(videoFileReader);**
frame = rgb2gray(framergb);
if mod(frameNumber, 10) == 0
bboxes = 2 * faceDetector.step(imresize(frame, 0.5));
if ~isempty(bboxes)
tracker.addDetections(frame, bboxes);
end
else
% Track faces
tracker.track(frame);
end
end
%% Clean up
release(videoPlayer);
But this actually considers every frame. I want to grab 1fps.
It cannot be done directly in Matlab 2013a, because the video access library does not provide the feature you want. Writing the necessary code to implement an efficient frame skipping routine is not really possible using just Matlab code (you would need to look inside the video libraries)
Working around it, you have two basic options:
Do as little work as possible on frames that you do not want to process.
Where you currently have
framergb = step(videoFileReader);
Instead do something like
for i=1:49,
step(videoFileReader);
end
framergb = step(videoFileReader);
(NB this does not allow for going beyond end of input)
Pre-process your file with a tool like ffmpeg, and reduce the frame-rate before you use Matlab.
The ffmpeg command might look something like this:
ffmpeg -i 05.mp4 -r 1 05_at_1fps.mp4

Making a gif from images

I have a load of data in 100 .sdf files (labelled 0000.sdf to 0099.sdf), each of which contain a still image, and I'm trying to produce a .gif from these images.
The code I use to plot the figure are (in the same directory as the sdf files):
q = GetDataSDF('0000.sdf');
imagesc(q.data');
I've attempted to write a for loop that would plot the figure and then save it with the same filename as the sdf file but to no avail, using:
for a = 1:100
q=GetDataSDF('0000.sdf');
fh = imagesc(q.dist_fn.x_px.Left.data');
frm = getframe( fh );
% save as png image
saveas(fh, 'current_frame_%02d.jpg');
end
EDIT: I received the following errors when trying to run this code:
Error using hg.image/get
The name 'Units' is not an accessible property for an instance of class 'image'.
Error in getframe>Local_getRectanglesOfInterest (line 138)
if ~strcmpi(get(h, 'Units'), 'Pixels')
Error in getframe (line 56)
[offsetRect, absoluteRect, figPos, figOuterPos] = ...
Error in loop_code (line 4)
frm = getframe( fh );
How do I save these files using a for loop, and how do I then use those files to produce a movie?
The reason for the error is that you pass an image handle to getframe, but this function excpects a figure handle.
Another problem is that you always load the same file, and that you saveas will not work for gifs. (For saving figures as static images, maybe print is the better option?)
I tried to modify my own gif-writing loop so that it works with your data. I'll try to be extra explicit in the comments, since you seem to be starting out. Remember, you can always use help name_of_command to display a short Matlab help.
% Define a variable that holds the frames per second your "movie" should have
gif_fps = 24;
% Define string variable that holds the filename of your movie
video_filename = 'video.gif';
% Create figure 1, store the handle in a variable, you'll need it later
fh = figure(1);
for a = 0:99
% Prepare file name so that you loop over the data
q = GetDataSDF(['00' num2str(a,'%02d') 'sdf']);
% Plot image
imagesc(q.dist_fn.x_px.Left.data');
% Force Matlab to actually do the plot (it sometimes gets lazy in loops)
drawnow;
% Take a "screenshot" of the figure fh
frame = getframe(fh);
% Turn screenshot into image
im = frame2im(frame);
% Turn image into indexed image (the gif format needs this)
[imind,cm] = rgb2ind(im,256);
% If first loop iteration: Create the file, else append to it
if a == 0;
imwrite(imind,cm,video_filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,video_filename,'gif','WriteMode','append','DelayTime',1/gif_fps);
end
end
One more note: When the size of the data is the same for each plot, it makes sense to only use the plot(or in this case, imagesc) command once, and in later loop iterations replace it with a set(ah,'Ydata',new_y_data) (or in this case set(ah,'CData',q.dist_fn.x_px.Left.data'), where ah is a handle of the plot axes (not the plot figure!). This is orders of magnitude faster than creating a whole new plot in each loop iteration. The downside is that the scaling (here, the color-scaling) will be the same for each plot. But in every case that I have worked on so far, that was actually desirable.

Creating Movie for each Generation of Data [duplicate]

This question already has an answer here:
How to create movies on each generation of a for loop in Matlab plot
(1 answer)
Closed 9 years ago.
I have the following code:
figure;
contour(X1,X2,f);
hold on
plot(top(1:size(top,1)), 'rx');
EDIT
figure;
for i = 1: G
contour(X1,X2,f);
hold on
plot(top(1:size(top,1)), 'rx');
end
NB: G is the maximum generation.
This is supposed to plot contours of sphere superimposed with selected individuals. In each iteration of the individuals, the best individuals is selected and these going on until the global optimum is reached. I need to show this in a movie form as shown in this below:
When you runs each stage of the iteration is indicated in the slides attached. This is what i am trying to do. Any idea please?
OK, I am just copying and pasting now, from here.
However I added FrameRate (per second) since you might want to use (or ask) it later.
writerObj = VideoWriter('Your_video.avi');
writerObj .FrameRate = 1; % 1 frames per second animation.
open(writerObj);
fig_h = figure;
for i = 1: G
contour(X1,X2,f);
hold on
plot(top(1:size(top,1)), 'rx');
frame = getframe(fig_h); % or frame = getframe; since getframe gets gcf.
writeVideo(writerObj, frame);
end
close(writerObj);
Now you will have a Your_video.avi file in your working directory.
If VideoWriter is not supported by your matlab, you could use use avifile same as mentioned in this answer (or in mathwork documentaion example here) like this:
aviobj = avifile('Your_video.avi','compression','None', 'fps', 1);
fig_h = figure;
for i = 1:G
contour(X1,X2,f);
hold on
plot(top(1:size(top,1)), 'rx');
frame = getframe(fig_h); % or frame = getframe; since getframe gets gcf.
aviobj = addframe(aviobj, frame);
end
aviobj = close(aviobj);
EDIT
A problem may occur as pointed out by this question also, which is the captured frame is a constant image. If you are running Matlab on windows, this problem may be caused by conjunction of windows in with certain graphics drivers, and may be solved as mentioned in this answer.

Resources