00001 /******************************************************************************* 00002 * ISoundElement.cpp (JackFX) 00003 ******************************************************************************/ 00004 00005 #include "ISoundElement.h" 00006 #include "JackClient.h" 00007 00008 ISoundElement::ISoundElement() 00009 { 00010 JackClient::GetSingleton()->m_elements.push_back(this); 00011 pthread_mutex_init(&m_mtx, NULL); 00012 } 00013 00014 ISoundElement::~ISoundElement() 00015 { 00016 pthread_mutex_destroy(&m_mtx); 00017 try { 00018 JackClient::GetSingleton()->m_elements.remove(this); 00019 } 00020 catch(...) {} //Ignore. 00021 } 00022 00023 00024 SoundFrame& ISoundElement::GetPipe() 00025 { 00026 return m_pipe; 00027 } 00028 00029 void ISoundElement::Process(jack_nframes_t count) 00030 { 00031 GetPipe().Zero(); 00032 list<ISoundElement*>::iterator i; 00033 for (i = m_inputs.begin(); i != m_inputs.end(); i++) { 00034 GetPipe() += (*i)->GetPipe(); 00035 } 00036 } 00037 00038 void ISoundElement::AddInput(ISoundElement* element) 00039 { 00040 Lock l(this); 00041 m_inputs.push_back(element); 00042 } 00043 00044 void ISoundElement::RemoveInput(ISoundElement* element) 00045 { 00046 Lock l(this); 00047 m_inputs.remove(element); 00048 } 00049 00050 ISoundElement* ISoundElement::GetParameter(const string& pname) 00051 { 00052 Lock l(this); 00053 map<string, ISoundElement*>::iterator i = m_parameters.find(pname); 00054 if (i != m_parameters.end()) { 00055 return i->second; 00056 } 00057 throw runtime_error("No parameter named " + pname + "." ); 00058 } 00059 00060 void ISoundElement::SetParameter(const string& pname, ISoundElement* e) 00061 { 00062 m_parameters[pname] = e; 00063 } 00064 00065 void ISoundElement::DelParameter(const string& pname) 00066 { 00067 m_parameters.erase(pname); 00068 } 00069 00070 bool ISoundElement::_Updatable(unsigned int tickid) 00071 { 00072 Lock l(this); 00073 00074 list<ISoundElement*>::iterator i; 00075 for (i = m_inputs.begin(); i != m_inputs.end(); ++i) { 00076 //If any of our inputs still need updating, we're not yet updatable. 00077 if ((*i)->_Ready(tickid) == true) { 00078 return false; 00079 } 00080 } 00081 00082 map<string, ISoundElement*>::iterator pi; 00083 for (pi = m_parameters.begin(); pi != m_parameters.end(); ++pi) { 00084 //If any of our parameters still need updating, we're not yet updatable. 00085 if (pi->second->_Ready(tickid) == true) { 00086 return false; 00087 } 00088 } 00089 00090 return true && _Ready(tickid); 00091 } 00092 00093 bool ISoundElement::_Ready(unsigned int tickid) 00094 { 00095 //Return whether our pipe is out of date. 00096 return m_lasttickid != tickid; 00097 } 00098 00099 void ISoundElement::_Update(unsigned int tickid, jack_nframes_t count) 00100 { 00101 //Lock l(this); 00102 00103 m_lasttickid = tickid; 00104 Process(count); 00105 } 00106 00107 00108 00109 ISoundSource::ISoundSource() 00110 { 00111 JackClient::GetSingleton()->m_sources.push_back(this); 00112 } 00113 00114 ISoundSource::~ISoundSource() 00115 { 00116 try { 00117 JackClient::GetSingleton()->m_sources.remove(this); 00118 } 00119 catch(...) {} //Ignore. 00120 } 00121 00122 void ISoundSource::Process(jack_nframes_t count) 00123 { 00124 GetPipe().Set(count); 00125 GetPipe().Zero(); 00126 } 00127 00128 ISoundElement::Lock::Lock(ISoundElement* e) : m_element(e) 00129 { 00130 pthread_mutex_lock(&(m_element->m_mtx)); 00131 } 00132 00133 ISoundElement::Lock::~Lock() 00134 { 00135 pthread_mutex_unlock(&(m_element->m_mtx)); 00136 } 00137