////////////////////////////////////////////////// // LADSPAplug.cpp: implementation of the LADSPAplug // Linux Audio Developers // Simple Plugin API // Model #include "Ladspaplug.h" #include LADSPAplug::LADSPAplug(SndObj *procobj, int controls, char **message, int vecsize, float sr) { // initialise members m_sndobj_vecsize = vecsize; m_sr = sr; m_pos = 0; // instantiate input SndObj m_inobj = new SndObj(0,m_sndobj_vecsize,m_sr); // set processing object m_procobj = procobj; procobj->Connect("input", m_inobj); // set controls m_controls = controls; // if there are any controls if(m_controls){ m_message = new char*[m_controls]; m_value = new float[m_controls]; m_parameter = new LADSPA_Data*[m_controls]; for(int i = 0; i < m_controls; i++){ m_message[i] = strdup(message[i]); m_value[i] = 0.f; } } } LADSPAplug::~LADSPAplug(){ // dispose of dynamic objects // including the processing SndObj delete[] m_message; delete[] m_parameter; delete[] m_value; delete m_procobj; delete m_inobj; } void LADSPAplug::Process(unsigned long blocksize){ // if the blocksize is bigger than the // SndObj vectorsize than we will have to // loop to create the output // otherwise, we will process input only when // the SndObj input buffer is full // The only requirement is that one // is a factor of the other. // One way of guarateeing this for all cases // is to set sndobj_vecsize to 1, which is // very unefficient. // However, it is reasonable to assume blocksizes // to be power-of-two sizes, so we can set // sndobj_vecsize to a power-of-two (say 256, // the default). int i; int samples = blocksize < m_sndobj_vecsize ? blocksize : m_sndobj_vecsize; // set the control values for(i=0; i < m_controls;i++){ if(m_value[i] != *m_parameter[i]) { m_value[i] = *m_parameter[i]; m_procobj->Set(m_message[i], m_value[i]); } } // process loop for(int i = 0; i < blocksize; i += m_sndobj_vecsize){ // this will only loop if the input blocksize is // bigger than the SndObj vectorsize // if so, we will read along different positions of // the input buffer // otherwise, it will only execute once m_pos = m_inobj->PushIn(m_insig+i, samples); // DoProcess() will always be called if the // blocksize is bigger than the SndObj vectorsize // otherwise it will only be called if the sndobj // input buffer is full if(m_pos == m_sndobj_vecsize) m_procobj->DoProcess(); // if the input blocksize is bigger than the SndObj // vectorsize we will write to different positions // along the output buffer // otherwise, we will write a single whole buffer m_procobj->PopOut(m_outsig+i, samples); } }