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

📄 sound.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 4 页
字号:
    }}/* * additional routines */void sound_print(snd_expr, n)  LVAL snd_expr;  long n;{    LVAL result;    xlsave1(result);    result = xleval(snd_expr);    if (vectorp(result)) {        /* make sure all elements are of type a_sound */        long i = getsize(result);        while (i > 0) {            i--;            if (!exttypep(getelement(result, i), a_sound)) {                xlerror("sound_print: array has non-sound element",                         result);            }        }        sound_print_array(result, n);    } else if (exttypep(result, a_sound)) {        sound_print_sound(getsound(result), n);    } else {        xlerror("sound_print: expression did not return a sound",                 result);    }    xlpop();}void sound_print_sound(sound_type s, long n){    int ntotal = 0;    long blocklen;    sample_block_type sampblock;    /* for debugging */    printing_this_sound = s;    nyquist_printf("sound_print: start at time %g\n", s->t0);    while (ntotal < n) {        if (s->logical_stop_cnt != UNKNOWN)            nyquist_printf("LST=%d ", (int)s->logical_stop_cnt);        sound_print_tree(s);        sampblock = sound_get_next(s, &blocklen);        if (sampblock == zero_block || blocklen == 0) {            break;        }        print_sample_block_type("sound_print", sampblock,                                MIN(blocklen, n - ntotal));        ntotal += blocklen;    }    nyquist_printf("total samples: %d\n", ntotal);}void sound_print_array(LVAL sa, long n){    long blocklen;    long i, len;    long upper = 0;    sample_block_type sampblock;    time_type t0, tmax;    len = getsize(sa);    if (len == 0) {        stdputstr("sound_print: 0 channels!\n");        return;    }    /* take care of prepending zeros if necessary */    t0 = tmax = (getsound(getelement(sa, 0)))->t0;    for (i = 1; i < len; i++) {        sound_type s = getsound(getelement(sa, i));        t0 = MIN(s->t0, t0);        tmax = MAX(s->t0, tmax);    }    /* if necessary, prepend zeros */    if (t0 != tmax) {        stdputstr("prepending zeros to channels: ");        for (i = 0; i < len; i++) {            sound_type s = getsound(getelement(sa, i));            if (t0 < s->t0) {                nyquist_printf(" %d ", (int)i);                sound_prepend_zeros(s, t0);            }        }        stdputstr("\n");    }    nyquist_printf("sound_print: start at time %g\n", t0);    while (upper < n) {        int i;        boolean done = true;        for (i = 0; i < len; i++) {            sound_type s = getsound(getelement(sa, i));            long current = -1;  /* always get first block */            while (current < upper) {                sampblock = sound_get_next(s, &blocklen);                if (sampblock != zero_block && blocklen != 0) {                      done = false;                }                current = s->current - blocklen;                nyquist_printf("chan %d current %d:\n", i, (int)current);                 print_sample_block_type("sound_print", sampblock,                                        MIN(blocklen, n - current));                current = s->current;                upper = MAX(upper, current);            }        }        if (done) break;    }    nyquist_printf("total: %d samples x %d channels\n",                   (int)upper, (int)len);}/* sound_play -- compute sound, do not retain samples *//* * NOTE: we want the capability of computing a sound without * retaining samples.  This requires that no references to * the sound exist, but if the sound is passed as an argument, * the argument stack will have a reference.  So, we pass in * an expression that evaluates to the sound we want.  The * expression is eval'd, the result copied (in case the * expression was a sound or a global variable and we really * want to preserve the sound), and then a GC is run to  * get rid of the original if there really are no other  * references.  Finally, the copy is used to play the * sounds. */void sound_play(snd_expr)  LVAL snd_expr;{    int ntotal;    long blocklen;    sample_block_type sampblock;    LVAL result;    sound_type s;    xlsave1(result);    result = xleval(snd_expr);    if (!exttypep(result, a_sound)) {        xlerror("sound_play: expression did not return a sound",                 result);    }    ntotal = 0;    s = getsound(result);    /* if snd_expr was simply a symbol, then s now points to        a shared sound_node.  If we read samples from it, then        the sound bound to the symbol will be destroyed, so        copy it first.  If snd_expr was a real expression that        computed a new value, then the next garbage collection        will reclaim the sound_node.  We need to explicitly         free the copy since the garbage collector cannot find        it.    */    s = sound_copy(s);    while (1) {        sampblock = sound_get_next(s, &blocklen);        if (sampblock == zero_block || blocklen == 0) {            break;        }        /* print_sample_block_type("sound_play", sampblock, blocklen); */        ntotal += blocklen;    }    nyquist_printf("total samples: %d\n", ntotal);    sound_unref(s);    xlpop();}/* sound_print_tree -- print a tree version of sound structure *//**/void sound_print_tree(snd)  sound_type snd;{/*    nyquist_printf("sample_block_free %p\n", sample_block_free);*/    nyquist_printf("SOUND PRINT TREE of %p\n", snd);    sound_print_tree_1(snd, 0);}void indent(int n){    while (n-- > 0) stdputstr(" ");}void sound_print_tree_1(snd, n)  sound_type snd;  int n;{    int i;    snd_list_type snd_list;    if (n > 100) {        stdputstr("... (skipping remainder of sound)\n");        return;    }    nyquist_printf("sound_type@%p(%s@%p)t0 "                   "%g stop %d sr %g lsc %d scale %g pc %d",                   snd,                    (snd->get_next == SND_get_next ? "SND_get_next" :                    (snd->get_next == SND_get_first ? "SND_get_first" : "?")),                   snd->get_next, snd->t0, (int)snd->stop, snd->sr,                    (int)snd->logical_stop_cnt, snd->scale,                   (int)snd->prepend_cnt);    if (!snd) {        stdputstr("\n");        return;    }    snd_list = snd->list;    nyquist_printf("->snd_list@%p", snd_list);    if (snd_list == zero_snd_list) {        stdputstr(" = zero_snd_list\n");        return;    }    for (i = 0; ; i++) {        if (snd_list == zero_snd_list) {            if (i > 1) nyquist_printf(" (skipping %d) ", i-1);            stdputstr("->zero_snd_list\n");            return;        }        if (!snd_list->block) {            if (i > 0) nyquist_printf(" (skipping %d) ", i);            stdputstr("->\n");            indent(n + 2);            nyquist_printf("susp@%p(%s)toss_cnt %d "                           "current %d lsc %d sr %g t0 %g %p\n",                           snd_list->u.susp, snd_list->u.susp->name,                           (int)snd_list->u.susp->toss_cnt,                           (int)snd_list->u.susp->current,                           (int)snd_list->u.susp->log_stop_cnt,                           snd_list->u.susp->sr,                           snd_list->u.susp->t0, snd_list);/*            stdputstr("HI THERE AGAIN\n");*/            susp_print_tree(snd_list->u.susp, n + 4);            return;        }        snd_list = snd_list->u.next;    }}/* compute constants p1 and p2:  pitchconvert(0) * 2 = pitchconvert(12)  - octaves          exp(p2) * 2 = exp(12 * p1 + p2)                    2 = exp(12 * p1)               log(2) = 12 * p1         p1 = log(2.0)/12;  pitchconvert(69) gives 440Hz          exp(69 * p1 + p2) = 440               69 * p1 + p2 = log(440)        p2 = log(440.0) - (69 * p1);*/#define p1 0.0577622650466621#define p2 2.1011784386926213double hz_to_step(double hz){    return (log(hz) - p2) / p1;}double step_to_hz(steps)  double steps;{    return exp(steps * p1 + p2);}/* * from old stuff... */static void sound_xlfree(s)sound_type s;{/*    nyquist_printf("sound_xlfree(%p)\n", s);*/    sound_unref(s);}static void sound_xlprint(LVAL fptr, sound_type s){        /* the type cast from s to LVAL is OK because         * putatm does not dereference the 3rd parameter */    putatm(fptr, "Sound", (LVAL) s);}static void sound_xlsave(fp, s)FILE *fp;sound_type s;{    stdputstr("sound_save called\n");}static unsigned char *sound_xlrestore(FILE *fp){   stdputstr("sound_restore called\n");   return NULL;}/* sound_xlmark -- mark LVAL nodes reachable from this sound *//**/void sound_xlmark(s)sound_type s;{    snd_list_type snd_list;    long counter = 0;#ifdef TRACESNDGC    nyquist_printf("sound_xlmark(%p)\n", s);#endif    if (!s) return; /* pointers to sounds are sometimes NULL */    snd_list = s->list;    while (snd_list->block != NULL) {        if (snd_list == zero_snd_list) {#ifdef TRACESNDGC            stdputstr(" terminates at zero_snd_list\n");#endif            return;        } else if (counter > 1000000) {            stdputstr("You created a recursive sound! This is a Nyquist bug.\n");            stdputstr("The only known way to do this is by a SETF on a\n");            stdputstr("local variable or parameter that is being passed to SEQ\n");            stdputstr("or SEQREP. The garbage collector assumes that sounds are\n");            stdputstr("not recursive or circular, and follows sounds to their\n");            stdputstr("end. After following a million nodes, I'm pretty sure\n");            stdputstr("that there is a cycle here, but since this is a bug,\n");            stdputstr("I cannot promise to recover. Prepare to crash. If you\n");            stdputstr("cannot locate the cause of this, contact the author -RBD.\n");        }         snd_list = snd_list->u.next;        counter++;    }    if (snd_list->u.susp->mark) {#ifdef TRACESNDGC        nyquist_printf(" found susp (%s) at %p with mark method\n",               snd_list->u.susp->name, snd_list->u.susp);#endif        (*(snd_list->u.susp->mark))(snd_list->u.susp);    } else {#ifdef TRACESNDGC        nyquist_printf(" no mark method on susp %p (%s)\n",               snd_list->u.susp, snd_list->u.susp->name);#endif    }}void sound_symbols(){   a_sound = xlenter("SOUND");}/* The SOUND Type: */boolean soundp(s)LVAL s;{   return (exttypep(s, a_sound));}/* sound_zero - create and return a zero that terminates now *//**/sound_type sound_zero(time_type t0,rate_type sr){    sound_type sound;    falloc_sound(sound, "sound_zero");    sound->get_next = SND_get_first;    sound->list = zero_snd_list;    sound->logical_stop_cnt = sound->current = 0;    sound->true_t0 = sound->t0 = t0;    sound->sr = sr;    sound->scale = 1.0F;    return sound;}LVAL cvsound(s)sound_type s;{/*   nyquist_printf("cvsound(%p)\n", s);*/   return (cvextern(sound_desc, (unsigned char *) s));}

⌨️ 快捷键说明

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