void breakgen_setsr(t_breakgen *x, double f) { if (f > 0.0) { x->sr = f; free(x->osc); x->osc = new_oscil(x->sr); } object_post((t_object *)x, "Sampling rate set to %f", x->freq); }
void *breakgen_new(t_symbol *s, long argc, t_atom *argv) { t_breakgen *x = NULL; if ((x = (t_breakgen *)object_alloc(breakgen_class))) { x->name = gensym(""); if (argc && argv) { x->name = atom_getsym(argv); } if (!x->name || x->name == gensym("")) x->name = symbol_unique(); atom_setlong(&x->val, 0); x->out = outlet_new(x, NULL); x->constsig = 0; x->constval = 1.0; x->rando_gen = NULL; x->rando_gen = new_rando(); if(x->rando_gen == NULL){ post("no memory for random generator\n"); } x->rando_func = no_rando; srand(time(NULL)); x->tick = sinetick; x->sr = 10000.00; x->freq = 100.00; x->osc = NULL; x->osc = new_oscil(x->sr); if(x->osc == NULL){ post("no memory for oscillator\n"); } x->buffy = buffer_ref_new((t_object *)x, gensym("buffy")); if (buffer_ref_exists(x->buffy) != 0) { post("buf ref exists"); } else { post("buf ref doesn't exist"); }; } return (x); }
void breakgen_setter(t_breakgen *x, t_symbol *s, long argc, t_atom *argv) { t_atom *ap; int wavetype; ap = argv; if (atom_gettype(ap) == A_SYM) { if (atom_getsym(ap) == gensym("freq")) { ap++; if (atom_gettype(ap) == A_FLOAT) { if (atom_getfloat(ap) > 0.0) { x->freq = atom_getfloat(ap); post("freq set to %f", atom_getfloat(ap)); } else { post("frequency must be positive"); } } else { post("set sr argument of incorrect type"); } } else if (atom_getsym(ap) == gensym("constval")) { ap++; if (atom_gettype(ap) == A_FLOAT) { post("const val set to %f", atom_getfloat(ap)); x->constval = atom_getfloat(ap); } else { post("set const val arg of incorrect type"); } } else if (atom_getsym(ap) == gensym("wavetype")) { ap++; if (atom_gettype(ap) == A_LONG) { wavetype = atom_getlong(ap); if (wavetype < 6) { x->constsig = 0; switch (wavetype) { case 0: /* sine */ x->tick = sinetick; break; case 1: /* triange */ x->tick = tritick; break; case 2: /* square */ x->tick = sqtick; break; case 3: /* sawdown */ x->tick = sawdtick; break; case 4: /* sawup */ x->tick = sawutick; break; case 5: x->constsig = 1; break; default: x->tick = sinetick; break; } post("wavetype set to %i", wavetype); } else { post("wavetype must be between 0 and 5"); } } else { post("set wavetype argument of incorrect type"); } } else if (atom_getsym(ap) == gensym("random")) { ap++; if (atom_gettype(ap) == A_LONG) { wavetype = atom_getlong(ap); if (wavetype < 4) { switch (wavetype) { case 0: /* no random number */ x->rando_func = no_rando; break; case 1: /* replace value with random number */ x->rando_func = rando_replace;; break; case 2: /* scale random and +/- from val */ x->rando_func = rando_multi; break; case 3: /* scale random and +/- from val with interval interp */ x->rando_func = rando_interp; break; default: x->rando_func = no_rando; break; } post("random mode set to %i", wavetype); } else { post("random mode must be between 0 and 3"); } } else { post("set random argument of incorrect type"); } } else if (atom_getsym(ap) == gensym("interval")) { ap++; if (atom_gettype(ap) == A_LONG) { x->rando_gen->interval = atom_getlong(ap); } else { post("set random interval argument of incorrect type"); } } else if (atom_getsym(ap) == gensym("intensity")) { ap++; if (atom_gettype(ap) == A_FLOAT) { x->rando_gen->intensity = atom_getfloat(ap); } else { post("set random intensity argument of incorrect type"); } } else if (atom_getsym(ap) == gensym("buffer")) { t_symbol *symb; ap++; if (atom_gettype(ap) == A_SYM) { symb = atom_getsym(ap); x->buffy = buffer_ref_new((t_object *)x, symb); if (buffer_ref_exists(x->buffy) != 0) { object_post((t_object *)x, "\"%s\" buffer referenced", symb->s_name); } else { object_post((t_object *)x, "\"%s\" buffer referenced but doesn't exist", symb->s_name); }; } else { post("set buffer argument of incorrect type"); } } else if (atom_getsym(ap) == gensym("sr")) { ap++; if (atom_gettype(ap) == A_FLOAT) { if (atom_getfloat(ap) > 0.0) { x->sr = atom_getfloat(ap); free(x->osc); x->osc = new_oscil(x->sr); post("sampling rate set to %f", atom_getfloat(ap)); } else { post("sampling rate can't be negative"); } } else { post("set sr arg of incorrect type"); } } } }
void sig_gen(int argc, char *argv[]) { //This function will generate simple waveforms --> Sine, Triangle, Square, Sawtooth up, Sawtooth down //Showcases Pseudo-Object Oriented Programming, Function Pointers (functoids) /***************USAGE*************** siggen outfile wavetype dur srate amp freq **********************************/ if(argc < SIG_GEN_NARGS) { fprintf(stderr, "insufficient arguments.\n" "usage: siggen outfile wavetype dur srate amp freq\n" "where wavetype =:\n" " 0 = sine\n" " 1 = triangle\n" " 2 = square\n" " 3 = sawtooth up\n" " 4 = sawtooth down\n" "dur = duration of outfile (seconds)\n" "srate = required sample rate of outfile\n" "amp = amplitude value or breakpoint file (0 < amp <= 1.0)\n" "freq = frequency value (freq > 0) or breakpoint file.\n" ); exit(1); } /********* initialize all dynamic resources to default states **********/ PSF_PROPS outprops; int ofd = -1; PSF_CHPEAK* peaks = NULL; psf_format outformat = PSF_FMT_UNKNOWN; //all psf* defined in portsf sound library long nframes = NFRAMES; float* outframe = NULL; double amp,freq,dur; unsigned long outframes,nbufs,i; long remainder; int wavetype; OSCIL* osc = NULL; //OSCIL pseudo-object defined in wave_generator.h node_func_ptr node; //function pointer defined in wave_generator.h FILE* fpfreq = NULL; FILE* fpamp = NULL; BRKSTREAM* freqstream = NULL; //BRKSTREAM* defined in breakpoint.h BRKSTREAM* ampstream = NULL; unsigned long brkfreqSize = 0, brkampSize = 0; double minval, maxval; /********** error checking on wave type **********/ wavetype = atoi(argv[SIG_GEN_TYPE]); if(wavetype < SINE_WAVE || wavetype >= NUM_WAVE_TYPES) { fprintf(stderr, "Error: wavetype not defined\n"); goto exit; } /********** assigning function pointer accordingly **********/ switch(wavetype) { case(SINE_WAVE): node = sine_wave_node; //node is a function pointer (type: node_func_ptr); sine_wave_node is function break; case(SQAURE_WAVE): node = square_wave_node; break; case(TRIANGLE_WAVE): node = triangle_wave_node; break; case(SAW_UP_WAVE): node = sawtooth_up_wave_node; break; case(SAW_DOWN_WAVE): node = sawtooth_down_wave_node; break; } /********** define outfile format (with embedded error checking) **********/ outprops.srate = atoi(argv[SIG_GEN_SRATE]); if(outprops.srate <= 0) { fprintf(stderr, "Error: srate must by positive (>=0)\n"); goto exit; } outprops.chans = 1; //as of this sig_gen implementation --> mono outprops.samptype = (psf_stype) PSF_SAMP_16; //16-bit samples outprops.chformat = STDWAVE; //STDWAVE defined in portsf library dur = atof(argv[SIG_GEN_DUR]); if(dur <= 0.0) { fprintf(stderr, "Error: duration must be positive (>=0)\n"); goto exit; } outframes = (unsigned long) (dur * outprops.srate + 0.5); nbufs = outframes / nframes; remainder = outframes - nbufs * nframes; if(remainder) nbufs++; /********** open breakpoint files, or set constants if no breakpoint file is defined **********/ /***** amp (amplitude) breakpoints file *****/ fpamp = fopen(argv[SIG_GEN_AMP], "r"); //try opening specified argument if(fpamp == NULL) { //meaning that either argument SIG_GEN_AMP is not a breakpoint file or error opening amp = atof(argv[SIG_GEN_AMP]); if(amp <= 0.0 || amp > 1) { fprintf(stderr, "Error: amplitude must be between 0 and 1 (0 <= amp <= 1)\n"); goto exit; } } else { //meaning that argument SIG_GEN_AMP is indeed a breakpoint file ampstream = bps_newstream(fpamp,outprops.srate,&brkampSize); if(ampstream == NULL) { fprintf(stderr, "Error reading amplitude breakpoint file: %s\n", argv[SIG_GEN_AMP]); goto exit; } if(bps_getminmax(ampstream, &minval, &maxval)) { //meaning we called upon said function that will put into minval and maxval appropriate values //if said function returns 1 --> we have error fprintf(stderr, "Error reading range breakpoint file: %s\n", argv[SIG_GEN_AMP]); goto exit; } if(minval < 0.0 || minval > 1.0 || maxval < 0.0 || maxval > 1.0) { fprintf(stderr, "Error: amplitude values out of range in breakpoint file\n"); goto exit; } } /***** freq (frequency) breakpoints file *****/ fpfreq = fopen(argv[SIG_GEN_FREQ], "r"); if(fpfreq == NULL) { //meaning that either argument SIG_GEN_FREQ is not a breakpoint file or error opening freq = atof(argv[SIG_GEN_FREQ]); if(freq <= 0.0) { fprintf(stderr, "Error: frequency must be positive\n"); goto exit; } } else { //meaning that argument SIG_GEN_FREQ is indeed a breakpoint file freqstream = bps_newstream(fpfreq, outprops.srate, &brkfreqSize); if(freqstream == NULL) { fprintf(stderr, "Error reading frequncy from breakpoint file: %s\n", argv[SIG_GEN_FREQ]); goto exit; } if(bps_getminmax(freqstream, &minval, &maxval)) { fprintf(stderr, "Error reading range from breakpoint file: %s\n", argv[SIG_GEN_FREQ]); goto exit; } if(minval <= 0.0) { fprintf(stderr, "Error in breakpoing file; Frequency values must be positive\n"); goto exit; } } /********** Initialize OSCIL pseudo-object **********/ osc = new_oscil(outprops.srate); if(osc == NULL) { fprintf(stderr, "No memory for oscillator\n"); goto exit; } /********** Initialize portsf **********/ if(psf_init()) { fprintf(stderr, "Error: Unable to initialize portsf\n"); goto exit; } /********** Sample Frame Buffer Memory Aloocation **********/ outframe = (float*)malloc(nframes * outprops.chans * sizeof(float)); if(outframe == NULL) { fprintf(stderr, "Error: No memory for outframe buffer\n"); goto exit; } /********** Check for correct output extension **********/ outformat = psf_getFormatExt(argv[SIG_GEN_OUTFILE]); if(outformat == PSF_FMT_UNKNOWN) { fprintf(stderr, "Error: invalid extension\n" "Possible extensions:\t *.wav\t *.aiff\t *.aif\t *.afc\t *.aifc\n"); goto exit; } //reach here meaning outformat is viable extension outprops.format = outformat; /********** Initialize Peak nfo **********/ peaks = (PSF_CHPEAK*)malloc(outprops.chans * sizeof(PSF_CHPEAK)); if(peaks == NULL) { fprintf(stderr, "Error: No memory for peaks\n"); goto exit; } /********** Create and Handle outfile **********/ ofd = psf_sndCreate(argv[SIG_GEN_OUTFILE],&outprops, 0, 0, PSF_CREATE_RDWR); //refer to sf2float for documentation if(ofd < 0) { fprintf(stderr, "Error: Unable to create outfile\n"); goto exit; } /********** Audio Processing **********/ for(i=0; i<nbufs; i++) { long j; if(i == nbufs-1) nframes = remainder; for(j=0; j<nframes; j++) { if(freqstream) freq = bps_tick(freqstream); if(ampstream) amp = bps_tick(ampstream); outframe[j] = (float)(amp * node(osc,freq)); //call upon function via function pointer with OSCIL pseudo-object and freq; } if(psf_sndWriteFloatFrames(ofd, outframe, nframes) != nframes) { fprintf(stderr, "Error: unable to write to outfile\n"); goto exit; } } /********** Clean_up section **********/ exit: fprintf(stderr, "Task Finished\n"); /***** Report PEAK values to user *****/ if(psf_sndReadPeaks(ofd,peaks,NULL) > 0){ long i; double peaktime; printf("PEAK information:\n"); for(i=0;i < outprops.chans;i++){ peaktime = (double) peaks[i].pos / (double) outprops.srate; printf("CH %d:\t%.4f at %.4f secs\n", (int)(i+1), peaks[i].val, peaktime); } } if(ofd >= 0) if(psf_sndClose(ofd)) printf("Error closing outfile %s\n",argv[SIG_GEN_OUTFILE]); if(outframe) free(outframe); if(peaks) free(peaks); /*TODO: cleanup any other resources */ if(osc) free(osc); if(fpfreq) if(fclose(fpfreq)) printf("Error closing breakpoint file %s\n",argv[SIG_GEN_FREQ]); if(fpamp) if(fclose(fpamp)) printf("Error closing breakpoint file %s\n",argv[SIG_GEN_AMP]); if(freqstream){ bps_freepoints(freqstream); free(freqstream); } if(ampstream){ bps_freepoints(ampstream); free(ampstream); } psf_finish(); exit(1); }