Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2013 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #ifndef MARSYAS_THREAD_ATOMIC_CONTROL_INCLUDED 00020 #define MARSYAS_THREAD_ATOMIC_CONTROL_INCLUDED 00021 00022 #include <marsyas/realtime/any.h> 00023 #include <marsyas/realtime/stage.h> 00024 00025 #include <marsyas/common_header.h> 00026 #include <marsyas/realvec.h> 00027 #include <marsyas/system/MarControl.h> 00028 00029 #include <atomic> 00030 #include <string> 00031 #include <cstring> 00032 00033 namespace Marsyas { 00034 namespace RealTime { 00035 00036 using std::atomic; 00037 00038 using Marsyas::MarControl; 00039 using Marsyas::MarControlPtr; 00040 00045 class AtomicControl 00046 { 00047 public: 00048 AtomicControl( const MarControlPtr & control ): 00049 m_control(control) 00050 {} 00051 00052 virtual ~AtomicControl() {} 00053 00057 virtual any value() = 0; 00058 00062 virtual void push() = 0; 00063 00064 MarControlPtr & systemControl() { return m_control; } 00065 00066 protected: 00067 MarControlPtr m_control; 00068 }; 00069 00070 template<typename T> 00071 class AtomicControlT : public AtomicControl 00072 { 00073 public: 00074 AtomicControlT( const MarControlPtr & control ): 00075 AtomicControl(control), 00076 m_value(T()) 00077 {} 00078 00079 any value() 00080 { 00081 return any(m_value.load()); 00082 } 00083 00084 void push() 00085 { 00086 m_value = m_control->to<T>(); 00087 } 00088 00089 private: 00090 atomic<T> m_value; 00091 }; 00092 00093 template<> 00094 class AtomicControlT<mrs_string> : public AtomicControl 00095 { 00096 public: 00097 AtomicControlT( const MarControlPtr & control ): 00098 AtomicControl(control) 00099 {} 00100 00101 any value() 00102 { 00103 MRSERR("AtomicControlT<mrs_string>::value(): not yet implemented!"); 00104 return any(mrs_string()); 00105 } 00106 00107 void push() 00108 { 00109 // FIXME: not real-time safe! 00110 // m_value = m_control->to<mrs_string>(); 00111 } 00112 }; 00113 00114 template<> 00115 class AtomicControlT<mrs_realvec> : public AtomicControl 00116 { 00117 public: 00118 AtomicControlT( const MarControlPtr & control ): 00119 AtomicControl(control) 00120 { 00121 resizeToFit(); 00122 } 00123 00124 void resizeToFit() 00125 { 00126 const mrs_realvec & vector = m_control->to<mrs_realvec>(); 00127 m_rows = vector.getRows(); 00128 m_columns = vector.getCols(); 00129 m_value.create( m_rows, m_columns ); 00130 m_stage.clear( m_value ); 00131 } 00132 00133 any value() 00134 { 00135 const_cast<stage<mrs_realvec>&>(m_stage).pop(); 00136 if (m_stage.has_front()) 00137 m_value = m_stage.front(); 00138 return any(m_value); 00139 } 00140 00141 void push() 00142 { 00143 const mrs_realvec & value = m_control->to<mrs_realvec>(); 00144 if (value.getRows() == m_rows && value.getCols() == m_columns) 00145 { 00146 mrs_realvec & stage_value = m_stage.back(); 00147 std::memcpy( stage_value.getData(), 00148 value.getData(), 00149 sizeof(mrs_real) * value.getSize() ); 00150 m_stage.push(); 00151 } 00152 else 00153 { 00154 MRSERR("AtomicControlT<mrs_realvec>::push(): realvec format mismatch!"); 00155 } 00156 } 00157 00158 private: 00159 mrs_natural m_rows; 00160 mrs_natural m_columns; 00161 mrs_realvec m_value; 00162 stage<mrs_realvec> m_stage; 00163 }; 00164 00165 00166 } // namespace RealTime 00167 } // namespace Marsyas 00168 00169 #endif // MARSYAS_THREAD_ATOMIC_CONTROL_INCLUDED