2015/08/02

LADSPA Amplifear (dB / Linear)

チェックボックスで、dBとLinearの切替ができるアンプを作ってみる。 チェックボックスと連動して、スライダー表示をマスクすることはできないので、dB、Linearどちらも普通に操作できてしまう。 またスライダーを1個にして、チェックボックスによって、表示を変化させることもできない。 何かとLADSPAのGUIは扱いにくい。


LADSPA Amplifear (dB / Linear) ソースコード

/* namagi_gui.c 
 * 2015.08.02
 * compile windows
 * gcc -shared -o namagi_amplifier.dll namagi_amplifier.c -ID
 * 
 * compile Ubuntu
 * gcc -fPIC -DPIC -shared -nostartfiles
   -o namagi_amplifier.so namagi_amplifier.c
*/
/**********************************************************/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "ladspa.h"
/**********************************************************/
#define AMP_INPUT1   0
#define AMP_OUTPUT1  1
#define MIN_GAIN   -100
#define MAX_GAIN    100
#define AMP_CKBOX    2
#define AMP_CONTROL1 3 /* dB */
#define AMP_CONTROL2 4 /* Linear */
/**********************************************************/
#ifdef WIN32
int bIsFirstTime = 1;
void _init();
#endif

#ifdef WIN32
    #define _WINDOWS_DLL_EXPORT_ __declspec(dllexport)
#else
    #define _WINDOWS_DLL_EXPORT_ 
#endif
/**********************************************************/
typedef struct {
  LADSPA_Data *m_pfCheckBox;
  LADSPA_Data *m_pfControlValue1; /* dB */
  LADSPA_Data *m_pfControlValue2; /* Linear */
  LADSPA_Data *m_pfInputBuffer1;
  LADSPA_Data *m_pfOutputBuffer1;
} Amplifier;
/**********************************************************/
LADSPA_Handle instantiateAmplifier(
         const LADSPA_Descriptor *Descriptor, 
         unsigned long  SampleRate){
               /* メモリ確保 */
               return malloc(sizeof(Amplifier));
}
/**********************************************************/
void connectPortToAmplifier(
                 LADSPA_Handle Instance,
                 unsigned long Port,
                 LADSPA_Data *DataLocation) {
  Amplifier *psAmplifier;
  psAmplifier = (Amplifier *)Instance;

  switch (Port){
  case AMP_CKBOX:
    psAmplifier -> m_pfCheckBox = DataLocation;
    break;  
  case AMP_CONTROL1: /* dB */
    psAmplifier -> m_pfControlValue1 = DataLocation;
    break;  
  case AMP_CONTROL2: /* Linear */
    psAmplifier -> m_pfControlValue2 = DataLocation;
    break;  
  case AMP_INPUT1:
    psAmplifier -> m_pfInputBuffer1 = DataLocation;
    break;
  case AMP_OUTPUT1:
    psAmplifier -> m_pfOutputBuffer1 = DataLocation;
    break;
  }
}
/**********************************************************/
void runAmplifier(LADSPA_Handle Instance,
              unsigned long SampleCount){
  LADSPA_Data fCheckBox;
  LADSPA_Data fGain1; /* dB */
  LADSPA_Data fGain2; /* Linear */
  LADSPA_Data *pfInput;
  LADSPA_Data *pfOutput;
  /*構造体のインスタンス*/
  Amplifier *psAmplifier;
  psAmplifier =  (Amplifier*) Instance;
  
  unsigned long lSampleIndex;
  fCheckBox = *(psAmplifier -> m_pfCheckBox);
  fGain1 = *(psAmplifier -> m_pfControlValue1); /* dB */
  fGain2 = *(psAmplifier -> m_pfControlValue2); /* Linear */
  pfInput = psAmplifier -> m_pfInputBuffer1;
  pfOutput = psAmplifier -> m_pfOutputBuffer1;

  if(fCheckBox == 0){
    /* dB */
    for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++){
       *(pfOutput++) = *(pfInput++) * pow(10,fGain1/20.0);
    }
  }else{
    /* Linear */
    for (lSampleIndex = 0; lSampleIndex < SampleCount; lSampleIndex++){
        *(pfOutput++) = *(pfInput++) * fGain2;
    }
  }
}
/**********************************************************/
void cleanupAmplifier(LADSPA_Handle Instance) {
  free(Instance);
}
/**********************************************************/
LADSPA_Descriptor * g_psDescriptor = NULL;
/**********************************************************/
void _init() {
  char ** pcPortNames;
  LADSPA_PortDescriptor * piPortDescriptors;
   /* スライドなど 構造体 */
  LADSPA_PortRangeHint * psPortRangeHints;
  int portsNum = 5; /* ポートの数 */
  /* メモリ確保 */
  g_psDescriptor
 = (LADSPA_Descriptor *)malloc(sizeof(LADSPA_Descriptor));
  
  if (g_psDescriptor) {
    /* Audacityに表示する情報 */
    g_psDescriptor -> UniqueID = 3;
    g_psDescriptor -> Label= strdup("Amplifier");
    g_psDescriptor -> Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
    g_psDescriptor -> Name  = strdup("Namagi: Amplifier ver 150802");
    g_psDescriptor -> Maker = strdup("Namagi Products");
    g_psDescriptor -> Copyright = strdup("None");
    g_psDescriptor -> PortCount = portsNum;

    /* メモリ確保 */
    piPortDescriptors
       = (LADSPA_PortDescriptor *)calloc(portsNum,
       sizeof(LADSPA_PortDescriptor));
    /*  */
    g_psDescriptor -> PortDescriptors
       = (const LADSPA_PortDescriptor *)piPortDescriptors;

    /* ポートの関連付け */
    piPortDescriptors[AMP_CKBOX]
         = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
    piPortDescriptors[AMP_CONTROL1]
         = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
    piPortDescriptors[AMP_CONTROL2]
         = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
    piPortDescriptors[AMP_INPUT1]
         = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO;
    piPortDescriptors[AMP_OUTPUT1]
         = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;

    /* メモリ確保 */
    pcPortNames = (char **)calloc(portsNum, sizeof(char *));
    /*  */
    g_psDescriptor -> PortNames = (const char **)pcPortNames;

    /* ポートの関連付け。ポート名 */
    pcPortNames[AMP_CKBOX]   = strdup("off(dB)- on(linear)");
    pcPortNames[AMP_CONTROL1] = strdup("Gain(dB)");
    pcPortNames[AMP_CONTROL2] = strdup("Gain(linear)");
    pcPortNames[AMP_INPUT1]   = strdup("Input");
    pcPortNames[AMP_OUTPUT1]  = strdup("Output");

    /* メモリ確保 ポート数を修正 */
    psPortRangeHints
        = ((LADSPA_PortRangeHint *)calloc(portsNum,
           sizeof(LADSPA_PortRangeHint)));
    /*  */
    g_psDescriptor -> PortRangeHints
         = (const LADSPA_PortRangeHint *)psPortRangeHints;

/* 1段目 checkbox 0:off(dB), 1:on(linear */
    psPortRangeHints[AMP_CKBOX].HintDescriptor
         = (LADSPA_HINT_TOGGLED | LADSPA_HINT_DEFAULT_0);
         
/* 2段目 dB */
    psPortRangeHints[AMP_CONTROL1].HintDescriptor
         = (LADSPA_HINT_BOUNDED_BELOW 
        | LADSPA_HINT_BOUNDED_ABOVE
        | LADSPA_HINT_DEFAULT_0);
    psPortRangeHints[AMP_CONTROL1].LowerBound
         =(LADSPA_Data)MIN_GAIN;/* dB */
    psPortRangeHints[AMP_CONTROL1].UpperBound
         =(LADSPA_Data)MAX_GAIN;/* -dB */

/* 3段目 Liniear */
    psPortRangeHints[AMP_CONTROL2].HintDescriptor
         = (LADSPA_HINT_BOUNDED_BELOW
          | LADSPA_HINT_BOUNDED_ABOVE
          | LADSPA_HINT_DEFAULT_1);
    psPortRangeHints[AMP_CONTROL2].LowerBound = 0; /*  */
    psPortRangeHints[AMP_CONTROL2].UpperBound = 20; /*  */
    
    
    /* input output */
    psPortRangeHints[AMP_INPUT1].HintDescriptor = 0;
    psPortRangeHints[AMP_OUTPUT1].HintDescriptor = 0;
    
    /* 初期値を入れる 関数の登録 */
    g_psDescriptor -> instantiate   = instantiateAmplifier;
    g_psDescriptor -> connect_port  = connectPortToAmplifier;
    g_psDescriptor -> activate      = NULL;
    g_psDescriptor -> run           = runAmplifier;
    g_psDescriptor -> run_adding    = NULL;
    g_psDescriptor -> set_run_adding_gain  = NULL;
    g_psDescriptor -> deactivate   = NULL;
    g_psDescriptor -> cleanup      = cleanupAmplifier;
  }
}
/**********************************************************/
void deleteDescriptor(LADSPA_Descriptor * psDescriptor){
  unsigned long lIndex;
  if (psDescriptor){
    free((char *)psDescriptor -> Label);
    free((char *)psDescriptor -> Name);
    free((char *)psDescriptor -> Maker);
    free((char *)psDescriptor -> Copyright);
    free((LADSPA_PortDescriptor *)psDescriptor -> PortDescriptors);

    for (lIndex=0; lIndex < psDescriptor -> PortCount; lIndex++){
      free((char *)(psDescriptor -> PortNames[lIndex]));
    }
    free((char **)psDescriptor -> PortNames);
    free((LADSPA_PortRangeHint *)psDescriptor -> PortRangeHints);
    free(psDescriptor);
  }
}
/**********************************************************/
void _fini(){
  deleteDescriptor(g_psDescriptor);
}
/**********************************************************/
_WINDOWS_DLL_EXPORT_
const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index){
   #ifdef WIN32
    if (bIsFirstTime) {
       _init();
       bIsFirstTime = 0;
    }
    #endif
    if (Index == 0)
       return g_psDescriptor;
    else
       return NULL;
}


sound programming 目次