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

📄 nyx.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
字号:
/**********************************************************************  nyx.c  Nyx: A very simple external interface to Nyquist  Dominic Mazzoni**********************************************************************//* system includes */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <math.h>#ifndef WIN32#include <unistd.h>#endif/* nyx includes */#include "nyx.h"/* xlisp includes */#include "switches.h"#include "xlisp.h"#include "term.h"#include "cext.h"/* nyquist includes */#include "sound.h"#include "falloc.h"/* nyquist externs */extern LVAL a_sound;extern snd_list_type zero_snd_list;/* globals */int                 nyx_output_pos;int                 nyx_output_len;char               *nyx_output_string;int                 nyx_expr_pos;int                 nyx_expr_len;const char         *nyx_expr_string;LVAL                nyx_result;XLCONTEXT           nyx_cntxt;int                 nyx_parse_error_flag;int                 nyx_first_time = 1;LVAL                nyx_old_obarray;typedef struct nyx_susp_struct {   snd_susp_node       susp;   nyx_audio_callback  callback;   void               *userdata;   long                len;   int                 channel;} nyx_susp_node, *nyx_susp_type;LVAL copylist(LVAL from){   if (from == NULL)      return NULL;   return cons(car(from), copylist(cdr(from)));}/* Make a copy of the obarray so that we can erase any   changes the user makes to global variables */void nyx_save_obarray(){   LVAL array, obarrayvec;   int i;   xlsave1(array);   array = newvector(HSIZE);   obarrayvec = getvalue(obarray);   for(i=0; i<HSIZE; i++) {      LVAL from = getelement(obarrayvec, i);      if (from)         setelement(array, i, copylist(from));   }   nyx_old_obarray = obarray;   obarray = xlmakesym("*OBARRAY*");   setvalue(obarray, array);   xlpop();}void nyx_init(){   if (nyx_first_time) {      char *argv[1];      argv[0] = "nyquist";      xlisp_main_init(1, argv);      nyx_output_len = 0;      nyx_output_pos = 0;      nyx_output_string = NULL;            nyx_first_time = 0;   }   /* keep nyx_result from being garbage-collected */   xlprot1(nyx_result);   nyx_save_obarray();}void nyx_cleanup(){   if (nyx_output_string) {      free(nyx_output_string);      nyx_output_string = NULL;      nyx_output_pos = 0;      nyx_output_len = 0;   }   xlpop(); /* garbage-collect nyx_result */   gc(); /* run the garbage-collector now */}void nyx_susp_fetch(register nyx_susp_type susp, snd_list_type snd_list){   sample_block_type         out;   sample_block_values_type  out_ptr;   long                      n;   int                       err;   falloc_sample_block(out, "nyx_susp_fetch");   out_ptr = out->samples;   snd_list->block = out;   n = max_sample_block_len;   if (susp->susp.current + n > susp->len)      n = susp->len - susp->susp.current;   err = susp->callback(out_ptr, susp->channel,                            susp->susp.current, n, susp->userdata);   if (err)      longjmp(nyx_cntxt.c_jmpbuf, 1);         snd_list->block_len = n;   susp->susp.current += n;   if (n == 0) {      /* we didn't read anything, but can't return length zero, so         convert snd_list to pointer to zero block */      snd_list_terminate(snd_list);   }   else if (n < max_sample_block_len) {      /* should free susp */      snd_list_unref(snd_list->u.next);      /* if something is in buffer, terminate by pointing to zero block */      snd_list->u.next = zero_snd_list;   }}void nyx_susp_free(nyx_susp_type susp){   ffree_generic(susp, sizeof(nyx_susp_node), "nyx_susp_free");}void nyx_susp_print_tree(nyx_susp_type susp, int n){}void nyx_capture_output(int max_len){   if (nyx_output_string)      free(nyx_output_string);   nyx_output_string = (char *)malloc(max_len);   nyx_output_len = max_len;   nyx_output_pos = 0;}void nyx_get_captured_output(int *out_len,                             const char **out_chars){   *out_len = nyx_output_pos;   *out_chars = (const char *)nyx_output_string;   nyx_output_pos = 0;}void nyx_set_input_audio(nyx_audio_callback callback,                         void *userdata,                         int num_channels,                         long len, double rate){   sample_type      scale_factor = 1.0;   time_type        t0 = 0.0;   nyx_susp_type   *susp;   sound_type      *snd;   double           stretch_len;   LVAL             warp;   int              ch;   susp = (nyx_susp_type *)malloc(num_channels * sizeof(nyx_susp_type));   snd = (sound_type *)malloc(num_channels * sizeof(sound_type));   for(ch=0; ch < num_channels; ch++) {      falloc_generic(susp[ch], nyx_susp_node, "nyx_set_input_audio");      susp[ch]->callback = callback;      susp[ch]->userdata = userdata;      susp[ch]->len = len;      susp[ch]->channel = ch;      susp[ch]->susp.sr = rate;      susp[ch]->susp.t0 = t0;      susp[ch]->susp.mark = NULL;      susp[ch]->susp.print_tree = nyx_susp_print_tree;      susp[ch]->susp.current = 0;      susp[ch]->susp.fetch = nyx_susp_fetch;      susp[ch]->susp.free = nyx_susp_free;      susp[ch]->susp.name = "nyx";            snd[ch] = sound_create((snd_susp_type)susp[ch], t0,                              rate,                              scale_factor);   }   /* Bind the sample rate to the "*sound-srate*" global */   setvalue(xlenter("*SOUND-SRATE*"), cvflonum(rate));   /* Bind selection len to "len" global */   setvalue(xlenter("LEN"), cvflonum(len));   if (len > 0)      stretch_len = len / rate;   else      stretch_len = 1.0;   /* Set the "*warp*" global based on the length of the audio */   xlprot1(warp);   warp = cons(cvflonum(0),                    /* time offset */               cons(cvflonum(stretch_len),     /* time stretch */                    cons(NULL,                 /* cont. time warp */                         NULL)));   setvalue(xlenter("*WARP*"), warp);   xlpop();   if (num_channels > 1) {      LVAL array = newvector(num_channels);      for(ch=0; ch<num_channels; ch++)         setelement(array, ch, cvsound(snd[ch]));      setvalue(xlenter("S"), array);   }   else {      LVAL s = cvsound(snd[0]);      setvalue(xlenter("S"), s);   }}int is_labels(LVAL expr){   /* make sure that we have a list whose first element is a      list of the form (time "label") */   if (!consp(expr))      return 0;   if (!consp(car(expr)))      return 0;   if (!(floatp(car(car(expr))) || fixp(car(car(expr)))))      return 0;   if (!consp(cdr(car(expr))))      return 0;   if (!(stringp(car(cdr(car(expr))))))      return 0;   /* If this is the end of the list, we're done */   if (cdr(expr) == NULL)      return 1;   /* Otherwise recurse */   return is_labels(cdr(expr));}nyx_rval nyx_get_type(LVAL expr){   if (expr==NULL)      return nyx_error;   switch(ntype(expr)) {   case FIXNUM:      return nyx_int;   case FLONUM:      return nyx_double;   case STRING:      return nyx_string;   case VECTOR: {      /* make sure it's a vector of sounds */      int i;      for(i=0; i<getsize(expr); i++)         if (!soundp(getelement(expr, i)))             return nyx_error;      return nyx_audio;   }   case CONS: {      /* see if it's a list of time/string pairs representing a         label track */      if (is_labels(expr))         return nyx_labels;      else         return nyx_error;   }   case EXTERN: {      if (soundp(expr))         return nyx_audio;   }   } /* switch */   return nyx_error;}nyx_rval nyx_eval_expression(const char *expr_string){   LVAL expr = NULL;   nyx_expr_string = expr_string;   nyx_expr_len = strlen(nyx_expr_string);   nyx_expr_pos = 0;   nyx_result = NULL;   nyx_parse_error_flag = 0;   xlprot1(expr);   /* setup the error return */   xlbegin(&nyx_cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,(LVAL)1);   if (setjmp(nyx_cntxt.c_jmpbuf))      goto finish;   while(nyx_expr_pos < nyx_expr_len) {      expr = NULL;      /* read an expression */      if (!xlread(getvalue(s_stdin), &expr, FALSE))         break;      #if 0      /* save the input expression (so the user can refer to it         as +, ++, or +++) */      xlrdsave(expr);      #endif            /* evaluate the expression */      nyx_result = xleval(expr);   }   xlflush(); finish:   xlend(&nyx_cntxt);   xlpop(); /* unprotect expr */   /* reset the globals to their initial state */   obarray = nyx_old_obarray;   setvalue(xlenter("S"), NULL);   gc();   return nyx_get_type(nyx_result);}int nyx_get_audio_num_channels(){   if (nyx_get_type(nyx_result) != nyx_audio)      return 0;   if (vectorp(nyx_result))      return getsize(nyx_result);   else      return 1;}void nyx_get_audio(nyx_audio_callback callback, void *userdata){   sample_block_type block;   sound_type snd;   sound_type *snds;   float *buffer;   long bufferlen;   long *totals;   long cnt;   int result = 0;   int num_channels;   int ch, i;   if (nyx_get_type(nyx_result) != nyx_audio)      return;   num_channels = nyx_get_audio_num_channels();   snds = (sound_type *)malloc(num_channels * sizeof(sound_type));   totals = (long *)malloc(num_channels * sizeof(long));   /* setup the error return */   xlbegin(&nyx_cntxt,CF_TOPLEVEL|CF_CLEANUP|CF_BRKLEVEL,(LVAL)1);   if (setjmp(nyx_cntxt.c_jmpbuf))      goto finish;   for(ch=0; ch<num_channels; ch++) {      if (num_channels == 1)         snd = getsound(nyx_result);      else         snd = getsound(getelement(nyx_result, ch));      snds[ch] = snd;      totals[ch] = 0;   }   buffer = NULL;   bufferlen = 0;   while(result==0) {      for(ch=0; ch<num_channels; ch++) {         snd = snds[ch];         cnt = 0;         block = snd->get_next(snd, &cnt);         if (block == zero_block || cnt == 0) {            result = -1;            break;         }         /* copy the data to a temporary buffer and scale it            by the appropriate scale factor */         if (cnt > bufferlen) {            if (buffer)               free(buffer);            buffer = (float *)malloc(cnt * sizeof(float));            bufferlen = cnt;         }         memcpy(buffer, block->samples, cnt * sizeof(float));         for(i=0; i<cnt; i++)            buffer[i] *= snd->scale;         result = callback(buffer, ch,                           totals[ch], cnt, userdata);         if (result == 0)            totals[ch] += cnt;      }   } finish:      if (buffer)         free(buffer);   free(snds);   free(totals);   xlend(&nyx_cntxt);}int nyx_get_int(){   if (nyx_get_type(nyx_result) != nyx_int)      return -1;   return getfixnum(nyx_result);}double nyx_get_double(){   if (nyx_get_type(nyx_result) != nyx_double)      return -1.0;   return getflonum(nyx_result);}const char *nyx_get_string(){   if (nyx_get_type(nyx_result) != nyx_string)      return NULL;   return (const char *)getstring(nyx_result);}int nyx_get_num_labels(){   LVAL s = nyx_result;   int count = 0;   if (nyx_get_type(nyx_result) != nyx_labels)      return 0;   while(s) {      count++;      s = cdr(s);   }   return count;}void nyx_get_label(int index,                   double *time,                   const char **label){   LVAL s = nyx_result;   LVAL t_expr;   if (nyx_get_type(nyx_result) != nyx_labels)      return;   if (index < 0 || index >= nyx_get_num_labels())      return;   while(index) {      index--;      s = cdr(s);   }   t_expr = car(car(s));   if (floatp(t_expr))      *time = getflonum(t_expr);   else if (fixp(t_expr))      *time = (double)getfixnum(t_expr);   *label = (const char *)getstring(car(cdr(car(s))));}const char *nyx_get_error_str(){   return NULL;}int ostgetc(){   if (nyx_expr_pos < nyx_expr_len) {      fflush(stdout);      return (nyx_expr_string[nyx_expr_pos++]);   }   else if (nyx_expr_pos == nyx_expr_len) {      /* Add whitespace at the end so that the parser         knows that this is the end of the expression */      nyx_expr_pos++;      return '\n';   }   else      return EOF;}/* osinit - initialize */void osinit(char *banner){}/* osfinish - clean up before returning to the operating system */void osfinish(void) {}/* oserror - print an error message */void oserror(char *msg){   printf("nyx error: %s\n", msg);}long osrand(long n){   return (((int) rand()) % n);}/* osaopen - open an ascii file */FILE *osaopen(name,mode) char *name,*mode;{   FILE *fp;   fp = fopen(name,mode);   return fp;}/* osbopen - open a binary file */FILE *osbopen(char *name, char *mode){   char bmode[10];   FILE *fp;      strncpy(bmode, mode, 8);   strcat(bmode,"b");   fp = fopen(name,bmode);   return fp;}/* osclose - close a file */int osclose(FILE *fp){   return (fclose(fp));}/* osagetc - get a character from an ascii file */int osagetc(FILE *fp){   return (getc(fp));}/* osaputc - put a character to an ascii file */int osaputc(int ch, FILE *fp){   return (putc(ch,fp));}extern int dbgflg;/* osbgetc - get a character from a binary file *//* int osbgetc(fp) FILE *fp; {return (getc(fp));} */#ifndef WIN32  // duplicated in winfun.c, per James Crook, 7/4/2003	int osbgetc(FILE *fp)	{		return (getc(fp));	}#endif/* osbputc - put a character to a binary file */int osbputc(int ch, FILE *fp){   return (putc(ch,fp));}/* ostputc - put a character to the terminal */void ostputc(int ch){        oscheck();		/* check for control characters */      if (nyx_output_pos < nyx_output_len)      nyx_output_string[nyx_output_pos++] = (char)ch;   else      putchar(((char) ch));}/* osflush - flush the terminal input buffer */void osflush(void){}/* oscheck - check for control characters during execution */void oscheck(void){   /* if they hit control-c:      xflush(); xltoplevel(); return;   */}/* xsystem - execute a system command */#ifndef WIN32  // duplicated in winfun.c, per James Crook, 7/4/2003LVAL xsystem(){   if (moreargs()) {      unsigned char *cmd;      cmd = (unsigned char *)getstring(xlgastring());      fprintf(stderr, "Will not execute system command: %s\n", cmd);   }   return s_true;}#endif/* xsetdir -- set current directory of the process */LVAL xsetdir(){   char *dir = (char *)getstring(xlgastring());   int result;   xllastarg();   result = chdir(dir);   if (result) {      perror("SETDIR");   }   return NULL;}/* xgetkey - get a key from the keyboard */#ifndef WIN32  // duplicated in winfun.c, per James Crook, 7/4/2003	LVAL xgetkey() {xllastarg(); return (cvfixnum((FIXTYPE)getchar()));}#endif/* ossymbols - enter os specific symbols */#ifndef WIN32  // duplicated in winfun.c, per James Crook, 7/4/2003	void ossymbols(void) {}#endif/* xsetupconsole -- used to configure window in Win32 version */#ifndef WIN32  // duplicated in winfun.c, per James Crook, 7/4/2003	LVAL xsetupconsole() { return NULL; }#endif/* control-C handling */void ctcinit()	{}

⌨️ 快捷键说明

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