1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h"
12cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org
13cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include <math.h>
14cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include <stdio.h>
15cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org
16cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include <algorithm>
17cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include <sstream>
18cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef MATLAB
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "engine.h"
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
24cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
25cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
26cbd78ae09f44b003a9969536b78f08cd1ff513e8pbos@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h"
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing namespace webrtc;
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef MATLAB
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabEngine eng;
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabLine::MatlabLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/)
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_xArray(NULL),
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_yArray(NULL),
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_maxLen(maxLen),
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_plotAttribute(),
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_name()
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_maxLen > 0)
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (plotAttrib)
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _plotAttribute = plotAttrib;
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (name)
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _name = name;
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabLine::~MatlabLine()
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_xArray != NULL)
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        mxDestroyArray(_xArray);
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_yArray != NULL)
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        mxDestroyArray(_yArray);
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::Append(double x, double y)
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
72b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org    if (_maxLen > 0 && _xData.size() > static_cast<uint32_t>(_maxLen))
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xData.resize(_maxLen);
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _yData.resize(_maxLen);
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _xData.push_front(x);
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _yData.push_front(y);
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// append y-data with running integer index as x-data
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::Append(double y)
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_xData.empty())
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // first element is index 0
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        Append(0, y);
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // take last x-value and increment
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double temp = _xData.back(); // last x-value
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        Append(temp + 1, y);
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::SetMaxLen(int maxLen)
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (maxLen <= 0)
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // means no maxLen
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _maxLen = -1;
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _maxLen = maxLen;
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_xArray != NULL)
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            mxDestroyArray(_xArray);
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            mxDestroyArray(_yArray);
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        maxLen = ((unsigned int)maxLen <= _xData.size()) ? maxLen : (int)_xData.size();
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xData.resize(maxLen);
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _yData.resize(maxLen);
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //// reserve the right amount of memory
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //_xData.reserve(_maxLen);
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //_yData.reserve(_maxLen);
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::SetAttribute(char *plotAttrib)
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotAttribute = plotAttrib;
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::SetName(char *name)
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _name = name;
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::GetPlotData(mxArray** xData, mxArray** yData)
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Make sure we have enough Matlab allocated memory.
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Assuming both arrays (x and y) are of the same size.
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_xData.empty())
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return; // No data
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned int size = 0;
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_xArray != NULL)
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        size = (unsigned int)mxGetNumberOfElements(_xArray);
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (size < _xData.size())
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_xArray != NULL)
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            mxDestroyArray(_xArray);
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            mxDestroyArray(_yArray);
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xArray = mxCreateDoubleMatrix(1, _xData.size(), mxREAL);
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _yArray = mxCreateDoubleMatrix(1, _yData.size(), mxREAL);
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_xData.empty())
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double* x = mxGetPr(_xArray);
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator it = _xData.begin();
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (int i = 0; it != _xData.end(); it++, i++)
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            x[i] = *it;
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_yData.empty())
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double* y = mxGetPr(_yArray);
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator it = _yData.begin();
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (int i = 0; it != _yData.end(); it++, i++)
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            y[i] = *it;
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *xData = _xArray;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *yData = _yArray;
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstd::string MatlabLine::GetXName()
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::ostringstream xString;
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    xString << "x_" << _name;
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return xString.str();
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstd::string MatlabLine::GetYName()
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::ostringstream yString;
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    yString << "y_" << _name;
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return yString.str();
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstd::string MatlabLine::GetPlotString()
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::ostringstream s;
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_xData.size() == 0)
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        s << "[0 1], [0 1]"; // To get an empty plot
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        s << GetXName() << "(1:" << _xData.size() << "),";
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        s << GetYName() << "(1:" << _yData.size() << ")";
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    s << ", '";
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    s << _plotAttribute;
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    s << "'";
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return s.str();
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstd::string MatlabLine::GetRefreshString()
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::ostringstream s;
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_xData.size() > 0)
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        s << "set(h,'xdata',"<< GetXName() <<"(1:" << _xData.size() << "),'ydata',"<< GetYName() << "(1:" << _yData.size() << "));";
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        s << "set(h,'xdata',[NaN],'ydata',[NaN]);";
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return s.str();
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstd::string MatlabLine::GetLegendString()
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ("'" + _name + "'");
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool MatlabLine::hasLegend()
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (!_name.empty());
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// remove data points, but keep attributes
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::Reset()
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _xData.clear();
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _yData.clear();
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabLine::UpdateTrendLine(MatlabLine * sourceData, double slope, double offset)
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Reset(); // reset data, not attributes and name
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    double thexMin = sourceData->xMin();
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    double thexMax = sourceData->xMax();
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Append(thexMin, thexMin * slope + offset);
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Append(thexMax, thexMax * slope + offset);
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgdouble MatlabLine::xMin()
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_xData.empty())
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theStart = _xData.begin();
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theEnd = _xData.end();
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return(*min_element(theStart, theEnd));
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (0.0);
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgdouble MatlabLine::xMax()
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_xData.empty())
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theStart = _xData.begin();
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theEnd = _xData.end();
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return(*max_element(theStart, theEnd));
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (0.0);
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgdouble MatlabLine::yMin()
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_yData.empty())
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theStart = _yData.begin();
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theEnd = _yData.end();
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return(*min_element(theStart, theEnd));
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (0.0);
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgdouble MatlabLine::yMax()
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_yData.empty())
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theStart = _yData.begin();
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::iterator theEnd = _yData.end();
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return(*max_element(theStart, theEnd));
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (0.0);
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabTimeLine::MatlabTimeLine(int horizonSeconds /*= -1*/, const char *plotAttrib /*= NULL*/,
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               const char *name /*= NULL*/,
318b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                               int64_t refTimeMs /* = -1*/)
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               :
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_timeHorizon(horizonSeconds),
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabLine(-1, plotAttrib, name) // infinite number of elements
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (refTimeMs < 0)
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _refTimeMs = TickTime::MillisecondTimestamp();
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _refTimeMs = refTimeMs;
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabTimeLine::Append(double y)
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    MatlabLine::Append(static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0, y);
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    PurgeOldData();
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabTimeLine::PurgeOldData()
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_timeHorizon > 0)
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // remove old data
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double historyLimit = static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            - _timeHorizon; // remove data points older than this
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::list<double>::reverse_iterator ritx = _xData.rbegin();
346b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org        uint32_t removeCount = 0;
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        while (ritx != _xData.rend())
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (*ritx >= historyLimit)
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                break;
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            ritx++;
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            removeCount++;
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (removeCount == 0)
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return;
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // remove the range [begin, it).
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //if (removeCount > 10)
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //{
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //    printf("Removing %lu elements\n", removeCount);
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        //}
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xData.resize(_xData.size() - removeCount);
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _yData.resize(_yData.size() - removeCount);
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
372b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.orgint64_t MatlabTimeLine::GetRefTime()
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return(_refTimeMs);
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabPlot::MatlabPlot()
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_figHandle(-1),
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_smartAxis(false),
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_critSect(CriticalSectionWrapper::CreateCriticalSection()),
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_timeToPlot(false),
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_plotting(false),
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_enabled(true),
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_firstPlot(true),
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_legendEnabled(true),
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_donePlottingEvent(EventWrapper::Create())
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _xlim[0] = 0;
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _xlim[1] = 0;
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _ylim[0] = 0;
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _ylim[1] = 0;
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef PLOT_TESTING
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotStartTime = -1;
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotDelay = 0;
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabPlot::~MatlabPlot()
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect->Enter();
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // delete all line objects
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (!_line.empty())
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete *(_line.end() - 1);
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _line.pop_back();
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _critSect;
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _donePlottingEvent;
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MatlabPlot::AddLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/)
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    MatlabLine *newLine = new MatlabLine(maxLen, plotAttrib, name);
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _line.push_back(newLine);
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (static_cast<int>(_line.size() - 1)); // index of newly inserted line
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MatlabPlot::AddTimeLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/,
439b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                            int64_t refTimeMs /*= -1*/)
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    MatlabTimeLine *newLine = new MatlabTimeLine(maxLen, plotAttrib, name, refTimeMs);
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _line.push_back(newLine);
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (static_cast<int>(_line.size() - 1)); // index of newly inserted line
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MatlabPlot::GetLineIx(const char *name)
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // search the list for a matching line name
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::vector<MatlabLine*>::iterator it = _line.begin();
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool matchFound = false;
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int lineIx = 0;
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (; it != _line.end(); it++, lineIx++)
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if ((*it)->_name == name)
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            matchFound = true;
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (matchFound)
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return (lineIx);
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return (-1);
485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::Append(int lineIndex, double x, double y)
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return;
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // sanity for index
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size()))
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        throw "Line index out of range";
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        exit(1);
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (_line[lineIndex]->Append(x, y));
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::Append(int lineIndex, double y)
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return;
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // sanity for index
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size()))
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        throw "Line index out of range";
522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        exit(1);
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (_line[lineIndex]->Append(y));
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MatlabPlot::Append(const char *name, double x, double y)
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // search the list for a matching line name
539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int lineIx = GetLineIx(name);
540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (lineIx < 0) //(!matchFound)
542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // no match; append new line
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        lineIx = AddLine(-1, NULL, name);
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // append data to line
548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Append(lineIx, x, y);
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (lineIx);
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MatlabPlot::Append(const char *name, double y)
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // search the list for a matching line name
562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int lineIx = GetLineIx(name);
563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (lineIx < 0) //(!matchFound)
565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // no match; append new line
567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        lineIx = AddLine(-1, NULL, name);
568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // append data to line
571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Append(lineIx, y);
572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (lineIx);
573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MatlabPlot::Length(char *name)
576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int ix = GetLineIx(name);
585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ix >= 0)
586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return (static_cast<int>(_line[ix]->_xData.size()));
588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return (-1);
592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::SetPlotAttribute(char *name, char *plotAttrib)
597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return;
603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int lineIx = GetLineIx(name);
606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (lineIx >= 0)
608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _line[lineIx]->SetAttribute(plotAttrib);
610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Must be called under critical section _critSect
614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::UpdateData(Engine* ep)
615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return;
619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        mxArray* xData = NULL;
624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        mxArray* yData = NULL;
625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        (*it)->GetPlotData(&xData, &yData);
626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (xData != NULL)
627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            std::string xName = (*it)->GetXName();
629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            std::string yName = (*it)->GetYName();
630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _critSect->Leave();
631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef MATLAB6
632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            mxSetName(xData, xName.c_str());
633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            mxSetName(yData, yName.c_str());
634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            engPutArray(ep, xData);
635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            engPutArray(ep, yData);
636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            int ret = engPutVariable(ep, xName.c_str(), xData);
638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            assert(ret == 0);
639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            ret = engPutVariable(ep, yName.c_str(), yData);
640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            assert(ret == 0);
641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _critSect->Enter();
643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool MatlabPlot::GetPlotCmd(std::ostringstream & cmd, Engine* ep)
648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect->Enter();
650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!DataAvailable())
652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return false;
654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_firstPlot)
657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        GetPlotCmd(cmd);
659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _firstPlot = false;
660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        GetRefreshCmd(cmd);
664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UpdateData(ep);
667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect->Leave();
669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return true;
671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Call inside critsect
674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::GetPlotCmd(std::ostringstream & cmd)
675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // we have something to plot
677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // empty the stream
678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    cmd.str(""); // (this seems to be the only way)
679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    cmd << "figure; h" << _figHandle << "= plot(";
681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // first line
683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::vector<MatlabLine*>::iterator it = _line.begin();
684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    cmd << (*it)->GetPlotString();
685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    it++;
687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // remaining lines
689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (; it != _line.end(); it++)
690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << ", ";
692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << (*it)->GetPlotString();
693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    cmd << "); ";
696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_legendEnabled)
698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        GetLegendCmd(cmd);
700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_smartAxis)
703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double xMin = _xlim[0];
705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double xMax = _xlim[1];
706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        double yMax = _ylim[1];
707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            xMax = std::max(xMax, (*it)->xMax());
710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            xMin = std::min(xMin, (*it)->xMin());
711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            yMax = std::max(yMax, (*it)->yMax());
713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            yMax = std::max(yMax, fabs((*it)->yMin()));
714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xlim[0] = xMin;
716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _xlim[1] = xMax;
717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _ylim[0] = -yMax;
718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _ylim[1] = yMax;
719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << "axis([" << _xlim[0] << ", " << _xlim[1] << ", " << _ylim[0] << ", " << _ylim[1] << "]);";
721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int i=1;
724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (it = _line.begin(); it != _line.end(); i++, it++)
725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << "set(h" << _figHandle << "(" << i << "), 'Tag', " << (*it)->GetLegendString() << ");";
727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Call inside critsect
731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::GetRefreshCmd(std::ostringstream & cmd)
732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    cmd.str(""); // (this seems to be the only way)
734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::vector<MatlabLine*>::iterator it = _line.begin();
735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (it = _line.begin(); it != _line.end(); it++)
736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << "h = findobj(0, 'Tag', " << (*it)->GetLegendString() << ");";
738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << (*it)->GetRefreshString();
739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //if (_legendEnabled)
741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //{
742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //    GetLegendCmd(cmd);
743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //}
744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::GetLegendCmd(std::ostringstream & cmd)
747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::vector<MatlabLine*>::iterator it = _line.begin();
749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool anyLegend = false;
750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (; it != _line.end(); it++)
751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        anyLegend = anyLegend || (*it)->hasLegend();
753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (anyLegend)
755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // create the legend
757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << "legend(h" << _figHandle << ",{";
759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // iterate lines
762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int i = 0;
763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (i > 0)
766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                cmd << ", ";
768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            cmd << (*it)->GetLegendString();
770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            i++;
771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        cmd << "}, 2); "; // place legend in upper-left corner
774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Call inside critsect
778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool MatlabPlot::DataAvailable()
779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_enabled)
781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return false;
783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        (*it)->PurgeOldData();
788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return true;
791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::Plot()
794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _timeToPlot = true;
798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef PLOT_TESTING
800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotStartTime = TickTime::MillisecondTimestamp();
801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::Reset()
806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _enabled = true;
810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        (*it)->Reset();
814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabPlot::SetFigHandle(int handle)
819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (handle > 0)
823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _figHandle = handle;
824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool
827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabPlot::TimeToPlot()
828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _enabled && _timeToPlot;
831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabPlot::Plotting()
835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotting = true;
838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabPlot::DonePlotting()
842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _timeToPlot = false;
845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotting = false;
846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _donePlottingEvent->Set();
847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid
850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabPlot::DisablePlot()
851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect->Enter();
853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (_plotting)
854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _critSect->Leave();
856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _donePlottingEvent->Wait(WEBRTC_EVENT_INFINITE);
857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _critSect->Enter();
858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _enabled = false;
860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint MatlabPlot::MakeTrend(const char *sourceName, const char *trendName, double slope, double offset, const char *plotAttrib)
863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int sourceIx;
867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int trendIx;
868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    sourceIx = GetLineIx(sourceName);
870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (sourceIx < 0)
871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // could not find source
873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return (-1);
874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    trendIx = GetLineIx(trendName);
877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (trendIx < 0)
878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // no trend found; add new line
880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        trendIx = AddLine(2 /*maxLen*/, plotAttrib, trendName);
881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _line[trendIx]->UpdateTrendLine(_line[sourceIx], slope, offset);
884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (trendIx);
886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabEngine::MatlabEngine()
891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org:
892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_critSect(CriticalSectionWrapper::CreateCriticalSection()),
893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_eventPtr(NULL),
894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_plotThread(NULL),
895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_running(false),
896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_numPlots(0)
897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _eventPtr = EventWrapper::Create();
899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotThread = ThreadWrapper::CreateThread(MatlabEngine::PlotThread, this, kLowPriority, "MatlabPlot");
901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_plotThread == NULL)
903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        throw "Unable to start MatlabEngine thread";
905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        exit(1);
906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _running = true;
909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned int tid;
911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotThread->Start(tid);
912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabEngine::~MatlabEngine()
916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect->Enter();
918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_plotThread)
920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _plotThread->SetNotAlive();
922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _running = false;
923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _eventPtr->Set();
924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        while (!_plotThread->Stop())
926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            ;
928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete _plotThread;
931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plots.clear();
934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plotThread = NULL;
936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _eventPtr;
938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _eventPtr = NULL;
939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _critSect->Leave();
941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _critSect;
942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgMatlabPlot * MatlabEngine::NewPlot(MatlabPlot *newPlot)
946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //MatlabPlot *newPlot = new MatlabPlot();
950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (newPlot)
952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        newPlot->SetFigHandle(++_numPlots); // first plot is number 1
954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _plots.push_back(newPlot);
955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (newPlot);
958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid MatlabEngine::DeletePlot(MatlabPlot *plot)
963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(_critSect);
965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (plot == NULL)
967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return;
969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::vector<MatlabPlot *>::iterator it;
972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (it = _plots.begin(); it < _plots.end(); it++)
973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (plot == *it)
975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert (plot == *it);
981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    (*it)->DisablePlot();
983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _plots.erase(it);
985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    --_numPlots;
986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete plot;
988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool MatlabEngine::PlotThread(void *obj)
992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!obj)
994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return (false);
996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    MatlabEngine *eng = (MatlabEngine *) obj;
999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Engine *ep = engOpen(NULL);
1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!ep)
1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        throw "Cannot open Matlab engine";
1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return (false);
1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    engSetVisible(ep, true);
1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    engEvalString(ep, "close all;");
1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (eng->_running)
1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        eng->_critSect->Enter();
1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // iterate through all plots
1015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        for (unsigned int ix = 0; ix < eng->_plots.size(); ix++)
1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            MatlabPlot *plot = eng->_plots[ix];
1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (plot->TimeToPlot())
1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                plot->Plotting();
1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                eng->_critSect->Leave();
1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                std::ostringstream cmd;
1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if (engEvalString(ep, cmd.str().c_str()))
1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    // engine dead
1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    return (false);
1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                // empty the stream
1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                cmd.str(""); // (this seems to be the only way)
1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if (plot->GetPlotCmd(cmd, ep))
1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    // things to plot, we have already accessed what we need in the plot
1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    plot->DonePlotting();
1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1037b57da6501f9db93536f51f7a64abf27306a7af04pbos@webrtc.org                    int64_t start = TickTime::MillisecondTimestamp();
1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    // plot it
1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    int ret = engEvalString(ep, cmd.str().c_str());
1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    printf("time=%I64i\n", TickTime::MillisecondTimestamp() - start);
1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    if (ret)
1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    {
1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                        // engine dead
1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                        return (false);
1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    }
1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef PLOT_TESTING
1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    if(plot->_plotStartTime >= 0)
1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    {
1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                        plot->_plotDelay = TickTime::MillisecondTimestamp() - plot->_plotStartTime;
1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                        plot->_plotStartTime = -1;
1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    }
1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                eng->_critSect->Enter();
1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        eng->_critSect->Leave();
1060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // wait a while
1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        eng->_eventPtr->Wait(66); // 33 ms
1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (ep)
1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        engClose(ep);
1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        ep = NULL;
1068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (true);
1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif // MATLAB
1075