<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5383877989815914374</id><updated>2012-01-09T11:06:09.938+08:00</updated><category term='matlab'/><category term='mex'/><category term='tcp'/><category term='spectral analyser'/><category term='socket'/><category term='plot'/><category term='optimisation'/><category term='java'/><category term='object oriented'/><category term='profiler'/><category term='WindowButtonMotionFcn'/><category term='gui'/><category term='ip'/><category term='c'/><title type='text'>Gaffer Tape and Matlab... Its all you need</title><subtitle type='html'>A collection of useful (or at least interesting) Matlab functions that I've created over the years as well as some from around the place that have caught my eye.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-1972790581707252320</id><published>2010-06-19T21:12:00.009+08:00</published><updated>2010-06-23T09:27:46.991+08:00</updated><title type='text'>Non-blocking Output Socket</title><content type='html'>My &lt;a href="http://iheartmatlab.blogspot.com/2009/09/tcpip-socket-communications-in-matlab.html"&gt;MATLAB TCP/IP&lt;/a&gt; example has been quite popular, and I myself use it at least once a week on various applications. However, one of the main limitations when compared to our C++ style output sockets was the limitation of only 1 client per socket.&lt;br /&gt;&lt;br /&gt;What was worse, is that I knew it COULD be done. I had just not found the time to write it! Cue a spare Saturday!&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/27975"&gt;Non-blocking Output Socket&lt;/a&gt; @ MATLAB Central&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;The Problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As per my previous server.m examples, you begin by constructing a Java &lt;span style="font-style: italic;"&gt;ServerSocket&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:courier new;"&gt;&gt;&gt; server_socket = ServerSocket(output_port);&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&gt;&gt; server_socket.setSoTimeout(1000);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;This attempts to bind the &lt;span style="font-style: italic;"&gt;ServerSocket &lt;/span&gt;to the specified port. HOWEVER, it is not listening for incoming connections! To do this, you must tell the &lt;span style="font-style: italic;"&gt;ServerSocket &lt;/span&gt;to &lt;span style="font-style: italic;"&gt;accept()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:courier new;"&gt;&gt;&gt; output_socket = server_socket.accept();&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;This is a BLOCKING call. That is, the code will wait for either the timeout (set above) to occur, or a client to connect.&lt;br /&gt;&lt;br /&gt;For a lot of what I do, the output socket exists mainly as a debugging / monitoring interface. So I don't even care if noone is listening. So what we need is something that manages the connection of clients and the distribution of any written data to each of them.&lt;br /&gt;&lt;br /&gt;Enter &lt;span style="font-style: italic;"&gt;OutputSocket &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;ListeningThread&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;OutputSocket&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;OutputSocket &lt;/span&gt;provides a very simple interface:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;// Description : Create an OutputSocket on the specified port&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;br /&gt;public &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;OutputSocket&lt;/span&gt;(&lt;span style="color: rgb(51, 51, 255);"&gt;int &lt;/span&gt;port) &lt;span style="color: rgb(51, 51, 255);"&gt;throws &lt;/span&gt;IOException&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;// Description : Write the supplied byte array to all connected clients&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;br /&gt;public void&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;write&lt;/span&gt;(&lt;span style="color: rgb(51, 51, 255);"&gt;byte&lt;/span&gt;[] data)&lt;/span&gt;  &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;&lt;br /&gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;// Description : Close the OutputSocket. This closes all client &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//               connections and stops listening for new connections.&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;br /&gt;public void&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;close&lt;/span&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;ListeningThread&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;OutputSocket &lt;/span&gt;utilises &lt;span style="font-style: italic;"&gt;ListeningThread &lt;/span&gt;to manage the accepting of new connections. &lt;span style="font-style: italic;"&gt;ListeningThread &lt;/span&gt;implements the &lt;span style="font-style: italic;"&gt;Runnable &lt;/span&gt;interface so can be started in its own thread (vital!).&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//-------------------------------------------------------------------------&lt;br /&gt;// Description : Helper class that listens for new TCP/IP client&lt;br /&gt;//               connections on a ServerSocket&lt;br /&gt;//&lt;br /&gt;// Parameters  : server_socket          - ServerSocket to listen on&lt;br /&gt;//               connection_list        - List of connected client&lt;br /&gt;//                                        Sockets to update&lt;br /&gt;//               connection_stream_list - List of connected client&lt;br /&gt;//                                        DataOutputStreams to update&lt;br /&gt;//---------------------------------------------------------------------&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;public &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;ListeningThread&lt;/span&gt;(ServerSocket server_socket,&lt;br /&gt;                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;List         connection_list,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;                   &lt;br /&gt;                   List         connection_stream_list)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;br /&gt;// Description : Called on Thread.start()&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;br /&gt;public void &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;run&lt;/span&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//---------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;// Description : Stop the thread&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;//---------------------------------------------------------------------&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;br /&gt;public void &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;stop&lt;/span&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Interaction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;OutputSocket &lt;/span&gt;constructor creates the &lt;span style="font-style: italic;"&gt;ServerSocket &lt;/span&gt;as before and stores it as a member variable. It also creates 2 empty lists, one for the &lt;span style="font-style: italic;"&gt;Socket &lt;/span&gt;client connections and one for the associated &lt;span style="font-style: italic;"&gt;DataOutputStream&lt;/span&gt;s used to write to them.&lt;br /&gt;&lt;br /&gt;It supplies a reference to these to the &lt;span style="font-style: italic;"&gt;ListeningThread &lt;/span&gt;on construction and then starts it running in its own &lt;span style="font-style: italic;"&gt;Thread&lt;/span&gt;. This is the important part. &lt;span style="font-style: italic;"&gt;OutputSocket &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;ListeningThread &lt;/span&gt;both share a reference to the &lt;span style="font-style: italic;"&gt;DataOutputStream &lt;/span&gt;list, so as &lt;span style="font-style: italic;"&gt;ListeningThread &lt;/span&gt;creates connections and output streams, these are pushed onto the client list.&lt;br /&gt;&lt;br /&gt;When &lt;span style="font-style: italic;"&gt;OutputSocket::write()&lt;/span&gt; is called, it writes the data across all output streams (be there 0 or 100!)&lt;br /&gt;&lt;br /&gt;When you have finished with the &lt;span style="font-style: italic;"&gt;OutputSocket&lt;/span&gt;, a call to&lt;span style="font-style: italic;"&gt; close()&lt;/span&gt; will stop the &lt;span style="font-style: italic;"&gt;ListeningThread&lt;/span&gt; from running and close all client connections.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Usage from within MATLAB&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Place the .class files in a suitable location (I've stuck them in my current working directory).&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);font-family:courier new;" &gt;&gt;&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;% Add the directory containing the .class files to your Java path&lt;/span&gt;&lt;br /&gt;&gt;&gt; javaaddpath(pwd)&lt;br /&gt;&gt;&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;% Create the OutputSocket&lt;/span&gt;&lt;br /&gt;&gt;&gt; output_socket = OutputSocket(1234)&lt;br /&gt;&lt;br /&gt;output_socket =&lt;br /&gt;&lt;br /&gt;OutputSocket@1c68b20&lt;br /&gt;&lt;br /&gt;&gt;&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;% Write some data to the output socket - text will do for now&lt;/span&gt;&lt;br /&gt;&gt;&gt; &lt;span style="color: rgb(51, 51, 255);"&gt;for &lt;/span&gt;i = 1:100&lt;br /&gt;output_socket.write(int8(sprintf(&lt;span style="color: rgb(204, 51, 204);"&gt;'This is line %03d\r\n'&lt;/span&gt;, i)));&lt;br /&gt;pause(1);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&gt;&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;% cleanup the socket - close connections&lt;/span&gt;&lt;br /&gt;&gt;&gt; output_socket.close()&lt;br /&gt;&gt;&gt; clear &lt;span style="color: rgb(204, 51, 204);"&gt;output_socket &lt;span style="color: rgb(0, 153, 0);"&gt;% no longer needed / useful&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;As you can see, multiple connections are supported. They can connect/disconnect at any time. Even if there are no connections, a call to &lt;span style="font-style: italic;"&gt;OutputSocket::write()&lt;/span&gt; will be successful.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xDCIlmJJ6bg/TBzQN8n_W2I/AAAAAAAAACI/5S3Gd2rnBUg/s1600/matlab_ss.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 264px;" src="http://1.bp.blogspot.com/_xDCIlmJJ6bg/TBzQN8n_W2I/AAAAAAAAACI/5S3Gd2rnBUg/s400/matlab_ss.png" alt="" id="BLOGGER_PHOTO_ID_5484487384261155682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;**Update**&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've included in the revised submission to MATLABCentral a wrapper MATLAB class that helps manage the lifetime of the Java object.&lt;br /&gt;&lt;br /&gt;This is VERY useful because if you happen to clear the Java object (ie &lt;span style="font-style: italic;"&gt;clear output_socket&lt;/span&gt;) before calling &lt;span style="font-style: italic;"&gt;.close()&lt;/span&gt; the &lt;span style="font-style: italic;"&gt;Thread &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;ServerSocket &lt;/span&gt;etc remain in memory (and stay connected!) until MATLAB is closed!&lt;br /&gt;&lt;br /&gt;Suggested usage of &lt;span style="font-style: italic;"&gt;MatlabOutputSocket &lt;/span&gt;below.&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);font-family:courier new;" &gt;&gt;&gt; javaaddpath(pwd); &lt;span style="color: rgb(0, 153, 0);"&gt;% get the Java class&lt;/span&gt;&lt;br /&gt;&gt;&gt; output_socket = MatlabOutputSocket(1234);&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;for &lt;/span&gt;i = 1:100&lt;br /&gt;output_socket.write(int8(sprintf(&lt;span style="color: rgb(204, 51, 204);"&gt;'Line %03d\r\n'&lt;/span&gt;, i)));&lt;br /&gt;pause(1);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&gt;&gt; output_socket.close()&lt;br /&gt;&gt;&gt; clear &lt;span style="color: rgb(204, 51, 204);"&gt;output_socket&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;I've included the Java source file in the MATLABCentral submission, so feel free to have a look at the source code, have a fiddle, recompile.&lt;br /&gt;&lt;br /&gt;To do this you will need to install the &lt;a href="http://java.sun.com/javase/downloads/widget/jdk6.jsp"&gt;Java Development Kit (JDK)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To compile the classes, navigate to the directory containing the .java file and type:&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);font-family:courier new;" &gt;&gt;&gt; javac OutputSocket.java&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;NOTE: You will have to repeat the call to javaaddpath() for the new files to be seen by MATLAB.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-1972790581707252320?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/1972790581707252320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=1972790581707252320' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/1972790581707252320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/1972790581707252320'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2010/06/non-blocking-output-socket.html' title='Non-blocking Output Socket'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xDCIlmJJ6bg/TBzQN8n_W2I/AAAAAAAAACI/5S3Gd2rnBUg/s72-c/matlab_ss.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-5320236539313996813</id><published>2009-09-07T14:00:00.005+08:00</published><updated>2009-09-09T09:14:12.912+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tcp'/><category scheme='http://www.blogger.com/atom/ns#' term='ip'/><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><title type='text'>TCP/IP Socket Communications in MATLAB - Part 2</title><content type='html'>So my little blog post about &lt;a href="http://iheartmatlab.blogspot.com/2008/08/tcpip-socket-communications-in-matlab.html"&gt;TCP/IP Socket Communications in MATLAB&lt;/a&gt; was rather popular despite being a very simple example.&lt;br /&gt;&lt;br /&gt;One of the main limitations that people found when trying to utilise the server/client scripts for their own applications, was that it was incredibly inefficient at shifting large volumes of data around. This is thanks to the following lines:&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;message = zeros(1, bytes_available, &lt;span style="color: rgb(204, 51, 204);"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="color: rgb(204, 102, 204);"&gt;uint&lt;/span&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;8'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;for &lt;/span&gt;i = 1:bytes_available&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    message(i) = d_input_stream.&lt;span style="color: rgb(0, 0, 0);" class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;readByte&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;For &lt;span style="font-weight: bold;"&gt;each individual byte&lt;/span&gt; within the message, there was the overhead of a function call.&lt;br /&gt;&lt;br /&gt;I mentioned in comments on MATLAB Central that I made a Java class that bypassed this overhead and allowed for more efficient transfer. Being in a caring sharing mood (and getting sick of emailing it to people all the time!) I thought I would upload it also.&lt;br /&gt;&lt;br /&gt;The is available on the Mathworks File Exchange: &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21131&amp;amp;objectType=file"&gt; &lt;/a&gt;&lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/25249"&gt;TCP/IP Socket Comms Example using Java Class&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Compiled Java?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The client/server scripts are essentially identical to their previous iterations.&lt;br /&gt;&lt;br /&gt;The server still uses a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html"&gt;ServerSocket&lt;/a&gt; and the resulting &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/DataOutputStream.html"&gt;DataOutputStream&lt;/a&gt; to which we write data.&lt;br /&gt;&lt;br /&gt;The client side uses a  &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html"&gt;Socket&lt;/a&gt; to connect to the specified host and port which provides us an &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html"&gt;InputStream&lt;/a&gt; which we wrap in a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/DataInputStream.html"&gt;DataInputStream&lt;/a&gt; to read data from. However, instead of using the interface of &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/DataInputStream.html"&gt;DataInputStream&lt;/a&gt; directly, we hand off to another function (the new DataReader class) to perform the read.&lt;br /&gt;&lt;br /&gt;The code for the example  client is outlined below.  I have bolded the changes. (The server is unchanged).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;client.m&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% CLIENT connect to a server and read a message&lt;br /&gt;%&lt;br /&gt;% Usage - message = client(host, port, number_of_retries)&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;message = client(host, port, number_of_retries)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    import &lt;span style="color: rgb(204, 51, 204);"&gt;java.net.Socket&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    import &lt;span style="color: rgb(204, 51, 204);"&gt;java.io.*&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;nargin &lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt; number_of_retries =" 20;" style="color: rgb(0, 153, 0);"&gt;% set to -1 for infinite&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    retry        = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    input_socket = [];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    message      = [];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;while &lt;/span&gt;true&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        retry = retry + 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;((number_of_retries &gt; 0) &amp;amp;&amp;amp; (retry &gt; number_of_retries))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;fprintf&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Too many retries\n'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;break&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;fprintf&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Retry %d connecting to %s:%d\n'&lt;/span&gt;, ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    retry, host, port);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% throws if unable to connect&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            input_socket = Socket(host, port);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% get a buffered data input stream from the socket&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            input_stream   = input_socket.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;getInputStream&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            d_input_stream = &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;DataInputStream&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(input_stream);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;fprintf&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Connected to server\n'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% read data from the socket - wait a short time first&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            pause(0.5);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            bytes_available = input_stream.available;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;fprintf&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Reading %d bytes\n'&lt;/span&gt;, bytes_available);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;            data_reader = DataReader(d_input_stream);&lt;br /&gt;        message     = data_reader.readBuffer(bytes_available);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="font-weight: bold;"&gt;message = char(message');&lt;/span&gt;&lt;/span&gt; % Data comes out as a column vector&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% cleanup&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            input_socket.close;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;break&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;catch&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;~&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;isempty&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(input_socket)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                input_socket.close;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% pause before retrying&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            pause(1);&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;    end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;Instead of looping for each byte, we now ask the DataReader object to read the specified number of bytes and return them to us. So a single function call per read. This could be used to read buffers of expected data sizes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;DataReader&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Below is the Java source for the DataReader class (available in the MATLAB File Exchange also).&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;import &lt;/span&gt;java.io.*;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;class &lt;/span&gt;DataReader&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;public &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;DataReader&lt;/span&gt;(DataInput data_input)&lt;br /&gt;{&lt;br /&gt;   m_data_input = data_input;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;public byte&lt;/span&gt;[] &lt;span style="font-weight: bold;"&gt;readBuffer&lt;/span&gt;(int length)&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;byte&lt;/span&gt;[] buffer = &lt;span style="color: rgb(51, 51, 255);"&gt;new byte&lt;/span&gt;[length];&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;try&lt;/span&gt;&lt;br /&gt;   {&lt;br /&gt;       m_data_input.&lt;span style="font-weight: bold;"&gt;readFully&lt;/span&gt;(buffer, 0, length);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;catch &lt;/span&gt;(StreamCorruptedException e)&lt;br /&gt;   {&lt;br /&gt;       System.out.&lt;span style="font-weight: bold;"&gt;println&lt;/span&gt;(&lt;span style="color: rgb(204, 51, 204);"&gt;"Stream Corrupted Exception Occured"&lt;/span&gt;);&lt;br /&gt;       buffer = &lt;span style="color: rgb(51, 51, 255);"&gt;new byte&lt;/span&gt;[0];&lt;br /&gt;   }&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;catch &lt;/span&gt;(EOFException e)&lt;br /&gt;   {&lt;br /&gt;       System.out.println(&lt;span style="color: rgb(204, 51, 204);"&gt;"EOF Reached"&lt;/span&gt;);&lt;br /&gt;       buffer = &lt;span style="color: rgb(51, 51, 255);"&gt;new byte&lt;/span&gt;[0];&lt;br /&gt;   }&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;catch &lt;/span&gt;(IOException e)&lt;br /&gt;   {&lt;br /&gt;       System.out.println(&lt;span style="color: rgb(204, 51, 204);"&gt;"IO Exception Occured"&lt;/span&gt;);&lt;br /&gt;       buffer = &lt;span style="color: rgb(51, 51, 255);"&gt;new byte&lt;/span&gt;[0];&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;return &lt;/span&gt;buffer;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;private &lt;/span&gt;DataInput m_data_input;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;It is very simple class that is given a DataInput to read from, and has a single public method &lt;span style="font-weight: bold;"&gt;readBuffer&lt;/span&gt;(&lt;span style="color: rgb(51, 51, 255);"&gt;int &lt;/span&gt;length) that returns a byte array.&lt;br /&gt;&lt;br /&gt;If you have the Java Software Development Kit installed, you can compile the class with:&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;C:\matlab\matlab_socket&gt; javac data_reader.java&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Running the Client/Server example with DataReader&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This is the same as the previous example, with one exception. You must tell MATLAB where to find the compiled DataReader class (In my case it is located in the C:\matlab\matlab_socket directory):&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&gt; javaaddpath(&lt;span style="color: rgb(204, 51, 204);"&gt;'C:\matlab\matlab_socket'&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Opening up two instances of Matlab:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Instance 1&lt;/span&gt;&lt;br /&gt;&gt;&gt; message = char(mod(1:1000, 255)+1);&lt;br /&gt;&gt;&gt; server(message, 3000, 10)&lt;br /&gt;Try 1 waiting for client to connect to this host on port : 3000&lt;br /&gt;Try 2 waiting for client to connect to this host on port : 3000&lt;br /&gt;Try 3 waiting for client to connect to this host on port : 3000&lt;br /&gt;Try 4 waiting for client to connect to this host on port : 3000&lt;br /&gt;Client connected&lt;br /&gt;Writing 1000 bytes&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Instance 2 (simultaneously)&lt;br /&gt;% NOTE: If the 'server' was runnning on a non local machine, substitute its IP address&lt;br /&gt;% or host name here:&lt;br /&gt;%   data = client('10.61.1.200', 2666); % To connect to server at IP 10.61.1.200:2666&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;&gt;&gt; javaaddpath(&lt;span style="color: rgb(204, 51, 204);"&gt;'C:\matlab\matlab_socket'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&gt;&gt; data = client(&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;localhost&lt;/span&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(204, 51, 204);font-family:trebuchet ms;" &gt;'&lt;/span&gt;, 3000)&lt;br /&gt;Retry 1 connecting to &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="font-family:trebuchet ms;"&gt;localhost&lt;/span&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;:3000&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Connected to server&lt;br /&gt;Reading 1000 bytes&lt;br /&gt;&lt;br /&gt;data =&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                     &lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                     &lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                     &lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Why not call readFully() from within client.m?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The more astute readers may be asking the above question. Why not do something like this in client.m:&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;message = zeros(1, bytes_available, &lt;span style="color: rgb(204, 51, 204);"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;uint8&lt;/span&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;d_input_stream.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;readFully(message, 0 bytes_available)&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;At first glance that seems great. It runs without error, but hey, you don't seem to be getting any output?¿?&lt;br /&gt;&lt;br /&gt;The problem is that &lt;span style="font-weight: bold;"&gt;DataInputStream.readFully()&lt;/span&gt; takes a &lt;span style="font-weight: bold;"&gt;reference &lt;/span&gt;to a byte array to populate.&lt;br /&gt;&lt;br /&gt;When you pass things around in MATLAB that are to be modified, MATLAB supplies a &lt;span style="font-weight: bold;"&gt;copy&lt;/span&gt;. Thus the Java most likely sees a byte array reference, and populates it, but it is only the copy that is populated, not the original message array.&lt;br /&gt;&lt;br /&gt;Until there exists some way in MATLAB to pass references to Java methods, I am stuck using helper Java classes (If anyone else has ideas on how this could be done better, feel free to comment!).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-5320236539313996813?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/5320236539313996813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=5320236539313996813' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/5320236539313996813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/5320236539313996813'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2009/09/tcpip-socket-communications-in-matlab.html' title='TCP/IP Socket Communications in MATLAB - Part 2'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-3152545605254663586</id><published>2008-09-18T15:40:00.005+08:00</published><updated>2008-10-14T15:15:28.587+08:00</updated><title type='text'>Mathworks File Exchange Profile Information - Part 2</title><content type='html'>Ok, A quick little update here before I head off on holidays!&lt;br /&gt;&lt;br /&gt;Continuing on from my previous &lt;a href="http://iheartmatlab.blogspot.com/2008/09/mathworks-file-exchange-profile.html"&gt;post&lt;/a&gt; I realised that I wanted to watch how my submissions were performing over time (my memory is not quite what it used to be).&lt;br /&gt;&lt;br /&gt;I had a crazy idea, could I create a Timer that would scrape my user statistics from the Mathworks File Exchange site and save them in a format such that I could plot them easily???&lt;br /&gt;&lt;br /&gt;Introducing &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21465&amp;objectType=FILE"&gt;Monitor File Exchange Statistics&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Plotting my stats for the past week:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xDCIlmJJ6bg/SNII3PIIBVI/AAAAAAAAABs/pUJnjDsMowc/s1600-h/author_rank.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_xDCIlmJJ6bg/SNII3PIIBVI/AAAAAAAAABs/pUJnjDsMowc/s400/author_rank.png" alt="" id="BLOGGER_PHOTO_ID_5247266260886488402" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xDCIlmJJ6bg/SNII-sY0jNI/AAAAAAAAAB0/J69AT3W467Y/s1600-h/submitted_files.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_xDCIlmJJ6bg/SNII-sY0jNI/AAAAAAAAAB0/J69AT3W467Y/s400/submitted_files.png" alt="" id="BLOGGER_PHOTO_ID_5247266389000228050" border="0" /&gt;&lt;/a&gt;I'm not a big fan of the look of the submitted files plot as it can get a bit busy. I'm envisaging a lightweight GUI with a drop-down selector for each submitted file might be nicer. Particularly for those people with a large number of submitted files. I'll update the submission after I get back to do something like this.&lt;br /&gt;&lt;br /&gt;To set the automatic scraping of your File Exchange statistics you need to do the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download the required MATLAB files from &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectId=1109866&amp;amp;objectType=author"&gt;here&lt;/a&gt;. Need Monitor File Exchange Stats and Retrieve File Exchange Profile Information.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Place the files somewhere in your MATLAB path. Note, if you already have a startup.m, just add the InitialiseFileExchangeInfoTimer and UpdateFileExchangeInfoTimerFcn to your existing startup.m and call InitialiseFileExchangeInfoTimer from within.&lt;/li&gt;&lt;li&gt;Modify FEX_AUTHOR_ID and UPDATE_PERIOD with your File Exchange Author ID and your desired scrape frequency (seconds). The cache file defaults to being stored in your MATLAB root directory, modify FEX_SAVE_FILE if you wish to customise this location.&lt;/li&gt;&lt;li&gt;Save any changes and restart MATLAB.&lt;/li&gt;&lt;li&gt;Each time you restart Matlab you will be presented with a plot of your current and historical stats (for as long as you have been scraping).&lt;/li&gt;&lt;li&gt;To manually plot your current stats, call plotLocalFileExchangeInfo(cache_file)&lt;/li&gt;&lt;/ol&gt;In terms of file size, I've had the script running every 10 minutes for nearly a week and my cache file is only 45 kB.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-3152545605254663586?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/3152545605254663586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=3152545605254663586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/3152545605254663586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/3152545605254663586'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/09/mathworks-file-exchange-profile_18.html' title='Mathworks File Exchange Profile Information - Part 2'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xDCIlmJJ6bg/SNII3PIIBVI/AAAAAAAAABs/pUJnjDsMowc/s72-c/author_rank.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-3841623669481224067</id><published>2008-09-04T12:53:00.002+08:00</published><updated>2008-09-05T09:05:35.969+08:00</updated><title type='text'>Mathworks File Exchange Profile Information - Part 1</title><content type='html'>I have been uploading files to the &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadCategory.do"&gt;Mathworks File Exchange&lt;/a&gt; and have found that I get a sick pleasure looking at my &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectId=1109866&amp;amp;objectType=author"&gt;profile page&lt;/a&gt; each morning and seeing what people are downloading.&lt;br /&gt;&lt;br /&gt;So I thought I would write some MATLAB that would streamline my morning operation as well as gather some additional stats such as downloads/rank over time.&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Part 1 - Retrieving File Exchange Profile Information&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I've developed a simple function that will, given an Author ID download the Author's profile page from the Mathworks File Exchange and parse it for the Name, Total Downloads, Rank and the list of submitted files.&lt;br /&gt;&lt;br /&gt;The function is available on the Mathworks File Exchange: &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21324&amp;amp;objectType=file"&gt;&lt;span style="text-decoration: underline;"&gt;Retrieve File Exchange Profile Information&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;function &lt;/span&gt;file_exchange_info = getFileExchangeProfileInfo(author_id)&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%GETFILEEXCHANGEPROFILEINFO Retrieve File Exchange information&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   file_exchange_info = GETFILEEXCHANGEPROFILEINFO(author_id) retrieves an&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   Author's information from the Mathworks File Exchange&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   (http://www.mathworks.com/matlabcentral/fileexchange/)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   file_exchange_info is a structure with the following fields:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   .author_id       - As supplied to the function&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   .author_name     - Author name&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   .rank            - Author rank&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   .num_downloads   - Total number of downloads&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   .submitted_files - An array of structures with the following fields:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%       .id             - File Exchange submission ID&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%       .num_downloads  - Number of downloads for this submission&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%       .name           - Number of reviews for this file&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   If the File Exchange page could not be loaded, file_exchange_info will be&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%   returned empty.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Examples:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% file_exchange_info = getFileExchangeProfileInfo(1109866) % My profile&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% See also urlread&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;To use the script simply call it supplying the author if interest's Author ID. For example lets have a look at Stuart McGarrity's profile page with Author ID 126174 (currently the number 1 ranked author):&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&gt; info = getFileExchangeProfileInfo(126174)&lt;br /&gt;info =&lt;br /&gt;   author_id: 126174&lt;br /&gt; author_name: 'Stuart McGarrity'&lt;br /&gt;        rank: 1&lt;br /&gt;num_downloads: 163181&lt;br /&gt;submitted_files: [1x23 struct]&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;Looking at each submitted file in particular:&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&gt; for i = 1:length(info.submitted_files)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;info.submitted_files(i)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 2262&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: '802.11b PHY Simulink Model'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 21054&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 722&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Bluetooth modulation and frequency hopping'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 19999&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 724&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'DTMF generator and receiver'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 15117&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 907&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Bluetooth voice transmission'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 12225&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 3213&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: '802.11b PHY MATLAB Code'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 11803&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 2283&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Bluetooth Full Duplex Voice  and Data Transmission'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 10830&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 746&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'IS-95A CDMA Power Control'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 10406&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 787&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'IS-95A Mobile Phone Call Processing'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 9214&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 4380&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'MATLAB for C/C++ Programmers'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 9174&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 9060&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Handling Large Data Sets Efficiently in MATLAB'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 8329&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 7595&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: [1x59 char]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 8165&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 2596&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: '10Base-T Ethernet'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 5366&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 1550&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Packet Switch'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 4564&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 9622&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'MDF Import Tool and Function'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 3491&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 3939&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Import Fig File to Axes'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 2386&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 6528&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Introduction to MATLAB 7 Webinar Demonstrations'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 2168&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 13548&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'chkmem'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 1941&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 18972&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: [1x78 char]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 1941&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 16075&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Textscantool'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 1511&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 18971&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: [1x70 char]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 1410&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 14438&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: [1x69 char]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 924&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 9298&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: 'Data and M-Files for Demonstrations on MATLAB Demo Page'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 663&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ans =&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;          id: 19540&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        name: [1x77 char]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;num_downloads: 614&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;Part 2 of this post will detail how I will be using the information returned by this function over time.&lt;br /&gt;&lt;br /&gt;Now all I need to do is write it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-3841623669481224067?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/3841623669481224067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=3841623669481224067' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/3841623669481224067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/3841623669481224067'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/09/mathworks-file-exchange-profile.html' title='Mathworks File Exchange Profile Information - Part 1'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-1345298310931526427</id><published>2008-08-19T22:03:00.002+08:00</published><updated>2008-09-06T09:29:37.194+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tcp'/><category scheme='http://www.blogger.com/atom/ns#' term='ip'/><category scheme='http://www.blogger.com/atom/ns#' term='socket'/><title type='text'>TCP/IP Socket Communications in MATLAB</title><content type='html'>I often see people asking about network communications on the MATLAB &lt;a href="http://www.mathworks.com/matlabcentral/newsreader/"&gt;Newsgroup&lt;/a&gt;. Often this is for the communication between instances of MATLAB.&lt;br /&gt;&lt;br /&gt;Using the ability to call Java directly from within MATLAB, I'm going to provide a short example of a client/server written solely in MATLAB and usable from Release 14 onwards (possibly even earlier).&lt;br /&gt;&lt;br /&gt;The example is available on the Mathworks File Exchange: &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectType=author&amp;amp;objectId=1109866"&gt;&lt;/a&gt;&lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21131&amp;amp;objectType=file"&gt;Simple TCP/IP Socket Comms Example&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm working on a little TCP/IP comms library at the moment using these techniques. It will provide a nice layer of abstraction and allow you to use Sockets as you would in other programming languages (as well as one can in a single thread). Keep an eye out for it on the &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadCategory.do"&gt;File Exchange&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Interpreted Java?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Amazingly we can execute Java code, even from within the Command Window without the need to compile. For example, the traditional example:&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&gt; import java.lang.*&lt;br /&gt;&gt;&gt; System.out.println(&lt;span style="color: rgb(204, 51, 204);"&gt;'Hello World'&lt;/span&gt;)&lt;br /&gt;Hello World&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;To perform socket communications, we utilise the Java Socket and Input/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;OutputStream&lt;/span&gt; classes to pass data around via &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;TCP&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;IP&lt;/span&gt; sockets.&lt;br /&gt;&lt;br /&gt;On the server side we use (&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;unsurprisingly&lt;/span&gt;) a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;ServerSocket&lt;/span&gt;&lt;/a&gt;, which once a client has been accepted, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;provides&lt;/span&gt; a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html"&gt;Socket&lt;/a&gt; around which we wrap a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/DataOutputStream.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;DataOutputStream&lt;/span&gt;&lt;/a&gt; to which we can write data.&lt;br /&gt;&lt;br /&gt;On the client side we use a  &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html"&gt;Socket&lt;/a&gt; to connect to the specified host and port which provides us an &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;InputStream&lt;/span&gt;&lt;/a&gt; which we wrap in a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/DataInputStream.html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;DataInputStream&lt;/span&gt;&lt;/a&gt; to read data from.&lt;br /&gt;&lt;br /&gt;The code for the example server and client is outlined below.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;client.m&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% CLIENT connect to a server and read a message&lt;br /&gt;%&lt;br /&gt;% Usage - message = client(host, port, number_of_retries)&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;message = client(host, port, number_of_retries)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;import &lt;span style="color: rgb(204, 51, 204);"&gt;java.net.Socket&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    import &lt;span style="color: rgb(204, 51, 204);"&gt;java.io.*&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;nargin&lt;/span&gt; &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        number_of_retries = 20; &lt;span style="color: rgb(0, 153, 0);"&gt;% set to -1 for infinite&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    retry        = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    input_socket = [];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    message      = [];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;while &lt;/span&gt;true&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        retry = retry + 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;((number_of_retries &gt; 0) &amp;amp;&amp;amp; (retry &gt; number_of_retries))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;fprintf&lt;/span&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Too many retries\n'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;break&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;fprintf&lt;/span&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Retry %d connecting to %s:%d\n'&lt;/span&gt;, ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    retry, host, port);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% throws if unable to connect&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            input_socket = Socket(host, port);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% get a buffered data input stream from the socket&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            input_stream   = input_socket.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;getInputStream&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            d_input_stream = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;DataInputStream&lt;/span&gt;(input_stream);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;fprintf&lt;/span&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Connected to server\n'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% read data from the socket - wait a short time first&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            pause(0.5);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            bytes_available = input_stream.available;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;fprintf&lt;/span&gt;(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Reading %d bytes\n'&lt;/span&gt;, bytes_available);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            message = zeros(1, bytes_available, &lt;span style="color: rgb(204, 51, 204);"&gt;'&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;uint&lt;/span&gt;8'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;for &lt;/span&gt;i = 1:bytes_available&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                message(i) = d_input_stream.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;readByte&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            message = char(message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% cleanup&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            input_socket.close;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;break&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;catch&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;~&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;isempty&lt;/span&gt;(input_socket)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                input_socket.close;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% pause before retrying&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            pause(1);&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;    end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;server.m&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% SERVER Write a message over the specified port&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Usage - server(message, output_port, number_of_retries)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;function &lt;/span&gt;server(message, output_port, number_of_retries)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    import &lt;span style="color: rgb(204, 51, 204);"&gt;java.net.ServerSocket&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    import &lt;span style="color: rgb(204, 51, 204);"&gt;java.io.*&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;nargin&lt;/span&gt; &lt;&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        number_of_retries = 20; &lt;span style="color: rgb(0, 153, 0);"&gt;% set to -1 for infinite&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    retry             = 0;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    server_socket  = [];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    output_socket  = [];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 102, 255);"&gt;while &lt;/span&gt;true&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        retry = retry + 1;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;((number_of_retries &gt; 0) &amp;amp;&amp;amp; (retry &gt; number_of_retries))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                fprintf(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Too many retries\n'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                &lt;span style="color: rgb(51, 102, 255);"&gt;break&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            fprintf(1, [&lt;span style="color: rgb(204, 51, 204);"&gt;'Try %d waiting for client to connect to this '&lt;/span&gt; ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                        &lt;span style="color: rgb(204, 51, 204);"&gt;'host on port : %d\n'&lt;/span&gt;], retry, output_port);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% wait for 1 second for client to connect server socket&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            server_socket = ServerSocket(output_port);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            server_socket.setSoTimeout(1000);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            output_socket = server_socket.accept;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            fprintf(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Client connected\n'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            output_stream   = output_socket.getOutputStream;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            d_output_stream = DataOutputStream(output_stream);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;           &lt;span style="color: rgb(0, 153, 0);"&gt; % output the data over the DataOutputStream&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;            % Convert to stream of bytes&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            fprintf(1, &lt;span style="color: rgb(204, 51, 204);"&gt;'Writing %d bytes\n'&lt;/span&gt;, length(message))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            d_output_stream.writeBytes(char(message));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            d_output_stream.flush;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% clean up&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            server_socket.close;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            output_socket.close;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;break&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 102, 255);"&gt;catch&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;~isempty(server_socket)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                server_socket.close&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;~isempty(output_socket)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                output_socket.close&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(0, 153, 0);"&gt;% pause before retrying&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            pause(1);&lt;/span&gt;&lt;br /&gt;   end&lt;br /&gt;end&lt;br /&gt;end&lt;/span&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Opening up two instances of Matlab:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Instance 1&lt;/span&gt;&lt;br /&gt;&gt;&gt; message = char(mod(1:1000, 255)+1);&lt;br /&gt;&gt;&gt; server(message, 3000, 10)&lt;br /&gt;Try 1 waiting for client to connect to this host on port : 3000&lt;br /&gt;Try 2 waiting for client to connect to this host on port : 3000&lt;br /&gt;Try 3 waiting for client to connect to this host on port : 3000&lt;br /&gt;Try 4 waiting for client to connect to this host on port : 3000&lt;br /&gt;Client connected&lt;br /&gt;Writing 1000 bytes&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Instance 2 (simultaneously)&lt;br /&gt;% NOTE: If the 'server' was runnning on a non local machine, substitute its IP address&lt;br /&gt;% or host name here:&lt;br /&gt;%   data = client('10.61.1.200', 2666); % To connect to server at IP 10.61.1.200:2666&lt;br /&gt;&lt;/span&gt;&gt;&gt; data = client(&lt;span style="color: rgb(204, 51, 204);"&gt;'&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;localhost&lt;/span&gt;'&lt;/span&gt;, 3000)&lt;br /&gt;Retry 1 connecting to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;localhost&lt;/span&gt;:3000&lt;br /&gt;Retry 2 connecting to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;localhost&lt;/span&gt;:3000&lt;br /&gt;Connected to server&lt;br /&gt;Reading 1000 bytes&lt;br /&gt;&lt;br /&gt;data =&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                     &lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                     &lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                     &lt;br /&gt;&lt;br /&gt; !"#$%&amp;amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                             &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;This code can be expanded to read/write arbitrary data types, and SHOULD be expanded to properly deal with errors (ie not getting all of the buffer on receive end), but it serves as a simple example of how to get communication between MATLAB and other applications / instances of MATLAB.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-1345298310931526427?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/1345298310931526427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=1345298310931526427' title='30 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/1345298310931526427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/1345298310931526427'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/08/tcpip-socket-communications-in-matlab.html' title='TCP/IP Socket Communications in MATLAB'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>30</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-2621848863765989980</id><published>2008-08-12T22:53:00.002+08:00</published><updated>2008-08-13T15:15:32.416+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='mex'/><category scheme='http://www.blogger.com/atom/ns#' term='profiler'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Optimisation through MEX files</title><content type='html'>Whilst MATLAB is an excellent expressive tool, it can occasionally run a little bit slow for our liking. However, the folks at Mathworks have provided an interface that can be used to speed up code execution in particular circumstances.&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;MEX Files&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;MATLAB allows for compilation of C or Fortran sub-routines into a DLL (or equivalent) such that it can be called from within MATLAB as per any other function.&lt;br /&gt;&lt;br /&gt;I'll be using a simple example I came across a while ago when attempting to read in large GPS logs containing on the order of a million GPS position records. As expected, the process of parsing these files took some time. What was unexpected was where the code was using up CPU time.&lt;br /&gt;&lt;br /&gt;A quick run of the &lt;a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/profile.html"&gt;MATLAB Profiler&lt;/a&gt; revealed that approximately 50% of my processing time was spent in the calculation of the NMEA checksum (defined &lt;a href="http://www8.garmin.com/support/faqs/faq.jsp?faq=40"&gt;here&lt;/a&gt;). The MATLAB calculateChecksum function used is outlined below.&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%===============================================================================&lt;br /&gt;% Description : Calculate the NMEA Checksum for the supplied string. Calculated&lt;br /&gt;%               as the successive bitwise exclusive OR of all characters&lt;br /&gt;%===============================================================================&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;checksum = calculateChecksum(sentence)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(0, 153, 0);"&gt;&lt;br /&gt;% Initialise checksum&lt;/span&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;checksum = uint8(0);&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;for &lt;/span&gt;i_char = 1:length(sentence)&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;checksum = bitxor(checksum, uint8(sentence(i_char)));&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;br /&gt;checksum = dec2hex(checksum, 2);&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;To demonstrate the CPU usage of the above code snippet, a short test function was created:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;function &lt;/span&gt;test_Checksum&lt;br /&gt;&lt;br /&gt;nmea_sentence = &lt;span style="color: rgb(204, 51, 204);"&gt;'GPGGA,195237,4308.639,S,07744.402,E,1,03,3.2,365.3,M,-34.5,M,1001,'&lt;/span&gt;;&lt;br /&gt;cs = &lt;span style="color: rgb(204, 51, 204);"&gt;''&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;tic&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;  for &lt;/span&gt;i = 1:50000&lt;br /&gt;cs = calculateChecksum(nmea_sentence);&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;  end&lt;/span&gt;&lt;br /&gt;toc&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;  % Verify Checksum&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;  if &lt;/span&gt;(~strcmp(cs, &lt;span style="color: rgb(204, 51, 204);"&gt;'7F'&lt;/span&gt;))&lt;br /&gt;error(&lt;span style="color: rgb(204, 51, 204);"&gt;'Incorrect Checksum calculated'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;  end    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;The result of this function when executed several times:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Elapsed time is 4.990806 seconds.&lt;br /&gt;Elapsed time is 4.978824 seconds.&lt;br /&gt;Elapsed time is 5.029520 seconds.&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Looking at the profiler output (run independently):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_xDCIlmJJ6bg/SKGqp7WxSQI/AAAAAAAAABA/zA8PVLJW16s/s1600-h/profiler_output.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_xDCIlmJJ6bg/SKGqp7WxSQI/AAAAAAAAABA/zA8PVLJW16s/s400/profiler_output.png" alt="" id="BLOGGER_PHOTO_ID_5233651879265782018" border="0" /&gt;&lt;/a&gt;The majority of the time is spent performing the iterative XOR and the conversion from decimal to hexadecimal.&lt;br /&gt;&lt;br /&gt;Using &lt;a href="http://www.mathworks.com/support/tech-notes/1600/1605.html#example3"&gt;this example&lt;/a&gt; from Mathworks as a guide I created a simple MEX compatible C function that would calculate the 2 character hexadecimal checksum from a supplied string.&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;#include "mex.h"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;void &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;calculateChecksumFunction&lt;/span&gt;(&lt;span style="color: rgb(51, 102, 255);"&gt;const char&lt;/span&gt;* in_string, &lt;span style="color: rgb(51, 102, 255);"&gt;char &lt;/span&gt;*out_string)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;int &lt;/span&gt;checksum_as_int = 0;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;int &lt;/span&gt;i, str_length = &lt;span style="font-weight: bold;"&gt;strlen&lt;/span&gt;(in_string);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;for &lt;/span&gt;(i = 0; i &lt; style="color: rgb(51, 102, 255);"&gt;int&lt;/span&gt;)*(in_string++);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;checksum_as_int &amp;amp;= 0xFF;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;sprintf&lt;/span&gt;(out_string, &lt;span style="color: rgb(204, 51, 204);"&gt;"%02X"&lt;/span&gt;, checksum_as_int);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;//****************************************************************&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;void &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;mexFunction&lt;/span&gt;(&lt;span style="color: rgb(51, 102, 255);"&gt;int &lt;/span&gt;nlhs, mxArray *plhs[],&lt;br /&gt;       &lt;span style="color: rgb(51, 102, 255);"&gt;int &lt;/span&gt;nrhs, &lt;span style="color: rgb(51, 102, 255);"&gt;const &lt;/span&gt;mxArray *prhs[])&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;char &lt;/span&gt;*input_buf, *output_buf;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;int   &lt;/span&gt;buflen, status;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; /* Check for proper number of arguments. */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;(nrhs != 1)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;mexErrMsgTxt&lt;/span&gt;(&lt;span style="color: rgb(204, 51, 204);"&gt;"One input required."&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;else if &lt;/span&gt;(nlhs &gt; 1)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;mexErrMsgTxt&lt;/span&gt;(&lt;span style="color: rgb(102, 51, 255);"&gt;"Too many output arguments."&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/* Input must be a string. */&lt;/span&gt;&lt;br /&gt;if (&lt;span style="font-weight: bold;"&gt;mxIsChar&lt;/span&gt;(prhs[0]) != 1)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;mexErrMsgTxt&lt;/span&gt;(&lt;span style="color: rgb(204, 51, 204);"&gt;"Input must be a string."&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/* Input must be a row vector. */&lt;/span&gt;&lt;br /&gt;if (&lt;span style="font-weight: bold;"&gt;mxGetM&lt;/span&gt;(prhs[0]) != 1)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;mexErrMsgTxt&lt;/span&gt;(&lt;span style="color: rgb(204, 51, 204);"&gt;"Input must be a row vector."&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/* Get the length of the input string. */&lt;/span&gt;&lt;br /&gt;buflen = (&lt;span style="font-weight: bold;"&gt;mxGetM&lt;/span&gt;(prhs[0]) * &lt;span style="font-weight: bold;"&gt;mxGetN&lt;/span&gt;(prhs[0])) + 1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/* Allocate memory for input and output strings.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   * output string should be 2 ASCII characters (plus terminator) */&lt;/span&gt;&lt;br /&gt;input_buf = &lt;span style="font-weight: bold;"&gt;mxCalloc&lt;/span&gt;(buflen, &lt;span style="color: rgb(51, 102, 255);"&gt;sizeof&lt;/span&gt;(&lt;span style="color: rgb(51, 102, 255);"&gt;char&lt;/span&gt;));&lt;br /&gt;output_buf = &lt;span style="font-weight: bold;"&gt;mxCalloc&lt;/span&gt;(3, &lt;span style="color: rgb(51, 102, 255);"&gt;sizeof&lt;/span&gt;(&lt;span style="color: rgb(51, 102, 255);"&gt;char&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/* Copy the string data from prhs[0] into a C string &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   * input_buf. */&lt;/span&gt;&lt;br /&gt;status = &lt;span style="font-weight: bold;"&gt;mxGetString&lt;/span&gt;(prhs[0], input_buf, buflen);&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;if &lt;/span&gt;(status != 0)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;mexWarnMsgTxt&lt;/span&gt;(&lt;span style="color: rgb(204, 51, 204);"&gt;"Not enough space. String is truncated."&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/* Calculate checksum and store result in output_buf */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;calculateChecksumFunction&lt;/span&gt;(input_buf, output_buf);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;/* Format return as a mex-string */&lt;/span&gt;&lt;br /&gt;plhs[0] = &lt;span style="font-weight: bold;"&gt;mxCreateString&lt;/span&gt;(output_buf);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;return&lt;/span&gt;;&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;This MEX compatible C file was then compiled using the 'mex' command from the MATLAB command window:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;mex &lt;span style="color: rgb(204, 51, 204);"&gt;calculateChecksumMEX.c&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;This created a DLL in the same directory named &lt;span style="color: rgb(204, 51, 204);"&gt;calculateChecksumMEX.dll&lt;/span&gt;.&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;Substituting a call to calculateChecksumMEX in the test function redirects the processing to the created DLL.&lt;br /&gt;&lt;br /&gt;The speed improvement is immediately noticeable:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="font-family:trebuchet ms;"&gt;Elapsed time is 0.423503 seconds.&lt;br /&gt;Elapsed time is 0.425224 seconds.&lt;br /&gt;Elapsed time is 0.430266 seconds. &lt;span style="color: rgb(204, 51, 204);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;An order of magnitude speed improvement was gained through the simple technique of identifying and isolating portions of code which were using the most CPU time and performing these operations in an an efficient C sub-routine.&lt;br /&gt;&lt;br /&gt;Now MEX is not the silver bullet for every slow performing MATLAB function, but can prove to be useful. I would always recommend running the MATLAB Profiler over your code at least once to identify regions of poor performance. Poorly written MATLAB can run orders of magnitude slower than well written MATLAB.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-2621848863765989980?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/2621848863765989980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=2621848863765989980' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/2621848863765989980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/2621848863765989980'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/08/optimisation-through-mex-files.html' title='Optimisation through MEX files'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_xDCIlmJJ6bg/SKGqp7WxSQI/AAAAAAAAABA/zA8PVLJW16s/s72-c/profiler_output.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-2643842221506720207</id><published>2008-07-29T21:27:00.005+08:00</published><updated>2008-07-30T10:00:39.765+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WindowButtonMotionFcn'/><category scheme='http://www.blogger.com/atom/ns#' term='plot'/><title type='text'>Display Cursor Coordinates</title><content type='html'>A simple callback function that prints the current cursor location in plot coordinates into the plot window in a user specified location/format/colour.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=20892&amp;amp;objectType=FILE"&gt;DisplayCursorLocation&lt;/a&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_xDCIlmJJ6bg/SI8eTNNAUNI/AAAAAAAAAAw/Py8cSvakk2c/s1600-h/cursor_location_screen.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_xDCIlmJJ6bg/SI8eTNNAUNI/AAAAAAAAAAw/Py8cSvakk2c/s320/cursor_location_screen.png" alt="" id="BLOGGER_PHOTO_ID_5228431007710990546" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% cursorLocation - WindowButtonMotionFcn displaying cursor location in plot&lt;br /&gt;%===============================================================================&lt;br /&gt;% Description : Display the current cursor location within the bounds of a&lt;br /&gt;%               figure window. Assigned as a WindowButtonMotionFcn callback&lt;br /&gt;%               function. Only updates when mouse is moved over plot contents.&lt;br /&gt;%&lt;br /&gt;% Parameters  : obj         - Figure originating the callback&lt;br /&gt;%               event       - not used (but required)&lt;br /&gt;%               location    - Location within plot window for text. Can be&lt;br /&gt;%                             'BottomLeft', 'BottomRight', 'TopRight', 'TopLeft'&lt;br /&gt;%                             or a [1x2] array of XY location&lt;br /&gt;%               format_str  - A sprintf format string that will accept 2 float&lt;br /&gt;%                             parameters. ie 'X: %.3f, Y: %.3f'&lt;br /&gt;%               text_color  - either a color character (ie 'r') or a RGB&lt;br /&gt;%                             triplet (ie [1.0 1.0 0.5])&lt;br /&gt;%&lt;br /&gt;% Return      : None&lt;br /&gt;%&lt;br /&gt;% Usage       : Assign to a Figure WindowButtonMotionFcn callback:&lt;br /&gt;%                 set(fig_handle, 'WindowButtonMotionFcn',&lt;br /&gt;%                     @(obj, event)cursorLocation(obj, event, 'BottomLeft',&lt;br /&gt;%                     'X: %.3f, Y: %.3f', 'r')&lt;br /&gt;%&lt;br /&gt;% Author      : Rodney Thomson&lt;br /&gt;%               http://iheartmatlab.blogspot.com&lt;br /&gt;%===============================================================================&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;cursorLocation(obj, event, location, format_str, text_color)&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The &lt;span style="font-weight: bold;"&gt;cursorLocation&lt;/span&gt; function is assigned as the WindowButtonMotionFcn for a figure. Any time the mouse is moved over the specified figure, the callback function will be executed.&lt;br /&gt;&lt;br /&gt;The callback function retrieves the cursor location in plot axes coordinates and uses the supplied sprintf format to produce a text label which is printed in a specific location in the plot. This location can be a preset value or an arbitrary [X,Y] coordinate.&lt;br /&gt;&lt;br /&gt;Example usage:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;t = linspace(-5,5);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;y = sinc(t);&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;f = figure;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;plot(t, y, &lt;span style="color: rgb(204, 51, 204);"&gt;'r'&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;set(f, &lt;span style="color: rgb(204, 51, 204);"&gt;'WindowButtonMotionFcn'&lt;/span&gt;,                           &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;@(obj, event)cursorLocation(obj, event, &lt;span style="color: rgb(204, 51, 204);"&gt;'BottomLeft'&lt;/span&gt;, &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;                          &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;' X: %.3f\n Y: %.3f'&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);"&gt;'r'&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;If you wanted to avoid setting the WindowButtonMotionFcn callback yourself, you could use the following wrapper function:&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function &lt;/span&gt;displayCursorLocation(figure_handle, location, format_string, text_color)&lt;br /&gt;&lt;br /&gt;  set(figure_handle, &lt;span style="color: rgb(204, 51, 204);"&gt;'WindowButtonMotionFcn'&lt;/span&gt;, &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;      @(obj, event)cursorLocation(obj, event, location, format_string, text_color));&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;en&lt;span style="font-family:trebuchet ms;"&gt;d&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-2643842221506720207?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/2643842221506720207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=2643842221506720207' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/2643842221506720207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/2643842221506720207'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/07/display-cursor-coordinates.html' title='Display Cursor Coordinates'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_xDCIlmJJ6bg/SI8eTNNAUNI/AAAAAAAAAAw/Py8cSvakk2c/s72-c/cursor_location_screen.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-378771560162129555</id><published>2008-07-22T20:35:00.003+08:00</published><updated>2008-07-23T14:30:58.525+08:00</updated><title type='text'>Recursive Directory Function Execution</title><content type='html'>A simple function that provides a large amount of flexibility in its use.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=20814&amp;amp;objectType=FILE"&gt;DirectoryRecurse&lt;/a&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% directoryRecurse - Recurse through sub directories executing function pointer&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%===============================================================================&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Description   : Recurses through each directory, passing the full directory&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                 path and any extraneous arguments (varargin) to the specified &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                 function pointer&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Parameters    : directory        - Top level directory begin recursion from&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                 function_pointer - function to execute with each directory as&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                                    its first argument&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                 varargin         - Any extra arguments that should be passed &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                                    to the function pointer.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Call Sequence : directoryRecurse(directory, function_pointer, varargin)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                 IE: To execute the 'rmdir' command with the 's' parameter over &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                     'c:\tmp' and all subdirectories&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                     directoryRecurse('c:\tmp', @rmdir, 's')&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Author        : Rodney Thomson&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                 http://iheartmatlab.blogspot.com&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%===============================================================================&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;function directoryRecurse(directory, function_pointer, varargin)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    contents    = dir(directory);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    directories = find([contents.isdir]);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(0, 153, 0);"&gt;% For loop will be skipped when directory contains no sub-directories&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 51, 255);"&gt;for &lt;/span&gt;i_dir = directories&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        sub_directory  = contents(i_dir).name;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        full_directory = fullfile(directory, sub_directory);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(0, 153, 0);"&gt;% ignore '.' and '..'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 51, 255);"&gt;if &lt;/span&gt;(strcmp(sub_directory, &lt;span style="color: rgb(204, 51, 204);"&gt;'.'&lt;/span&gt;) || strcmp(sub_directory, &lt;span style="color: rgb(204, 51, 204);"&gt;'..'&lt;/span&gt;))&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;span style="color: rgb(51, 51, 255);"&gt;continue&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(51, 51, 255);"&gt;end &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;span style="color: rgb(0, 153, 0);"&gt;% Recurse down&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        directoryRecurse(full_directory, function_pointer, varargin{:});&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;span style="color: rgb(0, 153, 0);"&gt;% execute the callback with any supplied parameters.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;    % Due to recursion will execute in a bottom up manner&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    function_pointer(directory, varargin{:});&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The &lt;span style="font-weight: bold;"&gt;directoryRecurse&lt;/span&gt; function finds all directories below the supplied directory and executes the supplied function with the full directory path as the first argument. Any extra arguments supplied to &lt;span style="font-weight: bold;"&gt;directoryRecurse&lt;/span&gt; are passed onto the function supplied in function_pointer.&lt;br /&gt;&lt;br /&gt;Its a hard concept to explain with words, so here are a few useful examples:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% add current directory and any sub-directory to the Matlab search path&lt;/span&gt;&lt;br /&gt;directoryRecurse(pwd, @addpath);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% delete all contents of 'c:\tmp', requires passing the 's' flag to the rmdir function&lt;/span&gt;&lt;br /&gt;directoryRecurse('c:\tmp', @rmdir, &lt;span style="color: rgb(204, 51, 204);"&gt;'s'&lt;/span&gt;)&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-378771560162129555?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/378771560162129555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=378771560162129555' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/378771560162129555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/378771560162129555'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/07/recursive-directory-function-execution.html' title='Recursive Directory Function Execution'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-2950786529117765408</id><published>2008-07-15T22:55:00.004+08:00</published><updated>2008-07-16T22:53:15.683+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spectral analyser'/><category scheme='http://www.blogger.com/atom/ns#' term='gui'/><category scheme='http://www.blogger.com/atom/ns#' term='object oriented'/><category scheme='http://www.blogger.com/atom/ns#' term='matlab'/><title type='text'>Sound Card Spectral Analyser GUI</title><content type='html'>&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Glancing at the title of this post &lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;you might be mistaken for thinking I have repeated my previous post! This is not the case.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=20721&amp;amp;objectType=file"&gt;SoundcardSpectralAnalyserGui&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_xDCIlmJJ6bg/SHy7vyUN11I/AAAAAAAAAAg/GhvslTNpqu0/s1600-h/SoundcardSpectralAnalyser_SCREEN.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_xDCIlmJJ6bg/SHy7vyUN11I/AAAAAAAAAAg/GhvslTNpqu0/s320/SoundcardSpectralAnalyser_SCREEN.PNG" alt="" id="BLOGGER_PHOTO_ID_5223256097477744466" border="0" /&gt;&lt;/a&gt;&lt;/div&gt; &lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;This GUI (developed using GUIDE) took the SoundcardSpectralAnalysis functionality and wrapped it in a Matlab class. An object of this class was then utilised by the GUI in order to display real time analysis of acoustic data sampled off the system sound card.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Object Oriented Matlab&lt;/span&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;A Matlab class named SoundcardSpectralAnalyser was developed. It has a constructor, and start(), stop() and set() methods.&lt;br /&gt;&lt;br /&gt;Unfortunately, as I am not yet using &lt;a href="http://www.mathworks.com/products/new_products/latest_features.html?s_cid=HP_RH_2008a"&gt;Matlab 2008a&lt;/a&gt;, I do not have access to its wonderful new &lt;a href="http://www.mathworks.com/products/matlab/object_oriented_programming.html"&gt;OO interface&lt;/a&gt;. I will not go into too much detail regarding the older OO mechanic because eventually it will be outdated... And it is nothing to be celebrated really. (Hmmm maybe i should register ihatematlab.blogspot.com)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Constructor&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;The responsibility of the constructor is to initialise any member variables and define the returned structure as a Matlab class of type 'SoundcardSpectralAnalyser'.&lt;br /&gt;&lt;br /&gt;Note that the constructor calls out to the set() method to initialise parameters from the variable length argument list. This has to be called AFTER the class type declaration to ensure the correct set method is used.&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;function &lt;/span&gt;this = SoundcardSpectralAnalyser(time_plot, freq_plot, varargin)&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 153, 0);"&gt;% Initialise default parameters if not supplied&lt;/span&gt;&lt;br /&gt;  this.Fs          = 44000;&lt;br /&gt;  this.n_bits      = 16;&lt;br /&gt;  this.n_channels  = 2;&lt;br /&gt;  this.update_rate = 5;&lt;br /&gt;&lt;br /&gt;  this.time_plot = time_plot;&lt;br /&gt;  this.freq_plot = freq_plot;&lt;br /&gt;&lt;br /&gt;  this.audio_recorder = [];&lt;br /&gt;&lt;br /&gt;  this = class(this, &lt;span style="color: rgb(204, 51, 204);"&gt;'SoundcardSpectralAnalyser'&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 153, 0);"&gt;% Set parameters as supplied&lt;/span&gt;&lt;br /&gt;  this = set(this, varargin{:});&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Start()&lt;br /&gt;&lt;/span&gt;The start method extracted the initialisation and audiorecorder starting functionality from the &lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=20541"&gt;SoundcardSpectrumAnalysis&lt;/a&gt; function. Separating this ensures that an object of SoundcardSpectrumAnalyser can be constructed at one time but not started until a later point in time. Also, subsequent audiorecorder objects will be using the current analysis parameters (sample rate, sample size, number of channels and update rate).&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;&lt;br /&gt;The start() method also contains the TimerFcn callback responsible for updating the supplied plots. This is functionally unchanged from the script version.&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function &lt;/span&gt;this = start(this)&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 153, 0);"&gt;% Setup the audiorecorder which will acquire data off default soundcard&lt;/span&gt;&lt;br /&gt;  this.audio_recorder = audiorecorder(this.Fs, this.n_bits, this.n_channels);&lt;br /&gt;&lt;br /&gt;  set(this.audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'TimerFcn'&lt;/span&gt;, {@audioRecorderTimerCallback, ...&lt;br /&gt;                                        this.time_plot, this.freq_plot});&lt;br /&gt;  set(this.audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'TimerPeriod'&lt;/span&gt;, 1/this.update_rate);&lt;br /&gt;  set(this.audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'BufferLength'&lt;/span&gt;, 1/this.update_rate);&lt;br /&gt;&lt;br /&gt;  record(this.audio_recorder);  &lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Stop&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;"&gt;()&lt;br /&gt;&lt;/span&gt;The stop method is responsible for stopping the audiorecorder object if it had been created. &lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function &lt;/span&gt;this = stop(this)  &lt;br /&gt;&lt;br /&gt;  if (~isempty(this.audio_recorder))&lt;br /&gt;      stop(this.audio_recorder);&lt;br /&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;end    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;"&gt;Set&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;"&gt;()&lt;br /&gt;&lt;/span&gt;The set method takes in a variable length argument list&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;. This list comprises of Value/Key parameter pairs for setting the sample rate, sample size, number of channels and update rate. All pairs can be set simultaneously or 1 at a time.&lt;br /&gt;&lt;br /&gt;I was considering using the &lt;a href="http://www.blogger.com/www.mathworks.com/access/helpdesk/help/techdoc/ref/inputparser.html"&gt;inputparser&lt;/a&gt; class to do this behaviour, but unfortunately I could not figure out how I could set only 1 of the parameters externally without the remaining parameters in the struct being returned as the specified defaults. Also, it was not available in my oldest version of Matlab (R14 SP2).&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function &lt;/span&gt;this = set (this, varargin)&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;if &lt;/span&gt;(mod(length(varargin), 2) ~= 0)&lt;br /&gt;      warning(&lt;span style="color: rgb(204, 51, 204);"&gt;'Parameters must be supplied in Key/Value pairs.'&lt;/span&gt;);&lt;br /&gt;      &lt;span style="color: rgb(51, 51, 255);"&gt;return&lt;/span&gt;;&lt;br /&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;for &lt;/span&gt;i_param = 1:2:(length(varargin) - 1)&lt;br /&gt;    &lt;br /&gt;      &lt;span style="color: rgb(51, 51, 255);"&gt;switch &lt;/span&gt;varargin{i_param}&lt;br /&gt;          &lt;span style="color: rgb(51, 51, 255);"&gt;case &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;'Fs'&lt;/span&gt;&lt;br /&gt;              this.Fs = varargin{i_param+1};&lt;br /&gt;          &lt;span style="color: rgb(51, 51, 255);"&gt;case &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;'SampleSize'&lt;/span&gt;&lt;br /&gt;              this.n_bits = varargin{i_param+1};&lt;br /&gt;          &lt;span style="color: rgb(51, 51, 255);"&gt;case &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;'Channels'&lt;/span&gt;&lt;br /&gt;              this.n_channels = varargin{i_param+1};&lt;br /&gt;          &lt;span style="color: rgb(51, 51, 255);"&gt;case &lt;/span&gt;&lt;span style="color: rgb(204, 51, 204);"&gt;'UpdateRate'&lt;/span&gt;&lt;br /&gt;              this.update_rate = varargin{i_param+1};&lt;br /&gt;          &lt;span style="color: rgb(51, 51, 255);"&gt;otherwise&lt;/span&gt;&lt;br /&gt;              warning(&lt;span style="color: rgb(204, 51, 204);"&gt;'Unknown parameter : %s\n'&lt;/span&gt;, varargin{i_param});&lt;br /&gt;      &lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;GUI Development in GUIDE&lt;/span&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;I developed the GUI using Matlab's inbuilt GUI editor known as &lt;a href="http://www.blogger.com/www.mathworks.com/access/helpdesk/help/techdoc/ref/guide.html"&gt;GUIDE&lt;/a&gt; (Graphical User Interface Development Environment). This provides a 'designer' like layout tool which will create the required .fig and .m files for your GUI. It also automatically creates hooks for object callbacks in the .m file for your convenience.&lt;br /&gt;&lt;br /&gt;I will not go into too much detail regarding the GUIDE tool. I'd personally recommend firing up the editor (type 'guide' at the Matlab Command Window) and just throw some things on there, put some fprintf() statements in the generated callbacks and go click crazy. I will go into a couple of things that annoy about GUI development in Matlab in particular.&lt;br /&gt;&lt;br /&gt;Disclaimer: This GUI was developed using R14 SP2... Guide may have been improved in later releases. I'm yet to investigate and the issues I have found with it may have been fixed!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Figure Resizing&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;Ok, the default behaviour of a Matlab GUI is to disallow resizing of the main figure window. This is convenient for a Matlab GUI developer... not so much for a Matlab GUI user. Particularly if there a plots involved as users with high resolution screens may wish to take advantage of their expensive toys.&lt;br /&gt;&lt;br /&gt;So.. you bring up the Property Inspector for the main figure and set the Resize property to 'on'. Run the GUI and *yay* you can resize the window. But all the contents stay wedged in the bottom left. Hmmm thats no better.&lt;br /&gt;&lt;br /&gt;Now, go into the Tools-&gt;GUI Options... menu and change the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;resize&lt;/span&gt; behaviour to 'Proportional'. Run the GUI and observe the behaviour.&lt;br /&gt;&lt;br /&gt;Hey, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;thats&lt;/span&gt; a little bit better. Any Axes you have in the GUI are being proportionally &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;resized&lt;/span&gt; and overall, things look good. However, the proportional &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;resize&lt;/span&gt; affects ALL objects - &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;pushbuttons&lt;/span&gt;, panels. Things can start to look a bit odd and often careful laying out of objects turns into a complete mess.&lt;br /&gt;&lt;br /&gt;So what is the alternative?&lt;br /&gt;&lt;br /&gt;Define a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;ResizeFcn&lt;/span&gt; on the main figure window. This is then called when the user &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;resizes&lt;/span&gt; the GUI window. From within this callback you can query the current figure position and size and shuffle around your objects manually.&lt;br /&gt;&lt;br /&gt;This process is quite tedious but unfortunately required for full control of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;resize&lt;/span&gt; behaviour (There appears to be no 'anchoring' of panels/objects).&lt;br /&gt;&lt;br /&gt;Check out &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;SoundcardSpectralAnalyser&lt;/span&gt;_GUI_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;ResizeCallback&lt;/span&gt; in the main GUI .m file for an example of the code required to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;achieve&lt;/span&gt; this control.&lt;br /&gt;&lt;br /&gt;The desired behaviour of my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Resize&lt;/span&gt; function is to keep the Parameters panel at the bottom of the figure, keeping its height constant but adjusting the width to match the figure. The remaining figure space is divided equally for the time and frequency domain plots (ensuring there was enough room around the axes for labels).&lt;br /&gt;&lt;br /&gt;I did not put any limitations in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Resize&lt;/span&gt; function to enforce a minimum figure size as at 30 lines it was getting long enough.&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Figure Axes&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;It was annoying having to remember to pad the size of the Axes to ensure sufficient size for the tick labels/text labels. Ideally the size specified by the Axes would be the maximum bounds containing titles/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;xlabel&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;ylabel&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;colorbars&lt;/span&gt; etc. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;Matlab&lt;/span&gt; should be smart enough to dynamically &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;resize&lt;/span&gt; the drawn chart area internally to cope with this (as it does with a figure window currently.. actually that gives me an idea.. embedding a figure into a GUI for this very reason. Stay tuned).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;span style="font-weight: bold;"&gt;Orphaned Objects&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Something I noticed whilst developing the GUI was that I was often getting orphaned instances of my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;SoundcardSpectralAnalyser&lt;/span&gt; object (and subsequently the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;audiorecorder&lt;/span&gt; object) when there was an error and the GUI did not close properly.&lt;br /&gt;&lt;br /&gt;When I tried to run 'clear classes' I received a warning that X instances of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;SoundcardSpectralAnalyser&lt;/span&gt; exist and classes could not be cleared. Doing a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;findall&lt;/span&gt;(0, 'Type', '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;SoundcardSpectralAnalyser&lt;/span&gt;') yielded no results, hence there is no way of clearing these.&lt;br /&gt;&lt;br /&gt;This may be a bug that has been fixed in more recent versions.&lt;br /&gt;&lt;br /&gt;Overall, I feel that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;Matlab&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;GUIs&lt;/span&gt; have a long way to go from that implemented in R14 SP2. I will have a look at 2007b (most recent installed version that I use) and see if things have improved. With care, reasonable &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;GUIs&lt;/span&gt; can be developed in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;Matlab&lt;/span&gt; but most of the effort will go into tasks that should really be much simpler.&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-2950786529117765408?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/2950786529117765408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=2950786529117765408' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/2950786529117765408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/2950786529117765408'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/07/sound-card-spectral-analyser-gui.html' title='Sound Card Spectral Analyser GUI'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_xDCIlmJJ6bg/SHy7vyUN11I/AAAAAAAAAAg/GhvslTNpqu0/s72-c/SoundcardSpectralAnalyser_SCREEN.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5383877989815914374.post-4388521068039802572</id><published>2008-07-01T23:44:00.017+08:00</published><updated>2008-07-11T13:30:43.103+08:00</updated><title type='text'>Sound Card Spectral Analysis</title><content type='html'>&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;As my first post on this blog I thought I would introduce a very simple function which exploits some of Matlab's high level data acquisition and plotting abilities.&lt;br /&gt;&lt;br /&gt;Although this blog's title is 'iheartmatlab' I will also explore areas about Matlab that I don't like so much.&lt;br /&gt;&lt;br /&gt;Ok, onto the first code example:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=20541&amp;amp;objectType=file"&gt;SoundcardSpectralAnalysis&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%===============================================================================&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Description : Acquire acoustic data from default system soundcard and plot&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% in both time and frequency domain.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Parameters : Fs          - Acquisition sample frequency   [44000] Hz&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%              n_bits      - Sample size                    [16] bits&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%              n_channels  - Number of channels to acquire&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                            from sound card                [2]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%              update_rate - Polls sound card for data this&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%                            many times per second          [5] Hz&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;%===============================================================================&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function&lt;/span&gt; soundcardSpectralAnalysis(Fs, n_bits, n_channels, update_rate)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;As per the description this function will continuously acquire data from the soundcard at the specified sample frequency, sample size and update rate for however many channels your soundcad supports.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Default Parameters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One thing I don't like about Matlab is the lack of an efficient manner to define the value of default parameters. I have had to resort to the following to initialise my parameters:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Initialise default parameters if not supplied&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;if &lt;/span&gt;(~exist(&lt;span style="color: rgb(204, 51, 204);"&gt;'Fs'&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);"&gt;'var'&lt;/span&gt;))&lt;br /&gt;  Fs = 44000;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;if &lt;/span&gt;(~exist(&lt;span style="color: rgb(204, 51, 204);"&gt;'n_bits'&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);"&gt;'var'&lt;/span&gt;))&lt;br /&gt;  n_bits = 16;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;if &lt;/span&gt;(~exist(&lt;span style="color: rgb(204, 51, 204);"&gt;'n_channels'&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);"&gt;'var'&lt;/span&gt;))&lt;br /&gt;  n_channels = 2;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;if &lt;/span&gt;(~exist(&lt;span style="color: rgb(204, 51, 204);"&gt;'update_rate'&lt;/span&gt;, &lt;span style="color: rgb(204, 51, 204);"&gt;'var'&lt;/span&gt;))&lt;br /&gt;  update_rate = 5;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The code checks whether a variable exists within the workspace; and if it does not, it creates it with the default value. There are other possible methods that could have been utilised such as:&lt;br /&gt;&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;if &lt;/span&gt;(nargin &amp;lt; 4)&lt;br /&gt;   update_rate = 5;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;    if &lt;/span&gt;(nargin &amp;lt; 3)&lt;br /&gt;       n_channels = 2;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;        if &lt;/span&gt;(nargin &amp;lt; 2)&lt;br /&gt;           n_bits = 16;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;            if &lt;/span&gt;(nargin &amp;lt; 1)&lt;br /&gt;               sample_frequency = 44000;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;            end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;        end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;    end&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;Although this method uses slightly less lines of code, the level of nesting makes it a bit hard to understand on first glance the purpose of the code. And the approach implemented is at least insensitive to changes in the order of parameters (which is unlikely... but you never know).&lt;br /&gt;&lt;br /&gt;My ideal dream solution for default parameters would be similar to C++ (the other language with which I have some experience):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;function &lt;/span&gt;soundcardSpectralAnalysis(Fs = 44000, n_bits = 16, n_channels = 2, update_rate = 5)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;If a parameter does NOT have an assignment against it, then its deemed to be a required parameter.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Initialising Plots&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When you are producing plots in Matlab and are going to be continuously updating the contents of the plot, typically overdrawing or updating the previous result (ie updating an line spectrum or vessel track) then I would recommend initializing a plot with your desired visual properties and then updating only the raw data values contained by the plot.&lt;br /&gt;&lt;br /&gt;Too often i've seen:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;tic&lt;br /&gt;figure&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;for &lt;/span&gt;i = 1:100&lt;br /&gt;   cla&lt;br /&gt;   plot(i, i, '.')&lt;br /&gt;   drawnow&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;toc&lt;br /&gt;Elapsed time is 4.899789 seconds.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;A much more efficient alternative:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;tic&lt;br /&gt;figure;&lt;br /&gt;point_plot = plot(nan, nan, &lt;span style="color: rgb(204, 51, 204);"&gt;'.'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;for &lt;/span&gt;i = 1:100&lt;br /&gt;   set(point_plot, &lt;span style="color: rgb(204, 51, 204);"&gt;'XData'&lt;/span&gt;, i);&lt;br /&gt;   set(point_plot, &lt;span style="color: rgb(204, 51, 204);"&gt;'YData'&lt;/span&gt;, i);&lt;br /&gt;   drawnow&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;toc&lt;br /&gt;Elapsed time is 1.086440 seconds.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;So the SoundcardSpectralAnalysis function initialises the time and frequency domain plots and sets up axis bounds / labels:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;plot_colors = hsv(n_channels);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Initialise plots, one above each other in a single figure window&lt;/span&gt;&lt;br /&gt;figure;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Time Domain plot&lt;/span&gt;&lt;br /&gt;subplot(2,1,1)&lt;br /&gt;hold &lt;span style="color: rgb(51, 51, 255);"&gt;on&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;for &lt;/span&gt;i_channel = 1:n_channels&lt;br /&gt;   time_domain_plots(i_channel) = plot(nan, nan, &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                       &lt;span style="color: rgb(204, 51, 204);"&gt;'Color'&lt;/span&gt;, plot_colors(i_channel, :));&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;xlabel(&lt;span style="color: rgb(204, 51, 204);"&gt;'Sample'&lt;/span&gt;)&lt;br /&gt;ylabel(&lt;span style="color: rgb(204, 51, 204);"&gt;'Counts'&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;y_max = 2^(n_bits-1);&lt;br /&gt;ylim([-y_max y_max]);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Frequency Domain plot&lt;/span&gt;&lt;br /&gt;subplot(2,1,2)&lt;br /&gt;hold &lt;span style="color: rgb(51, 51, 255);"&gt;on&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;for &lt;/span&gt;i_channel = 1:n_channels&lt;br /&gt;   freq_domain_plots(i_channel) = plot(nan, nan, &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                       &lt;span style="color: rgb(204, 51, 204);"&gt;'Color'&lt;/span&gt;, plot_colors(i_channel, :));&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;xlabel(&lt;span style="color: rgb(204, 51, 204);"&gt;'Frequency (Hz)'&lt;/span&gt;)&lt;br /&gt;ylabel(&lt;span style="color: rgb(204, 51, 204);"&gt;'dB re 1 count/sqrt(Hz)'&lt;/span&gt;)&lt;br /&gt;xlim([0 Fs/2])&lt;br /&gt;ylim([0 70])&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Audio Recorder&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Now we come to the guts of the data acquisition, the Matlab inbuilt audiorecorder.&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Setup the audiorecorder which will acquire data off default soundcard&lt;/span&gt;&lt;br /&gt;audio_recorder = audiorecorder(Fs, n_bits, n_channels);&lt;br /&gt;&lt;br /&gt;set(audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'TimerFcn'&lt;/span&gt;, {@audioRecorderTimerCallback, &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                audio_recorder,              &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                time_domain_plots,           &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                freq_domain_plots});&lt;br /&gt;set(audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'TimerPeriod'&lt;/span&gt;, 1/update_rate);&lt;br /&gt;set(audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'BufferLength'&lt;/span&gt;, 1/update_rate);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% Start the recorder&lt;/span&gt;&lt;br /&gt;record(audio_recorder);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The audiorecorder is a nice simple high level abstraction allowing us to retrieve data from a soundcard. However there is limited control as to how often and how much data is retrieved from the sound card.&lt;br /&gt;&lt;br /&gt;Ideally for this application we would determine the number of samples to be read from the sound card (sample_frequency/update_rate) and enter a loop reading this many samples each time. However audiorecorder does not contain this functionality. The only option is to specify a timer callback function and its timer period.&lt;br /&gt;&lt;br /&gt;In theory this should work perfectly, however in the real world, timers don't get called EXACTLY every 0.2 seconds (or however long their interval). Depending on CPU load and interrupt timings it can vary.&lt;br /&gt;&lt;br /&gt;The effect on audiorecoder is that often you will receive too much / too little data when you query it for the currently recorded data. Unfortunately i could not figure out a simple work around. So this function wil occasionally 'skip' and update and include that data into the next frame's analysis. Sorry folks!&lt;br /&gt;&lt;br /&gt;Now.. what makes this code work? Simple its this:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;set(audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'TimerFcn'&lt;/span&gt;, {@audioRecorderTimerCallback, &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                audio_recorder,              &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                time_domain_plots,           &lt;span style="color: rgb(0, 153, 0);"&gt;...&lt;/span&gt;&lt;br /&gt;                                freq_domain_plots});&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This says that for each time period as configured, execute the 'audioRecorderTimerCallback' function and supply to it these three parameters.&lt;br /&gt;&lt;br /&gt;By then starting the recorder you are beginning recording and starting the timer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Audio Recorder Callback&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The callback function we assigned to the audiorecorder will get called approximately ever 1/update_rate seconds. I wont go into too much detail regarding the callback as this post is long enough as is.&lt;br /&gt;&lt;br /&gt;The function initially queries the audiorecorder for some of its properties required for accurate frequency analysis.&lt;br /&gt;&lt;br /&gt;It then stops the recorder, retrieves the recorded data before starting the recorder again.&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;% stop the recorder, grab the data, restart the recorder. May miss some data&lt;/span&gt;&lt;br /&gt;stop(obj);&lt;br /&gt;data = getaudiodata(obj, data_format);&lt;br /&gt;record(obj);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;It then calculates the power spectrum of the audio data and updates the XData and YData fields of the appropriate time / frequency domain plots before forcing a drawing update of the plots.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Error Handling&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You might have noticed that the majority of the code in the Audio Recorder callback function is contained within a try block. This is for 2 reasons:&lt;br /&gt;&lt;br /&gt;1) If a systematic error is occuring within the function, then it will continue to occur within the function. Each time that function is called. Which is every time the Audio Recorder timer function is triggered. And because at the command line you do not have access to the soundcardSpectralAnalysis workspace, you cannot stop the timer. Your only solution is to close Matlab.&lt;br /&gt;2) You wish to stop the spectral analysis? Well, just closing the figure window will acheive this.&lt;br /&gt;&lt;br /&gt;The corresponding catch block does the following:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;catch &lt;/span&gt;exception&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;    % Stop the recorder and exit&lt;/span&gt;&lt;br /&gt;   stop(obj)&lt;br /&gt;   rethrow(exception)&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Most important line is "stop(obj)". This stops the recorder and hence the timer function. The error is then rethrown to alert the user to the issue.&lt;br /&gt;&lt;br /&gt;In the case of 1) above, you will be able to debug the code if you were extending its functionality withough having to restart Matlab often. In the case of 2), closing the figure window means that when it attempts to update the plot data fields, they do not exist, causing an error to be thrown. Hence the function can be stopped nicely.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Interesting Issue with Audio Recorder Callback Function&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The more observant readers might say:&lt;br /&gt;"Why supply "audio_recorder" to the audioRecorderTimerCallback. Particularly as the audio_recorder is the initiater of the callback available as the "obj" variable, and also because audio_recorder is not even used within the callback function whatsoever!"&lt;br /&gt;&lt;br /&gt;And I would completely agree with you.&lt;br /&gt;&lt;br /&gt;However. If you remove "audio_recorder" from the callback function parameter list, then the timer is never started and never executed:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;set(audio_recorder, &lt;span style="color: rgb(204, 51, 204);"&gt;'TimerFcn'&lt;/span&gt;, {@audioRecorderTimerCallback, ...&lt;br /&gt;                                time_domain_plots,           ...&lt;br /&gt;                                freq_domain_plots});&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;function &lt;/span&gt;audioRecorderTimerCallback(obj, event, ...&lt;br /&gt;                                   time_domain_plots, freq_domain_plots)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;!!!!FAILS!!!!&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;It is particularly puzzling seeing as though audio_recorder is not used anywhere within the callback function. This can be illustrated by calling "clear('audio_recorder')" at the start of the function. It still functions as per expected.&lt;br /&gt;&lt;br /&gt;It might be a bug, but possibly me misunderstanding the behaviour of the callback functions. If anyone has any suggestions, feel free to leave them in the comments below.&lt;br /&gt;&lt;br /&gt;Anyhow, thanks for reading my long post about a very simple function. Hopefully its highlighted some interesting aspects of Matlab that you may not have been too familiar with.&lt;br /&gt;&lt;br /&gt;I aim to provide a new sample each week along with a little explanation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5383877989815914374-4388521068039802572?l=iheartmatlab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iheartmatlab.blogspot.com/feeds/4388521068039802572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5383877989815914374&amp;postID=4388521068039802572' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/4388521068039802572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5383877989815914374/posts/default/4388521068039802572'/><link rel='alternate' type='text/html' href='http://iheartmatlab.blogspot.com/2008/07/sound-card-spectral-analysis.html' title='Sound Card Spectral Analysis'/><author><name>Rodney Thomson</name><uri>http://www.blogger.com/profile/11854209436110515025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry></feed>
