Esempio n. 1
0
/* 
 * a new segment is created with number of words equal to what is
 * in register rC, each word is initialized to zero, and the new ID is
 * placed in register rB
 */
extern void segMem_map(segment_data* segments, Seq_T freed_mem,
                       uint32_t* regs, uint32_t* tail, uint32_t* num_segments, 
                       int rc_size, int rb_id)
{       segment_data new_segment = NULL; 
        /* reusage of freed segment identifiers of available */
        if (Seq_length(freed_mem) > 0) {
                int* id = ((int*) Seq_remlo(freed_mem));
                new_segment = init_segment(regs, rc_size);
                segments[*id] = new_segment;
                regs[rb_id] = *id;
                free(id);
        }
        /* creates a new segment if an old one is not available */
        else {
                uint32_t id = *(tail);
                new_segment = init_segment(regs, rc_size);
                assert(new_segment);
                assert(segments);
                segments[id] = new_segment;
                assert(segments[0]);
                regs[rb_id] = id;
                *(tail) = id  + 1;
                /* resizing */
                if ((*tail) >= (*num_segments)) {
                       segment_data* new_segments = realloc(segments, 
                                                    2*sizeof(segment_data)*(*num_segments));
                       if (new_segments != NULL) {
                               segments = new_segments;
                               *(num_segments) = *(num_segments) * 2;
                       }
                }
        }
}
Esempio n. 2
0
void                      init_gdt()
{
  gdt_desc.limit = (sizeof(struct s_gdt_entry) * 6) - 1;
  gdt_desc.base = (unsigned int)&gdt;

  /* Null segment */
  init_segment(0, 0, 0, 0, 0);

  /*Ring 0*/
  /* Code segment */
  init_segment(1, BASE, LIMIT, 0xC, 0x9A);
  /* Data segment */
  init_segment(2, BASE, LIMIT, 0xC, 0x92);

  /*Ring 3*/
  /* Code segment */
  init_segment(3, BASE, LIMIT, 0xC, 0xFA);
  /* Data segment */
  init_segment(4, BASE, LIMIT, 0xC, 0xF2);

  /*TSS*/
  write_tss(5, 0x10, 0);

  flush_gdt();
  flush_tss();
}
Esempio n. 3
0
void init_mips(mips* arch){

	init_segment(&arch->segment[DATA], DATA);
	init_segment(&arch->segment[TEXT], TEXT);
	init_segment(&arch->segment[BSS], BSS);

	int i;
	for(i=0;i<35;i++){arch->reg[i]=0;}
}
Esempio n. 4
0
void init_mips(mips* arch){

	init_segment(&arch->segment[DATA], DATA);
	init_segment(&arch->segment[TEXT], TEXT);
	init_segment(&arch->segment[BSS], BSS);

	int i;
	for(i=0;i<36;i++){arch->reg[i].indice=i;}
	for(i=0;i<36;i++){arch->reg[i].val=0;}
	for(i=0;i<36;i++){arch->reg[i].mnemo=malloc(4*sizeof(char));}
	arch->reg[0].mnemo="zero";
	arch->reg[1].mnemo="at";
	arch->reg[2].mnemo="v0";
	arch->reg[3].mnemo="v1";
	arch->reg[4].mnemo="a0";
	arch->reg[5].mnemo="a1";
	arch->reg[6].mnemo="a2";
	arch->reg[7].mnemo="a3";
	arch->reg[8].mnemo="t0";
	arch->reg[9].mnemo="t1";
	arch->reg[10].mnemo="t2";
	arch->reg[11].mnemo="t3";
	arch->reg[12].mnemo="t4";
	arch->reg[13].mnemo="t5";
	arch->reg[14].mnemo="t6";
	arch->reg[15].mnemo="t7";
	arch->reg[16].mnemo="s0";
	arch->reg[17].mnemo="s1";
	arch->reg[18].mnemo="s2";
	arch->reg[19].mnemo="s3";
	arch->reg[20].mnemo="s4";
	arch->reg[21].mnemo="s5";
	arch->reg[22].mnemo="s6";
	arch->reg[23].mnemo="s7";
	arch->reg[24].mnemo="t8";
	arch->reg[25].mnemo="t9";
	arch->reg[26].mnemo="k0";
	arch->reg[27].mnemo="k1";
	arch->reg[28].mnemo="gp";	
	arch->reg[29].mnemo="sp";
	arch->reg[30].mnemo="fp";
	arch->reg[31].mnemo="ra";
	arch->reg[32].mnemo="pc";
	arch->reg[33].mnemo="hi";
	arch->reg[34].mnemo="lo";
	arch->reg[35].mnemo="sr";


}
Esempio n. 5
0
void
os_init_cont(void) {
   /* Reset the GDT. Although user processes in Nanos run in Ring 0,
      they have their own virtual address space. Therefore, the
      old GDT located in physical address 0x7C00 cannot be used again. */
   init_segment();

   /* Initialize the serial port. After that, you can use printk() */
   init_serial();

   /* Set up interrupt and exception handlers,
      just as we did in the game. */
   init_idt();

   /* Initialize the intel 8259 PIC. */
   init_intr();

   /* Initialize processes. You should fill this. */
   init_proc();

   welcome();

   sti();

   /* This context now becomes the idle process. */
   while (1) {
      wait_intr();
   }
}
Esempio n. 6
0
int main(int argc, char* argv[]) {
    int i;
    if( argc < 5 ) {
        printf("usage: integrate START END THREAD_NUM LUAFILE\n");
        return 0;
    }
    double start   = atof(argv[1]);
    double end     = atof(argv[2]);
    int thread_num = atoi(argv[3]);
    char* lua_file = argv[4];
    segment_t* segments;

    init_segment(&segments, start, end, thread_num, lua_file);
    pthread_t* handle = (pthread_t*)malloc(sizeof(pthread_t) * thread_num);
    /* セマフォ変数の初期化 */
    sem_init(&sem, 0, MAX_THREAD_NUM);

    for (i = 0; i < thread_num; ++i)
        pthread_create(&handle[i], NULL, (void *)thread_func, (void *)&segments[i]);

    for (i = 0; i < thread_num; ++i) 
        pthread_join(handle[i], NULL);

    printf("result: %.16f\n", sum);

    /* セマフォ変数の破棄 */
    sem_destroy(&sem);

    free(handle);
    free(segments);

    return 0;
}
Esempio n. 7
0
PyObject *
SKCurve_New(int length)
{
    SKCurveObject * self;
    int i;

    self = PyObject_New(SKCurveObject, &SKCurveType);
    if (self == NULL)
	return NULL;

    length = ROUNDUP(length, CURVE_BLOCK_LEN);
    self->len = 0;
    self->closed = 0;
    self->segments = malloc(length * sizeof(CurveSegment));
    if (!self->segments)
    {
	PyObject_Del(self);
	return PyErr_NoMemory();
    }
    self->allocated = length;

    for (i = 0; i < self->allocated; i++)
    {
	init_segment(self->segments + i, CurveLine);
    }

    paths_allocated++;

    return (PyObject *)self;
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
	if (argc < 2) {
		printf("usage: %s boardname\n", argv[0]);
		return 0;
	}
	chdir(FRGGHOME);
	init_segment();		/* load dict */
	build_ann_index(argv[1]);
	cleanup_segment();
	return 0;
}
void main(void){
	MAPMEM m=NULL;
	SEGMENT p=NULL;
	char name[512];
	char* str;
	char s[512];
	
	strncpy(s,"abcdefghijklmnop",sizeof("abcdefghijklmnop"));
	strcpy(name,"section1");
	m=init_memory_arm();
	p=init_segment(name,00,2000);
	(p->contenu)=strdup(s);
	(p->taille)=strlen(s);
	
	printf("%d \n",p->taille);
	

	affiche_segment(p,NULL,NULL);

	affiche_segment(p,"0x100" , "0x0");
	printf("%x \n",p->taille_max);

	
	p = change_val_seg(p,"5",10);
	affiche_segment(p,NULL,NULL);
	
	
	str=get_byte_seg(p,"5");
	
	printf("----------------------test et byte plus loin------------------------\n");
	str=get_byte_seg(p,"100");
	
	
	printf("%x \n",str[0]);
	affiche_segment(p,NULL,NULL);
	
	
	m=ajout_seg_map(m,name,256,2000,0);
	m[0]->contenu=strdup("0000000000000000000000000000000000");
	m[0]->taille=strlen("0000000000000000000000000000000000");

	printf("-----------------------affichage mémoire----------------------------\n");
	affiche_segment(m[0],NULL,NULL);
	//affiche_segment(m[0],"105","2020");
	
	change_plage_seg(m[0],"120","130","fuckyouallofyousorry");

	affiche_segment(m[0],NULL,NULL);
	
	change_plage_seg(m[0],"100","115","------------");
	affiche_segment(m[0],"0","2900");
	}
Esempio n. 10
0
static void               write_tss(int num, unsigned short ss0, unsigned esp0)
{
  unsigned                base;
  unsigned                limit;

  // tss_entry = kmalloc(sizeof(*tss_entry));

  base = (unsigned) &tss_entry;
  limit = base + sizeof(tss_entry);

  init_segment(num, base, limit, 0x00, 0xE9);
  memset(&tss_entry, 0, sizeof(tss_entry));

  tss_entry.ss0  = ss0;
  tss_entry.esp0 = esp0;

  tss_entry.cs   = 0x0b;
  tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13;
}
Esempio n. 11
0
File: main.c Progetto: CunNH3/oslab
void init_cond()
{
	
	init_segment();
	init_idt();
	init_intr();
	init_serial();
	init_timer();
	init_mem();
	sem_init();
	readsect((void *)directory_d.entries,201 + 256);
	printk("Filename = %s\n",directory_d.entries[0].filename);
	env_init();
	kernel_env.file[0].opened = true;
	kernel_env.file[0].offset = 0;
	curenv = &kernel_env;
	set_timer_intr_handler(kernel_timer_event);
	//asm volatile("cli");
	
	env_create(200,0,ENV_TYPE_USER);
	env_run(&envs[0]);
}
Esempio n. 12
0
static NOINLINE void *
find_segment(struct alloc_ptr *ptr)
{
	unsigned int blocksize_log2 = ALLOC_PTR_TO_BLOCKSIZE_LOG2(ptr);
	struct segment *seg;
	struct subheap *subheap = &global_subheaps[blocksize_log2];
	void *obj;

	ASSERT(BLOCKSIZE_MIN_LOG2 <= blocksize_log2
	       && blocksize_log2 <= BLOCKSIZE_MAX_LOG2);

	UNRESERVED_NEXT(subheap->unreserved, seg);
	if (seg) {
		/* seg have at least one free block. */
		set_alloc_ptr(ptr, seg);
		obj = find_bitmap(ptr);
		ASSERT(obj != NULL);
		GCSTAT_COUNT_MOVE(find[blocksize_log2], next[blocksize_log2]);
		return obj;
	}

	seg = new_segment();
	if (seg) {
		init_segment(seg, blocksize_log2);
		UNRESERVED_APPEND(subheap->unreserved, seg);
		set_alloc_ptr(ptr, seg);

		ASSERT(!BITPTR_TEST(ptr->freebit));
		GCSTAT_ALLOC_COUNT(new, blocksize_log2, ptr->blocksize_bytes);
		BITPTR_INC(ptr->freebit);
		obj = ptr->free;
		ptr->free += ptr->blocksize_bytes;
		return obj;
	}

	return NULL;
}
Esempio n. 13
0
File: main.c Progetto: zzt93/os-lab1
void
os_init_cont(void) {
    /* Reset the GDT. Although user processes in Nanos run in Ring 0,
       they have their own virtual address space. Therefore, the
       old GDT located in physical address 0x7C00 cannot be used again. */
    init_segment();

    /* Initialize the serial port. After that, you can use printk() */
    init_serial();

    /* Set up interrupt and exception handlers,
       just as we did in the game. */
    init_idt();

    /* Initialize the intel 8259 PIC. */
    //The Intel 8259 is a Programmable Interrupt Controller (PIC)
    init_intr();

    /**
       initialize kmalloc -- have to initialize it before init
       process, for using it in allocating memory for PCB
    */
    init_kmalloc();
    // make it NOINTR, can receive msg, can schedule
    init_idle();

    NOINTR;

    /**
       init_driver() have to before init_file_system() for FM have
       to send message to `ide` to read file system
     */
    init_driver();
    init_manager();
    NOINTR;
    init_error_msg();
    // init_proc() and init_manager() can replace??
    // solved by split set count_of_lock out of init_proc();

    //more_frequent();
    // init empty thread
    init_proc_test();

    // here is to initialize shell process, which must later
    // than init_manager -- for it will send message to
    // managers
    //ram_user_process();


    // @checked: move from locked state to unlocked state
    init_file_system();

    unlock(); // set interrupt enabled
    INTR;

    /**
       init_file_system() have to before init_proc()
       for init_proc() will using the `default_cwd` which is
       initialized by FM
    */
    /* Initialize the state of process idle, ie the running
       process for set up right lock num to avoid other
       initialization enable the interrupt and cause problem
    */

    // @checked: move from locked state to unlocked state
    welcome();

    user_process();
    // set idle not to using cpu time
    // for it is originally set to sleep when send message
    current->state = SLEEPED;


    /* This context now becomes the idle process. */
    while (1) {
        printk("!");
        wait_intr();
    }
}
Esempio n. 14
0
int main(int argc, char* argv[])
{
  int i, j;
  gaspi_number_t gsize;
  int comm_state = WORKING;
  int num_failures = 0;
  int timesteps = 0;
  
  ASSERT (gaspi_proc_init(GASPI_BLOCK));
  ASSERT (gaspi_proc_rank(&myrank));
  ASSERT (gaspi_proc_num(&numprocs));

  read_params(argc, argv, &timesteps, &numprocs_idle);
	
  numprocs_working = numprocs - numprocs_idle;
  numprocs_working_and_idle = numprocs_working + numprocs_idle;
  gaspi_rank_t *comm_main_ranks = malloc( numprocs_idle * sizeof(gaspi_rank_t));
  init_array_2(comm_main_ranks, numprocs_working);

  /* contains info of all processes:
     which are working(0), broken(1) and idle(2).
     keeps updated all the time(iterations) */
  int * status_processes = (int *) malloc(numprocs * sizeof(int));
	
  init_array_3(status_processes, numprocs, WORKING);
  for(i = numprocs-1, j=0; j < numprocs_idle;--i,++j)
    {
      status_processes[i] = IDLE; // putting last processes to IDLE
    }
	
  // ===== GASPI group creation =====
  if(status_processes[myrank]==WORKING)
    {
      ASSERT(gaspi_group_create(&COMM_MAIN));

      gaspi_number_t i;
      for(i=0; i<numprocs; i++)
	{
	  if(status_processes[i]==WORKING)
	    {
	      ASSERT(gaspi_group_add(COMM_MAIN, i));
	      ASSERT(gaspi_group_size(COMM_MAIN, &gsize));
	    }
	}
      ASSERT(gaspi_group_ranks (COMM_MAIN, comm_main_ranks));
      ASSERT(gaspi_group_commit (COMM_MAIN, GASPI_BLOCK));
    }

  /* ====== Init a SYNC FLAGS Segment ====== */
  /* used to communicate the WORKING, BROKEN, or FINISHED_WORK status between the working and idle processes. */

  gaspi_size_t SYNC_global_mem_size;
  SYNC_global_mem_size = numprocs * sizeof(int);

  gaspi_pointer_t gm_ptr_sync=NULL;
  ASSERT(init_segment (gm_seg_sync_flags_id, SYNC_global_mem_size));
  ASSERT(gaspi_segment_ptr (gm_seg_sync_flags_id, &gm_ptr_sync));

  int * sync_flags = (int *) gm_ptr_sync;
  init_array_3(sync_flags, numprocs, WORKING);
	
  /* ====== Init a health check write FLAGS Segment ====== */
  /* This array is used to send the gaspi_write message write before health_chk routine,
     which will then update the gaspi internal health vector */

  gaspi_size_t health_chk_global_mem_size;
  health_chk_global_mem_size = numprocs*sizeof(int);
  gaspi_pointer_t gm_ptr_health_chk=NULL;
  ASSERT(init_segment (gm_seg_health_chk_array_id, health_chk_global_mem_size));
  ASSERT(gaspi_segment_ptr (gm_seg_health_chk_array_id, &gm_ptr_health_chk));
	
  gaspi_state_vector_t health_vec = (gaspi_state_vector_t) malloc(numprocs);
  ASSERT(gaspi_state_vec_get(health_vec));

  gaspi_rank_t * avoid_list= (gaspi_rank_t *) malloc(numprocs * sizeof(gaspi_rank_t));
  for(i = 0;i < numprocs; ++i)
    avoid_list[i] = (gaspi_rank_t) 0;
	
  gaspi_barrier(GASPI_GROUP_ALL, GASPI_BLOCK);

  /* ===== TIME-STEP LOOP =====  */
  if(status_processes[myrank]==IDLE)
    {
      /* IDLE processes remain in this loop */
      while(1)
	{
	  gaspi_printf("%d.", myrank);
	  if(sync_flags[0] == WORKING)
	    {
	      /*  NO FAILURE REPORTED  */
	      usleep(1000000);
	    }
	  if(sync_flags[0] == BROKEN)
	    {
	      /* FAILURE REPORTED */
	      gaspi_printf("myrank: %d Broken reported\n", myrank);
	      comm_state=BROKEN;
	      break;
	    }
	  if(sync_flags[0] == WORKFINISHED)
	    {
	      /* WORKFINISHED REPORTED */
	      gaspi_printf("myrank: %d WorkFinished reported\n", myrank);
	      comm_state = WORKFINISHED;
	      break;
	    }
	}
    }

  int time_step;
  for(time_step=1; time_step <= timesteps && comm_state!=WORKFINISHED; time_step++)
    {
      gaspi_printf("== time_step: %d ==\n", time_step);
      if(comm_state==WORKING && status_processes[myrank]==WORKING)
	{
	  gaspi_barrier(COMM_MAIN, GASPI_TIMEOUT_TIME);
	  sleep(1); // NOTE: this is the work section.
	  if(time_step == 5 && myrank== 1)
	    {
	      exit (-1);
	    }
	}
      
      if(time_step<timesteps )
	{
	  send_global_msg_to_check_state(health_vec, avoid_list);
	  num_failures = check_comm_health(status_processes, health_vec);

	  gaspi_printf("%d NUM_FAILURES at timestep %d = %d\n", myrank, time_step, num_failures);

	  if( num_failures != 0 )
	    {
	      rescue_process = numprocs_working;
	      if(myrank==0)
		{
		  // message the IDLE process
		  sync_flags[0]=BROKEN;
		  
		  for(i = 0 ; i < num_failures ; ++i)
		    {
		      /* TODO: multiple failures at the same time. */
		      gaspi_printf("messaging rescue_process: %d\n", rescue_process);
		      ASSERT(gaspi_write(gm_seg_sync_flags_id, 0, rescue_process, gm_seg_sync_flags_id, 0, sizeof(int), 0, GASPI_BLOCK));
		      rescue_process++;
		    }
		}

	      if(myrank==0 || myrank==rescue_process)
		gaspi_printf("%d REPAIRING COMM_MAIN FLAG 1\n", myrank);

	      update_status_processes_array(status_processes, health_vec);
	      numprocs_working_and_idle = refresh_numprocs_working_and_idle(status_processes);
	      
	      if(myrank != rescue_process)
		{
		  ASSERT(gaspi_group_delete(COMM_MAIN));
		  ASSERT(recover());
		}
	  
	      ASSERT(gaspi_group_create(&COMM_MAIN_NEW));

	      for(i = 0; i < numprocs; i++)
		{
		  if(status_processes[i]==WORKING)
		    {
		      ASSERT(gaspi_group_add(COMM_MAIN_NEW, i));
		      ASSERT(gaspi_group_size(COMM_MAIN_NEW, &gsize));
		      if(gsize == numprocs_working)
			break;
		    }
		}
	  
	      gaspi_printf("%d: COMM_MAIN_NEW size is: %hi\n", myrank, gsize);

	      ASSERT(gaspi_group_commit (COMM_MAIN_NEW, GASPI_BLOCK));
	  
	      init_array_2(comm_main_ranks, numprocs_working);
	  
	      ASSERT(gaspi_group_ranks (COMM_MAIN_NEW, comm_main_ranks));

	      gaspi_printf("printing group_ranks_main: \n");
	      gaspi_printf_array(comm_main_ranks, numprocs_working);

	      comm_state = WORKING;
	      gaspi_printf("%d REPAIRING COMM_MAIN_NEW FLAG 2\n", myrank);
				
	      if(status_processes[myrank] == WORKING)
		{
		  ASSERT(gaspi_barrier(COMM_MAIN_NEW, GASPI_BLOCK));
		  ASSERT(gaspi_barrier(COMM_MAIN_NEW, GASPI_BLOCK));
		}

	      /* set things to work again */
	      COMM_MAIN = COMM_MAIN_NEW;
	      time_step = 5;
	    }
	}
    }
  
  if(myrank == 0)
    {
      gaspi_printf("finished successfully\n");
    }
  
  gaspi_proc_term(10000);

  return EXIT_SUCCESS;
}
Esempio n. 15
0
static int convert_coeffs(AVFilterContext *ctx)
{
    AudioFIRContext *s = ctx->priv;
    int left, offset = 0, part_size, max_part_size;
    int ret, i, ch, n;
    float power = 0;

    s->nb_taps = ff_inlink_queued_samples(ctx->inputs[1]);
    if (s->nb_taps <= 0)
        return AVERROR(EINVAL);

    if (s->minp > s->maxp) {
        s->maxp = s->minp;
    }

    left = s->nb_taps;
    part_size = 1 << av_log2(s->minp);
    max_part_size = 1 << av_log2(s->maxp);

    s->min_part_size = part_size;

    for (i = 0; left > 0; i++) {
        int step = part_size == max_part_size ? INT_MAX : 1 + (i == 0);
        int nb_partitions = FFMIN(step, (left + part_size - 1) / part_size);

        s->nb_segments = i + 1;
        ret = init_segment(ctx, &s->seg[i], offset, nb_partitions, part_size);
        if (ret < 0)
            return ret;
        offset += nb_partitions * part_size;
        left -= nb_partitions * part_size;
        part_size *= 2;
        part_size = FFMIN(part_size, max_part_size);
    }

    ret = ff_inlink_consume_samples(ctx->inputs[1], s->nb_taps, s->nb_taps, &s->in[1]);
    if (ret < 0)
        return ret;
    if (ret == 0)
        return AVERROR_BUG;

    if (s->response)
        draw_response(ctx, s->video);

    s->gain = 1;

    switch (s->gtype) {
    case -1:
        /* nothing to do */
        break;
    case 0:
        for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
            float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];

            for (i = 0; i < s->nb_taps; i++)
                power += FFABS(time[i]);
        }
        s->gain = ctx->inputs[1]->channels / power;
        break;
    case 1:
        for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
            float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];

            for (i = 0; i < s->nb_taps; i++)
                power += time[i];
        }
        s->gain = ctx->inputs[1]->channels / power;
        break;
    case 2:
        for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
            float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];

            for (i = 0; i < s->nb_taps; i++)
                power += time[i] * time[i];
        }
        s->gain = sqrtf(ch / power);
        break;
    default:
        return AVERROR_BUG;
    }

    s->gain = FFMIN(s->gain * s->ir_gain, 1.f);
    av_log(ctx, AV_LOG_DEBUG, "power %f, gain %f\n", power, s->gain);
    for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
        float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];

        s->fdsp->vector_fmul_scalar(time, time, s->gain, FFALIGN(s->nb_taps, 4));
    }

    av_log(ctx, AV_LOG_DEBUG, "nb_taps: %d\n", s->nb_taps);
    av_log(ctx, AV_LOG_DEBUG, "nb_segments: %d\n", s->nb_segments);

    for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
        float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];
        int toffset = 0;

        for (i = FFMAX(1, s->length * s->nb_taps); i < s->nb_taps; i++)
            time[i] = 0;

        av_log(ctx, AV_LOG_DEBUG, "channel: %d\n", ch);

        for (int segment = 0; segment < s->nb_segments; segment++) {
            AudioFIRSegment *seg = &s->seg[segment];
            float *block = (float *)seg->block->extended_data[ch];
            FFTComplex *coeff = (FFTComplex *)seg->coeff->extended_data[ch];

            av_log(ctx, AV_LOG_DEBUG, "segment: %d\n", segment);

            for (i = 0; i < seg->nb_partitions; i++) {
                const float scale = 1.f / seg->part_size;
                const int coffset = i * seg->coeff_size;
                const int remaining = s->nb_taps - toffset;
                const int size = remaining >= seg->part_size ? seg->part_size : remaining;

                memset(block, 0, sizeof(*block) * seg->fft_length);
                memcpy(block, time + toffset, size * sizeof(*block));

                av_rdft_calc(seg->rdft[0], block);

                coeff[coffset].re = block[0] * scale;
                coeff[coffset].im = 0;
                for (n = 1; n < seg->part_size; n++) {
                    coeff[coffset + n].re = block[2 * n] * scale;
                    coeff[coffset + n].im = block[2 * n + 1] * scale;
                }
                coeff[coffset + seg->part_size].re = block[1] * scale;
                coeff[coffset + seg->part_size].im = 0;

                toffset += size;
            }

            av_log(ctx, AV_LOG_DEBUG, "nb_partitions: %d\n", seg->nb_partitions);
            av_log(ctx, AV_LOG_DEBUG, "partition size: %d\n", seg->part_size);
            av_log(ctx, AV_LOG_DEBUG, "block size: %d\n", seg->block_size);
            av_log(ctx, AV_LOG_DEBUG, "fft_length: %d\n", seg->fft_length);
            av_log(ctx, AV_LOG_DEBUG, "coeff_size: %d\n", seg->coeff_size);
            av_log(ctx, AV_LOG_DEBUG, "input_size: %d\n", seg->input_size);
            av_log(ctx, AV_LOG_DEBUG, "input_offset: %d\n", seg->input_offset);
        }
    }

    av_frame_free(&s->in[1]);
    s->have_coeffs = 1;

    return 0;
}