Ejemplo n.º 1
0
void
pseudo_tcp_channel_free(PseudoTcpChannel *tcp) {
	signal_free(tcp->on_connected);
	signal_free(tcp->on_data_received);

	// TODO: how to free pseudo_tcp?

	free(tcp);
}
Ejemplo n.º 2
0
void
config_free (struct config *config)
{
    struct mbox *mbox = config->mailboxes, *mbox_o;
    while (mbox) {
	mbox_o = mbox;
	mbox = mbox->next;
	mbox_free (mbox_o);
    }
    struct signal *signal = config->signals, *signal_o;
    while (signal) {
	signal_o = signal;
	signal = signal->next;
	signal_free (signal_o);
    }
    free (config_filename);
    config_filename = NULL;
    free (config);
}
Ejemplo n.º 3
0
void PICLANG_next()
{
  picos_size_t command;
  picos_size_t a,b,c;// parameters, can be shared
  picos_signed_t siga;// a, but signed.
  signed char sch1;// signed char parameters
  char ch1;// char parameter
  static bit flag1;

  extern char ARG_buffer[ARG_SIZE];

  if(curr_process.page_size == 0)
    return;
  
  if(picos_processes[picos_curr_process].expires == 0)
    {
      if((curr_process.bitmap & PICLANG_BLOCKING_CALL) == 0 || PICLANG_debug == true)// Check for blocking call
	{
	  PICLANG_save(PICLANG_SUSPENDED);
	  return;
	}
    }
  
  if(picos_processes[picos_curr_process].signal_sent != PICOS_NUM_SIGNALS)
    {
      if(signal_valid_id(picos_processes[picos_curr_process].signal_sent) == false)
	{
	  PICLANG_exception(THREAD_INVALID_SIGNAL);
	  return;
	}
      curr_process.pc = signals[picos_processes[picos_curr_process].signal_sent].sig_action_addr;
      signal_free(picos_processes[picos_curr_process].signal_sent);
      picos_processes[picos_curr_process].signal_sent = PICOS_NUM_SIGNALS;
    }

  command = PICLANG_get_next_word();
  if(curr_process.status != PICLANG_SUCCESS)
    return;

  if(PICLANG_debug == true)
    PICLANG_debug_out(command);


  switch(command)
    {
    case PICLANG_UMINUS:
      {
	picos_signed_t inv = (picos_signed_t)PICLANG_pop();
	PICLANG_pushl(-inv);
	break;
      }
    case PICLANG_ADD:
      PICLANG_pushl(PICLANG_pop() + PICLANG_pop());
      PICLANG_update_arith_status();
      break;
    case PICLANG_MOD:case PICLANG_DIV:
      {
	// a/b --> c rem a
	b = PICLANG_pop();
	a = PICLANG_pop();
	c = 0;
	while(a >= b)
	  {
	    a -= b;
	    c++;
	  }
	if(command == PICLANG_MOD)
	  PICLANG_pushl(a);
	else
	  PICLANG_pushl(c);
	PICLANG_update_arith_status();
	break;
      }
    case PICLANG_SUB:
      {
	b = PICLANG_pop();
	a = PICLANG_pop();
	PICLANG_pushl(a - b);
	PICLANG_update_arith_status();
	break;
      }
    case PICLANG_MULT:
      a = PICLANG_pop();
      b = PICLANG_pop();
      c = a*b;
      PICLANG_pushl(c);
      PICLANG_update_arith_status();
      break;
    case PICLANG_PUSHL:
      a = PICLANG_get_next_word();
      PICLANG_pushl(a);
      break;
    case PICLANG_PUSH:
      {
	a = PICLANG_get_next_word();
	b = PAGE_get(a,picos_curr_process);
	if(error_code != SUCCESS)
	  PICLANG_exception(error_code);
	else
	  PICLANG_pushl(b);
	break;
      }
    case PICLANG_DROP:
      PICLANG_pop();
      break;
    case PICLANG_SWAP:
      a = PICLANG_pop();
      b = PICLANG_pop();
      PICLANG_pushl(a);
      PICLANG_pushl(b);
      break;
    case PICLANG_POP:
      {
	a = PICLANG_get_next_word();
	b = PICLANG_pop();
	PAGE_set(a,b,picos_curr_process);
	break;
      }
    case PICLANG_ARGC:
      PICLANG_pushl(picos_processes[picos_curr_process].nargs);
      break;
    case PICLANG_ARGV:
      {
	a = PICLANG_pop();
	sch1 = ARG_get(a);
	if(sch1 < 0)
	  {
	    PICLANG_exception(PICLANG_INVALID_PARAMETER);
	    break;
	  }
	b = (picos_size_t)sch1;
	PICLANG_pushl(b);
	break;
      }
    case PICLANG_PRINT:
      {
	a = PICLANG_pop();
	putch(a);
	IO_flush();
	break;
      }
    case PICLANG_DEREF:
      {
	a = PICLANG_pop();// array index
	b = PICLANG_pop();// array starting address
	PICLANG_next_dereference(b+a,command);
	break;
      }
    case PICLANG_BSL: case PICLANG_BSR:// bit shifts
      {
	a /*shift_amount*/ = PICLANG_pop();
	b /*val*/ = PICLANG_pop();
	if(command == PICLANG_BSL)
	  b <<= a;
	else
	  b >>= a;
	PICLANG_pushl(b);
	PICLANG_update_arith_status();
	break;
      }
    case PICLANG_FPUTD:
      {
	char hex_val[PICOS_SIZE_T_DECIMAL_DIGITS];//ch1 = index
	dec_to_word(hex_val,PICLANG_pop());
	ch1 = 0;
	flag1 = false;
	for(;ch1 < 5;ch1++)
	  {
	    if(flag1 == true || hex_val[ch1] != 0x30)
	      {
		SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER+PICLANG_file_buffer_index++,&hex_val[ch1],sizeof(char));
		flag1 = true;
	      }
	    if(PICLANG_file_buffer_index >= FS_BUFFER_SIZE)
	      {
		picfs_dump(picos_processes[picos_curr_process].program_file);
		SRAM_write(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE);
		memset((char*)picfs_buffer,0,FS_BUFFER_SIZE);
		SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE);
		SRAM_read(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE);
		PICLANG_file_buffer_index = 0;
	      }
	  }
	if(flag1 == false)
	  {
	    ch1 = '0';
	    SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER+PICLANG_file_buffer_index++,&ch1,sizeof(char));
	    if(PICLANG_file_buffer_index >= FS_BUFFER_SIZE)
	      {
		picfs_dump(picos_processes[picos_curr_process].program_file);
		SRAM_write(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE);
		memset((char*)picfs_buffer,0,FS_BUFFER_SIZE);
		SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE);
		SRAM_read(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE);
		PICLANG_file_buffer_index = 0;
	      }
	  }
	break;
      }
    case PICLANG_PWDIR:
      PICLANG_pushl(curr_dir);
      break;
    case PICLANG_MOUNT:
      a = PICLANG_pop();// device
      b = PICLANG_pop();// address of first byte
      if(picfs_mount((picos_addr_t)b,(picos_dev_t)a) != SUCCESS)
	curr_process.status = error_code;
      break;
    case PICLANG_CHDIR:
      {
	a = PICLANG_pop();
	picfs_chdir(a);
	break;
      }
    case PICLANG_MOVE:
      a = PICLANG_pop();// y
      b = PICLANG_pop();// x
      IO_move(a,b);
      break;
    case PICLANG_GETY: case PICLANG_GETX:
      IO_getxy(&a,&b);
      if(command == PICLANG_GETX)
	PICLANG_pushl(a);
      else
	PICLANG_pushl(b);
      break;
    case PICLANG_FPUTCH:// KEEP FPUTCH before FFLUSH
      {
	ch1 = (char)PICLANG_pop();
	SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER+PICLANG_file_buffer_index++,&ch1,sizeof(char));
	if(PICLANG_file_buffer_index < FS_BUFFER_SIZE)
	  break;
      }
    case PICLANG_FFLUSH:// KEEP FPUTCH before FFLUSH  KEEP FFLUSH before FCLEAR
      picfs_dump(picos_processes[picos_curr_process].program_file);
    case PICLANG_FCLEAR:// KEEP FFLUSH before FCLEAR
      SRAM_write(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE);
      memset((char*)picfs_buffer,0,FS_BUFFER_SIZE);
      SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE);
      SRAM_read(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE);
      PICLANG_file_buffer_index = 0;
      break;
    case PICLANG_FSTAT:
      a = PICLANG_pop();
      sch1 = picfs_stat(a);
      if(sch1 < 0)
	{
	  PICLANG_set_errno();
	  sch1 = 0;
	}
      a = picfs_buffer[ST_SIZE] << 8;
      a += picfs_buffer[ST_SIZE+1];
      PICLANG_pushl(a);
      break;
    case PICLANG_READDIR:
      a = PICLANG_pop();
      sch1 = picfs_readdir(1,a);
      if(sch1 != SUCCESS)
	PICLANG_set_errno();
      PICLANG_pushl(sch1);
      break;
    case PICLANG_FOPEN:
      {
	/*	mount_t mount;
		SRAM_read(curr_dir*sizeof(mount_t)+SRAM_MTAB_ADDR,&mount,sizeof(mount_t));*/
	a = PICLANG_pop();
	if(a < ARG_SIZE)
	  {
	    sch1 = picfs_open(ARG_buffer+a,curr_dir);
	  }
	else if(a < ARG_SIZE + FS_BUFFER_SIZE)
	  {
	    a -= ARG_SIZE;
	    sch1 = picfs_open((const char*)picfs_buffer+a,curr_dir);
	  }
	else
	  {
	    c = 0;
	    a -= ARG_SIZE + picos_processes[picos_curr_process].block_size;
	    sch1 = PICLANG_next_dereference(a,command);
	  }
	if(sch1 == -1)
	  PICLANG_set_errno();
	PICLANG_pushl(sch1);
	break;
      }
    case PICLANG_FCLOSE:
      a = PICLANG_pop();
      picfs_close(a);
      break;
    case PICLANG_FREAD:
      a = PICLANG_pop();
      sch1 = picfs_load(a);
      b = sch1;
      if(sch1 < 0)
	{
	  b = -1;
	  error_code = SUCCESS;
	  PICLANG_exception(error_code);
	}
      PICLANG_pushl(b);
      break;
    case PICLANG_PRINTL:
      IO_putd(PICLANG_pop());
      IO_flush();
      break;
    case PICLANG_CLEAR:
      clear_output();
      break;
    case PICLANG_MUTEX_LOCK:
      PICLANG_block();
      break;
    case PICLANG_MUTEX_UNLOCK:
      PICLANG_unblock();
      break;
    case PICLANG_GETCH:
      {
	PICLANG_block();
	PICLANG_pushl(getch());
	PICLANG_unblock();
	break;
      }
    case PICLANG_GETD:
      {
	PICLANG_block();
	ch1 = getch();
	PICLANG_unblock();
	if(ch1 < '0' || ch1 > '9')
	  {
	    PICLANG_exception(ARG_INVALID);
	    break;
	  }
	ch1 -= 0x30;
	PICLANG_pushl(ch1);
	break;
      }
    case PICLANG_SPRINT:case PICLANG_SPRINTN:
      {
	// string addresses start with arguments then const strings in executable
	/*string_pointer*/a = PICLANG_pop();
	PICLANG_next_dereference(a,command);
	IO_flush();
	break;
      }
    case PICLANG_LSOF:
      IO_puts("Implement lsof");
      break;
    case PICLANG_LSMOUNT:
      lsmount();
      break;
    case PICLANG_ERRNO:
      PICLANG_pushl(PICLANG_get_errno());
      break;
    case PICLANG_KVERSION:
      a = PICLANG_pop();
      if(a > 3)
      {
          PICLANG_exception(PICFS_EINVAL);
          break;
      }
      if(a == 0)
          b = KERNEL_MAJOR_VERSION;
      else if(a == 1)
          b = KERNEL_MINOR_VERSION;
      else if(a == 2)
          b = KERNEL_REVISION;
      else
          b = KERNEL_ID_TAG;
      PICLANG_pushl(b);
      break;
    case PICLANG_SIGNAL:
      a = PICLANG_get_next_word();// signal id
      b = PICLANG_get_next_word();// signal action
      if(a == PICOS_NUM_SIGNALS)
	{
	  signal_free(b);
	  break;
	}
      sch1 = signal_assign(a,picos_curr_process,b);
      if(sch1 != 0)
	PICLANG_exception(error_code);
      break;
    case PICLANG_SLEEP:
      a = PICLANG_pop();
      ch1 = picos_curr_process;
      PICLANG_save(PICLANG_SUSPENDED);
      picos_processes[ch1].expires = (quantum_t)a;
      break;
    case PICLANG_MORSE:
      {
	char two[2];
	/*addr*/a = PICLANG_pop();
	two[1] = PICLANG_pop();//char or string?
	if(two[1] == PICLANG_MORSE_STRING)
	  SRAM_read(a++,two,1);
	else
	  {
	    two[0] = (char)a;
	    two[1] = 0;
	    morse_sound(two);
	    break;
	  }
	two[1] = 0;
	while(two[0] != 0)
	  {
	    morse_sound(two);
	    SRAM_read(a++,two,1);
	  }
	break;
      }
    case PICLANG_TIME:
      {
	const TIME_t *thetime = TIME_get();
	ch1 = PICLANG_pop();
	switch(ch1)
	  {
	  case 'Y':
	    PICLANG_pushl(thetime->year);
	    break;
	  case 'm':
	    PICLANG_pushl(thetime->month);
	    break;
	  case 'd':
	    PICLANG_pushl(thetime->day);
	    break;
	  case 'H':
	    PICLANG_pushl(thetime->hours);
	    break;
	  case 'M':
	    PICLANG_pushl(thetime->minutes);
	    break;
	  case 'S':
	    PICLANG_pushl(thetime->seconds);
	    break;
	  default:
	    PICLANG_exception(PICLANG_INVALID_PARAMETER);
	    break;
	  }
	break;
      }
    case PICLANG_SET_TIME:case PICLANG_SET_DATE:
      {
	TIME_t newtime = *(TIME_get());
	if(command == PICLANG_SET_TIME)
	  {
	    newtime.minutes = PICLANG_pop();
	    newtime.hours = PICLANG_pop();
	    if(newtime.minutes > 59 || newtime.hours > 23)
	      {
		newtime.minutes = newtime.hours = 0;
		PICLANG_exception(TIME_INVALID);
	      }
	  }
	else
	  {
	    newtime.year = PICLANG_pop();
	    newtime.day = PICLANG_pop();
	    newtime.month = PICLANG_pop();
	    if(newtime.month > 12 || newtime.day > 31)
	      {
		newtime.month = newtime.day = 0;
		PICLANG_exception(TIME_INVALID);
	      }
	  }
	TIME_set(&newtime);
	break;
      }
    case PICLANG_JZ:case PICLANG_JMP:case PICLANG_CALL:
      {
	b = curr_process.pc;
	a = PICLANG_get_next_word();
	if(curr_process.status != PICLANG_SUCCESS)
	  {
	    curr_process.pc = b;
	    break;
	  }
	if(command == PICLANG_CALL)
	  {
	    PICLANG_call_push(curr_process.pc);
	    curr_process.pc = a;
	  }
	else if(command == PICLANG_JMP)
	  curr_process.pc = a;
	else if((curr_process.bitmap & PICLANG_ZERO) == 0)
	  curr_process.pc = a;
	if(curr_process.status != PICLANG_SUCCESS)
	  {
	    curr_process.pc = b;
	    break;
	  }
	break;
      }
    case PICLANG_RETURN:
      {
	b = curr_process.pc;
	curr_process.pc = PICLANG_call_pop();
	if(curr_process.status != PICLANG_SUCCESS)
	  {
	    curr_process.pc = b;
	    break;
	  }
	break;
      }
    case PICLANG_EXIT:
      PICLANG_save(PICLANG_pop());
      break;
    case PICLANG_LABEL:
      break;
    case PICLANG_COMPLT:
      {
	b = PICLANG_pop();
	a = PICLANG_pop();
	if(a < b)
	  curr_process.bitmap |= PICLANG_ZERO;
	else
	  curr_process.bitmap &= ~PICLANG_ZERO;
	break;
      }
    case PICLANG_COMPGT:
      {
	b = PICLANG_pop();
	a = PICLANG_pop();
	if(a > b)
	  curr_process.bitmap |= PICLANG_ZERO;
	else
	  curr_process.bitmap &= ~PICLANG_ZERO;
	break;
      }
    case PICLANG_COMPEQ:case PICLANG_COMPNE:
      {
	b = PICLANG_pop();
	a = PICLANG_pop();
	if(a == b)
	  curr_process.bitmap |= PICLANG_ZERO;
	else
	  curr_process.bitmap &= ~PICLANG_ZERO;
	if(command == PICLANG_COMPNE)
	  curr_process.bitmap ^= PICLANG_ZERO;
	break;
      }
    case PICLANG_AND:
      a = PICLANG_pop();
      b = PICLANG_pop();
      PICLANG_pushl(a & b);
      break;
    case PICLANG_OR:
      a = PICLANG_pop();
      b = PICLANG_pop();
      PICLANG_pushl(a | b);
      break;
    case PICLANG_NOT:
      a = PICLANG_pop();
      PICLANG_pushl(~a);
      break;
    case PICLANG_RAWLOAD:
      SRAM_read(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE);
      break;
    case PICLANG_NUM_COMMANDS:default:
      PICLANG_exception(PICLANG_UNKNOWN_COMMAND);
      break;
    }

}
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{
    int f;
    int i;
    int16_t amp[8000];
    int16_t value;
    int signal;
    float power[10];
    tone_gen_descriptor_t tone_desc;
    tone_gen_state_t tone_state;
    awgn_state_t noise_source;
    fir32_state_t line_model_d2;
    fir32_state_t line_model_d3;
    fir32_state_t line_model_d4;
    fir32_state_t line_model_d5;
    fir32_state_t line_model_d6;
    fir32_state_t line_model_d7;
    fir32_state_t line_model_d8;
    fir32_state_t line_model_d9;
    fir_float_state_t level_measurement_bp;

    signal_load(&local_css, "sound_c1_8k.wav");
    signal_load(&far_css, "sound_c3_8k.wav");

    fir32_create(&line_model_d2,
                 line_model_d2_coeffs,
                 sizeof(line_model_d2_coeffs)/sizeof(int32_t));
    fir32_create(&line_model_d3,
                 line_model_d3_coeffs,
                 sizeof(line_model_d3_coeffs)/sizeof(int32_t));
    fir32_create(&line_model_d4,
                 line_model_d4_coeffs,
                 sizeof(line_model_d4_coeffs)/sizeof(int32_t));
    fir32_create(&line_model_d5,
                 line_model_d5_coeffs,
                 sizeof(line_model_d5_coeffs)/sizeof(int32_t));
    fir32_create(&line_model_d6,
                 line_model_d6_coeffs,
                 sizeof(line_model_d6_coeffs)/sizeof(int32_t));
    fir32_create(&line_model_d7,
                 line_model_d7_coeffs,
                 sizeof(line_model_d7_coeffs)/sizeof(int32_t));
    fir32_create(&line_model_d8,
                 line_model_d8_coeffs,
                 sizeof(line_model_d8_coeffs)/sizeof(int32_t));
    fir32_create(&line_model_d9,
                 line_model_d9_coeffs,
                 sizeof(line_model_d9_coeffs)/sizeof(int32_t));
    fir_float_create(&level_measurement_bp,
                     level_measurement_bp_coeffs,
                     sizeof(level_measurement_bp_coeffs)/sizeof(float));

    for (f = 10;  f < 4000;  f++)
    {
         tone_gen_descriptor_init(&tone_desc,
                                  f,
                                  -10,
                                  0,
                                  0,
                                  1,
                                  0,
                                  0,
                                  0,
                                  true);
        tone_gen_init(&tone_state, &tone_desc);
        tone_gen(&tone_state, amp, 8000);
        for (i = 0;  i < 10;  i++)
            power[i] = 0.0f;
        for (i = 0;  i < 800;  i++)
        {
            signal = fir32(&line_model_d2, amp[i]);
            power[0] += ((signal*signal - power[0])/32.0f);
            signal = fir32(&line_model_d3, amp[i]);
            power[1] += ((signal*signal - power[1])/32.0f);
            signal = fir32(&line_model_d4, amp[i]);
            power[2] += ((signal*signal - power[2])/32.0f);
            signal = fir32(&line_model_d5, amp[i]);
            power[3] += ((signal*signal - power[3])/32.0f);
            signal = fir32(&line_model_d6, amp[i]);
            power[4] += ((signal*signal - power[4])/32.0f);
            signal = fir32(&line_model_d7, amp[i]);
            power[5] += ((signal*signal - power[5])/32.0f);
            signal = fir32(&line_model_d8, amp[i]);
            power[6] += ((signal*signal - power[6])/32.0f);
            signal = fir32(&line_model_d9, amp[i]);
            power[7] += ((signal*signal - power[7])/32.0f);
            signal = fir_float(&level_measurement_bp, amp[i]);
            power[8] += ((signal*signal - power[8])/32.0f);
            signal = amp[i];
            power[9] += ((signal*signal - power[9])/32.0f);
        }
        printf("%d %f %f %f %f %f %f %f %f %f %f\n",
               f,
               sqrt(power[0])*LINE_MODEL_D2_GAIN,
               sqrt(power[1])*LINE_MODEL_D3_GAIN,
               sqrt(power[2])*LINE_MODEL_D4_GAIN,
               sqrt(power[3])*LINE_MODEL_D5_GAIN,
               sqrt(power[4])*LINE_MODEL_D6_GAIN,
               sqrt(power[5])*LINE_MODEL_D7_GAIN,
               sqrt(power[6])*LINE_MODEL_D8_GAIN,
               sqrt(power[7])*LINE_MODEL_D9_GAIN,
               sqrt(power[8]),
               sqrt(power[9]));
    }
    awgn_init_dbm0(&noise_source, 1234567, -20.0f);
    for (i = 0;  i < 10;  i++)
        power[i] = 0.0f;
    signal_restart(&local_css, 0.0f);
    signal_restart(&far_css, 0.0f);
    for (i = 0;  i < SAMPLE_RATE;  i++)
    {
        value = signal_amp(&local_css);
        //value = awgn(&noise_source);
        signal = fir32(&line_model_d2, value);
        power[0] += ((signal*signal - power[0])/32.0f);
        signal = fir32(&line_model_d3, value);
        power[1] += ((signal*signal - power[1])/32.0f);
        signal = fir32(&line_model_d4, value);
        power[2] += ((signal*signal - power[2])/32.0f);
        signal = fir32(&line_model_d5, value);
        power[3] += ((signal*signal - power[3])/32.0f);
        signal = fir32(&line_model_d6, value);
        power[4] += ((signal*signal - power[4])/32.0f);
        signal = fir32(&line_model_d7, value);
        power[5] += ((signal*signal - power[5])/32.0f);
        signal = fir32(&line_model_d8, value);
        power[6] += ((signal*signal - power[6])/32.0f);
        signal = fir32(&line_model_d9, value);
        power[7] += ((signal*signal - power[7])/32.0f);
        signal = fir_float(&level_measurement_bp, value);
        power[8] += ((signal*signal - power[8])/32.0f);
        signal = value;
        power[9] += ((signal*signal - power[9])/32.0f);
    }
    for (i = 0;  i < 10;  i++)
        power[i] = 0.0f;
    for (i = 0;  i < SAMPLE_RATE;  i++)
    {
        value = signal_amp(&local_css);
        //value = awgn(&noise_source);
        signal = fir32(&line_model_d2, value);
        power[0] += ((signal*signal - power[0])/32.0f);
        signal = fir32(&line_model_d3, value);
        power[1] += ((signal*signal - power[1])/32.0f);
        signal = fir32(&line_model_d4, value);
        power[2] += ((signal*signal - power[2])/32.0f);
        signal = fir32(&line_model_d5, value);
        power[3] += ((signal*signal - power[3])/32.0f);
        signal = fir32(&line_model_d6, value);
        power[4] += ((signal*signal - power[4])/32.0f);
        signal = fir32(&line_model_d7, value);
        power[5] += ((signal*signal - power[5])/32.0f);
        signal = fir32(&line_model_d8, value);
        power[6] += ((signal*signal - power[6])/32.0f);
        signal = fir32(&line_model_d9, value);
        power[7] += ((signal*signal - power[7])/32.0f);
        signal = fir_float(&level_measurement_bp, value);
        power[8] += ((signal*signal - power[8])/32.0f);
        signal = value;
        power[9] += ((signal*signal - power[9])/32.0f);
    }
    printf("%d %f %f %f %f %f %f %f %f %f %f\n",
           0,
           sqrt(power[0])*LINE_MODEL_D2_GAIN,
           sqrt(power[1])*LINE_MODEL_D3_GAIN,
           sqrt(power[2])*LINE_MODEL_D4_GAIN,
           sqrt(power[3])*LINE_MODEL_D5_GAIN,
           sqrt(power[4])*LINE_MODEL_D6_GAIN,
           sqrt(power[5])*LINE_MODEL_D7_GAIN,
           sqrt(power[6])*LINE_MODEL_D8_GAIN,
           sqrt(power[7])*LINE_MODEL_D9_GAIN,
           sqrt(power[8]),
           sqrt(power[9]));
    printf("%d %f %f %f %f %f %f %f %f %f %f\n",
           0,
           sqrt(power[0]),
           sqrt(power[1]),
           sqrt(power[2]),
           sqrt(power[3]),
           sqrt(power[4]),
           sqrt(power[5]),
           sqrt(power[6]),
           sqrt(power[7]),
           sqrt(power[8]),
           sqrt(power[9]));
    printf("%d %f %f %f %f %f %f %f %f %f %f\n",
           0,
           sqrt(power[0])/sqrt(power[9]),
           sqrt(power[1])/sqrt(power[9]),
           sqrt(power[2])/sqrt(power[9]),
           sqrt(power[3])/sqrt(power[9]),
           sqrt(power[4])/sqrt(power[9]),
           sqrt(power[5])/sqrt(power[9]),
           sqrt(power[6])/sqrt(power[9]),
           sqrt(power[7])/sqrt(power[9]),
           sqrt(power[8]),
           sqrt(power[9]));
    printf("%d %f %f %f %f %f %f %f %f %f %f\n",
           0,
           sqrt(power[0])*LINE_MODEL_D2_GAIN/sqrt(power[9]),
           sqrt(power[1])*LINE_MODEL_D3_GAIN/sqrt(power[9]),
           sqrt(power[2])*LINE_MODEL_D4_GAIN/sqrt(power[9]),
           sqrt(power[3])*LINE_MODEL_D5_GAIN/sqrt(power[9]),
           sqrt(power[4])*LINE_MODEL_D6_GAIN/sqrt(power[9]),
           sqrt(power[5])*LINE_MODEL_D7_GAIN/sqrt(power[9]),
           sqrt(power[6])*LINE_MODEL_D8_GAIN/sqrt(power[9]),
           sqrt(power[7])*LINE_MODEL_D9_GAIN/sqrt(power[9]),
           sqrt(power[8]),
           sqrt(power[9]));

    for (i = 0;  i < (int) (sizeof(css_c1)/sizeof(css_c1[0]));  i++)
        printf("%d\n", css_c1[i]);
    printf("\n");
    for (i = 0;  i < (int) (sizeof(css_c1)/sizeof(css_c3[0]));  i++)
        printf("%d\n", css_c3[i]);
    signal_free(&local_css);
    signal_free(&far_css);
    fir32_free(&line_model_d2);
    fir32_free(&line_model_d3);
    fir32_free(&line_model_d4);
    fir32_free(&line_model_d5);
    fir32_free(&line_model_d6);
    fir32_free(&line_model_d7);
    fir32_free(&line_model_d8);
    fir32_free(&line_model_d9);
    fir_float_free(&level_measurement_bp);
    return 0;
}
Ejemplo n.º 5
0
static void
signal_monitor_generic_handler (SignalMonitor *m,
                                SignalName     signal,
                                GtkTreeModel  *model,
                                GtkTreeIter   *iter,
                                GtkTreePath   *path,
                                int           *new_order)
{
  Signal *s;

  if (g_queue_is_empty (m->queue))
    {
      gchar *path_str;

      path_str = gtk_tree_path_to_string (path);
      g_error ("Signal queue empty, got signal %s path %s",
               signal_name_to_string (signal), path_str);
      g_free (path_str);

      g_assert_not_reached ();
    }

  if (m->client != model)
    {
      g_error ("Model mismatch; expected %p, got %p",
               m->client, model);
      g_assert_not_reached ();
    }

  s = g_queue_peek_tail (m->queue);

#if 0
  /* For debugging: output signals that are coming in.  Leaks memory. */
  g_print ("signal=%s path=%s\n", signal_name_to_string (signal),
           gtk_tree_path_to_string (path));
#endif

  if (s->signal != signal ||
      (gtk_tree_path_get_depth (s->path) == 0 &&
       gtk_tree_path_get_depth (path) != 0) ||
      (gtk_tree_path_get_depth (s->path) != 0 &&
       gtk_tree_path_compare (s->path, path) != 0))
    {
      gchar *path_str, *s_path_str;

      s_path_str = gtk_tree_path_to_string (s->path);
      path_str = gtk_tree_path_to_string (path);

      g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s",
               signal_name_to_string (s->signal), s_path_str,
               signal_name_to_string (signal), path_str);

      g_free (s_path_str);
      g_free (path_str);

      g_assert_not_reached ();
    }

  if (signal == ROWS_REORDERED && s->new_order != NULL)
    {
      int i, len;

      g_assert (new_order != NULL);

      len = gtk_tree_model_iter_n_children (model, iter);
      g_assert (s->len == len);

      for (i = 0; i < len; i++)
        g_assert (s->new_order[i] == new_order[i]);
    }

  s = g_queue_pop_tail (m->queue);

  signal_free (s);
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
    echo_can_state_t *ctx;
    awgn_state_t local_noise_source;
    awgn_state_t far_noise_source;
    int i;
    int clean;
    int residue;
    int16_t rx;
    int16_t tx;
    int j;
    int k;
    tone_gen_descriptor_t tone_desc;
    tone_gen_state_t tone_state;
    int16_t local_sound[40000];
    int local_max;
    int local_cur;
    int16_t hoth_noise;
    //int16_t far_sound[SAMPLE_RATE];
    //int16_t result_sound[64000];
    //int32_t coeffs[200][128];
    //int coeff_index;
    int far_cur;
    int result_cur;
    //int far_tx;
    AFfilehandle resulthandle;
    AFfilesetup filesetup;
    AFfilesetup filesetup2;
    //int outframes;
    time_t now;
    int tone_burst_step;
    level_measurement_device_t *power_meter_1;
    level_measurement_device_t *power_meter_2;
    float pp1;
    float pp2;
    int model_number;
    int use_gui;

    power_meter_1 = NULL;
    power_meter_2 = NULL;
    /* Check which tests we should run */
    if (argc < 2)
        fprintf(stderr, "Usage: echo tests <list of test numbers>\n");
    test_list = 0;
    model_number = 0;
    use_gui = FALSE;
    for (i = 1;  i < argc;  i++)
    {
        if (strcasecmp(argv[i], "2a") == 0)
            test_list |= PERFORM_TEST_2A;
        else if (strcasecmp(argv[i], "2b") == 0)
            test_list |= PERFORM_TEST_2B;
        else if (strcasecmp(argv[i], "2c") == 0)
            test_list |= PERFORM_TEST_2C;
        else if (strcasecmp(argv[i], "3a") == 0)
            test_list |= PERFORM_TEST_3A;
        else if (strcasecmp(argv[i], "3b") == 0)
            test_list |= PERFORM_TEST_3B;
        else if (strcasecmp(argv[i], "3c") == 0)
            test_list |= PERFORM_TEST_3C;
        else if (strcasecmp(argv[i], "4") == 0)
            test_list |= PERFORM_TEST_4;
        else if (strcasecmp(argv[i], "5") == 0)
            test_list |= PERFORM_TEST_5;
        else if (strcasecmp(argv[i], "6") == 0)
            test_list |= PERFORM_TEST_6;
        else if (strcasecmp(argv[i], "7") == 0)
            test_list |= PERFORM_TEST_7;
        else if (strcasecmp(argv[i], "8") == 0)
            test_list |= PERFORM_TEST_8;
        else if (strcasecmp(argv[i], "9") == 0)
            test_list |= PERFORM_TEST_9;
        else if (strcasecmp(argv[i], "10a") == 0)
            test_list |= PERFORM_TEST_10A;
        else if (strcasecmp(argv[i], "10b") == 0)
            test_list |= PERFORM_TEST_10B;
        else if (strcasecmp(argv[i], "10c") == 0)
            test_list |= PERFORM_TEST_10C;
        else if (strcasecmp(argv[i], "11") == 0)
            test_list |= PERFORM_TEST_11;
        else if (strcasecmp(argv[i], "12") == 0)
            test_list |= PERFORM_TEST_12;
        else if (strcasecmp(argv[i], "13") == 0)
            test_list |= PERFORM_TEST_13;
        else if (strcasecmp(argv[i], "14") == 0)
            test_list |= PERFORM_TEST_14;
        else if (strcasecmp(argv[i], "15") == 0)
            test_list |= PERFORM_TEST_15;
        else if (strcmp(argv[i], "-m") == 0)
        {
            if (++i < argc)
                model_number = atoi(argv[i]);
        }
        else if (strcmp(argv[i], "-g") == 0)
        {
            use_gui = TRUE;
        }
        else
        {
            fprintf(stderr, "Unknown test '%s' specified\n", argv[i]);
            exit(2);
        }
    }
    if (test_list == 0)
    {
        fprintf(stderr, "No tests have been selected\n");
        exit(2);
    }
    time(&now);
    tone_burst_step = 0;
    ctx = echo_can_create(TEST_EC_TAPS, 0);
    awgn_init_dbm0(&far_noise_source, 7162534, -50.0f);

    signal_load(&local_css, "sound_c1_8k.wav");
    signal_load(&far_css, "sound_c3_8k.wav");

    filesetup = afNewFileSetup();
    if (filesetup == AF_NULL_FILESETUP)
    {
        fprintf(stderr, "    Failed to create file setup\n");
        exit(2);
    }
    afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
    afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
    afInitFileFormat(filesetup, AF_FILE_WAVE);
    afInitChannels(filesetup, AF_DEFAULT_TRACK, 6);

    filesetup2 = afNewFileSetup();
    if (filesetup2 == AF_NULL_FILESETUP)
    {
        fprintf(stderr, "    Failed to create file setup\n");
        exit(2);
    }
    afInitSampleFormat(filesetup2, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
    afInitRate(filesetup2, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
    afInitFileFormat(filesetup2, AF_FILE_WAVE);
    afInitChannels(filesetup2, AF_DEFAULT_TRACK, 1);

    resulthandle = afOpenFile("result_sound.wav", "w", filesetup);
    if (resulthandle == AF_NULL_FILEHANDLE)
    {
        fprintf(stderr, "    Failed to open result file\n");
        exit(2);
    }

    residuehandle = afOpenFile("residue_sound.wav", "w", filesetup2);
    if (residuehandle == AF_NULL_FILEHANDLE)
    {
        fprintf(stderr, "    Failed to open residue file\n");
        exit(2);
    }
    local_cur = 0;
    far_cur = 0;
    result_cur = 0;
    if (channel_model_create(model_number))
    {
        fprintf(stderr, "    Failed to create line model\n");
        exit(2);
    }
#if defined(ENABLE_GUI)
    if (use_gui)
    {
        start_echo_can_monitor(TEST_EC_TAPS);
        echo_can_monitor_line_model_update(line_model.coeffs, line_model.taps);
    }
#endif
    power_meter_1 = level_measurement_device_create(0);
    power_meter_2 = level_measurement_device_create(0);

    level_measurement_device(power_meter_1, 0);

#if 0
    echo_can_flush(ctx);
    /* Converge the canceller */
    signal_restart(&local_css);
    for (i = 0;  i < 800*2;  i++)
    {
        clean = echo_can_update(ctx, 0, 0);
        put_residue(clean);
    }
    for (i = 0;  i < SAMPLE_RATE*5;  i++)
    {
        tx = signal_amp(&local_css);
        channel_model(&tx, &rx, tx, 0);
        clean = echo_can_update(ctx, tx, rx);
        put_residue(clean);
    }
    echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CNG);
    for (i = 0;  i < SAMPLE_RATE*5;  i++)
    {
        tx = signal_amp(&local_css);
        channel_model(&tx, &rx, tx, 0);
        clean = echo_can_update(ctx, tx, rx);
        put_residue(clean);
    }
    echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
    
    for (i = 0;  i < SAMPLE_RATE*10;  i++)
    {
        tx = signal_amp(&local_css);
#if 0
        if ((i/10000)%10 == 9)
        {
            /* Inject a burst of far sound */
            if (far_cur >= far_max)
            {
                far_max = afReadFrames(farhandle, AF_DEFAULT_TRACK, far_sound, SAMPLE_RATE);
                if (far_max < 0)
                {
                    fprintf(stderr, "    Error reading far sound\n");
                    exit(2);
                }
                if (far_max == 0)
                    break;
                far_cur = 0;
            }
            far_tx = far_sound[far_cur++];
        }
        else
        {
            far_tx = 0;
        }
#else
        far_sound[0] = 0;
        far_tx = 0;
#endif
        channel_model(&tx, &rx, tx, far_tx);
        //rx += awgn(&far_noise_source);
        //tx += awgn(&far_noise_source);
        clean = echo_can_update(ctx, tx, rx);

#if defined(XYZZY)
        if (i%SAMPLE_RATE == 0)
        {
            if (coeff_index < 200)
            {
                for (j = 0;  j < ctx->taps;  j++)
                    coeffs[coeff_index][j] = ctx->fir_taps32[j];
                coeff_index++;
            }
        }
#endif
        result_sound[result_cur++] = tx;
        result_sound[result_cur++] = rx;
        result_sound[result_cur++] = clean - far_tx;
        //result_sound[result_cur++] = ctx->tx_power[2];
        //result_sound[result_cur++] = ctx->tx_power[1];
        result_sound[result_cur++] = (ctx->tx_power[1] > 64)  ?  SAMPLE_RATE  :  -SAMPLE_RATE;
        //result_sound[result_cur++] = ctx->tap_set*SAMPLE_RATE;
        //result_sound[result_cur++] = (ctx->nonupdate_dwell > 0)  ?  SAMPLE_RATE  :  -SAMPLE_RATE;
        //result_sound[result_cur++] = ctx->latest_correction >> 8;
        //result_sound[result_cur++] = level_measurement_device(tx)/(16.0*65536.0);
        //result_sound[result_cur++] = level_measurement_device(tx)/4096.0;
        result_sound[result_cur++] = (ctx->tx_power[1] > ctx->rx_power[0])  ?  SAMPLE_RATE  :  -SAMPLE_RATE;
        //result_sound[result_cur++] = (ctx->tx_power[1] > ctx->rx_power[0])  ?  SAMPLE_RATE  :  -SAMPLE_RATE;
        //result_sound[result_cur++] = (ctx->narrowband_score)*5; //  ?  SAMPLE_RATE  :  -SAMPLE_RATE;
        //result_sound[result_cur++] = ctx->tap_rotate_counter*10;
        result_sound[result_cur++] = ctx->vad;
        
        put_residue(clean - far_tx);
        if (result_cur >= 6*SAMPLE_RATE)
        {
            outframes = afWriteFrames(resulthandle,
                                      AF_DEFAULT_TRACK,
                                      result_sound,
                                      result_cur/6);
            if (outframes != result_cur/6)
            {
                fprintf(stderr, "    Error writing result sound\n");
                exit(2);
            }
            result_cur = 0;
        }
    }
    if (result_cur > 0)
    {
        outframes = afWriteFrames(resulthandle,
                                  AF_DEFAULT_TRACK,
                                  result_sound,
                                  result_cur/6);
        if (outframes != result_cur/4)
        {
            fprintf(stderr, "    Error writing result sound\n");
            exit(2);
        }
    }
#endif

    /* Test 1 - Steady state residual and returned echo level test */
    /* This functionality has been merged with test 2 in newer versions of G.168,
       so test 1 no longer exists. */

    /* Test 2 - Convergence and steady state residual and returned echo level test */
    if ((test_list & PERFORM_TEST_2A))
    {
        printf("Performing test 2A - Convergence with NLP enabled\n");
        /* Test 2A - Convergence with NLP enabled */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP);
        /* Converge the canceller */
        signal_restart(&local_css);
        for (i = 0;  i < 800*2;  i++)
        {
            clean = echo_can_update(ctx, 0, 0);
            put_residue(clean);
        }
        for (i = 0;  i < SAMPLE_RATE*50;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            pp1 = level_measurement_device(power_meter_1, rx);
            pp2 = level_measurement_device(power_meter_2, clean);
            residue = 100.0*pp1/pp2;
            put_residue(residue);
#if defined(ENABLE_GUI)
            if (use_gui)
                echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
        }
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_2B))
    {
        printf("Performing test 2B - Convergence with NLP disabled\n");
        /* Test 2B - Convergence with NLP disabled */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        /* Converge a canceller */
        signal_restart(&local_css);
        for (i = 0;  i < 800*2;  i++)
        {
            clean = echo_can_update(ctx, 0, 0);
            put_residue(clean);
        }
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
#if defined(ENABLE_GUI)
            if (use_gui)
                echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
        }
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_2C))
    {
        printf("Performing test 2C - Convergence with background noise present\n");
        /* Test 2C - Convergence with background noise present */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        /* Converge a canceller */
        signal_restart(&local_css);
        for (i = 0;  i < 800*2;  i++)
        {
            clean = echo_can_update(ctx, 0, 0);
            put_residue(clean);
        }
        /* TODO: This uses a crude approx. to Hoth noise. We need the real thing. */
        awgn_init_dbm0(&far_noise_source, 7162534, -40.0f);
        hoth_noise = 0;
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            hoth_noise = hoth_noise*0.625 + awgn(&far_noise_source)*0.375;
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, hoth_noise);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Now freeze adaption, and measure the echo. */
        echo_can_adaption_mode(ctx, 0);
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    /* Test 3 - Performance under double talk conditions */
    if ((test_list & PERFORM_TEST_3A))
    {
        printf("Performing test 3A - Double talk test with low cancelled-end levels\n");
        /* Test 3A - Double talk test with low cancelled-end levels */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        signal_restart(&local_css);
        signal_restart(&far_css);
        /* Apply double talk, with a weak far end signal */
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            rx = signal_amp(&far_css)/20;
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean - rx);
        }
        /* Now freeze adaption. */
        echo_can_adaption_mode(ctx, 0);
        for (i = 0;  i < 800*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Now measure the echo */
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_3B))
    {
        printf("Performing test 3B - Double talk test with high cancelled-end levels\n");
        /* Test 3B - Double talk test with high cancelled-end levels */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        signal_restart(&local_css);
        signal_restart(&far_css);
        /* Converge the canceller */
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Apply double talk */
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            rx = signal_amp(&far_css);
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean - rx);
        }
        /* Now freeze adaption. */
        echo_can_adaption_mode(ctx, 0);
        for (i = 0;  i < 800*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Now measure the echo */
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_3C))
    {
        printf("Performing test 3C - Double talk test with simulated conversation\n");
        /* Test 3C - Double talk test with simulated conversation */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        signal_restart(&local_css);
        signal_restart(&far_css);
        /* Apply double talk */
        for (i = 0;  i < 800*56;  i++)
        {
            tx = signal_amp(&local_css);
            rx = signal_amp(&far_css);
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean - rx);
        }
        /* Stop the far signal */
        for (i = 0;  i < 800*14;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Continue measuring the resulting echo */
        for (i = 0;  i < 800*50;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Reapply double talk */
        signal_restart(&far_css);
        for (i = 0;  i < 800*56;  i++)
        {
            tx = signal_amp(&local_css);
            rx = signal_amp(&far_css);
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean - rx);
        }
        /* Now the far signal only */
        for (i = 0;  i < 800*56;  i++)
        {
            tx = 0;
            rx = signal_amp(&far_css);
            channel_model(&tx, &rx, 0, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean - rx);
        }
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_4))
    {
        printf("Performing test 4 - Leak rate test\n");
        /* Test 4 - Leak rate test */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        /* Converge a canceller */
        signal_restart(&local_css);
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Put 2 minutes of silence through it */
        for (i = 0;  i < SAMPLE_RATE*120;  i++)
        {
            clean = echo_can_update(ctx, 0, 0);
            put_residue(clean);
        }
        /* Now freeze it, and check if it is still well adapted. */
        echo_can_adaption_mode(ctx, 0);
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_5))
    {
        printf("Performing test 5 - Infinite return loss convergence test\n");
        /* Test 5 - Infinite return loss convergence test */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        /* Converge the canceller */
        signal_restart(&local_css);
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Now stop echoing, and see we don't do anything unpleasant as the
           echo path is open looped. */
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            rx = 0;
            tx = codec_munge(tx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_6))
    {
        printf("Performing test 6 - Non-divergence on narrow-band signals\n");
        /* Test 6 - Non-divergence on narrow-band signals */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        /* Converge the canceller */
        signal_restart(&local_css);
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        /* Now put 5s bursts of a list of tones through the converged canceller, and check
           that bothing unpleasant happens. */
        for (k = 0;  tones_6_4_2_7[k][0];  k++)
        {
            make_tone_gen_descriptor(&tone_desc,
                                     tones_6_4_2_7[k][0],
                                     -11,
                                     tones_6_4_2_7[k][1],
                                     -9,
                                     1,
                                     0,
                                     0,
                                     0,
                                     1);
            tone_gen_init(&tone_state, &tone_desc);
            j = 0;
            for (i = 0;  i < 5;  i++)
            {
                local_max = tone_gen(&tone_state, local_sound, SAMPLE_RATE);
                for (j = 0;  j < SAMPLE_RATE;  j++)
                {
                    tx = local_sound[j];
                    channel_model(&tx, &rx, tx, 0);
                    clean = echo_can_update(ctx, tx, rx);
                    put_residue(clean);
                }
#if defined(ENABLE_GUI)
                if (use_gui)
                {
                    echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
                    echo_can_monitor_update_display();
                    usleep(100000);
                }
#endif
            }
        }
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_7))
    {
        printf("Performing test 7 - Stability\n");
        /* Test 7 - Stability */
        /* Put tones through an unconverged canceller, and check nothing unpleasant
           happens. */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        make_tone_gen_descriptor(&tone_desc,
                                 tones_6_4_2_7[0][0],
                                 -11,
                                 tones_6_4_2_7[0][1],
                                 -9,
                                 1,
                                 0,
                                 0,
                                 0,
                                 1);
        tone_gen_init(&tone_state, &tone_desc);
        j = 0;
        for (i = 0;  i < 120;  i++)
        {
            local_max = tone_gen(&tone_state, local_sound, SAMPLE_RATE);
            for (j = 0;  j < SAMPLE_RATE;  j++)
            {
                tx = local_sound[j];
                channel_model(&tx, &rx, tx, 0);
                clean = echo_can_update(ctx, tx, rx);
                put_residue(clean);
            }
#if defined(ENABLE_GUI)
            if (use_gui)
            {
                echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
                echo_can_monitor_update_display();
                usleep(100000);
            }
#endif
        }
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    if ((test_list & PERFORM_TEST_8))
    {
        printf("Performing test 8 - Non-convergence on No 5, 6, and 7 in-band signalling\n");
        /* Test 8 - Non-convergence on No 5, 6, and 7 in-band signalling */
        fprintf(stderr, "Test 8 not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_9))
    {
        printf("Performing test 9 - Comfort noise test\n");
        /* Test 9 - Comfort noise test */
        /* Test 9 part 1 - matching */
        echo_can_flush(ctx);
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION);
        /* Converge the canceller */
        signal_restart(&local_css);
        for (i = 0;  i < SAMPLE_RATE*5;  i++)
        {
            tx = signal_amp(&local_css);
            channel_model(&tx, &rx, tx, 0);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CNG);
        awgn_init_dbm0(&far_noise_source, 7162534, -45.0f);
        for (i = 0;  i < SAMPLE_RATE*30;  i++)
        {
            tx = 0;
            rx = awgn(&far_noise_source);
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        awgn_init_dbm0(&local_noise_source, 1234567, -10.0f);
        for (i = 0;  i < SAMPLE_RATE*2;  i++)
        {
            tx = awgn(&local_noise_source);
            rx = awgn(&far_noise_source);
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }

        /* Test 9 part 2 - adjust down */
        awgn_init_dbm0(&far_noise_source, 7162534, -55.0f);
        for (i = 0;  i < SAMPLE_RATE*10;  i++)
        {
            tx = 0;
            rx = awgn(&far_noise_source);
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
        for (i = 0;  i < SAMPLE_RATE*2;  i++)
        {
            tx = awgn(&local_noise_source);
            rx = awgn(&far_noise_source);
            channel_model(&tx, &rx, tx, rx);
            clean = echo_can_update(ctx, tx, rx);
            put_residue(clean);
        }
#if defined(ENABLE_GUI)
        if (use_gui)
            echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS);
#endif
    }

    /* Test 10 - FAX test during call establishment phase */
    if ((test_list & PERFORM_TEST_10A))
    {
        printf("Performing test 10A - Canceller operation on the calling station side\n");
        /* Test 10A - Canceller operation on the calling station side */
        fprintf(stderr, "Test 10A not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_10B))
    {
        printf("Performing test 10B - Canceller operation on the called station side\n");
        /* Test 10B - Canceller operation on the called station side */
        fprintf(stderr, "Test 10B not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_10C))
    {
        printf("Performing test 10C - Canceller operation on the calling station side during page\n"
               "transmission and page breaks (for further study)\n");
        /* Test 10C - Canceller operation on the calling station side during page
                      transmission and page breaks (for further study) */
        fprintf(stderr, "Test 10C not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_11))
    {
        printf("Performing test 11 - Tandem echo canceller test (for further study)\n");
        /* Test 11 - Tandem echo canceller test (for further study) */
        fprintf(stderr, "Test 11 not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_12))
    {
        printf("Performing test 12 - Residual acoustic echo test (for further study)\n");
        /* Test 12 - Residual acoustic echo test (for further study) */
        fprintf(stderr, "Test 12 not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_13))
    {
        printf("Performing test 13 - Performance with ITU-T low-bit rate coders in echo path (Optional, under study)\n");
        /* Test 13 - Performance with ITU-T low-bit rate coders in echo path
                     (Optional, under study) */
        fprintf(stderr, "Test 13 not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_14))
    {
        printf("Performing test 14 - Performance with V-series low-speed data modems\n");
        /* Test 14 - Performance with V-series low-speed data modems */
        fprintf(stderr, "Test 14 not yet implemented\n");
    }

    if ((test_list & PERFORM_TEST_15))
    {
        printf("Performing test 15 - PCM offset test (Optional)\n");
        /* Test 15 - PCM offset test (Optional) */
        fprintf(stderr, "Test 15 not yet implemented\n");
    }

    echo_can_free(ctx);

    signal_free(&local_css);
    signal_free(&far_css);

    if (afCloseFile(resulthandle) != 0)
    {
        fprintf(stderr, "    Cannot close speech file '%s'\n", "result_sound.wav");
        exit(2);
    }
    if (afCloseFile(residuehandle) != 0)
    {
        fprintf(stderr, "    Cannot close speech file '%s'\n", "residue_sound.wav");
        exit(2);
    }
    afFreeFileSetup(filesetup);
    afFreeFileSetup(filesetup2);

#if defined(XYZZY)
    for (j = 0;  j < ctx->taps;  j++)
    {
        for (i = 0;  i < coeff_index;  i++)
            fprintf(stderr, "%d ", coeffs[i][j]);
        fprintf(stderr, "\n");
    }
#endif
    printf("Run time %lds\n", time(NULL) - now);
    
#if defined(ENABLE_GUI)
    if (use_gui)
        echo_can_monitor_wait_to_end();
#endif

    if (power_meter_1)
        level_measurement_device_release(power_meter_1);
    if (power_meter_2)
        level_measurement_device_release(power_meter_2);

    printf("Tests passed.\n");
    return  0;
}