/*
**  2014.09.17 K.Takagi @ Sif
**
**  main.cpp をベースに従来の引数指定に加えてパラメータファイル対応
**  引数でパラメータファイルを指定可能
**  引数指定のパラメータ --> パラメータファイル読み込みの順に処理
**  
**  ソッケト経由でのパラメータ設定に対応
**  --SET に続けてパラメータファイルと同じ書式の文字列を指定
**  設定したパラメータはHARKの処理を開始するときに反映される
**  
**  HARK-CPU基板では分離音をBluetoothでタブレットに転送する
**  処理は定位と分離なのでパラメータファイルへの対応も定位と分離を実装
**  
**  --config 修正
**      処理が未実装だったので実装
**  --daemon 追加 
**      デーモンとして起動させる
**  --stanby 追加
**      起動後に外部からの開始命令を待って処理を開始する
**      未指定時は従来どおり起動後にHARKの処理が開始される
**  
**  device_is_usbをdevice_is_socketに変更
**  
**  補足
**  main.cpp のコードをベースにインデントを整理
**  space=4でインデント
**  
*/

/*-------------------------------------------------------------------*/
#include <signal.h>

/* パラメータファイル関係 */
#define PRM_ERR     -1
#define PRM_SKIP     0
#define PRM_READ     1

#define PRM_STR_LENGTH 256

/* パラメータ解析の共通関数 */
static int ParamFileReadLine(FILE *fp, char *prm_str)
{
    char *ptr;
    char *pos;
    
    ptr = fgets(prm_str, PRM_STR_LENGTH, fp);
    if(ptr == NULL)
    {
        return PRM_ERR;
    }
    
    /* #以降はコメントのため削除 */
    pos = strchr(prm_str, (int)'#');
    if(pos != NULL)
    {
        *pos = '\0';
    }
    
    pos = strchr(prm_str, (int)'\n');
    if(pos != NULL)
    {
        *pos = '\0';
    }
    
    pos = strchr(prm_str, (int)'\r');
    if(pos != NULL)
    {
        *pos = '\0';
    }
    
    if(strlen(prm_str) > 0)
    {
        return PRM_READ;
    }
    
    return PRM_SKIP;
}

static int ParamStringReadInt(char *prm_str, int *val)
{
    int num;
    int tmp;
    
    num = sscanf(prm_str, "%*s %d", &tmp);
    if(num == 1)
    {
        *val = tmp;
        return 0;
    }
    return PRM_ERR;
}

static int ParamStringReadInt2(char *prm_str, int *val1, int *val2)
{
    int num;
    int tmp1;
    int tmp2;
    
    num = sscanf(prm_str, "%*s %d %d", &tmp1, &tmp2);
    if(num == 2)
    {
        *val1 = tmp1;
        *val2 = tmp2;
        return 0;
    }
    return PRM_ERR;
}

static int ParamStringReadFloat(char *prm_str, float *val)
{
    int num;
    float tmp;
    
    num = sscanf(prm_str, "%*s %f", &tmp);
    if(num == 1)
    {
        *val = tmp;
        return 0;
    }
    return PRM_ERR;
}

static int ParamStringReadString(char *prm_str, char *str)
{
    int num;
    char tmp[256];
    
    num = sscanf(prm_str, "%*s %s", tmp);
    if(num == 1)
    {
        strcpy(str, tmp);
        return 0;
    }
    return PRM_ERR;
}

/**** Localize Music関係 ****/

static Param_LocalizeMUSIC_t PF_localize_music;

static void ParamPrintLocalizeMusic()
{
    printf("\n[Localize Music]\n");
    printf("length        = %d\n", PF_localize_music.length);
    printf("sampling_rate = %d\n", PF_localize_music.sampling_rate);
    printf("elevation     = %f\n", PF_localize_music.elevation);
    printf("window        = %d\n", PF_localize_music.window);
    printf("period        = %d\n", PF_localize_music.period);
    printf("num_source    = %d(%d)\n", PF_localize_music.num_source, PF_localize_music.export_num_source);
    printf("deg           = %d %d\n", PF_localize_music.min_deg, PF_localize_music.max_deg);
    printf("freq          = %d %d\n", PF_localize_music.low_bound_frequency, PF_localize_music.upper_bound_frequency);
}

void ParamSetLocalizeMusic(Param_LocalizeMUSIC_t *prm)
{
    PF_localize_music = *prm;
}

void ParamGetLocalizeMusic(Param_LocalizeMUSIC_t *prm)
{
    prm->elevation             = PF_localize_music.elevation;
    prm->window                = PF_localize_music.window;
    prm->period                = PF_localize_music.period;
    prm->num_source            = PF_localize_music.num_source;
    prm->export_num_source     = PF_localize_music.export_num_source;
    prm->min_deg               = PF_localize_music.min_deg;
    prm->max_deg               = PF_localize_music.max_deg;
    prm->low_bound_frequency   = PF_localize_music.low_bound_frequency;
    prm->upper_bound_frequency = PF_localize_music.upper_bound_frequency;
}

static int ParamReadLocalizeMusic(char *prm_str)
{
    int ret;
    char *ptr;
    
    ret = PRM_ERR;
    if((ptr = strstr(prm_str, "length")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_localize_music.length);
    }
    else if((ptr = strstr(prm_str, "sampling-rate")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_localize_music.sampling_rate);
    }
    else if((ptr = strstr(prm_str, "elevation")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_localize_music.elevation);
    }
    else if((ptr = strstr(prm_str, "window")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_localize_music.window);
    }
    else if((ptr = strstr(prm_str, "period")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_localize_music.period);
    }
    else if((ptr = strstr(prm_str, "export-num-source")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_localize_music.export_num_source);
    }
    else if((ptr = strstr(prm_str, "num-source")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_localize_music.num_source);
    }
    else if((ptr = strstr(prm_str, "deg-min-max")) != NULL)
    {
        ret = ParamStringReadInt2(prm_str, &PF_localize_music.min_deg, &PF_localize_music.max_deg);
    }
    else if((ptr = strstr(prm_str, "freq-low-upper")) != NULL)
    {
        ret = ParamStringReadInt2(prm_str, &PF_localize_music.low_bound_frequency, &PF_localize_music.upper_bound_frequency);
    }

    return ret;
}

/**** Source Tracker 関係 ****/

static Param_SourceTracker_t PF_source_tracker;

static void ParamPrintSourceTracker()
{
    printf("\n[Source Tracker]\n");
    printf("thresh           = %f\n", PF_source_tracker.thresh);
    printf("pause_length     = %f\n", PF_source_tracker.pause_length);
    printf("min_src_interval = %f\n", PF_source_tracker.min_src_interval);
    printf("min_id           = %d\n", PF_source_tracker.min_id);
}

void ParamSetSourceTracker(Param_SourceTracker_t *prm)
{
    PF_source_tracker = *prm;
}

void ParamGetSourceTracker(Param_SourceTracker_t *prm)
{
    /*
    prm->thresh = PF_source_tracker.thresh;
    */
    *prm = PF_source_tracker;
}

static int ParamReadSourceTracker(char *prm_str)
{
    int ret;
    char *ptr;
    
    ret = PRM_ERR;
    if((ptr = strstr(prm_str, "thresh")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_source_tracker.thresh);
    }
    else if((ptr = strstr(prm_str, "pause-length")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_source_tracker.pause_length);
    }
    else if((ptr = strstr(prm_str, "min-source-interval")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_source_tracker.min_src_interval);
    }
    else if((ptr = strstr(prm_str, "min_id")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_source_tracker.min_id);
    }

    return ret;
}

/**** Source Interval Extender 関係 ****/

static Param_SourceIntervalExtender_t PF_source_interval_extender;

static void ParamPrintSourceIntervalExtender()
{
    printf("\n[Source Interval Extender]\n");
    printf("preroll_length  = %d\n", PF_source_interval_extender.preroll_length);
}

void ParamSetSourceIntervalExtender(Param_SourceIntervalExtender_t *prm)
{
    PF_source_interval_extender = *prm;
}

void ParamGetSourceIntervalExtender(Param_SourceIntervalExtender_t *prm)
{
    *prm = PF_source_interval_extender;
}

static int ParamReadSourceIntervalExtender(char *prm_str)
{
    int ret;
    char *ptr;

    ret = PRM_ERR;
    if((ptr = strstr(prm_str, "preroll-length")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_source_interval_extender.preroll_length);
    }

    return ret;
}

/**** HRLE 関係 ****/
static Param_HRLE_t PF_hrle;

static void ParamPrintHrle()
{
    printf("\n[HRLE]\n");
    printf("lx       = %f\n", PF_hrle.lx);
    printf("tr       = %f\n", PF_hrle.tr);
    printf("min_lv   = %f\n", PF_hrle.min_lv);
    printf("step_lv  = %f\n", PF_hrle.step_lv);
    printf("num_bin  = %d\n", PF_hrle.num_bin);
}

void ParamSetHrle(Param_HRLE_t *prm)
{
    PF_hrle = *prm;
}

void ParamGetHrle(Param_HRLE_t *prm)
{
    *prm = PF_hrle;
}

static int ParamReadHrle(char *prm_str)
{
    int ret;
    char *ptr;

    ret = PRM_ERR;
    if((ptr = strstr(prm_str, "lx")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_hrle.lx);
    }
    else if((ptr = strstr(prm_str, "tr")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_hrle.tr);
    }
    else if((ptr = strstr(prm_str, "min-lv")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_hrle.min_lv);
    }
    else if((ptr = strstr(prm_str, "step-lv")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_hrle.step_lv);
    }
    else if((ptr = strstr(prm_str, "num-bin")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_hrle.num_bin);
    }

    return ret;
}

/**** PreEmphasis 関係 ****/
static Param_PreEmphasis_t PF_pre_emphasis;

static void ParamPrintPreEmphasis()
{
    printf("\n[PreEmphasis]\n");
    printf("cutoff       = %d\n", PF_pre_emphasis.cutoff);
    printf("preem_coef   = %f\n", PF_pre_emphasis.preem_coef);
}

void ParamSetPreEmphasis(Param_PreEmphasis_t *prm)
{
    PF_pre_emphasis = *prm;
}

void ParamGetPreEmphasis(Param_PreEmphasis_t *prm)
{
    prm->cutoff     = PF_pre_emphasis.cutoff;
    prm->preem_coef = PF_pre_emphasis.preem_coef;
}

static int ParamReadPreEmphasis(char *prm_str)
{
    int ret;
    char *ptr;

    ret = PRM_ERR;
    if((ptr = strstr(prm_str, "cutoff")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_pre_emphasis.cutoff);
    }
    else if((ptr = strstr(prm_str, "preem-coef")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_pre_emphasis.preem_coef);
    }

    return ret;
}

/**** Estimate Leak 関係 ****/
Param_EstimateLeak_t PF_estimate_leak;

static void ParamPrintEstimateLeak()
{
    printf("\n[EstimateLeak]\n");
    printf("leak_factor   = %f\n", PF_estimate_leak.leak_factor);
}

void ParamSetEstimateLeak(Param_EstimateLeak_t *prm)
{
    PF_estimate_leak = *prm;
}

void ParamGetEstimateLeak(Param_EstimateLeak_t *prm)
{
    prm->leak_factor = PF_estimate_leak.leak_factor;
}

static int ParamReadEstimateLeak(char *prm_str)
{
    int ret;
    char *ptr;

    ret = PRM_ERR;
    if((ptr = strstr(prm_str, "factor")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_estimate_leak.leak_factor);
    }

    return ret;
}

/**** White Noise Adder 関係 ****/
Param_WhiteNoiseAdder_t PF_white_noise_adder;

static void ParamPrintWhiteNoiseAdder()
{
    printf("\n[WhiteNoiseAdder]\n");
    printf("wn_level   = %f\n", PF_white_noise_adder.wn_level);
}

void ParamSetWhiteNoiseAdder(Param_WhiteNoiseAdder_t *prm)
{
    PF_white_noise_adder = *prm;
}

void ParamGetWhiteNoiseAdder(Param_WhiteNoiseAdder_t *prm)
{
    prm->wn_level = PF_white_noise_adder.wn_level;
}

static int ParamReadWhiteNoiseAdder(char *prm_str)
{
    int ret;
    char *ptr;

    ret = PRM_ERR;
    if((ptr = strstr(prm_str, "wn-level")) != NULL)
    {
        ret = ParamStringReadFloat(prm_str, &PF_white_noise_adder.wn_level);
    }

    return ret;
}

// 
/**** Bluetooth 関係 ****/
Param_Bluetooth_t PF_bluetooth = {
  .mic_enable = 0,
  .min_deg = -180,
  .max_deg = 180,
};

static void ParamPrintBluetooth()
{
    printf("\n[Bluetooth]\n");
    printf("mic     = %d\n", PF_bluetooth.mic_enable);
    printf("min_deg = %d\n", PF_bluetooth.min_deg);
    printf("max_deg = %d\n", PF_bluetooth.max_deg);
}

void ParamSetBluetooth(Param_Bluetooth_t *prm)
{
    PF_bluetooth = *prm;
}

void ParamGetBluetooth(Param_Bluetooth_t *prm)
{
    *prm = PF_bluetooth;
}

static int ParamReadBluetooth(char *prm_str)
{
    int ret;
    char *ptr;

    ret = PRM_ERR;

    if((ptr = strstr(prm_str, "mic-enable")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_bluetooth.mic_enable);
    }
    else if((ptr = strstr(prm_str, "deg-min-max")) != NULL)
    {
        ret = ParamStringReadInt2(prm_str, &PF_bluetooth.min_deg, &PF_bluetooth.max_deg);
    }

    return ret;
}
// 
/**** Flac 関係 ****/
Param_Flac_t PF_Flac = {
  .blocksize = 0,
  .mic_enable = 0,
  .mic_max_lpc_order = 8,
  .mic_rice_partition_order = 4,
  .sep_enable = 0,
  .sep_hostname = {},
  .sep_max_lpc_order = 8,
  .sep_rice_partition_order = 4,
};

static void ParamPrintFlac()
{
    printf("\n[Flac]\n");
    printf("blocksize                = %d\n", PF_Flac.blocksize);
    printf("mic                      = %d\n", PF_Flac.mic_enable);
    printf("mic_max_lpc_order        = %d\n", PF_Flac.mic_max_lpc_order);
    printf("mic_rice_partition_order = %d\n", PF_Flac.mic_rice_partition_order);
    printf("sep                      = %d\n", PF_Flac.sep_enable);
    printf("sep_hostname             = '%s'\n", PF_Flac.sep_hostname);
    printf("sep_max_lpc_order        = %d\n", PF_Flac.sep_max_lpc_order);
    printf("sep_rice_partition_order = %d\n", PF_Flac.sep_rice_partition_order);

}

void ParamSetFlac(Param_Flac_t *prm)
{
    PF_Flac = *prm;
}

void ParamGetFlac(Param_Flac_t *prm)
{
    *prm = PF_Flac;
}

static int ParamReadFlac(char *prm_str)
{
    int ret;
    char *ptr;

    ret = PRM_ERR;

    if((ptr = strstr(prm_str, "mic-enable")) != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_Flac.mic_enable);
    }
    else if((ptr = strstr(prm_str, "blocksize")) != NULL)
      {
        ret = ParamStringReadInt(prm_str, &PF_Flac.blocksize);
      }
    else if((ptr = strstr(prm_str, "mic-max-lpc-order")) != NULL)
      {
        ret = ParamStringReadInt(prm_str, &PF_Flac.mic_max_lpc_order);
      }
    else if((ptr = strstr(prm_str, "mic-rice-partition-order")) != NULL)
      {
        ret = ParamStringReadInt(prm_str, &PF_Flac.mic_rice_partition_order);
      }
    else if((ptr = strstr(prm_str, "sep-enable")) != NULL)
      {
        ret = ParamStringReadInt(prm_str, &PF_Flac.sep_enable);
      }
    else if((ptr = strstr(prm_str, "sep-hostname")) != NULL)
      {
        ret = ParamStringReadString(prm_str, PF_Flac.sep_hostname);
      }
    else if((ptr = strstr(prm_str, "sep-max-lpc-order")) != NULL)
      {
        ret = ParamStringReadInt(prm_str, &PF_Flac.sep_max_lpc_order);
      }
    else if((ptr = strstr(prm_str, "sep-rice-partition-order")) != NULL)
      {
        ret = ParamStringReadInt(prm_str, &PF_Flac.sep_rice_partition_order);
      }

    return ret;
}


/**** その他 ****/
static int  PF_device_type;
static char PF_hostname_mic[32];
static char PF_hostname_julius[32];
static char PF_input_wav_file_path[128];
static char PF_save_mic_pcm[128];
static char PF_save_sep_pcm[128];
static char PF_save_sep_tmppcm[128];
static char PF_loc_tf_file_path[128];
static char PF_sep_tf_file_path[128];
static int  PF_save_mic_pcm_type;
static int  PF_save_sep_pcm_type;
static int  PF_send_port;
static int  PF_mic_target_channel;
static int  PF_mic_channel_offset;
static int  PF_bypass_oute;

/**** パラメータ解析の実処理 ****/

static int ParamFileReadSub(char *prm_str)
{
    int ret;
    char tmp_str[64];
    
    ret = PRM_ERR;
    
    if(strstr(prm_str, "localize-music") != NULL)
    {
        ret = ParamReadLocalizeMusic(prm_str);
    }
    else if(strstr(prm_str, "source-tracker") != NULL)
    {
        ret = ParamReadSourceTracker(prm_str);
    }
    else if(strstr(prm_str, "source-interval-extender") != NULL)
    {
        ret = ParamReadSourceIntervalExtender(prm_str);
    }
    else if(strstr(prm_str, "hrle") != NULL)
    {
        ret = ParamReadHrle(prm_str);
    }
    else if(strstr(prm_str, "pre-emphasis") != NULL)
    {
        ret = ParamReadPreEmphasis(prm_str);
    }
    else if(strstr(prm_str, "estimate") != NULL)
    {
        ret = ParamReadEstimateLeak(prm_str);
    }
    else if(strstr(prm_str, "white-noise") != NULL)
    {
        ret = ParamReadWhiteNoiseAdder(prm_str);
    }
    else if(strstr(prm_str, "bluetooth") != NULL)
    {
        ret = ParamReadBluetooth(prm_str);
    }
    else if(strstr(prm_str, "flac") != NULL)
    {
        ret = ParamReadFlac(prm_str);
    }
    else if(strstr(prm_str, "transfer-function") != NULL)
    {
        if(strstr(prm_str, "localize") != NULL)
        {
            ret = ParamStringReadString(prm_str, PF_loc_tf_file_path);
        }
        else if(strstr(prm_str, "separate") != NULL)
        {
            ret = ParamStringReadString(prm_str, PF_sep_tf_file_path);
        }
    }
    else if(strstr(prm_str, "hostname-microphone") != NULL)
    {
        ret = ParamStringReadString(prm_str, PF_hostname_mic);
    }
    else if(strstr(prm_str, "hostname-julius") != NULL)
    {
        ret = ParamStringReadString(prm_str, PF_hostname_julius);
    }
    else if(strstr(prm_str, "device-type") != NULL)
    {
        if(     strstr(prm_str, "WAVE")   != NULL){PF_device_type = 2;}
        else if(strstr(prm_str, "SOCKET") != NULL){PF_device_type = 1;}
        else {PF_device_type = 0;};
    }
    else if(strstr(prm_str, "mic-target-channel") != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_mic_target_channel);
    }
    else if(strstr(prm_str, "mic-channel-offset") != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_mic_channel_offset);
    }
    else if(strstr(prm_str, "bypass-oute") != NULL)
    {
        ret = ParamStringReadInt(prm_str, &PF_bypass_oute);
    }
    else if(strstr(prm_str, "input-filename-wave-pcm") != NULL)
    {
        ret = ParamStringReadString(prm_str, PF_input_wav_file_path);
    }
    else if(strstr(prm_str, "output-filename") != NULL)
    {
        if(strstr(prm_str, "mic-pcm") != NULL)
        {
            ret = ParamStringReadString(prm_str, PF_save_mic_pcm);
        }
        else if(strstr(prm_str, "sep-pcm") != NULL)
        {
            ret = ParamStringReadString(prm_str, PF_save_sep_pcm);
        }
        else if(strstr(prm_str, "sep-tmppcm") != NULL)
        {
            ret = ParamStringReadString(prm_str, PF_save_sep_tmppcm);
        }
    }
    else if(strstr(prm_str, "output-filetype") != NULL)
    {
        int pcm_type = PCM_NONE;
        
        ret = 0;
        if(     strstr(prm_str, "RAW_SINT16")   != NULL){pcm_type = PCM_RAW_SINT16;}
        else if(strstr(prm_str, "RAW_SINT24")   != NULL){pcm_type = PCM_RAW_SINT24;}
        else if(strstr(prm_str, "RAW_SINT32")   != NULL){pcm_type = PCM_RAW_SINT32;}
        else if(strstr(prm_str, "RAW_FLOAT32")  != NULL){pcm_type = PCM_RAW_FLOAT32;}
        else if(strstr(prm_str, "RAW_RAWFLOAT") != NULL){pcm_type = PCM_RAW_RAWFLOAT;}
        else if(strstr(prm_str, "WAV_SINT16")   != NULL){pcm_type = PCM_WAV_SINT16;}
        else if(strstr(prm_str, "WAV_SINT24")   != NULL){pcm_type = PCM_WAV_SINT24;}
        else if(strstr(prm_str, "WAV_SINT32")   != NULL){pcm_type = PCM_WAV_SINT32;}
        else if(strstr(prm_str, "WAV_FLOAT32")  != NULL){pcm_type = PCM_WAV_FLOAT32;}
        else {ret = PRM_ERR;}
        
        if(ret == 0)
        {
            if(strstr(prm_str, "mic-pcm") != NULL)
            {
                PF_save_mic_pcm_type = pcm_type;
            }
            else if(strstr(prm_str, "sep-pcm") != NULL)
            {
                PF_save_sep_pcm_type = pcm_type;
            }
            else
            {
                ret = PRM_ERR;
            }
        }
    }
    else if(strstr(prm_str, "--set-port") != NULL)
    {
        int num;
        int i;
        
        num = sscanf(prm_str, "%*s %s", tmp_str);
        //printf("%s\n", prm_str);
        //printf("%s(%d)\n", tmp_str, strlen(tmp_str));
        if(num == 1)
        {
            ret = 0;
            for(i=0; i<strlen(tmp_str); i++)
            {
                switch(tmp_str[i])
                {
                    case 'a':
                    case 'A':
                        PF_send_port |= SEND_PORT_A;
                        break;
                    case 'b':
                    case 'B':
                        PF_send_port |= SEND_PORT_B;
                        break;
                    case 'c':
                    case 'C':
                        PF_send_port |= SEND_PORT_C;
                        break;
                    case 'd':
                    case 'D':
                        PF_send_port |= SEND_PORT_D;
                        break;
                    case 'e':
                    case 'E':
                        PF_send_port |= SEND_PORT_E;
                        break;
                    case 'f':
                    case 'F':
                        PF_send_port |= SEND_PORT_F;
                        break;
                    case 'j':
                    case 'J':
                        PF_send_port |= SEND_JULIUS;
                        break;
                    default:
                        break;
                }
            }
        }
        else
        {
            ret = PRM_ERR;
        }
    }
    else if(strstr(prm_str, "--clear-port") != NULL)
    {
        int num;
        int i;
        int clear_port = 0;
        
        num = sscanf(prm_str, "%*s %s", tmp_str);
        if(num == 1)
        {
            ret = 0;
            for(i=0; i<strlen(tmp_str); i++)
            {
                switch(tmp_str[i])
                {
                    case 'a':
                    case 'A':
                        clear_port |= SEND_PORT_A;
                        break;
                    case 'b':
                    case 'B':
                        clear_port |= SEND_PORT_B;
                        break;
                    case 'c':
                    case 'C':
                        clear_port |= SEND_PORT_C;
                        break;
                    case 'd':
                    case 'D':
                        clear_port |= SEND_PORT_D;
                        break;
                    case 'e':
                    case 'E':
                        clear_port |= SEND_PORT_E;
                        break;
                    case 'f':
                    case 'F':
                        clear_port |= SEND_PORT_F;
                        break;
                    case 'j':
                    case 'J':
                        clear_port |= SEND_JULIUS;
                        break;
                    default:
                        break;
                }
            }
            
            PF_send_port = PF_send_port & (~clear_port);
        }
        else
        {
            ret = PRM_ERR;
        }
    }
    
    return ret;
}


/**** パラメータファイルアクセスのメインループ ****/

static int ParamFileReadMain(char *prm_file_name)
{
    FILE *fp;
    char prm_str[PRM_STR_LENGTH];
    int  ret;
    
    fp = fopen(prm_file_name, "rt");
    if(fp == NULL)
    {
        return -1;
    }
    
    ret = 0;
    while(1)
    {
        ret = ParamFileReadLine(fp, prm_str);
        
        if(ret == PRM_READ)
        {
            /*
            printf("%s\n", prm_str);
            */
            ParamFileReadSub(prm_str);
        }
        
        if(ret < 0)
        {
            break;
        }
    }
    
    printf("\n-- Param File --\n");
    ParamPrintLocalizeMusic();
    ParamPrintSourceTracker();
    ParamPrintSourceIntervalExtender();
    ParamPrintHrle();
    ParamPrintPreEmphasis();
    ParamPrintEstimateLeak();
    ParamPrintWhiteNoiseAdder();
    ParamPrintBluetooth();
    ParamPrintFlac();
    
    printf("\n[other]\n");
    printf("device_type        = %d\n", PF_device_type);
    printf("mic_target_channel = %d\n", PF_mic_target_channel);
    printf("mic_channel_offset = %d\n", PF_mic_channel_offset);
    printf("bypass_oute        = %d\n", PF_bypass_oute);
    printf("hostname_mic       = %s\n", PF_hostname_mic);
    printf("hostname_julius    = %s\n", PF_hostname_julius);
    printf("input_wav_file     = %s\n", PF_input_wav_file_path);
    printf("save_mic_pcm       = %s\n", PF_save_mic_pcm);
    printf("  pcm_type         = %d\n", PF_save_mic_pcm_type);
    printf("save_sep_pcm       = %s\n", PF_save_sep_pcm);
    printf("  pcm_type         = %d\n", PF_save_sep_pcm_type);
    printf("save_sep_tmppcm    = %s\n", PF_save_sep_tmppcm);
    printf("loc_tf_file        = %s\n", PF_loc_tf_file_path);
    printf("sep_tf_file        = %s\n", PF_sep_tf_file_path);
    printf("send_port          = 0x%x\n", PF_send_port);
    
    printf("\n-- Param File --\n");
    
    fclose(fp);

    return 0;
}


void sigpipe_action(int signum, siginfo_t *info, void *ctx)
{
    fprintf(stderr, "SigPIPE.\n");
}

static int main_end_flag = 0;

void sigint_action(int signum, siginfo_t *info, void *ctx)
{
    fprintf(stderr, "SigINT.\n");
    main_end_flag = 1;
}


/*-------------------------------------------------------------------*/

void version()
{
    fprintf(stdout, "Version 3.5.0 base\n\n");
}

void help()
{
  fprintf(stdout, "usage:\n> hark [options]\n");
  fprintf(stdout, "** All options will be overwritten by the options that are set later.\n");
  fprintf(stdout, "** Smart setting method adds only the parameters that change frequently later,");
  fprintf(stdout, "   that you specify a configuration file in the first argument.\n");
  fprintf(stdout, "options:\n");
  fprintf(stdout, "  [-h | --help]\n");
  fprintf(stdout, "    :: show this help\n");
  fprintf(stdout, "  [-v | --verbose]\n");
  fprintf(stdout, "    :: verbosely list processed\n");
  fprintf(stdout, "  [     --version]\n");
  fprintf(stdout, "    :: show version and this help\n");
  fprintf(stdout, "  [-c | --config] [file_path]\n");
  fprintf(stdout, "    :: set configuration filename\n");
  fprintf(stdout, "  [--daemon]\n");
  fprintf(stdout, "    :: run in the background\n");
  fprintf(stdout, "  [--stanby]\n");
  fprintf(stdout, "    :: waiting for execution\n");
  fprintf(stdout, "  [-de | --device-easy-config] [select_device_number]\n");
  fprintf(stdout, "    :: easy configuration for specific device of AudioStreamFromMic\n");
  fprintf(stdout, "    :: this option set Advance=160, Channels, Bits and MusicThreshold for 1 source.\n");
  fprintf(stdout, "    :: <select_device_number>\n");
  fprintf(stdout, "    ::   UnDefined : This function is disabled (default)\n");
  fprintf(stdout, "    ::   RASP-LC4  : [USB]        RASP-LC 4ch type\n");
  fprintf(stdout, "    ::   RASP-LC   : [USB]        RASP-LC 8ch type\n");
  fprintf(stdout, "    ::   RASP-ZXo  : [USB/Socket] RASP-ZX old model\n");
  fprintf(stdout, "    ::   RASP-ZX   : [USB/Socket] RASP-ZX\n");
  fprintf(stdout, "    ::   RASP-24   : [Socket]     RASP-24 (unsupported yet)\n");
  fprintf(stdout, "    ::   PS-EYE    : [USB]        PS-Eye\n");
  fprintf(stdout, "    ::   Kinect    : [USB]        Kinect\n");
  fprintf(stdout, "    ::   Microcone : [USB]        Microcone\n");
  fprintf(stdout, "    ::   HRI-KM    : [USB/Socket] KM (USB-UART device, can't control from ALSA)\n");
  fprintf(stdout, "    ::   HRI-SHT   : [USB]        SHT (not USBAudioClass device, can't control from ALSA)\n");
  fprintf(stdout, "    ::   SingleMic : Single channel microphone\n");
  fprintf(stdout, "  [-dt | --device-type] [device_type]\n");
  fprintf(stdout, "    :: set device type of AudioStreamFromMic\n");
  fprintf(stdout, "    :: <device_type>\n");
  fprintf(stdout, "    ::   WAVE   : Wave input for debug\n");
  fprintf(stdout, "    ::   SOCKET : Socket microphone used by librasp/libkm\n");
  fprintf(stdout, "    ::   USB    : USB microphone used by ioctl\n");
  fprintf(stdout, "    ::   ALSA   : USB microphone used by TinyALSA (obsolete)\n");
  fprintf(stdout, "    ::   LIBUSB : USB microphone used by libusb-1.0 (obsolete)\n");
  fprintf(stdout, "    :: ** if you use DEVICE_NUM_SELECT_MODE, please set -dn option\n");
  fprintf(stdout, "  [-db | --device-bits] [device_bits]\n");
  fprintf(stdout, "    :: set device bits of device parameter (16 or 24)\n");
  fprintf(stdout, "  [-dc | --device-channels] [device_channels]\n");
  fprintf(stdout, "    :: set device channels of device parameter (1 - 8)\n");

  fprintf(stdout, "  [-pga | --param-generic-advance] [advance]\n");
  fprintf(stdout, "    :: set advance of generic parameter (sorry, unsupported yet)\n");

  fprintf(stdout, "  [       --param-localize-music-length] [length]\n");
  fprintf(stdout, "    :: set length of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [       --param-localize-music-sampling-rate] [sampling rate]\n");
  fprintf(stdout, "    :: set sampling rate of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [-ple | --param-localize-music-elevation] [elevation]\n");
  fprintf(stdout, "    :: set elevation of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [       --param-localize-music-window] [window]\n");
  fprintf(stdout, "    :: set window of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [-plp | --param-localize-music-period] [period]\n");
  fprintf(stdout, "    :: set period of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [-pln | --param-localize-music-num-source] [num source]\n");
  fprintf(stdout, "    :: set num source of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [-plx | --param-localize-music-export-num-source] [export num source]\n");
  fprintf(stdout, "    :: set export num source of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [-pld | --param-localize-music-deg-min-max] [min deg] [max deg]\n");
  fprintf(stdout, "    :: set min/max degree of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [-plf | --param-localize-music-freq-low-upper] [lower freq] [upper freq]\n");
  fprintf(stdout, "    :: set low/upper frequency of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [       --param-localize-music-spectrum-weight-type] [weight type]\n");
  fprintf(stdout, "    :: set spectrum weight type of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [       --param-localize-music-enable-eigenvalue-weight] [weight]\n");
  fprintf(stdout, "    :: set eigenvalue weight of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [       --param-localize-music-a-char-scaling] [scale]\n");
  fprintf(stdout, "    :: set A character scaling of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [       --param-localize-music-spline-num] [splines]\n");
  fprintf(stdout, "    :: set spline num of LocalizeMUSIC parameter\n");
  fprintf(stdout, "  [       --param-localize-music-square-num] [squares]\n");
  fprintf(stdout, "    :: set square num of LocalizeMUSIC parameter\n");

  fprintf(stdout, "  [-ptt | --param-source-tracker-threshold] [threshold]\n");
  fprintf(stdout, "    :: set threshold of SourceTracker parameter\n");
  fprintf(stdout, "  [-ptp | --param-source-tracker-pause-length] [pause length]\n");
  fprintf(stdout, "    :: set pause length of SourceTracker parameter\n");
  fprintf(stdout, "  [-pti | --param-source-tracker-min-source-interval] [interval]\n");
  fprintf(stdout, "    :: set min source interval of SourceTracker parameter\n");
  fprintf(stdout, "  [-ptm | --param-source-tracker-min-id] [min id]\n");
  fprintf(stdout, "    :: set min source id of SourceTracker parameter\n");

  fprintf(stdout, "  [-pxp | --param-source-interval-extender-preroll-length] [preroll length]\n");
  fprintf(stdout, "    :: set pre-roll length of SourceIntervalExtender parameter\n");

  fprintf(stdout, "  [       --param-estimate-leak-fft-length] [fft length]\n");
  fprintf(stdout, "    :: set FFT length of EstimateLeak parameter\n");
  fprintf(stdout, "  [-pel | --param-setimate-leak-leak-factor] [leak factor]\n");
  fprintf(stdout, "    :: set leak factor of EstimateLeak parameter\n");

  fprintf(stdout, "  [       --param-hrle-fft-length] [fft length]\n");
  fprintf(stdout, "    :: set FFT length of HRLE parameter\n");
  fprintf(stdout, "  [-phl | --param-hrle-lx] [lx]\n");
  fprintf(stdout, "    :: set lx of HRLE parameter\n");
  fprintf(stdout, "  [-pht | --param-hrle-tr] [tr]\n");
  fprintf(stdout, "    :: set tr of HRLE parameter\n");
  fprintf(stdout, "  [-phm | --param-hrle-min-lv] [min lv]\n");
  fprintf(stdout, "    :: set min level of HRLE parameter\n");
  fprintf(stdout, "  [-phs | --param-hrle-step-lv] [step lv]\n");
  fprintf(stdout, "    :: set step level of HRLE parameter\n");
  fprintf(stdout, "  [-phn | --param-hrle-num-bin] [num bin]\n");
  fprintf(stdout, "    :: set num bin of HRLE parameter\n");

  fprintf(stdout, "  [       --param-white-noise-adder-length] [length]\n");
  fprintf(stdout, "    :: set length of WhiteNoiseAdder parameter\n");
  fprintf(stdout, "  [       --param-white-noise-adder-fft-length] [fft length]\n");
  fprintf(stdout, "    :: set fft length of WhiteNoiseAdder parameter\n");
  fprintf(stdout, "  [-pwl | --param-white-noise-adder-wn-level] [level]\n");
  fprintf(stdout, "    :: set white noise level of WhiteNoiseAdder parameter\n");

  fprintf(stdout, "  [       --param-pre-emphasis-length] [length]\n");
  fprintf(stdout, "    :: set length of PreEmphasis parameter\n");
  fprintf(stdout, "  [       --param-pre-emphasis-fft-length] [fft length]\n");
  fprintf(stdout, "    :: set fft length of PreEmphasis parameter\n");
  fprintf(stdout, "  [       --param-pre-emphasis-sampling-rate] [sampling rate]\n");
  fprintf(stdout, "    :: set sampling rate of PreEmphasis parameter\n");
  fprintf(stdout, "  [-pwc | --param-pre-emphasis-cutoff] [cutoff]\n");
  fprintf(stdout, "    :: set cutoff frequency of PreEmphasis parameter\n");
  fprintf(stdout, "  [-pwp | --param-pre-emphasis-preem-coef] [preem coef]\n");
  fprintf(stdout, "    :: set pre-emphasis coefficient of PreEmphasis parameter\n");

  fprintf(stdout, "  [       --param-mel-filter-bank-fbank] [banks]\n");
  fprintf(stdout, "    :: set num banks of MelFilterBank parameter\n");
  fprintf(stdout, "  [       --param-mel-filter-bank-length] [length]\n");
  fprintf(stdout, "    :: set length of MelFilterBank parameter\n");
  fprintf(stdout, "  [       --param-mel-filter-bank-fft-length] [fft length]\n");
  fprintf(stdout, "    :: set fft length of MelFilterBank parameter\n");
  fprintf(stdout, "  [       --param-mel-filter-bank-sampling-rate] [sampling rate]\n");
  fprintf(stdout, "    :: set sampling rate of MelFilterBank parameter\n");
  fprintf(stdout, "  [-pmc | --param-mel-filter-bank-cutoff] [cutoff]\n");
  fprintf(stdout, "    :: set cutoff frequency of MelFilterBank parameter\n");
  fprintf(stdout, "    :: Ex) -pmc 8000\n");
  fprintf(stdout, "  [-pmf | --param-mel-filter-freq-min-max] [min freq] [max freq]\n");
  fprintf(stdout, "    :: set min/max frequency of MelFilterBank parameter\n");
  fprintf(stdout, "    :: Ex) -pmf 63 8000\n");



  fprintf(stdout, "  -pmd [device_channels]\n");
  fprintf(stdout, "  -pmt [target_channels]\n");
  fprintf(stdout, "  -pmo [offset_channels]\n");
  fprintf(stdout, "    :: set device/target/offset channels of microphone parameter (unsupported yet)\n");
  fprintf(stdout, "    :: Ex) -pcd 8 -pct 4 -pco 2\n");
  fprintf(stdout, "    ::     [from_MIC] 0,1,2,3,4,5,6,7 => [Select] 2,3,4,5\n");
  fprintf(stdout, "    ::     device is 8ch, input target is 4ch, offset 2ch\n");

  fprintf(stdout, "  [-if* | --input-filename-*] [file_path]\n");
  fprintf(stdout, "    :: set input filenames\n");
  fprintf(stdout, "    :: [-ifw | --input-filename-wave-pcm] [file_path]\n");
  fprintf(stdout, "    :: ** set (I)nput (F)ilename of multi channel [W]av PCM :: AudioStreamFromWave\n");
  fprintf(stdout, "    :: !!Information!! sorry, compatibility was lost. -iw ==> -ifw");

  fprintf(stdout, "  [-of* | --output-filename-*] [file_path]\n");
  fprintf(stdout, "    :: set output filenames\n");
  fprintf(stdout, "    :: [-ofm | --output-filename-mic-pcm] [file_path]\n");
  fprintf(stdout, "    :: ** set (O)utput (F)ilename of (M)icrophone recording :: SaveRawPCM/SaveWavePCM\n");
  fprintf(stdout, "    :: [-ofs | --output-filename-sep-spec] [file_path]\n");
  fprintf(stdout, "    :: ** set (O)utput (F)ilename of separated (S)pectrum\n");
  fprintf(stdout, "    :: [-ofp | --output-filename-sep-pcm] [file_path]\n");
  fprintf(stdout, "    :: ** set (O)utput (F)ilename of separated (P)CM :: SaveRawPCM/SaveWavePCM\n");
  fprintf(stdout, "    :: !!Information!! sorry, compatibility was lost. -or ==> -ofp");
  fprintf(stdout, "    :: [-oft | --output-filename-sep-tmppcm] [file_path]\n");
  fprintf(stdout, "    :: ** set (O)utput (F)ilename of separating (T)emporary PCM :: SaveRawPCM/SaveWavePCM\n");
  fprintf(stdout, "    :: [-off | --output-filename-sep-feature] [file_path]\n");
  fprintf(stdout, "    :: ** set (O)utput (F)ilename of separated (F)eature :: SaveFeature/SaveHTKFeature\n");
  fprintf(stdout, "    :: !!Information!! sorry, compatibility was lost. -of ==> -off");
  fprintf(stdout, "    :: [-ofd | --output-filename-source] [file_path]\n");
  fprintf(stdout, "    :: ** set (O)utput (F)ilename of source (D)irection :: SaveSource\n");
  fprintf(stdout, "    :: [-ofl | --output-localized-power-sepc] [file_path]\n");
  fprintf(stdout, "    :: ** set (O)utput (F)ilename of (L)ocalize power :: LocalizeMUSIC debug\n");
  fprintf(stdout, "  [-ot* | --output-filetype-*] [file_type]\n");
  fprintf(stdout, "    :: set output filetypes\n");
  fprintf(stdout, "    :: [-otm | --output-filetype-mic-pcm] [pcm_type]\n");
  fprintf(stdout, "    :: ** set (O)utput file(T)ype of (M)icrophone recording :: SaveRawPCM/SaveWavePCM\n");
  fprintf(stdout, "    :: <pcm_type>\n");
  fprintf(stdout, "    ::   NONE         : This function is disabled (default)\n");
  fprintf(stdout, "    ::   RAW_SINT16   : raw file signed integer 16bit\n");
  fprintf(stdout, "    ::   RAW_SINT24   : raw file signed integer 24bit\n");
  fprintf(stdout, "    ::   RAW_SINT32   : raw file signed integer 32bit\n");
  fprintf(stdout, "    ::   RAW_FLOAT32  : raw file float 32bit (IEEE float -1.0f ~ 1.0f)\n");
  fprintf(stdout, "    ::   RAW_RAWFLOAT : raw file float 32bit (raw integer range value)\n");
  fprintf(stdout, "    ::   WAV_SINT16   : raw file signed integer 16bit\n");
  fprintf(stdout, "    ::   WAV_SINT24   : raw file signed integer 24bit\n");
  fprintf(stdout, "    ::   WAV_SINT32   : raw file signed integer 32bit\n");
  fprintf(stdout, "    ::   WAV_FLOAT32  : raw file float 32bit (IEEE float -1.0f ~ 1.0f)\n");
  fprintf(stdout, "    :: [-otp | --output-filetype-sep-pcm] [pcm_type]\n");
  fprintf(stdout, "    :: ** set (O)utput file(T)ype of separated (P)CM :: SaveRawPCM/SaveWavePCM\n");
  fprintf(stdout, "    :: <pcm_type>\n");
  fprintf(stdout, "    ::   NONE         : This function is disabled (default)\n");
  fprintf(stdout, "    ::   RAW_SINT16   : raw file signed integer 16bit\n");
  fprintf(stdout, "    ::   RAW_SINT24   : raw file signed integer 24bit\n");
  fprintf(stdout, "    ::   RAW_SINT32   : raw file signed integer 32bit\n");
  fprintf(stdout, "    ::   RAW_FLOAT32  : raw file float 32bit (IEEE float -1.0f ~ 1.0f)\n");
  fprintf(stdout, "    ::   RAW_RAWFLOAT : raw file float 32bit (raw integer range value)\n");
  fprintf(stdout, "    ::   WAV_SINT16   : raw file signed integer 16bit\n");
  fprintf(stdout, "    ::   WAV_SINT24   : raw file signed integer 24bit\n");
  fprintf(stdout, "    ::   WAV_SINT32   : raw file signed integer 32bit\n");
  fprintf(stdout, "    ::   WAV_FLOAT32  : raw file float 32bit (IEEE float -1.0f ~ 1.0f)\n");
  fprintf(stdout, "    :: [-otf | --output-filetype-sep-feature] [feature_data_type] [feature_format_type]\n");
  fprintf(stdout, "    :: ** set (O)utput file(T)ype of separated (F)eature :: SaveFeature/SaveHTKFeature\n");
  fprintf(stdout, "    :: <feature_data_type>\n");
  fprintf(stdout, "    ::   NONE     : This function is disabled (default)\n");
  fprintf(stdout, "    ::   NOSMN    : Save data isn't spectrum mean normalized data\n");
  fprintf(stdout, "    ::   SMN      : Save data is spectrum mean normalized data\n");
  fprintf(stdout, "    :: <feature_format_type>\n");
  fprintf(stdout, "    ::   NOHEADER  : Save format is raw feature data (no header)\n");
  fprintf(stdout, "    ::   USER      : Save format is USER of HTKHeader (default for MSLS)\n");
  fprintf(stdout, "    ::   MFCC      : Save foramt is MFCC of HTKHeader\n");
  fprintf(stdout, "    ::     with _E : Log energy included flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _N : absolute energy suppressed flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _D : delta coef appended flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _A : acceleration coefs appended flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _C : is compressed flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _Z : zero meaned flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _K : has CRC check flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _0 : 0'th Cepstra included flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _V : has VQ index attached flag ON (for MFCC)\n");
  fprintf(stdout, "    ::     with _T : has Delta-Delta-Delta index attached flag ON (for MFCC)\n");
  fprintf(stdout, "    :: Ex) -oft SMN USER  <== SpectralMeanNormalized MSLS\n");
  fprintf(stdout, "    :: Ex) -oft NOSMN MFCC_E_D_A_Z  <== double delta MFCC (feature calculation unsupported yet)\n");
  fprintf(stdout, "    :: !!CAUTION!! MFCC only supports header generation. This is a temporary implementation for the future.\n");

  fprintf(stdout, "  [-sp | --set-port] [abcdefj]\n");
  fprintf(stdout, "    :: set send port type\n");
  fprintf(stdout, "    :: ** can specify multiple, order is independent, ignoring the extraneous characters\n");
  fprintf(stdout, "    :: ** ignoring upper and lower case difference\n");
  fprintf(stdout, "    :: Ex) -sp cJxf  <== enable send port of c,f,j and ignoring character of x\n");
  fprintf(stdout, "    :: -sp [a|A] : send input acoustic wave\n");
  fprintf(stdout, "    :: -sp [b|B] : send input calculate fft\n");
  fprintf(stdout, "    :: -sp [c|C] : send localize source informations\n");
  fprintf(stdout, "    :: -sp [d|D] : send separated calculate fft\n");
  fprintf(stdout, "    :: -sp [e|E] : send separated features\n");
  fprintf(stdout, "    :: -sp [f|F] : send separated acoustic waves\n");
  fprintf(stdout, "    :: -sp [j|J] : send to julius_mft\n");
  fprintf(stdout, "  [-sh* | --set-hostname-*] [hostname]\n");
  fprintf(stdout, "    :: set socket ip-address/hostname\n");
  fprintf(stdout, "    :: [-shm | --set-hostname-microphone] [hostname]\n");
  fprintf(stdout, "    :: set socket microphone ip-address/hostname\n");
  fprintf(stdout, "    :: Ex) -shm 192.168.24.26 : connect hostname of RASP-ZX microphone\n");
  fprintf(stdout, "    :: Ex) -shm 192.168.254.1 : connect hostname of HRI special microphone\n");
  fprintf(stdout, "    :: [-shj | --set-hostname-julius] [hostname]\n");
  fprintf(stdout, "    :: set julius_mft ip-address/hostname\n");
  fprintf(stdout, "    :: Ex) -shj 127.0.0.1 : connect hostname of julius_mft\n");
  fprintf(stdout, "  [-t* | --transfer-function-*] [file_path]\n");
  fprintf(stdout, "    :: set TF(transfer function) filenames\n");
  fprintf(stdout, "    :: -tl [file_path] : set localization TF filename\n");
  fprintf(stdout, "    :: -ts [file_path] : set separation TF filename\n");
}

int main(int argc, char *argv[])
{
    int ret, i, flags;
    FILE *fp;

    int verbose = 0;
    char tmp[4192];
    
    int is_daemonic = 0;
    int run_flag = 1;
    int connect_end = 0;
    int stanby_mode = 0;
    int update_param = 0;

    int param_port, param_use_time_stamp_port, param_use_source_filter_port;
    int param_save_mic_pcm_format, param_save_sep_pcm_format, param_save_sep_feature_type, param_save_sep_feature_format;
    int param_save_mic_spec, param_save_localize_power_spec, param_save_sep_spec, param_save_source;
    int param_localize_algorithm, param_separation_algorithm, param_filter_algorithm;

    char *param_mic_hostname, *param_julius_hostname;
    char *param_in_pcm_filename;
    char *param_input_pcm_filename;
    char *param_save_input_pcm_filename, *param_save_input_spec_filename, *param_save_output_spec_filename, *param_save_output_pcm_filename, *param_save_output_pcm_tmp_filename;
    char *param_save_output_locpow_spec_filename, *param_save_output_feature_filename, *param_save_output_source_filename;
    char *param_loc_tf_filename, *param_sep_tf_filename;
    char config_file_path[128];

    int param_device_type, param_advance, param_ch, param_offset, param_bits;
    int param_dev_ch;
    float param_localize_music_thresh;
    
    int param_mic_channel_offset = 0;

    //initialize to default for undefined string variables
    param_port                             = SEND_DUMMY;        // Default : All disable
    param_use_time_stamp_port              = TIMESTAMP_DUMMY;   // Default : All disable
    param_use_source_filter_port           = SRC_FILTER_DUMMY;  // Default : All disable
    param_save_mic_pcm_format              = PCM_NONE;          // Default : Save none
    param_save_sep_pcm_format              = PCM_NONE;          // Default : Save none
    param_save_sep_feature_type            = FEATURE_SAVE_NONE; // Default : Save none
    param_save_sep_feature_format          = FEATURE_USER;      // Default : HTKFeatureType is USER for MSLS
    param_save_mic_spec                    = 0;                 // Default : Save none
    param_save_localize_power_spec         = 0;                 // Default : Save none
    param_save_sep_spec                    = 0;                 // Default : Save none
    param_localize_algorithm               = LOC_MUSIC;         // Default : use LocalizeMUSIC
    param_separation_algorithm             = SEP_GHDSS;         // Default : use GHDSS
    param_filter_algorithm                 = FILTER_NONE;       // Default : use HRLE
    //param_mic_hostname                     = "192.168.254.1";   // Default : HRI Special microphone type KM IP address
    //param_mic_hostname                     = "192.168.1.1";     // Default : RaspZX IP address (Client mode)
    param_mic_hostname                     = (char*) "192.168.24.26";   // Default : RaspZX IP address (HostAP mode)
    param_julius_hostname                  = (char*) "127.0.0.1";       // Default : localhost
    param_in_pcm_filename                  = (char*) "./hark-data/MultiSpeech.wav";
    param_save_input_pcm_filename          = (char*) "./hark-data/input";
    param_save_input_spec_filename         = (char*) "./hark-data/input";
    param_save_output_locpow_spec_filename = (char*) "./hark-data/direc_pow";
    param_save_output_source_filename      = (char*) "./hark-data/source.txt";
    param_save_output_spec_filename        = (char*) "./hark-data/output";
    param_save_output_pcm_filename         = (char*) "./hark-data/output";
    param_save_output_pcm_tmp_filename     = (char*) "./hark-data/_output";
    param_save_output_feature_filename     = (char*) "./hark-data/output";
    param_loc_tf_filename                  = (char*) "./hark-data/mic-ary.dat";
    param_sep_tf_filename                  = (char*) "./hark-data/mic-ary.tff";

    ::Param_LocalizeMUSIC_t param_localize_music;
    param_localize_music.music_algorithm          = GSVD; // SEVD;
    param_localize_music.tf_channel_num           = ARY_NUM_MIC;
    for(int i=0; i<ARY_NUM_MIC; i++){
        param_localize_music.tf_channel_selection[i] = i;
    }
    param_localize_music.length                   = ARY_NUM_WAVE;
    param_localize_music.sampling_rate            = DEFAULT_SAMPLING_RATE;
    //param_localize_music.a_matrix;
    param_localize_music.elevation                = 15.0f;
    param_localize_music.window                   = 50;
    param_localize_music.period                   = 50;
    param_localize_music.num_source               = 3; // org 1
    param_localize_music.export_num_source        = 3;
    param_localize_music.min_deg                  = -180;
    param_localize_music.max_deg                  = 180;
    param_localize_music.low_bound_frequency      = 500;
    param_localize_music.upper_bound_frequency    = 2800;
    param_localize_music.spectrum_weight_type     = Uniform;
    param_localize_music.enable_eigenvalue_weight = 1;
    param_localize_music.a_char_scaling           = 1.0f;
    param_localize_music.spline_num               = 0;
    ////param_localize_music.manual_weight_spline;
    param_localize_music.square_num               = 0;
    ////param_localize_music.manual_weight_square;

    ::Param_SourceTracker_t param_source_tracker;
    param_source_tracker.thresh                   = 29.5f;
    param_source_tracker.pause_length             = 800.0f;
    param_source_tracker.min_src_interval         = 20.0f;
    param_source_tracker.min_id                   = 0;

    ::Param_SourceIntervalExtender_t param_source_interval_extender;
    param_source_interval_extender.preroll_length = 50;

    //::Param_GHDSS_t param_ghdss;
    //param_ghdss.length = ARY_NUM_WAVE;
    //param_ghdss.advance = 160;
    //param_ghdss.sampling_rate = DEFAULT_SAMPLING_RATE;
    //param_ghdss.lower_bound_frequency;
    //param_ghdss.upper_bound_frequency;
    //::strcpy(param_ghdss.tf_conj, "DATABASE");
    //param_ghdss.tf_conj_filename;
    //param_ghdss.mic_filename;
    //param_ghdss.mic_pos_shift;
    //param_ghdss.fixed_noise;
    //param_ghdss.fixed_noise_filename;
    //param_ghdss.initw_filename;
    //param_ghdss.speed_of_sound;
    //::strcpy(param_ghdss.ss_method, "ADAPTIVE");
    //param_ghdss.ss_scal;
    //param_ghdss.ss_myu;
    //param_ghdss.noise_floor;
    //::strcpy(param_ghdss.lc_const, "FULL");
    //::strcpy(param_ghdss.lc_method, "ADAPTIVE");
    //param_ghdss.lc_myu;
    //param_ghdss.update_method_tf_conj;
    //param_ghdss.update_method_w;
    //param_ghdss.update_accept_angle;
    //param_ghdss.export_w;
    //param_ghdss.wxport_w_filename;
    //param_ghdss.update;

    ::Param_EstimateLeak_t param_estimate_leak;
    param_estimate_leak.fft_length = ARY_NUM_FFT;
    param_estimate_leak.leak_factor = 0.25f;

    ::Param_HRLE_t param_hrle;
    param_hrle.fft_length = ARY_NUM_FFT;
    param_hrle.lx         = 0.400000f;
    param_hrle.tr         = 0.999937f;
    param_hrle.min_lv     = -160.000000f;
    param_hrle.step_lv    = 0.400000f;
    param_hrle.num_bin    = 800;

    ::Param_WhiteNoiseAdder_t param_white_noise_adder;
    param_white_noise_adder.length     = ARY_NUM_WAVE;
    param_white_noise_adder.fft_length = ARY_NUM_FFT;
    param_white_noise_adder.wn_level   = 300.0f;

    ::Param_PreEmphasis_t param_pre_emphasis;
    param_pre_emphasis.length        = ARY_NUM_WAVE;
    param_pre_emphasis.fft_length    = ARY_NUM_FFT;
    param_pre_emphasis.sampling_rate = DEFAULT_SAMPLING_RATE;
    param_pre_emphasis.cutoff        = 7900;
    param_pre_emphasis.preem_coef    = 0.97f;

    ::Param_MelFilterBank_t param_mel_filter_bank;
    param_mel_filter_bank.fbank         = ARY_NUM_FBANK;
    param_mel_filter_bank.length        = ARY_NUM_WAVE;
    param_mel_filter_bank.fft_length    = ARY_NUM_FFT;
    param_mel_filter_bank.sampling_rate = DEFAULT_SAMPLING_RATE;
    param_mel_filter_bank.cutoff        = 8000;
    param_mel_filter_bank.min_frequency = 63;
    param_mel_filter_bank.max_frequency = 8000;

    ::Param_Bluetooth_t param_bluetooth = {
      .mic_enable = 0,
      .min_deg = -180,
      .max_deg = 180,
    };


    Param_Flac_t param_flac = {
      .blocksize = 0,
      .mic_enable = 0,
      .mic_max_lpc_order = 8,
      .mic_rice_partition_order = 4,
      .sep_enable = 0,
      .sep_hostname = {},
      .sep_max_lpc_order = 8,
      .sep_rice_partition_order = 4,
    };

    //int init_device = DEVICE_PS_EYE; // Easy setting for previous version compatibility of 2.4.x
    int init_device = DEVICE_RASP_ZX;
    int device_is_socket = false;
    switch(init_device)
    {
        case DEVICE_RASP_LC4:   // RASP-LC   4ch 24bit
            param_dev_ch = 4; param_bits = 24; param_source_tracker.thresh = 30.0f;
            break;
        case DEVICE_RASP_LC:    // RASP-LC   8ch 24bit
            param_dev_ch = 8; param_bits = 24; param_source_tracker.thresh = 29.0f; // 27.0f; // for AudioVisualiser // 34.0f; // first/last 4ch
            break;
        case DEVICE_RASP_ZX:    // RASP-ZX   8ch 24bit old
            param_dev_ch = 8; param_bits = 24; param_source_tracker.thresh = 30.0f;//29.0f;
            break;
        case DEVICE_RASP_ZX8:   // RASP-ZX   8ch 24bit new
            param_dev_ch = 8; param_bits = 24; param_source_tracker.thresh = 29.0f;
            break;
        case DEVICE_RASP_24:    // RASP-24   8ch 24bit
            param_dev_ch = 8; param_bits = 24; param_source_tracker.thresh = 29.0f; // 27.0f; // for AudioVisualiser // 34.0f; // first/last 4ch
            break;
        case DEVICE_PS_EYE:     // PS-EYE    4ch 16bit
            param_dev_ch = 4; param_bits = 16; param_source_tracker.thresh = 39.0f; // takigahira hark 2.4.0 test
            break;
        case DEVICE_KINECT:     // KINECT    4ch 24bit
            param_dev_ch = 4; param_bits = 24; param_source_tracker.thresh = 34.0f;
            break;
        case DEVICE_MICROCONE:  // Microcone 7ch 24bit
            param_dev_ch = 7; param_bits = 24; param_source_tracker.thresh = 34.0f;
            break;
        case DEVICE_HRI_SP_KM:  // KM        4ch 16bit
            param_dev_ch = 4; param_bits = 16; param_source_tracker.thresh = 39.0f; // takigahira hark 2.4.0 test
            break;
        case DEVICE_HRI_SP_SHT: // SHT       4ch 16bit
            param_dev_ch = 4; param_bits = 16; param_source_tracker.thresh = 26.5f;
            break;
        case DEVICE_SINGLE_MIC: // Reference 1ch 16bit
            param_dev_ch = 1; param_bits = 16; param_source_tracker.thresh = 34.0f;
            break;
        default:                // Default   8ch 24bit
            param_dev_ch = 8; param_bits = 24; param_source_tracker.thresh = 28.0f;
            break;
    }
    param_offset = 0;
    param_ch = param_dev_ch - param_offset;

    param_advance = 160;
    //param_advance = 512;
    
    config_file_path[0] = '\0';

    //loop for get command line options
    i = 1; flags = 0;
    bool flag_of_tmp_pcm = false;
    while(i < argc){
        if(argv[i][0] == '-'){
            switch(argv[i][1]){
                case '-': //switch long option mode
                    //fprintf(stderr, "sorry, long option is unsupported yet.\n"); help(); return -1;
                    // not use yet
                    if(     NULL != strstr(argv[i], "--verbose")){ verbose = 1; }
                    else if(NULL != strstr(argv[i], "--version")){ version(); help(); return 0; }
                    else if(NULL != strstr(argv[i], "--help")){ help(); return 0; }
                    else if(NULL != strstr(argv[i], "--enable")){
                    }
                    else if(NULL != strstr(argv[i], "--disable")){
                    }
                    else if(NULL != strstr(argv[i], "--config")){
                        i++;
                        if(NULL != (fp = fopen(argv[i], "rt"))){ fclose(fp); strcpy(config_file_path, argv[i]); i++; }
                        else{ config_file_path[0] = '\0'; }
                    }
                    else if(NULL != strstr(argv[i], "--daemon")){
                        is_daemonic = 1;
                        i++;
                    }
                    else if(NULL != strstr(argv[i], "--stanby")){
                        stanby_mode = 1;
                        i++;
                    }
                    else if(NULL != strstr(argv[i], "--set")){
                        if(     NULL != strstr(argv[i], "--set-port")){
                        }
                        else if(NULL != strstr(argv[i], "--set-hostname")){
                            if(     NULL != strstr(argv[i], "--set-hostname-microphone")){
                            }
                            else if(NULL != strstr(argv[i], "--set-hostname-julius")){
                            }
                            else{
                            }
                        }
                        else{
                        }
                    }
                    else if(NULL != strstr(argv[i], "--transfer-function")){
                        if(     NULL != strstr(argv[i], "--transfer-function-for-localize")){
                        }
                        else if(NULL != strstr(argv[i], "--transfer-function-for-separate")){
                        }
                        else{
                        }
                    }
                    else if(NULL != strstr(argv[i], "--param")){
                        if(     NULL != strstr(argv[i], "--param-generic")){
                            if(     NULL != strstr(argv[i], "--param-generic-advance")){
                            }
                            //else if(NULL != strstr(argv[i], "--param-generic-dummy")){
                            //}
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-localize-music")){
                            if(     NULL != strstr(argv[i], "--param-localize-music-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-sampling-rate")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-elevation")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-window")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-period")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-num-source")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-export-num-source")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-deg-min-max")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-freq-low-upper")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-spectrum-weight-type")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-enable-eigenvalue-weight")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-a-char-scaling")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-spline-num")){
                            }
                            else if(NULL != strstr(argv[i], "--param-localize-music-square-num")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-source-tracker")){
                            if(     NULL != strstr(argv[i], "--param-source-tracker-threshold")){
	                            i++;
	                            param_source_tracker.thresh = atof(argv[i]);
	                            i++;
                            }
                            else if(NULL != strstr(argv[i], "--param-source-tracker-pause-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-source-tracker-min-source-interval")){
                            }
                            else if(NULL != strstr(argv[i], "--param-source-tracker-min-id")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-source-interval-extender")){
                            if(     NULL != strstr(argv[i], "--param-source-interval-extender-preroll-length")){
                            }
                            //else if(NULL != strstr(argv[i], "--param-source-interval-extender-dummy")){
                            //}
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-estimate-leak")){
                            if(     NULL != strstr(argv[i], "--param-estimate-leak-fft-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-setimate-leak-leak-factor")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-hrle")){
                            if(     NULL != strstr(argv[i], "--param-hrle-fft-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-hrle-lx")){
                            }
                            else if(NULL != strstr(argv[i], "--param-hrle-tr")){
                            }
                            else if(NULL != strstr(argv[i], "--param-hrle-min-lv")){
                            }
                            else if(NULL != strstr(argv[i], "--param-hrle-step-lv")){
                            }
                            else if(NULL != strstr(argv[i], "--param-hrle-num-bin")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-white-noise-adder")){
                            if(     NULL != strstr(argv[i], "--param-white-noise-adder-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-white-noise-adder-fft-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-white-noise-adder-wn-level")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-pre-emphasis")){
                            if(     NULL != strstr(argv[i], "--param-pre-emphasis-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-pre-emphasis-fft-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-pre-emphasis-sampling-rate")){
                            }
                            else if(NULL != strstr(argv[i], "--param-pre-emphasis-cutoff")){
                            }
                            else if(NULL != strstr(argv[i], "--param-pre-emphasis-preem-coef")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-mel-filter-bank")){
                            if(     NULL != strstr(argv[i], "--param-mel-filter-bank-fbank")){
                            }
                            else if(NULL != strstr(argv[i], "--param-mel-filter-bank-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-mel-filter-bank-fft-length")){
                            }
                            else if(NULL != strstr(argv[i], "--param-mel-filter-bank-sampling-rate")){
                            }
                            else if(NULL != strstr(argv[i], "--param-mel-filter-bank-cutoff")){
                            }
                            else if(NULL != strstr(argv[i], "--param-mel-filter-freq-min-max")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-bluetooth")){
                            if(     NULL != strstr(argv[i], "--param-bluetooth-mic-enable")){
                            }
                            else if(NULL != strstr(argv[i], "--param-bluetooth-deg-min-max")){
                            }
                            else{
                            }
                        }
                        else if(NULL != strstr(argv[i], "--param-flac")){
                            if(     NULL != strstr(argv[i], "--param-flac-mic-enable")){
                            }
                            else if(NULL != strstr(argv[i], "--param-flac-mic-max-lpc-order")) {
                            }
                            else if(NULL != strstr(argv[i], "--param-flac-mic-rice-partition-order")) {
                            }
                            else if(NULL != strstr(argv[i], "--param-flac-sep-enable")) {
                            }
                            else if(NULL != strstr(argv[i], "--param-flac-sep-hostname")) {
                            }
                            else if(NULL != strstr(argv[i], "--param-flac-sep-max-lpc-order")) {
                            }
                            else if(NULL != strstr(argv[i], "--param-flac-sep-rice-partition-order")) {
                            }
                            else{
                            }
                        }
                        else{
                        }
                    }
                    else if(NULL != strstr(argv[i], "--input-filename")){
                        if(     NULL != strstr(argv[i], "--input-filename-wave-pcm")){ //microphone recording pcm filename
                            i++;
                            if(argv[i][0] != '-'){
                                if(NULL != (fp = fopen(argv[i], "rb"))){ fclose(fp); param_in_pcm_filename = argv[i]; i++; }
                                else{ fprintf(stderr, "error, \"%s\" was not found.\n", argv[i]); help(); return -1; }
                            }
                            else{ 
                                fprintf(stderr, "error, input wav filename was not specified.\n"); help(); return -1; 
                            }
                        }
                        else{
                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                        }
                    }
                    else if(NULL != strstr(argv[i], "--output-filename")){
                        if(     NULL != strstr(argv[i], "--output-filename-mic-pcm")){ //microphone recording pcm filename
                            i++;
                            if(argv[i][0] != '-'){ param_save_input_pcm_filename = argv[i]; i++; }
                            else{ fprintf(stderr, "error, output microphone recording pcm filename was not specified.\n"); help(); return -1; }
                        }
                        else if(NULL != strstr(argv[i], "--output-filename-sep-spec")){ //separated spectrum filename
                            i++;
                            if(argv[i][0] != '-'){ param_save_output_spec_filename = argv[i]; i++; }
                            else{ fprintf(stderr, "error, output separated spectrum filename was not specified.\n"); help(); return -1; }
                        }
                        else if(NULL != strstr(argv[i], "--output-filename-sep-pcm")){ //separated pcm filename
                            i++;
                            if(argv[i][0] != '-'){ param_save_output_pcm_filename = argv[i]; i++; }
                            else{ fprintf(stderr, "error, output separated pcm filename was not specified.\n"); help(); return -1; }
                        }
                        else if(NULL != strstr(argv[i], "--output-filename-sep-tmppcm")){ //separating temporary pcm filename
                            i++;
                            if(argv[i][0] != '-'){ param_save_output_pcm_tmp_filename = argv[i]; flag_of_tmp_pcm = true; i++; }
                            else{ fprintf(stderr, "error, output separating temporary pcm filename was not specified.\n"); help(); return -1; }
                        }
                        else if(NULL != strstr(argv[i], "--output-filename-sep-feature")){ //separated feature filename
                            i++;
                            if(argv[i][0] != '-'){ param_save_output_feature_filename = argv[i]; i++; }
                            else{ fprintf(stderr, "error, output separated feature filename was not specified.\n"); help(); return -1; }
                        }
                        else if(NULL != strstr(argv[i], "--output-filename-source")){ //direction of source filename
                            i++;
                            if(argv[i][0] != '-'){ param_save_output_source_filename = argv[i]; i++; }
                            else{ fprintf(stderr, "error, output source filename was not specified.\n"); help(); return -1; }
                        }
                        else if(NULL != strstr(argv[i], "--output-localized-power-sepc")){ //localized power spectrum filename
                            i++;
                            if(argv[i][0] != '-'){ param_save_output_locpow_spec_filename = argv[i]; i++; }
                            else{ fprintf(stderr, "error, output localize power spectrum filename was not specified.\n"); help(); return -1; }
                        }
                        else{
                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                        }
                    }
                    else if(NULL != strstr(argv[i], "--output-filetype")){
                    }
                    else{
                        fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                    }
                    break;
                    
                case 'd': //device option
                    switch(argv[i][2]){
                        case 'e': //device type setting
                            i++;
                            break;
                        case 't': //device type setting
                            i++;
                            if(NULL != strstr(argv[i], "SOCKET"))
                            {
                                device_is_socket = true;
                            }
                            else
                            {
                                device_is_socket = false;
                            }
                            i++;
                            break;
                        case 'n': //device number setting
                            fprintf(stderr, "sorry, device number is unsupported yet.\n"); help(); return -1;
                            break;
                        default:
                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                            break;
                    }
                    break;
                
                case 'i': //input option
                    switch(argv[i][2]){
                        case 'f': //set filename option
                            switch(argv[i][3]){
                                case 'w': //wav file
                                    i++;
                                    if(argv[i][0] != '-'){
                                        if(NULL != (fp = fopen(argv[i], "rb"))){ fclose(fp); param_in_pcm_filename = argv[i]; i++; }
                                        else{ fprintf(stderr, "error, \"%s\" was not found.\n", argv[i]); help(); return -1; }
                                    }
                                    else{ fprintf(stderr, "error, input wav file was not specified.\n"); help(); return -1; }
                                    break;
                                default:
                                    fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                                    break;
                            }
                            break;
                        default:
                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                            break;
                    }
                    break;
                    
                case 'o': //optput option
                    switch(argv[i][2]){
                        case 'f': //set filename option
                            switch(argv[i][3]){
                                case 'm': //microphone recording pcm filename
                                    i++;
                                    if(argv[i][0] != '-'){ param_save_input_pcm_filename = argv[i]; i++; }
                                    else{ fprintf(stderr, "error, output microphone recording pcm filename was not specified.\n"); help(); return -1; }
                                    break;
                                case 's': //separated spectrum filename
                                    i++;
                                    if(argv[i][0] != '-'){ param_save_output_spec_filename = argv[i]; i++; }
                                    else{ fprintf(stderr, "error, output separated spectrum filename was not specified.\n"); help(); return -1; }
                                    break;
                                case 'p': //separated pcm filename
                                    i++;
                                    if(argv[i][0] != '-'){ param_save_output_pcm_filename = argv[i]; i++; }
                                    else{ fprintf(stderr, "error, output separated pcm filename was not specified.\n"); help(); return -1; }
                                    break;
                                case 't': //separating temporary pcm filename
                                    i++;
                                    if(argv[i][0] != '-'){ param_save_output_pcm_tmp_filename = argv[i]; flag_of_tmp_pcm = true; i++; }
                                    else{ fprintf(stderr, "error, output microphone recording pcm filename was not specified.\n"); help(); return -1; }
                                    break;
                                case 'f': //separated feature filename
                                    i++;
                                    if(argv[i][0] != '-'){ param_save_output_feature_filename = argv[i]; i++; }
                                    else{ fprintf(stderr, "error, output separated feature filename was not specified.\n"); help(); return -1; }
                                    break;
                                case 'd': //direction of source filename
                                    i++;
                                    if(argv[i][0] != '-'){ param_save_output_source_filename = argv[i]; i++; }
                                    else{ fprintf(stderr, "error, output source filename was not specified.\n"); help(); return -1; }
                                    break;
                                case 'l': //localized power spectrum filename
                                    i++;
                                    if(argv[i][0] != '-'){ param_save_output_locpow_spec_filename = argv[i]; i++; }
                                    else{ fprintf(stderr, "error, output localize power spectrum filename was not specified.\n"); help(); return -1; }
                                    break;
                                default:
                                    fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                                    break;
                            }
                            break;
                            
                        case 't':
                            switch(argv[i][3]){
                                case 'm': //microphone recording pcm file type
                                    i++;
                                    if(argv[i][0] != '-'){
                                        if(     NULL != strstr(argv[i], "NONE")){
                                            param_save_mic_pcm_format = PCM_NONE;
                                        }
                                        else if(NULL != strstr(argv[i], "RAW" )){
                                            if(     NULL != strstr(argv[i], "RAW_SINT16"  )){ param_save_mic_pcm_format = PCM_RAW_SINT16; }
                                            else if(NULL != strstr(argv[i], "RAW_SINT24"  )){ param_save_mic_pcm_format = PCM_RAW_SINT24; }
                                            else if(NULL != strstr(argv[i], "RAW_SINT32"  )){ param_save_mic_pcm_format = PCM_RAW_SINT32; }
                                            else if(NULL != strstr(argv[i], "RAW_FLOAT32" )){ param_save_mic_pcm_format = PCM_RAW_FLOAT32; }
                                            else if(NULL != strstr(argv[i], "RAW_RAWFLOAT")){ param_save_mic_pcm_format = PCM_RAW_RAWFLOAT; }
                                            else{ fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; }
                                        }
                                        else if(NULL != strstr(argv[i], "WAV" )){
                                            if(     NULL != strstr(argv[i], "WAV_SINT16"  )){ param_save_mic_pcm_format = PCM_WAV_SINT16; }
                                            else if(NULL != strstr(argv[i], "WAV_SINT24"  )){ param_save_mic_pcm_format = PCM_WAV_SINT24; }
                                            else if(NULL != strstr(argv[i], "WAV_SINT32"  )){ param_save_mic_pcm_format = PCM_WAV_SINT32; }
                                            else if(NULL != strstr(argv[i], "WAV_FLOAT32" )){ param_save_mic_pcm_format = PCM_WAV_FLOAT32; }
                                            else{ fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; }
                                        }
                                        else{ 
                                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; 
                                        }
                                        i++;
                                    }
                                    else{ 
                                        fprintf(stderr, "error, output microphone recording pcm file type was not specified.\n"); help(); return -1; 
                                    }
                                    break;
                                    
                                case 'p': //separated pcm file type
                                    i++;
                                    if(argv[i][0] != '-'){
                                        if(     NULL != strstr(argv[i], "NONE")){
                                            param_save_sep_pcm_format = PCM_NONE;
                                        }
                                        else if(NULL != strstr(argv[i], "RAW" )){
                                            if(     NULL != strstr(argv[i], "RAW_SINT16"  )){ param_save_sep_pcm_format = PCM_RAW_SINT16; }
                                            else if(NULL != strstr(argv[i], "RAW_SINT24"  )){ param_save_sep_pcm_format = PCM_RAW_SINT24; }
                                            else if(NULL != strstr(argv[i], "RAW_SINT32"  )){ param_save_sep_pcm_format = PCM_RAW_SINT32; }
                                            else if(NULL != strstr(argv[i], "RAW_FLOAT32" )){ param_save_sep_pcm_format = PCM_RAW_FLOAT32; }
                                            else if(NULL != strstr(argv[i], "RAW_RAWFLOAT")){ param_save_sep_pcm_format = PCM_RAW_RAWFLOAT; }
                                            else{ fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; }
                                        }
                                        else if(NULL != strstr(argv[i], "WAV" )){
                                            if(     NULL != strstr(argv[i], "WAV_SINT16"  )){ param_save_sep_pcm_format = PCM_WAV_SINT16; }
                                            else if(NULL != strstr(argv[i], "WAV_SINT24"  )){ param_save_sep_pcm_format = PCM_WAV_SINT24; }
                                            else if(NULL != strstr(argv[i], "WAV_SINT32"  )){ param_save_sep_pcm_format = PCM_WAV_SINT32; }
                                            else if(NULL != strstr(argv[i], "WAV_FLOAT32" )){ param_save_sep_pcm_format = PCM_WAV_FLOAT32; }
                                            else{ fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; }
                                        }
                                        else{ 
                                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; 
                                        }
                                        i++;
                                    }
                                    else{ 
                                        fprintf(stderr, "error, output separated pcm file type was not specified.\n"); help(); return -1; 
                                    }
                                    break;
                                
                                case 'f': //separated feature file type
                                    i++;
                                    if(argv[i][0] != '-'){
                                        if(     NULL != strstr(argv[i], "NONE" )){ param_save_sep_feature_type = PCM_NONE; }
                                        else if(NULL != strstr(argv[i], "NOSMN")){ param_save_sep_feature_type = PCM_RAW_SINT16; }
                                        else if(NULL != strstr(argv[i], "SMN"  )){ param_save_sep_feature_type = PCM_WAV_SINT16; }
                                        else{ fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; }
                                        i++;
                                    }
                                    else{ 
                                        fprintf(stderr, "error, output feature file data type was not specified.\n"); help(); return -1; 
                                    }
                                    if(argv[i][0] != '-'){
                                        if(     NULL != strstr(argv[i], "NOHEADER")){
                                            param_save_sep_feature_format = FEATURE_NOHEADER;
                                        }
                                        else if(NULL != strstr(argv[i], "USER" )){
                                            param_save_sep_feature_format = FEATURE_USER;
                                        }
                                        else if(NULL != strstr(argv[i], "MFCC" )){
                                            param_save_sep_feature_format = FEATURE_MFCC;
                                            if(NULL != strstr(argv[i], "_E")){ param_save_sep_feature_format |= FEATURE_USE_E; }
                                            if(NULL != strstr(argv[i], "_N")){ param_save_sep_feature_format |= FEATURE_USE_N; }
                                            if(NULL != strstr(argv[i], "_D")){ param_save_sep_feature_format |= FEATURE_USE_D; }
                                            if(NULL != strstr(argv[i], "_A")){ param_save_sep_feature_format |= FEATURE_USE_A; }
                                            if(NULL != strstr(argv[i], "_C")){ param_save_sep_feature_format |= FEATURE_USE_C; }
                                            if(NULL != strstr(argv[i], "_Z")){ param_save_sep_feature_format |= FEATURE_USE_Z; }
                                            if(NULL != strstr(argv[i], "_K")){ param_save_sep_feature_format |= FEATURE_USE_K; }
                                            if(NULL != strstr(argv[i], "_0")){ param_save_sep_feature_format |= FEATURE_USE_0; }
                                            if(NULL != strstr(argv[i], "_V")){ param_save_sep_feature_format |= FEATURE_USE_V; }
                                            if(NULL != strstr(argv[i], "_T")){ param_save_sep_feature_format |= FEATURE_USE_T; }
                                        }
                                        else{ 
                                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1; 
                                        }
                                        i++;
                                    }
                                    else{ 
                                        fprintf(stderr, "error, output feature file format type was not specified.\n"); help(); return -1; 
                                    }
                                    break;
                                default:
                                    fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                                    break;
                            }
                            break;
                        default:
                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                            break;
                    }
                    break;
                case 't': //TF option
                    switch(argv[i][2]){
                        case 'l':
                            i++;
                            if(argv[i][0] != '-'){
                                if(NULL != (fp = fopen(argv[i], "rb"))){ fclose(fp); param_loc_tf_filename = argv[i]; i++; }
                                else{ fprintf(stderr, "error, \"%s\" was not found.\n", argv[i]); help(); return -1; }
                            }
                            else{ 
                                fprintf(stderr, "error, localization TF file was not specified.\n"); help(); return -1; 
                            }
                            break;
                        case 's':
                            i++;
                            if(argv[i][0] != '-'){
                                if(NULL != (fp = fopen(argv[i], "rb"))){ fclose(fp); param_sep_tf_filename = argv[i]; i++; }
                                else{ fprintf(stderr, "error, \"%s\" was not found.\n", argv[i]); help(); return -1; }
                            }
                            else{ 
                                fprintf(stderr, "error, separation TF file was not specified.\n"); help(); return -1; 
                            }
                            break;
                        default:
                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                            break;
                    }
                    break;
                case 's': //set option
                    switch(argv[i][2]){
                        case 'p': //set send port
                            i++;
                            if(argv[i][0] != '-'){
                                if((NULL != strstr(argv[i], "a")) || (NULL != strstr(argv[i], "A"))){ param_port |= SEND_PORT_A; }
                                if((NULL != strstr(argv[i], "b")) || (NULL != strstr(argv[i], "B"))){ param_port |= SEND_PORT_B; }
                                if((NULL != strstr(argv[i], "c")) || (NULL != strstr(argv[i], "C"))){ param_port |= SEND_PORT_C; }
                                if((NULL != strstr(argv[i], "d")) || (NULL != strstr(argv[i], "D"))){ param_port |= SEND_PORT_D; }
                                if((NULL != strstr(argv[i], "e")) || (NULL != strstr(argv[i], "E"))){ param_port |= SEND_PORT_E; }
                                if((NULL != strstr(argv[i], "f")) || (NULL != strstr(argv[i], "F"))){ param_port |= SEND_PORT_F; }
                                if((NULL != strstr(argv[i], "j")) || (NULL != strstr(argv[i], "J"))){ param_port |= SEND_JULIUS; }
                            }
                            else{ 
                                fprintf(stderr, "error, send port was not specified.\n"); help(); return -1; 
                            }
	                        i++;
                            break;
                        case 'h': //set hostname
                            switch(argv[i][3]){
                                case 'm': //set socket microphone hostname
                                    i++;
                                    if(argv[i][0] != '-'){
                                        // host/ip error check isn't written yet.
                                        param_mic_hostname = argv[i]; i++;
                                    }
                                    else{ 
                                        fprintf(stderr, "error, scoket microphone hostname was not specified.\n"); help(); return -1; 
                                    }
                                    break;
                                case 'j': //set julius hostname
                                    i++;
                                    if(argv[i][0] != '-'){
                                        // host/ip error check isn't written yet.
                                        param_julius_hostname = argv[i]; i++;
                                    }
                                    else{ 
                                        fprintf(stderr, "error, julius hostname was not specified.\n"); help(); return -1; 
                                    }
                                    break;
                                default:
                                    fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                                    break;
                            }
                            break;
                        default:
                            fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                            break;
                    }
                    break;
                case 'h': //show help
                    help();
                    return 0;
                    break;
                case 'v': //verbose
                    verbose = 1;
                    i++;
                    break;
                case 'c': //config
                    i++;
                    if(NULL != (fp = fopen(argv[i], "rt"))){ fclose(fp); strcpy(config_file_path, argv[i]); i++; }
                    else{ config_file_path[0] = '\0'; }
                    break;
                default:
                    fprintf(stderr, "unsupported option [%s] found.\n", argv[i]); help(); return -1;
                    break;
            }
        }
    }
  
    if(!flag_of_tmp_pcm){
        sprintf(tmp, "%s_", param_save_output_pcm_filename); param_save_output_pcm_tmp_filename = tmp;
    }
    
    /*
    **
    ** SIGPIPEが起きたときに強制終了しないようにする
    **
    */
    struct sigaction sa_sigpipe;
    
    memset(&sa_sigpipe, 0, sizeof(sa_sigpipe));
    sa_sigpipe.sa_sigaction = sigpipe_action;
    sa_sigpipe.sa_flags = SA_RESTART | SA_SIGINFO;
    if (sigaction(SIGPIPE, &sa_sigpipe, NULL) < 0)
    {
        printf("sigaction error.\n");
    }
    
    /*
    **
    ** Ctrl+cが起きたときに停止-->終了となるようにする
    **
    */
    struct sigaction sa_sigint;
    
    memset(&sa_sigint, 0, sizeof(sa_sigint));
    sa_sigint.sa_sigaction = sigint_action;
    sa_sigint.sa_flags = SA_RESTART | SA_SIGINFO;
    if (sigaction(SIGINT, &sa_sigint, NULL) < 0)
    {
        printf("sigaction error.\n");
    }
    
    /*
    **
    ** HARKをデーモンとして動作させ
    ** 外部からのコマンドで開始・停止・終了等ができるようにする
    **
    */
    int status;
    int socket_addr_size;
    int main_server_socket_fd;
    struct sockaddr_in main_server_addr;

    int socket_fd;
    struct sockaddr_in client_addr;
    
    struct timeval timeout;
    fd_set rfds;
    int  read_size;
    int  write_size;
    char sock_buffer[256];
    char *cmd_ptr;
    
    /* socketの構造体を初期化 */
    socket_addr_size = sizeof(struct sockaddr_in);
    bzero((char *)&main_server_addr, socket_addr_size);
    
    main_server_addr.sin_family      = AF_INET;
    main_server_addr.sin_port        = htons(31099);
    main_server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    /* socket作成 */
    main_server_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(main_server_socket_fd <= 0)
    {
        fprintf(stderr, "Socket Create Error.\n");
        return -1;
    }
    
    /* socketにアドレス割り当て */
    status = bind(main_server_socket_fd, 
                  (struct sockaddr *)&main_server_addr,
                  socket_addr_size);
    if(status < 0)
    {
        fprintf(stderr, "Bind Error.\n");
        close(main_server_socket_fd);
        return -1;
    }
    
    /* acceptがタイムアウトできるようにする */
    struct timeval sock_timeout;
    sock_timeout.tv_sec  = 3;
    sock_timeout.tv_usec = 0;
    status = setsockopt(main_server_socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&sock_timeout, sizeof(sock_timeout));
    
    /* 接続許可 */
    status = listen(main_server_socket_fd, 3);
    if(status < 0)
    {
        fprintf(stderr, "Listen Error.\n");
        close(main_server_socket_fd);
        return -1;
    }
    
    
    
    if(is_daemonic)
    {
        printf("---------------\n");
        printf("run background.\n");
        printf("---------------\n");
        
        daemon(0, verbose);
    }
    
    
    
    /* コンフィグファイルからパラメータを取得 */
    if(config_file_path[0] != '\0')
    {
        /* ここまでで設定されてたパラメータを登録する */
        ParamSetLocalizeMusic(&param_localize_music);
        ParamSetSourceTracker(&param_source_tracker);
        ParamSetSourceIntervalExtender(&param_source_interval_extender);
        ParamSetHrle(&param_hrle);
        ParamSetPreEmphasis(&param_pre_emphasis);
        ParamSetEstimateLeak(&param_estimate_leak);
        ParamSetWhiteNoiseAdder(&param_white_noise_adder);
        
        PF_save_mic_pcm_type = param_save_mic_pcm_format;
        PF_save_sep_pcm_type = param_save_sep_pcm_format;
        
        PF_send_port = param_port;
        
        ret = ParamFileReadMain(config_file_path);
        if(ret == 0)
        {
            update_param = 1;
            /*
            ParamGetLocalizeMusic(&param_localize_music);
            ParamGetSourceTracker(&param_source_tracker);
            ParamGetSourceIntervalExtender(&param_source_interval_extender);
            
            if(PF_input_wav_file_path[0] != '\0') param_in_pcm_filename              = PF_input_wav_file_path;
            if(PF_save_mic_pcm[0] != '\0')        param_save_input_pcm_filename      = PF_save_mic_pcm;
            if(PF_save_sep_pcm[0] != '\0')        param_save_output_pcm_filename     = PF_save_sep_pcm;
            if(PF_save_sep_tmppcm[0] != '\0')     param_save_output_pcm_tmp_filename = PF_save_sep_tmppcm;
            
            if(PF_loc_tf_file_path[0] != '\0')    param_loc_tf_filename = PF_loc_tf_file_path;
            if(PF_sep_tf_file_path[0] != '\0')    param_sep_tf_filename = PF_sep_tf_file_path;
            
            param_save_mic_pcm_format = PF_save_mic_pcm_type;
            param_save_sep_pcm_format = PF_save_sep_pcm_type;
            
            param_port |= PF_send_port;
            */
        }
    }
    
    if(HARKAndroid::HARKControl == NULL)
    {
        HARKAndroid::HARKControl = new HARKAndroid::ControlObject;
        HARKAndroid::HARKControl->Create();
    }

    run_flag = 1;
    while(run_flag)
    {
        if(!stanby_mode)
        {
            socket_fd = 0;
        }
        else
        {
            /* 受信待機 */
            socket_addr_size = sizeof(struct sockaddr_in);
            socket_fd = accept(main_server_socket_fd,
                               (struct sockaddr *)&client_addr,
                               (socklen_t *)&socket_addr_size);
        }
        
        if(socket_fd < 0)
        {
        
            if(main_end_flag)
            {
                printf("HARK Stop & Exit.\n");
                run_flag    = 0x0;
                ret = HARKAndroid::HARKControl->Stop();
            }

        }
        else
        {
            do
            {
                if(!stanby_mode)
                {
                    strcpy(sock_buffer, "--start");
                }
                else
                {
                    /* 受信可能を確認 */
                    do
                    {
                        FD_ZERO(&rfds);
                        FD_SET(socket_fd, &rfds);
                        
                        timeout.tv_sec  = 1;
                        timeout.tv_usec = 0;
                        status = select(socket_fd+1, &rfds, NULL, NULL, &timeout);
                    
                    }while(status == 0);
                    
                    if(status < 0)
                    {
                        fprintf(stderr, "rfds select error [%d]\n", status);
                        read_size = 0;
                    }
                    else
                    {
                        /* メッセージを受信 */
                        read_size = read(socket_fd, sock_buffer, sizeof(sock_buffer));
                    }
                    
                    /* 他方がソケットをCloseしたか判定 */
                    if((status < 0) || (read_size <= 0))
                    {
                        /* サーバー終了フラグ設定 */
                        connect_end = 0x1;
                        
                        break;
                    }
                }
                
                printf("Recieve CMD : %s\n", sock_buffer);

                if((cmd_ptr = strstr(sock_buffer, "--start")) != NULL)
                {
                    printf("start.\n");
                    sprintf(sock_buffer, "start OK.");
                    
                    /* パラメータを更新 */
                    if(update_param)
                    {
                        ParamGetLocalizeMusic(&param_localize_music);
                        ParamGetSourceTracker(&param_source_tracker);
                        ParamGetSourceIntervalExtender(&param_source_interval_extender);
                        ParamGetHrle(&param_hrle);
                        ParamGetPreEmphasis(&param_pre_emphasis);
                        ParamGetEstimateLeak(&param_estimate_leak);
                        ParamGetWhiteNoiseAdder(&param_white_noise_adder);

                        ParamGetBluetooth(&param_bluetooth);
                        ParamGetFlac(&param_flac);
                        
                        if(PF_device_type == 2) /* WAVE */
                        {
                            /*
                            ** WAVE(debug)は指定デバイスがオープンできないときに実行される
                            ** 強制的にオープンできないデバイスを指定する
                            */
                            device_is_socket = true;
                            sprintf(PF_hostname_mic, "127.0.0.1");
                        }
                        else if(PF_device_type == 1) /* SOCKET */
                        {
                            device_is_socket = true;
                        }
                        
                        if(PF_hostname_mic[0] != '\0')        param_mic_hostname    = PF_hostname_mic;
                        if(PF_hostname_julius[0] != '\0')     param_julius_hostname = PF_hostname_julius;
                        
                        if(PF_input_wav_file_path[0] != '\0') param_in_pcm_filename              = PF_input_wav_file_path;
                        if(PF_save_mic_pcm[0] != '\0')        param_save_input_pcm_filename      = PF_save_mic_pcm;
                        if(PF_save_sep_pcm[0] != '\0')        param_save_output_pcm_filename     = PF_save_sep_pcm;
                        if(PF_save_sep_tmppcm[0] != '\0')     param_save_output_pcm_tmp_filename = PF_save_sep_tmppcm;
                        
                        if(PF_loc_tf_file_path[0] != '\0')    param_loc_tf_filename = PF_loc_tf_file_path;
                        if(PF_sep_tf_file_path[0] != '\0')    param_sep_tf_filename = PF_sep_tf_file_path;
                        
                        param_save_mic_pcm_format = PF_save_mic_pcm_type;
                        param_save_sep_pcm_format = PF_save_sep_pcm_type;
                        
                        param_port |= PF_send_port;
                        
                        if(PF_mic_target_channel == 16)
                        {
                            /* 16ch動作ならCHオフセットは0 */
                            param_ch = PF_mic_target_channel;
                            param_mic_channel_offset = 0;
                        }
                        else if(PF_mic_target_channel == 8)
                        {
                            /* 8ch動作ならCHオフセットは0または8 */
                            param_ch = PF_mic_target_channel;
                            param_mic_channel_offset = PF_mic_channel_offset;
                        }
                        else
                        {
                            /* その他ch数動作ならCHオフセットは0 */
                            param_ch = PF_mic_target_channel;
                            param_mic_channel_offset = 0;
                        }

                    }
                    update_param = 0;
                    
                    /* 実行パラメータ表示 */
                    if(verbose)
                    {
                        printf("LocalizeMUSIC Param\n");
                        switch(param_localize_music.music_algorithm)
                        {
                            case SEVD:
                                printf("  music algorithm        = SEVD\n");
                                break;
                            case GEVD:
                                printf("  music algorithm        = GEVD\n");
                                break;
                            case GSVD:
                                printf("  music algorithm        = GSVD\n");
                                break;
                            default:
                                printf("  music algorithm        = Unknown\n");
                                break;
                        }
                    
                        switch(param_localize_music.spectrum_weight_type)
                        {
                            case Uniform:
                                printf("  spectrum_weight_type   = Uniform\n");
                                break;
                            case A_Characteristic:
                                printf("  spectrum_weight_type   = A_Characteristic\n");
                                printf("  a_char_scaling         = %f\n", param_localize_music.a_char_scaling);
                                break;
                            case Manual_Spline:
                                printf("  spectrum_weight_type   = Manual_Spline\n");
                                printf("  spline_num             = %d\n", param_localize_music.spline_num);
                                break;
                            case Manual_Square:
                                printf("  spectrum_weight_type   = Manual_Square\n");
                                printf("  square_num             = %d\n", param_localize_music.square_num);
                                break;
                            default:
                                printf("  spectrum_weight_type   = Unknown\n");
                                break;
                        }
                        
                        printf("  num_source (export)    = %d (%d)\n", param_localize_music.num_source, param_localize_music.export_num_source);
                        printf("  window                 = %d\n", param_localize_music.window);
                        printf("  period                 = %d\n", param_localize_music.period);
                        printf("  elevation              = %f\n", param_localize_music.elevation);
                        printf("  frequency [low, upper] = [%d, %d]\n", param_localize_music.low_bound_frequency, param_localize_music.upper_bound_frequency);
                        printf("  degree [min, max]      = [%d, %d]\n", param_localize_music.min_deg, param_localize_music.max_deg);
                        printf("  localize TF filename   = %s\n", param_loc_tf_filename/*param_localize_music.a_matrix*/);
                        printf("SourceTracker Param\n");
                        printf("  thresh                 = %f\n", param_source_tracker.thresh);
                        printf("  pause_length           = %f\n", param_source_tracker.pause_length);
                        printf("  min_src_interval       = %f\n", param_source_tracker.min_src_interval);
                        printf("  min_id                 = %d\n", param_source_tracker.min_id);
                        printf("SourceIntervalExtender Param\n");
                        printf("  preroll_length         = %d\n", param_source_interval_extender.preroll_length);
            
                        printf("GHDSS Param\n");
                        printf("  separation TF filename = %s\n", param_sep_tf_filename);
                    
                        printf("EstimateLeak Param\n");
                        printf("  fft_length             = %d\n", param_estimate_leak.fft_length);
                        printf("  leak_factor            = %f\n", param_estimate_leak.leak_factor);
                    
                        printf("HRLE Param\n");
                        printf("  fft_length             = %d\n", param_hrle.fft_length);
                        printf("  lx                     = %f\n", param_hrle.lx);
                        printf("  tr                     = %f\n", param_hrle.tr);
                        printf("  min_lv                 = %f\n", param_hrle.min_lv);
                        printf("  step_lv                = %f\n", param_hrle.step_lv);
                        printf("  num_bin                = %d\n", param_hrle.num_bin);
                    
                        printf("WhiteNoiseAdder Param\n");
                        printf("  length                 = %d\n", param_white_noise_adder.length);
                        printf("  fft_length             = %d\n", param_white_noise_adder.fft_length);
                        printf("  wn_level               = %f\n", param_white_noise_adder.wn_level);
                    
                        printf("PreEmphasis Param\n");
                        printf("  length                 = %d\n", param_pre_emphasis.length);
                        printf("  fft_length             = %d\n", param_pre_emphasis.fft_length);
                        printf("  sampling_rate          = %d\n", param_pre_emphasis.sampling_rate);
                        printf("  cutoff                 = %d\n", param_pre_emphasis.cutoff);
                        printf("  preem_coef             = %f\n", param_pre_emphasis.preem_coef);
                    
                        printf("MelFilterBank Param\n");
                        printf("  fbank                  = %d\n", param_mel_filter_bank.fbank);
                        printf("  length                 = %d\n", param_mel_filter_bank.length);
                        printf("  fft_length             = %d\n", param_mel_filter_bank.fft_length);
                        printf("  sampling_rate          = %d\n", param_mel_filter_bank.sampling_rate);
                        printf("  cutoff                 = %d\n", param_mel_filter_bank.cutoff);
                        printf("  min_frequency          = %d\n", param_mel_filter_bank.min_frequency);
                        printf("  max_frequency          = %d\n", param_mel_filter_bank.max_frequency);
                    }

                    /* 実行時のパラメータを設定 */
                    {
                        // setParam() を使いたかったが開発段階のパラメータ追加で構造体の型が一致する可能性があるので
                        // 書き換えが頻繁に発生しないように当面はパラメータ個別の設定関数を使用する
                        // Set paths
                        HARKAndroid::HARKControl->SetInputParamPCMFilePath(param_in_pcm_filename);
                        HARKAndroid::HARKControl->SetOutputParamMicPCMFilePath(param_save_input_pcm_filename);
                        //HARKAndroid::HARKControl->SetOutputParamMicSpwcFilePath(param_save_input_spec_filename);
                        HARKAndroid::HARKControl->SetOutputParamPowSpecFilePath(param_save_output_locpow_spec_filename);
                        //HARKAndroid::HARKControl->SetOutputParamSepSpwcFilePath(param_save_output_spec_filename);
                        HARKAndroid::HARKControl->SetOutputParamSepPCMFilePath(param_save_output_pcm_filename);
                        HARKAndroid::HARKControl->SetOutputParamSepPCMTMPFilePath(param_save_output_pcm_tmp_filename);
                        HARKAndroid::HARKControl->SetOutputParamSepFeatureFilePath(param_save_output_feature_filename);
                        HARKAndroid::HARKControl->SetOutputParamSourceFilePath(param_save_output_source_filename);
                        // Set selected algorithm
                        HARKAndroid::HARKControl->SetParamSwitchLocalizeAlgorithm(param_localize_algorithm);
                        HARKAndroid::HARKControl->SetParamSwitchSeparationAlgorithm(param_separation_algorithm);
                        HARKAndroid::HARKControl->SetParamSwitchFilterAlgorithm(param_filter_algorithm);
                        // Set selected data send port
                        if (param_flac.mic_enable != 0) {
                            //printf("*************** flac mic enable\n");
                            param_port |= SEND_PORT_A_FLAC;
                        }
                        if (param_flac.sep_enable != 0) {
                            //printf("*************** flac sep enable\n");
                            param_port |= SEND_PORT_F_FLAC;
                        }
                        HARKAndroid::HARKControl->SetParamSendPort(param_port); // int port
                        HARKAndroid::HARKControl->SetParamUseTimeStampPort(param_use_time_stamp_port); // int port
                        if((param_localize_algorithm == LOC_MUSIC_FILTER) || (param_localize_algorithm == LOC_NMUSIC_FILTER))
                        {
                            param_use_source_filter_port = param_port | SRC_FILTER_USE; // test
                        }
                        HARKAndroid::HARKControl->SetParamUseSourceFilterPort(param_use_source_filter_port); // int port
                
                        // Set save formats
                        HARKAndroid::HARKControl->SetParamSaveMicRawType(param_save_mic_pcm_format); // int raw_format
                        HARKAndroid::HARKControl->SetParamSaveMicSpecType(param_save_mic_spec); // int spec_type [0(disable), 1(enable)]
                        HARKAndroid::HARKControl->SetParamSaveLocalizePowerSpecType(param_save_localize_power_spec); // int [0(disable), 1(enable)]
                        HARKAndroid::HARKControl->SetParamSaveSepRawType(param_save_sep_pcm_format); // int raw_format
                        HARKAndroid::HARKControl->SetParamSaveSepSpecType(param_save_sep_spec); // int spec_type [0(disable), 1(enable)]
                        HARKAndroid::HARKControl->SetParamSaveSepFeatureType(param_save_sep_feature_type, param_save_sep_feature_format); // int feature_type, feature_format [always FEATURE_USER now]
                        HARKAndroid::HARKControl->SetParamSaveSourceType(param_save_source); // int source_type [0(disable), 1(enable)]
                        //
                        HARKAndroid::HARKControl->SetAudioParam(param_ch, param_advance); // int ch, int advance
                        // Set hostname
                        HARKAndroid::HARKControl->set_SocketMic(device_is_socket, param_mic_hostname); //const char* hostname
                        HARKAndroid::HARKControl->set_jiliusMFThostname(param_julius_hostname); //const char* hostname
                        // Set parameter of LocalizeMUSIC
                        //HARKAndroid::HARKControl->setParam(param_localize_music);
                        HARKAndroid::HARKControl->SetLocalizeMusicParamDeg(param_localize_music.min_deg, param_localize_music.max_deg);
                        HARKAndroid::HARKControl->SetLocalizeMusicParamFilePath(param_loc_tf_filename); //const char* filename
                        HARKAndroid::HARKControl->SetLocalizeMusicParamFrequency(param_localize_music.low_bound_frequency, param_localize_music.upper_bound_frequency);
                        HARKAndroid::HARKControl->SetLocalizeMusicParamNumSource(param_localize_music.num_source);
                        HARKAndroid::HARKControl->SetLocalizeMusicParamPeriod(param_localize_music.period);
                        // Set parameter of SourceTracker
                        //HARKAndroid::HARKControl->setParam(param_source_tracker);
                        HARKAndroid::HARKControl->SetSourceTrackerParamMinSrcInterval(param_source_tracker.min_src_interval);
                        HARKAndroid::HARKControl->SetSourceTrackerParamPauseLength(param_source_tracker.pause_length);
                        HARKAndroid::HARKControl->SetSourceTrackerParamThresh(param_source_tracker.thresh);
                        // Set parameter of SourceIntervalExtender
                        ////HARKAndroid::HARKControl->SetParam(param_source_interval_extender);
                        HARKAndroid::HARKControl->SetSourceIntervalExtenderParam(param_source_interval_extender.preroll_length);
                        // Set parameter of GHDSS
                        ////HARKAndroid::HARKControl->setParam(param_ghdss);
                        HARKAndroid::HARKControl->SetGhdssParamFilePath(param_sep_tf_filename); //const char* filename
                        // Set parameter of EstimateLeak
                        //HARKAndroid::HARKControl->setParam(param_estimate_leak);
                        HARKAndroid::HARKControl->SetEstimateLeakParamFactor(param_estimate_leak.leak_factor); //float factor
                        // Set parameter of HRLE
                        //HARKAndroid::HARKControl->setParam(param_hrle);
                        HARKAndroid::HARKControl->SetHrleParamLx(param_hrle.lx);
                        HARKAndroid::HARKControl->SetHrleParamTr(param_hrle.tr);
                        HARKAndroid::HARKControl->SetHrleParamMinLv(param_hrle.min_lv);
                        HARKAndroid::HARKControl->SetHrleParamNumBin(param_hrle.num_bin);
                        HARKAndroid::HARKControl->SetHrleParamStepLv(param_hrle.step_lv);
                        // Set parameter of WhiteNoiseAddr
                        //HARKAndroid::HARKControl->setParam(param_white_noise_adder);
                        HARKAndroid::HARKControl->SetWhiteNoiseAdderParamLevel(param_white_noise_adder.wn_level);
                        // Set parameter of PreEmphasis
                        //HARKAndroid::HARKControl->setParam(param_pre_emphasis);
                        HARKAndroid::HARKControl->SetPreEmphasisParamCutoff(param_pre_emphasis.cutoff);
                        HARKAndroid::HARKControl->SetPreEmphasisParamCoef(param_pre_emphasis.preem_coef);
                        // Set parameter of MelFilterBank
                        //HARKAndroid::HARKControl->setParam(param_mel_filter_bank);
                        HARKAndroid::HARKControl->SetMelFilterParamCutoff(param_mel_filter_bank.cutoff);
                        HARKAndroid::HARKControl->SetMelFilterParamFreq(param_mel_filter_bank.min_frequency, param_mel_filter_bank.max_frequency);
                        
                        HARKAndroid::HARKControl->SetParamMicChannelOffset(param_mic_channel_offset);
                        HARKAndroid::HARKControl->SetParamBypassOutE(PF_bypass_oute);

                        // Bluetooth

                        //printf("************************ setting bt\n");
                        //printf("************************ %d %d %d\n", param_bluetooth.mic_enable, param_bluetooth.min_deg, param_bluetooth.max_deg);
                        //printf("************************ %d %d %d\n", PF_bluetooth.mic_enable, PF_bluetooth.min_deg, PF_bluetooth.max_deg);

                        HARKAndroid::HARKControl->SetBluetoothParamMicEnable(param_bluetooth.mic_enable);
                        HARKAndroid::HARKControl->SetBluetoothParamMinDeg(param_bluetooth.min_deg);
                        HARKAndroid::HARKControl->SetBluetoothParamMaxDeg(param_bluetooth.max_deg);

                        // FLAC

                        HARKAndroid::HARKControl->SetFlacParamBlocksize(param_flac.blocksize);

                        HARKAndroid::HARKControl->SetFlacParamMicMaxLpcOrder(param_flac.mic_max_lpc_order);
                        HARKAndroid::HARKControl->SetFlacParamMicRicePartitionOrder(param_flac.mic_rice_partition_order);

                        HARKAndroid::HARKControl->SetFlacParamSepHostname(param_flac.sep_hostname);
                        HARKAndroid::HARKControl->SetFlacParamSepMaxLpcOrder(param_flac.sep_max_lpc_order);
                        HARKAndroid::HARKControl->SetFlacParamSepRicePartitionOrder(param_flac.sep_rice_partition_order);
                        
                    }
                    
                    ret = HARKAndroid::HARKControl->Start();
                }
                else if((cmd_ptr = strstr(sock_buffer, "--stop")) != NULL)
                {
                    printf("stop.\n");
                    sprintf(sock_buffer, "stop OK.");
                    
                    ret = HARKAndroid::HARKControl->Stop();
                }
                else if((cmd_ptr = strstr(sock_buffer, "--exit")) != NULL)
                {
                    connect_end = 0x1;
                    run_flag    = 0x0;
                    sprintf(sock_buffer, "exit OK.");
                    
                    ret = HARKAndroid::HARKControl->Stop();
                }
                else if((cmd_ptr = strstr(sock_buffer, "--SET")) != NULL)
                {
                    /* --SET以降の文字列からパラメータを取得する */
                    cmd_ptr += 5;
                    
                    ret = ParamFileReadSub(cmd_ptr);
                    if(ret == 0)
                    {
                        strcat(sock_buffer, "  : OK");
                        update_param = 1;
                    }
                    else
                    {
                        strcat(sock_buffer, "  : Error");
                    }
                }
                else if((cmd_ptr = strstr(sock_buffer, "--GET")) != NULL)
                {
                    sprintf(sock_buffer, "--GET no support");
                }
                else
                {
                    sprintf(sock_buffer, "????");
                }
                
                if(!stanby_mode)
                {
                    connect_end = 0x1;
                }
                else
                {
                    /* ステータスを返信 */
                    write_size = write(socket_fd, sock_buffer, strlen(sock_buffer)+1);
            
                    /* 他方がソケットをCloseしたか判定 */
                    if(write_size <= 0)
                    {
                        /* サーバー終了フラグ設定 */
                        connect_end = 0x1;
                    }
                }
                
            }while(connect_end == 0x0); /* End of do{}while */
            
            if(stanby_mode)
            {
                /* 通信の終了処理 */
                close(socket_fd);
            }
            
            stanby_mode = 0x1;
            
        }
    }
    close(main_server_socket_fd);

    return 0;
}

