⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 add.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 3 页
字号:
         * 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 + -