Blame src/plugins/sine.cpp

Packit 995986
/* sine.cpp
Packit 995986
Packit 995986
   Free software by Richard W.E. Furse. Do with as you will. No
Packit 995986
   warranty. 
Packit 995986
Packit 995986
   This LADSPA plugin is written in C++ and provides a class that
Packit 995986
   implements a sine oscillator using a wavetable. Band-limiting to
Packit 995986
   avoid aliasing is trivial because of the waveform in use. Four
Packit 995986
   versions of the oscillator are provided, allowing the amplitude and
Packit 995986
   frequency inputs of the oscillator to be audio signals rather than
Packit 995986
   controls (for use in AM and FM synthesis).
Packit 995986
Packit 995986
   This file has poor memory protection. Failures during new() will
Packit 995986
   not recover nicely. */
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
#include <math.h>
Packit 995986
#include <stdlib.h>
Packit 995986
#include <string.h>
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
#include "ladspa.h"
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
/* The port numbers for the plugin: */
Packit 995986
Packit 995986
#define OSC_FREQUENCY 0
Packit 995986
#define OSC_AMPLITUDE 1
Packit 995986
#define OSC_OUTPUT    2
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
/* Sine table size is given by (1<
Packit 995986
#define SINE_TABLE_BITS 14
Packit 995986
#define SINE_TABLE_SHIFT (8 * sizeof(unsigned long) - SINE_TABLE_BITS)
Packit 995986
Packit 995986
LADSPA_Data * g_pfSineTable = NULL;
Packit 995986
LADSPA_Data g_fPhaseStepBase = 0;
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
inline char * 
Packit 995986
localStrdup(const char * input) {
Packit 995986
  char * output = new char[strlen(input) + 1];
Packit 995986
  strcpy(output, input);
Packit 995986
  return output;
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void
Packit 995986
initialise_sine_table() {
Packit 995986
  if (g_pfSineTable == NULL) {
Packit 995986
    long lTableSize = (1 << SINE_TABLE_BITS);
Packit 995986
    double dShift = (double(M_PI) * 2) / lTableSize;
Packit 995986
    g_pfSineTable = new float[lTableSize];
Packit 995986
    if (g_pfSineTable != NULL)
Packit 995986
      for (long lIndex = 0; lIndex < lTableSize; lIndex++)
Packit 995986
	g_pfSineTable[lIndex] = LADSPA_Data(sin(dShift * lIndex));
Packit 995986
  }
Packit 995986
  if (g_fPhaseStepBase == 0) {
Packit 995986
    g_fPhaseStepBase = (LADSPA_Data)pow(2, sizeof(unsigned long) * 8);
Packit 995986
  }
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
class SineOscillator {
Packit 995986
private:
Packit 995986
Packit 995986
  /* Ports: */
Packit 995986
  LADSPA_Data * m_pfFrequency;
Packit 995986
  LADSPA_Data * m_pfAmplitude;
Packit 995986
  LADSPA_Data * m_pfOutput;
Packit 995986
Packit 995986
  /* Oscillator state: */
Packit 995986
  unsigned long     m_lPhase;
Packit 995986
  unsigned long     m_lPhaseStep;
Packit 995986
  LADSPA_Data       m_fCachedFrequency;
Packit 995986
  const LADSPA_Data m_fLimitFrequency;
Packit 995986
  const LADSPA_Data m_fPhaseStepScalar;
Packit 995986
Packit 995986
  SineOscillator(const long lSampleRate) 
Packit 995986
    : m_lPhaseStep(0), 
Packit 995986
    m_fCachedFrequency(0),
Packit 995986
    m_fLimitFrequency(LADSPA_Data(lSampleRate * 0.5)),
Packit 995986
    m_fPhaseStepScalar(LADSPA_Data(g_fPhaseStepBase / lSampleRate)) {
Packit 995986
  }
Packit 995986
Packit 995986
  void setPhaseStepFromFrequency(const LADSPA_Data fFrequency) {
Packit 995986
    if (fFrequency != m_fCachedFrequency) {
Packit 995986
      if (fFrequency >= 0 && fFrequency < m_fLimitFrequency) 
Packit 995986
	m_lPhaseStep = (unsigned long)(m_fPhaseStepScalar * fFrequency);
Packit 995986
      else 
Packit 995986
	m_lPhaseStep = 0;
Packit 995986
      m_fCachedFrequency = fFrequency;
Packit 995986
    }
Packit 995986
  }
Packit 995986
Packit 995986
  friend LADSPA_Handle instantiateSineOscillator(const LADSPA_Descriptor *,
Packit 995986
						 unsigned long SampleRate);
Packit 995986
  friend void connectPortToSineOscillator(LADSPA_Handle Instance,
Packit 995986
					  unsigned long Port,
Packit 995986
					  LADSPA_Data * DataLocation);
Packit 995986
  friend void activateSineOscillator(void * pvHandle);
Packit 995986
  friend void runSineOscillator_FreqAudio_AmpAudio(LADSPA_Handle Instance,
Packit 995986
						   unsigned long SampleCount);
Packit 995986
  friend void runSineOscillator_FreqAudio_AmpCtrl(LADSPA_Handle Instance,
Packit 995986
						  unsigned long SampleCount);
Packit 995986
  friend void runSineOscillator_FreqCtrl_AmpAudio(LADSPA_Handle Instance,
Packit 995986
						  unsigned long SampleCount);
Packit 995986
  friend void runSineOscillator_FreqCtrl_AmpCtrl(LADSPA_Handle Instance,
Packit 995986
						 unsigned long SampleCount);
Packit 995986
  friend void cleanupSineOscillator(void *pvHandle);
Packit 995986
Packit 995986
};
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
LADSPA_Handle 
Packit 995986
instantiateSineOscillator(const LADSPA_Descriptor *,
Packit 995986
                          unsigned long SampleRate) {
Packit 995986
  return new SineOscillator(SampleRate);
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void 
Packit 995986
connectPortToSineOscillator(LADSPA_Handle Instance,
Packit 995986
                            unsigned long Port,
Packit 995986
                            LADSPA_Data * DataLocation) {
Packit 995986
  switch (Port) {
Packit 995986
  case OSC_FREQUENCY:
Packit 995986
    ((SineOscillator *)Instance)->m_pfFrequency = DataLocation;
Packit 995986
    break;
Packit 995986
  case OSC_AMPLITUDE:
Packit 995986
    ((SineOscillator *)Instance)->m_pfAmplitude = DataLocation;
Packit 995986
    break;
Packit 995986
  case OSC_OUTPUT:
Packit 995986
    ((SineOscillator *)Instance)->m_pfOutput = DataLocation;
Packit 995986
    break;
Packit 995986
  }
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void
Packit 995986
activateSineOscillator(void * pvHandle) {
Packit 995986
  ((SineOscillator *)pvHandle)->m_lPhase = 0;
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void 
Packit 995986
runSineOscillator_FreqAudio_AmpAudio(LADSPA_Handle Instance,
Packit 995986
                                     unsigned long SampleCount) {
Packit 995986
  SineOscillator * poSineOscillator = (SineOscillator *)Instance;
Packit 995986
  for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
Packit 995986
    /* Extract frequency at this point to guarantee inplace
Packit 995986
       support. */
Packit 995986
    LADSPA_Data fFrequency
Packit 995986
      = (poSineOscillator->m_pfFrequency[lIndex]);
Packit 995986
    poSineOscillator->m_pfOutput[lIndex]
Packit 995986
      = (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
Packit 995986
         * poSineOscillator->m_pfAmplitude[lIndex]);
Packit 995986
    poSineOscillator->setPhaseStepFromFrequency(fFrequency);
Packit 995986
    poSineOscillator->m_lPhase 
Packit 995986
      += poSineOscillator->m_lPhaseStep;
Packit 995986
  }
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void
Packit 995986
runSineOscillator_FreqAudio_AmpCtrl(LADSPA_Handle Instance,
Packit 995986
                                    unsigned long SampleCount) {
Packit 995986
  SineOscillator * poSineOscillator = (SineOscillator *)Instance;
Packit 995986
  LADSPA_Data fAmplitude = *(poSineOscillator->m_pfAmplitude);
Packit 995986
  for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
Packit 995986
    /* Extract frequency at this point to guarantee inplace
Packit 995986
       support. */
Packit 995986
    LADSPA_Data fFrequency
Packit 995986
      = (poSineOscillator->m_pfFrequency[lIndex]);
Packit 995986
    poSineOscillator->m_pfOutput[lIndex]
Packit 995986
      = (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
Packit 995986
         * fAmplitude);
Packit 995986
    poSineOscillator->setPhaseStepFromFrequency(fFrequency);
Packit 995986
    poSineOscillator->m_lPhase 
Packit 995986
      += poSineOscillator->m_lPhaseStep;
Packit 995986
  }
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void
Packit 995986
runSineOscillator_FreqCtrl_AmpAudio(LADSPA_Handle Instance,
Packit 995986
                                    unsigned long SampleCount) {
Packit 995986
  SineOscillator * poSineOscillator = (SineOscillator *)Instance;
Packit 995986
  poSineOscillator->setPhaseStepFromFrequency
Packit 995986
    (*(poSineOscillator->m_pfFrequency));
Packit 995986
  for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
Packit 995986
    poSineOscillator->m_pfOutput[lIndex]
Packit 995986
      = (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
Packit 995986
         * poSineOscillator->m_pfAmplitude[lIndex]);
Packit 995986
    poSineOscillator->m_lPhase 
Packit 995986
      += poSineOscillator->m_lPhaseStep;
Packit 995986
  }
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void
Packit 995986
runSineOscillator_FreqCtrl_AmpCtrl(LADSPA_Handle Instance,
Packit 995986
                                   unsigned long SampleCount) {
Packit 995986
  SineOscillator * poSineOscillator = (SineOscillator *)Instance;
Packit 995986
  LADSPA_Data fAmplitude = *(poSineOscillator->m_pfAmplitude);
Packit 995986
  poSineOscillator->setPhaseStepFromFrequency
Packit 995986
    (*(poSineOscillator->m_pfFrequency));
Packit 995986
  for (unsigned long lIndex = 0; lIndex < SampleCount; lIndex++) {
Packit 995986
    poSineOscillator->m_pfOutput[lIndex]
Packit 995986
      = (g_pfSineTable[poSineOscillator->m_lPhase >> SINE_TABLE_SHIFT]
Packit 995986
         * fAmplitude);
Packit 995986
    poSineOscillator->m_lPhase 
Packit 995986
      += poSineOscillator->m_lPhaseStep;
Packit 995986
  }
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
void
Packit 995986
cleanupSineOscillator(void *pvHandle) {
Packit 995986
  delete (SineOscillator *)pvHandle;
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
typedef char * char_ptr;
Packit 995986
Packit 995986
LADSPA_Descriptor * g_psDescriptors[4] = { NULL, NULL, NULL, NULL };
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
/* Global object used handle startup initialisation and shut down
Packit 995986
   tidying. Performs the function of the _init() and _fini() calls in
Packit 995986
   the C modules. */
Packit 995986
class StartupShutdownHandler {
Packit 995986
public:
Packit 995986
  
Packit 995986
  StartupShutdownHandler() {
Packit 995986
Packit 995986
    char ** pcPortNames;
Packit 995986
    LADSPA_PortDescriptor * piPortDescriptors;
Packit 995986
    LADSPA_PortRangeHint * psPortRangeHints;
Packit 995986
    
Packit 995986
    initialise_sine_table();
Packit 995986
    
Packit 995986
    for (long lPluginIndex = 0; lPluginIndex < 4; lPluginIndex++) {
Packit 995986
      
Packit 995986
      g_psDescriptors[lPluginIndex] = new LADSPA_Descriptor;
Packit 995986
      if (g_psDescriptors[lPluginIndex] == NULL)
Packit 995986
	break;
Packit 995986
      
Packit 995986
      g_psDescriptors[lPluginIndex]->UniqueID
Packit 995986
	= 1044 + lPluginIndex; /* 1044-1047. */
Packit 995986
      g_psDescriptors[lPluginIndex]->Properties
Packit 995986
	= LADSPA_PROPERTY_HARD_RT_CAPABLE;
Packit 995986
      g_psDescriptors[lPluginIndex]->Maker
Packit 995986
	= localStrdup("Richard Furse (LADSPA example plugins)");
Packit 995986
      g_psDescriptors[lPluginIndex]->Copyright
Packit 995986
	= localStrdup("None");
Packit 995986
      g_psDescriptors[lPluginIndex]->PortCount 
Packit 995986
	= 3;
Packit 995986
      piPortDescriptors
Packit 995986
	= new LADSPA_PortDescriptor[3];
Packit 995986
      g_psDescriptors[lPluginIndex]->PortDescriptors 
Packit 995986
	= (const LADSPA_PortDescriptor *)piPortDescriptors;
Packit 995986
      piPortDescriptors[OSC_OUTPUT]
Packit 995986
	= LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
Packit 995986
      pcPortNames
Packit 995986
	= new char_ptr[3];
Packit 995986
      g_psDescriptors[lPluginIndex]->PortNames
Packit 995986
	= (const char **)pcPortNames;
Packit 995986
      pcPortNames[OSC_FREQUENCY]
Packit 995986
	= localStrdup("Frequency (Hz)");
Packit 995986
      pcPortNames[OSC_AMPLITUDE] 
Packit 995986
	= localStrdup("Amplitude");
Packit 995986
      pcPortNames[OSC_OUTPUT]
Packit 995986
	= localStrdup("Output");
Packit 995986
      psPortRangeHints 
Packit 995986
	= new LADSPA_PortRangeHint[3];
Packit 995986
      g_psDescriptors[lPluginIndex]->PortRangeHints
Packit 995986
	= (const LADSPA_PortRangeHint *)psPortRangeHints;
Packit 995986
      psPortRangeHints[OSC_FREQUENCY].HintDescriptor
Packit 995986
	= (LADSPA_HINT_BOUNDED_BELOW
Packit 995986
	   | LADSPA_HINT_BOUNDED_ABOVE
Packit 995986
	   | LADSPA_HINT_SAMPLE_RATE
Packit 995986
	   | LADSPA_HINT_LOGARITHMIC
Packit 995986
	   | LADSPA_HINT_DEFAULT_440);
Packit 995986
      psPortRangeHints[OSC_FREQUENCY].LowerBound 
Packit 995986
	= 0;
Packit 995986
      psPortRangeHints[OSC_FREQUENCY].UpperBound
Packit 995986
	= 0.5;
Packit 995986
      psPortRangeHints[OSC_AMPLITUDE].HintDescriptor
Packit 995986
	= (LADSPA_HINT_BOUNDED_BELOW 
Packit 995986
	   | LADSPA_HINT_LOGARITHMIC
Packit 995986
	   | LADSPA_HINT_DEFAULT_1);
Packit 995986
      psPortRangeHints[OSC_AMPLITUDE].LowerBound 
Packit 995986
	= 0;
Packit 995986
      psPortRangeHints[OSC_OUTPUT].HintDescriptor
Packit 995986
	= 0;
Packit 995986
      g_psDescriptors[lPluginIndex]->instantiate
Packit 995986
	= instantiateSineOscillator;
Packit 995986
      g_psDescriptors[lPluginIndex]->connect_port 
Packit 995986
	= connectPortToSineOscillator;
Packit 995986
      g_psDescriptors[lPluginIndex]->activate
Packit 995986
	= activateSineOscillator;
Packit 995986
      g_psDescriptors[lPluginIndex]->run_adding
Packit 995986
	= NULL;
Packit 995986
      g_psDescriptors[lPluginIndex]->set_run_adding_gain
Packit 995986
	= NULL;
Packit 995986
      g_psDescriptors[lPluginIndex]->deactivate
Packit 995986
	= NULL;
Packit 995986
      g_psDescriptors[lPluginIndex]->cleanup
Packit 995986
	= cleanupSineOscillator;
Packit 995986
      
Packit 995986
      switch (lPluginIndex) {
Packit 995986
      case 0:
Packit 995986
	g_psDescriptors[lPluginIndex]->Label
Packit 995986
	  = localStrdup("sine_faaa");
Packit 995986
	g_psDescriptors[lPluginIndex]->Name 
Packit 995986
	  = localStrdup("Sine Oscillator (Freq:audio, Amp:audio)");
Packit 995986
	piPortDescriptors[OSC_FREQUENCY]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
Packit 995986
	piPortDescriptors[OSC_AMPLITUDE]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
Packit 995986
	g_psDescriptors[lPluginIndex]->run 
Packit 995986
	  = runSineOscillator_FreqAudio_AmpAudio;
Packit 995986
	break;
Packit 995986
      case 1:
Packit 995986
	g_psDescriptors[lPluginIndex]->Label
Packit 995986
	  = localStrdup("sine_faac");
Packit 995986
	g_psDescriptors[lPluginIndex]->Name 
Packit 995986
	  = localStrdup("Sine Oscillator (Freq:audio, Amp:control)");
Packit 995986
	piPortDescriptors[OSC_FREQUENCY]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
Packit 995986
	piPortDescriptors[OSC_AMPLITUDE]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
Packit 995986
	g_psDescriptors[lPluginIndex]->run 
Packit 995986
	  = runSineOscillator_FreqAudio_AmpCtrl;
Packit 995986
	break;
Packit 995986
      case 2:
Packit 995986
	g_psDescriptors[lPluginIndex]->Label
Packit 995986
	  = localStrdup("sine_fcaa");
Packit 995986
	g_psDescriptors[lPluginIndex]->Name 
Packit 995986
	  = localStrdup("Sine Oscillator (Freq:control, Amp:audio)");
Packit 995986
	piPortDescriptors[OSC_FREQUENCY]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
Packit 995986
	piPortDescriptors[OSC_AMPLITUDE]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
Packit 995986
	g_psDescriptors[lPluginIndex]->run 
Packit 995986
	  = runSineOscillator_FreqCtrl_AmpAudio;
Packit 995986
	break;
Packit 995986
      case 3:
Packit 995986
	g_psDescriptors[lPluginIndex]->Label
Packit 995986
	  = localStrdup("sine_fcac");
Packit 995986
	g_psDescriptors[lPluginIndex]->Name 
Packit 995986
	  = localStrdup("Sine Oscillator (Freq:control, Amp:control)");
Packit 995986
	piPortDescriptors[OSC_FREQUENCY]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
Packit 995986
	piPortDescriptors[OSC_AMPLITUDE]
Packit 995986
	  = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
Packit 995986
	g_psDescriptors[lPluginIndex]->run 
Packit 995986
	  = runSineOscillator_FreqCtrl_AmpCtrl;
Packit 995986
	break;
Packit 995986
      }
Packit 995986
    }
Packit 995986
  }
Packit 995986
  
Packit 995986
  void deleteDescriptor(LADSPA_Descriptor * psDescriptor) {
Packit 995986
    unsigned long lIndex;
Packit 995986
    if (psDescriptor) {
Packit 995986
      delete [] psDescriptor->Label;
Packit 995986
      delete [] psDescriptor->Name;
Packit 995986
      delete [] psDescriptor->Maker;
Packit 995986
      delete [] psDescriptor->Copyright;
Packit 995986
      delete [] psDescriptor->PortDescriptors;
Packit 995986
      for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++)
Packit 995986
	delete [] psDescriptor->PortNames[lIndex];
Packit 995986
      delete [] psDescriptor->PortNames;
Packit 995986
      delete [] psDescriptor->PortRangeHints;
Packit 995986
      delete psDescriptor;
Packit 995986
    }
Packit 995986
  }
Packit 995986
  
Packit 995986
  ~StartupShutdownHandler() {
Packit 995986
    deleteDescriptor(g_psDescriptors[0]);
Packit 995986
    deleteDescriptor(g_psDescriptors[1]);
Packit 995986
    deleteDescriptor(g_psDescriptors[2]);
Packit 995986
    deleteDescriptor(g_psDescriptors[3]);
Packit 995986
    delete [] g_pfSineTable;
Packit 995986
  }
Packit 995986
Packit 995986
} g_oShutdownStartupHandler;
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
  
Packit 995986
const LADSPA_Descriptor * 
Packit 995986
ladspa_descriptor(unsigned long Index) {
Packit 995986
  if (Index < 4)
Packit 995986
    return g_psDescriptors[Index];
Packit 995986
  else
Packit 995986
    return NULL;
Packit 995986
}
Packit 995986
Packit 995986
/*****************************************************************************/
Packit 995986
Packit 995986
/* EOF */