📄 add.c
字号:
* and going to the rest of the block) -- just do pointers. */ /* just fetch and pass blocks on */D nyquist_printf("add[%p,%p] (s%d_nn) %p starting uncopy, togo %d\n", susp->s2, susp->s1, 2, susp, togo); snd_list->block = susp->s2_bptr; (susp->s2_bptr->refcnt)++;D nyquist_printf("add[%p,%p] (s%d_nn) %p shared block %p zero_block %p\n",susp->s2, susp->s1, 2, susp, susp->s2_bptr, zero_block); susp_took(s2_cnt, togo); snd_list->block_len = togo; /* if other is terminated and sound_types match, collapse */ /* NOTE: in order to collapse, we need s1 to be generating * blocks and linking them onto a sound list. This is true * when the get_next fn is SND_get_next. (A counterexample is * SND_get_zeros, which returns zero blocks but does not link * them onto the sound list. */ if (0) nyquist_printf("s1 %p thissr %g suspsr %g get_next %d lsc %d\n", susp->s1, susp->s2->sr, susp->susp.sr, susp->s2->get_next == SND_get_next, susp->s2->logical_stop_cnt == UNKNOWN); if (susp->s1 == NULL && susp->s2->sr == susp->susp.sr && susp->s2->get_next == SND_get_next && susp->s2->logical_stop_cnt == UNKNOWN) { snd_list_type addend_list;D nyquist_printf("add[%p,%p]: collapsing! LSC %d\n", susp->s2, susp->s1, (int)susp->s2->logical_stop_cnt);D sound_print_tree(susp->s2); /* will "current" values match? */ /* test for logical stop */ if (susp->logically_stopped) { snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) { susp->logically_stopped = true; } /* free the superfluous sound_type and susp */ addend_list = susp->s2->list->u.next; snd_list_ref(addend_list); snd_list_unref(snd_list->u.next); snd_list->u.next = addend_list; return; } } else { /* * we want to copy a partial block */ /* assume the snd_list is the one with a null block */ /* * put a fresh, clean block in the snd_list * (get new snd_list later) */ falloc_sample_block(out, "add_s2_nn_fetch"); snd_list->block = out; out_ptr = out->samples;B nyquist_printf("add[%p,%p] (s2_nn) %p new block %p\n", susp->s2, susp->s1, susp, out); n = togo; if (n == 0) stdputstr("zero block length error in add_s2_nn_fetch\n");B nyquist_printf( "add[%p,%p] (s2_nn) %p starting copy loop, togo %d\n", susp->s2, susp->s1, susp, togo); while (n--) { /* the inner sample computation loop */ /* scale? */ *out_ptr++ = *(susp->s2_ptr++); } /* inner loop */ susp_took(s2_cnt, togo); snd_list->block_len = togo; } /* add a new snd_list for the susp */ susp->susp.current += togo; if (0) stdputstr("testing..."); /* * test for termination or change of state, * note s1_start computed earlier */ if (susp->s1 && susp->susp.current == s1_start && susp->s2->list != zero_snd_list) { /* s1 starting and s2 continues */ /* go to s1+s2 state */ susp->susp.fetch = add_s1_s2_nn_fetch;D stdputstr("add_s_nn_fetch: add_s1_s2_fetch installed\n"); }/* else if (!susp->s1 && susp->s2->list == zero_snd_list) { */ else if (susp->terminate_bits == 3) { /* s1 finished and s2 stops */ /* go to terminal state */ susp->s2 = NULL;D nyquist_printf("add_s_nn_fetch: go to terminal state. susp->s1 %p, \ susp->susp.current %d, s1_start %d, susp->s2->list %p, \ zero_snd_list %p\n", susp->s1, (int)susp->susp.current, s1_start, susp->s2->list, zero_snd_list); /* !!! free resources and set up pointers to terminal snd_list */ /* !!! logically stopped? */ } /* test for logical stop */ if (susp->logically_stopped) {D stdputstr("add_s_nn_fetch: snd_list->logically_stopped\n"); snd_list->logically_stopped = true; } else if (susp->susp.log_stop_cnt == susp->susp.current) {D stdputstr("add_s_nn_fetch: susp->logically_stopped\n"); susp->logically_stopped = true; } if (0) { if (susp->logically_stopped || snd_list->logically_stopped) stdputstr("STOPPED\n"); else nyquist_printf("ok: current %d\n", (int)susp->susp.current); }}void add_zero_fill_nn_fetch(susp, snd_list) register add_susp_type susp; snd_list_type snd_list;{ int togo, s_start=0;#ifdef GC_DEBUG snd_list_report(snd_list, "add_zero_fill_nn_fetch");#endif togo = max_sample_block_len; if (0) fprintf(stderr, "add_zero_fill_nn_fetch, susp.current %d\n", (int)susp->susp.current); /* don't run past start time ... */ if (susp->s1) { s_start = ROUND((susp->s1->t0 - susp->susp.t0) * susp->s1->sr); if (s_start < susp->susp.current + togo) { togo = s_start - susp->susp.current; } } else if (susp->s2) { s_start = ROUND((susp->s2->t0 - susp->susp.t0) * susp->s2->sr); if (s_start < susp->susp.current + togo) { togo = s_start - susp->susp.current; } } snd_list->block_len = togo; susp->susp.current += togo; /* * test for change of state, * note s_start computed earlier */ if (susp->s1 && susp->susp.current == s_start) { /* s1 starting, go to s1 state */ susp->susp.fetch = add_s1_nn_fetch;D stdputstr("add_zero_fill_nn_fetch: add_s1_nn_fetch installed\n"); } else if (susp->s2 && susp->susp.current == s_start) { /* s2 starting, go to s2 state */ susp->susp.fetch = add_s2_nn_fetch;D stdputstr("add_zero_fill_nn_fetch: add_s2_nn_fetch installed\n"); }} /* add_zero_fill_nn_fetch */void add_free(add_susp_type susp){ sound_unref(susp->s1); sound_unref(susp->s2); ffree_generic(susp, sizeof(add_susp_node), "add_free");}void add_mark(add_susp_type susp){/* nyquist_printf("add_mark(%p)\n", susp);*//* nyquist_printf("marking s1@%p in add@%p\n", susp->s1, susp);*/ sound_xlmark(susp->s1);/* nyquist_printf("marking s2@%p in add@%p\n", susp->s2, susp);*/ sound_xlmark(susp->s2);}void add_print_tree(add_susp_type susp, int n){ indent(n); nyquist_printf("logically_stopped %d logical_stop_bits %d terminate_bits %d\n", susp->logically_stopped, susp->logical_stop_bits, susp->terminate_bits); indent(n); stdputstr("s1:"); if (susp->s1) sound_print_tree_1(susp->s1, n); else stdputstr(" NULL\n"); indent(n); stdputstr("s2:"); if (susp->s2) sound_print_tree_1(susp->s2, n); else stdputstr(" NULL\n");}sound_type snd_make_add(s1, s2) sound_type s1; sound_type s2;{ register add_susp_type susp; rate_type sr = MAX(s1->sr, s2->sr); time_type t0 = MIN(s1->t0, s2->t0); int interp_desc = 0; double sample_offset; /* sort commutative signals: (S1 S2) */ snd_sort_2(&s1, &s2, sr); falloc_generic(susp, add_susp_node, "snd_make_add"); /* select a susp fn based on sample rates */ interp_desc = (interp_style(s1, sr) << 2) + interp_style(s2, sr); switch (interp_desc) { case INTERP_nn: case INTERP_ns: case INTERP_ss: /* eliminate scale factor on s1 if any */ if (((interp_desc >> INTERP_SHIFT) & INTERP_MASK) == INTERP_s) { /* stdputstr("add: prescaling s1\n");*/ s1 = snd_make_normalize(s1); } /* eliminate scale factor on s2 if any */ if ((interp_desc & INTERP_MASK) == INTERP_s) { /* stdputstr("add: prescaling s2\n"); */ s2 = snd_make_normalize(s2); } sample_offset = (s2->t0 - s1->t0) * sr; if (sample_offset >= 0.5) { /* s1 starts first */ susp->susp.fetch = add_s1_nn_fetch;D stdputstr("snd_make_add: add_s1_nn_fetch installed\n"); } else if (sample_offset < -0.5) { /* s2 starts first */ susp->susp.fetch = add_s2_nn_fetch;D stdputstr("snd_make_add: add_s2_nn_fetch installed\n"); } else { /* equal start times */ susp->susp.fetch = add_s1_s2_nn_fetch;D stdputstr("snd_make_add: add_s1_s2_nn_fetch installed\n"); } break; case INTERP_ni: case INTERP_nr: errputstr("add: can't interpolate!\n"); EXIT(1); default: errputstr("add: can't add these operands!\n"); EXIT(1); } susp->terminate_cnt = UNKNOWN; susp->terminate_bits = 0; /* bits for s1 and s2 termination */ susp->logical_stop_bits = 0; /* bits for s1 and s2 logical stop */ /* initialize susp state */ susp->susp.free = add_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = add_mark; susp->susp.print_tree = add_print_tree; susp->susp.name = "add"; susp->logically_stopped = false; susp->susp.log_stop_cnt = UNKNOWN; susp->started = false; susp->susp.current = 0; susp->s1 = s1; susp->s1_cnt = 0; susp->s2 = s2; susp->s2_cnt = 0;#ifdef UPSAMPLECODE susp->susp.s2_phase = 0.0; susp->susp.s2_phase_incr = s2->sr / sr; susp->susp.output_per_s2 = sr / s2->sr;#endif return sound_create((snd_susp_type)susp, t0, sr, 1.0);}sound_type snd_add(s1, s2, t0) sound_type s1; sound_type s2; time_type t0;{ sound_type s1_copy = sound_copy(s1); sound_type s2_copy = sound_copy(s2);/* nyquist_printf("snd_add %p %p copied to %p %p\n", s1, s2, s1_copy, s2_copy); */ return snd_make_add(s1_copy, s2_copy, t0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -