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

📄 yin.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
             * interesting thing can happen here.  snd_list_create, which             * we just called, MAY have invoked the garbage collector, and             * the GC MAY have freed all references to this channel, in which             * case yin_free(susp) will have been called, and susp->chan[0]             * will now be NULL!             */            if (!susp->chan[0]) {                ffree_snd_list(snd_list, "yin_fetch");            } else {                susp->chan[0]->u.next = snd_list;            }        }        /* see the note above: we don't know if susp->chan still exists */        /* Note: We DO know that susp still exists because even if we lost         * some channels in a GC, someone is still calling SND_get_next on         * some channel.  I suppose that there might be some very pathological         * code that could free a global reference to a sound that is in the         * midst of being computed, perhaps by doing something bizarre in the         * closure that snd_seq activates at the logical stop time of its first         * sound, but I haven't thought that one through.         */        if (susp->chan[0]) {            susp->chan[0]->block = f0;            /* check some assertions */            if (susp->chan[0]->u.next->u.susp != (snd_susp_type) susp) {                nyquist_printf("didn't find susp at end of list for chan 0\n");            }        } else if (f0) { /* we allocated f0, but don't need it anymore due to GC */            ffree_sample_block(f0, "yin_fetch");            f0_ptr = NULL;        }    }    /* Now, repeat for channel 1 (comments omitted) */    if (susp->chan[1]) {        falloc_sample_block(harmonicity, "yin_fetch");        harmonicity_ptr = harmonicity->samples;        if (!susp->chan[1]) {            ffree_sample_block(harmonicity, "yin_fetch");            harmonicity = NULL; /* make sure we don't free it again */            harmonicity_ptr = NULL;        } else if (!susp->chan[1]->block) {            snd_list_type snd_list = snd_list_create((snd_susp_type) susp);            if (!susp->chan[1]) {                ffree_snd_list(snd_list, "yin_fetch");            } else {                susp->chan[1]->u.next = snd_list;            }        }        if (susp->chan[1]) {            susp->chan[1]->block = harmonicity;            if (susp->chan[1]->u.next->u.susp != (snd_susp_type) susp) {                nyquist_printf("didn't find susp at end of list for chan 1\n");            }        } else if (harmonicity) { /* we allocated harmonicity, but don't need it anymore due to GC */            ffree_sample_block(harmonicity, "yin_fetch");            harmonicity_ptr = NULL;        }    }    while (cnt < max_sample_block_len) { /* outer loop */        /* first, compute how many samples to generate in inner loop: */        /* don't overflow the output sample block */        togo = (max_sample_block_len - cnt) * susp->stepsize;        /* don't run past the s input sample block */        susp_check_term_log_samples(s, s_ptr, s_cnt);        togo = min(togo, susp->s_cnt);        /* don't run past terminate time */        if (susp->terminate_cnt != UNKNOWN &&            susp->terminate_cnt <= susp->susp.current + cnt + togo/susp->stepsize) {            togo = (susp->terminate_cnt - (susp->susp.current + cnt)) * susp->stepsize;            if (togo == 0) break;        }        /* don't run past logical stop time */        if (!susp->logically_stopped && susp->susp.log_stop_cnt != UNKNOWN) {            int to_stop = susp->susp.log_stop_cnt - (susp->susp.current + cnt);            /* break if to_stop = 0 (we're at the logical stop)             * AND cnt > 0 (we're not at the beginning of the output block)             */            if (to_stop < togo/susp->stepsize) {                if (to_stop == 0) {                    if (cnt) {                        togo = 0;                        break;                    } else /* keep togo as is: since cnt == 0, we can set                            * the logical stop flag on this output block                            */                        susp->logically_stopped = true;                } else /* limit togo so we can start a new block a the LST */                    togo = to_stop * susp->stepsize;            }        }        n = togo;        s_ptr_reg = susp->s_ptr;        fillptr_reg = susp->fillptr;        if (n) do { /* the inner sample computation loop */            *fillptr_reg++ = *s_ptr_reg++;            if (fillptr_reg >= endptr_reg) {                float f0;                float harmonicity;                yin_compute(susp, &f0, &harmonicity);                if (f0_ptr) *f0_ptr++ = f0;                if (harmonicity_ptr) *harmonicity_ptr++ = harmonicity;                cnt++;                fillptr_reg -= susp->stepsize;            }        } while (--n); /* inner loop */        /* using s_ptr_reg is a bad idea on RS/6000: */        susp->s_ptr += togo;        susp->fillptr = fillptr_reg;        susp_took(s_cnt, togo);    } /* outer loop */    /* test for termination */    if (togo == 0 && cnt == 0) {        snd_list_terminate(snd_list);    } else {        snd_list->block_len = cnt;        susp->susp.current += cnt;    }    /* 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;    }} /* yin_fetch */  void yin_mark(yin_susp_type susp){    sound_xlmark(susp->s);}void yin_free(yin_susp_type susp){    int j;    boolean active = false;/*    stdputstr("yin_free: "); */    for (j = 0; j < 2; j++) {        if (susp->chan[j]) {            if (susp->chan[j]->refcnt) active = true;            else {                susp->chan[j] = NULL;                /* nyquist_printf("deactivating channel %d\n", j); */            }        }    }    if (!active) {/*      stdputstr("all channels freed, freeing susp now\n"); */        ffree_generic(susp, sizeof(yin_susp_node), "yin_free");        sound_unref(susp->s);        free(susp->block);        free(susp->temp);    }}void yin_print_tree(yin_susp_type susp, int n){    indent(n);    stdputstr("s:");    sound_print_tree_1(susp->s, n);}LVAL snd_make_yin(sound_type s, double low_step, double high_step, long stepsize){    LVAL result;    int j;    register yin_susp_type susp;    rate_type sr = s->sr;    time_type t0 = s->t0;    falloc_generic(susp, yin_susp_node, "snd_make_yin");    susp->susp.fetch = yin_fetch;    susp->terminate_cnt = UNKNOWN;        /* initialize susp state */    susp->susp.free = yin_free;    susp->susp.sr = sr / stepsize;    susp->susp.t0 = t0;    susp->susp.mark = yin_mark;    susp->susp.print_tree = yin_print_tree;    susp->susp.name = "yin";    susp->logically_stopped = false;    susp->susp.log_stop_cnt = logical_stop_cnt_cvt(s);    susp->susp.current = 0;    susp->s = s;    susp->s_cnt = 0;    susp->m = (long) (sr / step_to_hz(high_step));    if (susp->m < 2) susp->m = 2;    /* add 1 to make sure we round up */    susp->middle = (long) (sr / step_to_hz(low_step)) + 1;    susp->blocksize = susp->middle * 2;    susp->stepsize = stepsize;    /* blocksize must be at least step size to implement stepping */    if (susp->stepsize > susp->blocksize) susp->blocksize = susp->stepsize;    susp->block = (sample_type *) malloc(susp->blocksize * sizeof(sample_type));    susp->temp = (float *) malloc((susp->middle - susp->m + 1) * sizeof(float));    susp->fillptr = susp->block;    susp->endptr = susp->block + susp->blocksize;    xlsave1(result);    result = newvector(2);      /* create array for F0 and harmonicity */    /* create sounds to return */    for (j = 0; j < 2; j++) {        sound_type snd = sound_create((snd_susp_type)susp,                                       susp->susp.t0, susp->susp.sr, 1.0);        LVAL snd_lval = cvsound(snd);/*      nyquist_printf("yin_create: sound %d is %x, LVAL %x\n", j, snd, snd_lval); */        setelement(result, j, snd_lval);        susp->chan[j] = snd->list;    }    xlpop();    return result;}LVAL snd_yin(sound_type s, double low_step, double high_step, long stepsize){    sound_type s_copy = sound_copy(s);    return snd_make_yin(s_copy, low_step, high_step, stepsize);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -