Unanticipated host error Zoom R24
Hi all, I have a problem with my audio setup, hope this is the right place to post and maybe someone else has had the same problem.
I have a Zoom R24 which is connectet by usb to my computer and used as an external sound card. Whenever I try to set the zoom as my output device, I get this error:
Error opening audio: Unanticipated host error
I only have this issue with the zoom, when I use a generic ASIO driver, it doesn't happen. Sample rate is set to 44.1 on all devices, so that shouldn't be the issue. Latest firmware installed on the zoom.
What's weird is that a few times, it works. I try to remember what I did differently then, but the next time I do that it doesn't work.
This might be a far shot, but if anyone could help I'd be very thankful!
Attached a pic of my settings
First bootup problems
Hey guys,
A quick search on the forums did not reveal a straightforward answer for how to deal with my bootup problem. I'm a big noob, with no programming experience, and I'm trying to get Purr Data to bootup on my busted old Linux Mint laptop. I'm using pd 2.8.1, and Mint 18. I have JACK on my computer, but I'm pretty sure everything is running through ALSA. Anyway, first bootup of PD looked like this:
Welcome to Purr Data
warning: your system's font stack is not optimal
Pd has started the GUI
canvasinfo: v0.1
stable canvasinfo methods: args dir dirty editmode vis
pdinfo: v.0.1
stable pdinfo methods: dir dsp version
classinfo: v.0.1
stable classinfo methods: size
objectinfo: v.0.1
stable objectinfo methods: class
[import] $Revision: 1.2 $
[import] is still in development, the interface could change!
compiled against Pd-l2ork version 2.8.1 (20190207-rev.e216f5a)
PD_FLOATSIZE = 32 bits
sys_nmidiin 1, nmidiindev 0
working directory is /home/jjwitte
Opened Alsa Client 128 in:1 out:1
libdir loader 1.10
compiled on Feb 7 2019 at 19:29:50
compiled against Pd version 0.48.0.
GEM: Graphics Environment for Multimedia
verbose( -1):GEM: ver: 0.93.git 438dab3
verbose( -1):GEM: compiled: Feb 7 2019
verbose( -1):GEM: maintained by IOhannes m zmoelnig
verbose( -1):GEM: Authors : Mark Danks (original version)
verbose( -1):GEM: Chris Clepper
verbose( -1):GEM: Cyrille Henry
verbose( -1):GEM: IOhannes m zmoelnig
verbose( -1):GEM: with help by Guenter Geiger, Daniel Heckenberg, James Tittle, Hans-Christoph Steiner, et al.
verbose( -1):GEM: found a bug? miss a feature? please report it:
verbose( -1):GEM: homepage http://gem.iem.at/
verbose( -1):GEM: bug-tracker http://sourceforge.net/projects/pd-gem/
verbose( -1):GEM: mailing-list http://lists.puredata.info/listinfo/gem-dev/
verbose( -1):GEM: compiled for MMX/SSE2 architecture
verbose( -1):GEM: using SSE2 optimization
verbose( -1):GEM: detected 4 CPUs
GEM: image loading support: magick SGI jpeg tiff
GEM: image saving support: jpeg magick tiff
libdir_loader: added 'cyclone' to the global objectclass path
libdir_loader: added 'zexy' to the global objectclass path
libdir_loader: added 'creb' to the global objectclass path
libdir_loader: added 'cxc' to the global objectclass path
libdir_loader: added 'iemlib' to the global objectclass path
libdir_loader: added 'mapping' to the global objectclass path
libdir_loader: added 'markex' to the global objectclass path
libdir_loader: added 'maxlib' to the global objectclass path
libdir_loader: added 'memento' to the global objectclass path
libdir_loader: added 'mjlib' to the global objectclass path
libdir_loader: added 'motex' to the global objectclass path
libdir_loader: added 'oscx' to the global objectclass path
libdir_loader: added 'pddp' to the global objectclass path
libdir_loader: added 'pdogg' to the global objectclass path
libdir_loader: added 'pixeltango' to the global objectclass path
libdir_loader: added 'rradical' to the global objectclass path
libdir_loader: added 'sigpack' to the global objectclass path
libdir_loader: added 'smlib' to the global objectclass path
libdir_loader: added 'unauthorized' to the global objectclass path
vbap - v1.1 - 14 Aug. 2014 - (c) Ville Pulkki 1999-2006 (Pd port by HCS)
libdir_loader: added 'pan' to the global objectclass path
freeverb~ v1.2
libdir_loader: added 'hcs' to the global objectclass path
libdir_loader: added 'jmmmp' to the global objectclass path
libdir_loader: added 'ext13' to the global objectclass path
libdir_loader: added 'ggee' to the global objectclass path
libdir_loader: added 'ekext' to the global objectclass path
libdir_loader: added 'disis' to the global objectclass path
libdir_loader: added 'lyonpotpourri' to the global objectclass path
pdlua 0.9 (GPL) 2014-2018 Martin Peach et al., based on
lua 0.6~svn (GPL) 2008 Claude Heiland-Allen claude@mathr.co.uk
pdlua: compiled for pd-0.48 on Feb 7 2019 19:31:25
Using lua version 5.3
pdlua: using JavaScript interface (Pd-l2ork nw.js version)
[14] error: audio I/O dropout
So, I get the impression that these audio I/O dropout issues happen quite a bit. But does anyone have any ideas for what I can try next? Also, I apologize if this is the wrong forum this question. If someone could just point me in the right direction, that would be awesome.
possible deken bug + general question on dependencies
@oystersauce You are looking for freeverb~ ...... which has been compiled for 64-bit windows and is available on Deken.
I am pretty certain that your recent posts are all about the same problem.
If nobody has recompiled an external for 64-bit for the OS that you are running (and added a link to Deken) then Deken will not find it.
Some externals might have been compiled but not added, some have not been compiled, and maybe some cannot be compiled.
You might find repositories for the C code on github that will allow you to compile for your system.
Please share them afterwards as it will help others with the same problem.
64-bit Vanilla is starting to have some useful tools, but if you don't need them or the higher precision of 64-bit then Extended or Deken for 32-bit Vanilla are still a better bet at the moment.
Of course on a 64-bit OSX that is not an option.
If you are willing to try a fork like Purr Data then the developers are often more active and willing to help rebuild old (or even new) externals for their version.
A lot of people have been looking for [knob] and @yoichi_tbbb recently made a great one here........ https://forum.pdpatchrepo.info/topic/10938/new-knob-gui-object which I am surprised no-one has compiled for 64-bit.
David.
[small job offer] porting max external to pd
Edit 1: Took a shot porting it in this little textarea. Probably doesn't compile yet...
Edit 2: Ok, this should compile now. I haven't actually tried to instantiate it yet, though. It's possible I set it up with the wrong number of xlets.
Edit 3: Seems to instantiate ok. It appears it doesn't take signal input so the CLASS_MAINSIGNALIN macro is neccessary. Just comment that part out to make it a control signal.
Note-- in my port it's called [vb_fourses~]
for the reason noted below.
I have no idea if the algorithm behaves correctly, but it does output sound.
Btw-- AFAICT you should be able to compile this external for the 64-bit version of Purr Data and it should work properly. It doesn't require a special 64-bit codepath in Pd so I commented that part out.
Btw 2-- there should probably be a "best practices" rule that states you can only name your class something that is a legal C function name. Because this class doesn't follow that practice I made a mistake in the port. Further, the user will make a mistake because I had to change the class name. If I had instead made the setup function a different name than the creator I would create an additional problem that would force users to declare the lib before using it. Bad all around, and not worth whatever benefit there is to naming a class "foo.bar" instead of "foo_bar"
/*
#include "ext.h"
#include "ext_obex.h"
#include "z_dsp.h"
#include "ext_common.h"
*/
#include "m_pd.h"
#include "math.h"
/*
a chaotic oscillator network
based on descriptions of the 'fourses system' by ciat-lonbarde
www.ciat-lonbarde.net
07.april 2013, volker b?hm
*/
#define NUMFOURSES 4
static void *myObj_class;
typedef struct {
// this is a horse... basically a ramp generator
double val;
double inc;
double dec;
double adder;
double incy, incym1; // used for smoothing
double decy, decym1; // used for smoothing
} t_horse;
typedef struct {
t_object x_obj;
double r_sr;
t_horse fourses[NUMFOURSES+2]; // four horses make a fourse...
double smoother;
t_sample x_f;
} t_myObj;
// absolute limits
static void myObj_hilim(t_myObj *x, t_floatarg input);
static void myObj_lolim(t_myObj *x, t_floatarg input);
// up and down freqs for all oscillators
static void myObj_upfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4);
static void myObj_downfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4);
static void myObj_smooth(t_myObj *x, t_floatarg input);
static void myObj_info(t_myObj *x);
// DSP methods
static void myObj_dsp(t_myObj *x, t_signal **sp);
static t_int *myObj_perform(t_int *w);
//void myObj_dsp64(t_myObj *x, t_object *dsp64, short *count, double samplerate,
// long maxvectorsize, long flags);
//void myObj_perform64(t_myObj *x, t_object *dsp64, double **ins, long numins,
// double **outs, long numouts, long sampleframes, long flags, void *userparam);
//
static void *myObj_new( t_symbol *s, int argc, t_atom *argv);
//void myObj_assist(t_myObj *x, void *b, long m, long a, char *s);
void vb_fourses_tilde_setup(void) {
t_class *c;
myObj_class = class_new(gensym("vb_fourses~"), (t_newmethod)myObj_new, 0, sizeof(t_myObj),
0, A_GIMME, NULL);
c = myObj_class;
class_addmethod(c, (t_method)myObj_dsp, gensym("dsp"), A_CANT, 0);
// class_addmethod(c, (t_method)myObj_dsp64, gensym("dsp64"), A_CANT, 0);
class_addmethod(c, (t_method)myObj_smooth, gensym("smooth"), A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_hilim, gensym("hilim"), A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_lolim, gensym("lolim"), A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_upfreq, gensym("upfreq"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_downfreq, gensym("downfreq"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_addmethod(c, (t_method)myObj_info, gensym("info"), 0);
//class_addmethod(c, (t_method)myObj_assist, "assist", A_CANT,0);
CLASS_MAINSIGNALIN(myObj_class, t_myObj, x_f);
// class_dspinit(c);
// class_register(CLASS_BOX, c);
post("vb_fourses~ by volker b?hm\n");
// return 0;
}
static void myObj_smooth(t_myObj *x, t_floatarg input) {
// input = CLAMP(input, 0., 1.);
if (input < 0.) input = 0;
if (input > 1.) input = 1;
x->smoother = 0.01 - pow(input,0.2)*0.01;
}
static void myObj_hilim(t_myObj *x, t_floatarg input) {
x->fourses[0].val = input; // store global high limit in fourses[0]
}
static void myObj_lolim(t_myObj *x, t_floatarg input) {
x->fourses[5].val = input; // store global low limit in fourses[5]
}
static void myObj_upfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4) {
x->fourses[1].inc = fabs(freq1)*4*x->r_sr;
x->fourses[2].inc = fabs(freq2)*4*x->r_sr;
x->fourses[3].inc = fabs(freq3)*4*x->r_sr;
x->fourses[4].inc = fabs(freq4)*4*x->r_sr;
}
static void myObj_downfreq(t_myObj *x, t_floatarg freq1, t_floatarg freq2, t_floatarg freq3, t_floatarg freq4) {
x->fourses[1].dec = fabs(freq1)*-4*x->r_sr;
x->fourses[2].dec = fabs(freq2)*-4*x->r_sr;
x->fourses[3].dec = fabs(freq3)*-4*x->r_sr;
x->fourses[4].dec = fabs(freq4)*-4*x->r_sr;
}
//#pragma mark 64bit dsp-loop ------------------
//void myObj_dsp64(t_myObj *x, t_object *dsp64, short *count, double samplerate,
// long maxvectorsize, long flags) {
// object_method(dsp64, gensym("dsp_add64"), x, myObj_perform64, 0, NULL);
//
// if(samplerate<=0) x->r_sr = 1.0/44100.0;
// else x->r_sr = 1.0/samplerate;
//
//
//}
//static void myObj_perform64(t_myObj *x, t_object *dsp64, double **ins, long numins,
// double **outs, long numouts, long sampleframes, long flags, void *userparam){
//
// t_double **output = outs;
// int vs = sampleframes;
// t_horse *fourses = x->fourses;
// double val, c, hilim, lolim;
// int i, n;
//
// if (x->x_obj.z_disabled)
// return;
//
// c = x->smoother;
// hilim = fourses[0].val;
// lolim = fourses[5].val;
//
// for(i=0; i<vs; i++)
// {
// for(n=1; n<=NUMFOURSES; n++) {
// // smoother
// fourses[n].incy = fourses[n].inc*c + fourses[n].incym1*(1-c);
// fourses[n].incym1 = fourses[n].incy;
//
// fourses[n].decy = fourses[n].dec*c + fourses[n].decym1*(1-c);
// fourses[n].decym1 = fourses[n].decy;
//
// val = fourses[n].val;
// val += fourses[n].adder;
//
// if(val <= fourses[n+1].val || val <= lolim ) {
// fourses[n].adder = fourses[n].incy;
// }
// else if( val >= fourses[n-1].val || val >= hilim ) {
// fourses[n].adder = fourses[n].decy;
// }
//
// output[n-1][i] = val;
//
// fourses[n].val = val;
// }
// }
//
// return;
//
//}
//#pragma mark 32bit dsp-loop ------------------
static void myObj_dsp(t_myObj *x, t_signal **sp)
{
dsp_add(myObj_perform, 6, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n);
if(sp[0]->s_sr<=0)
x->r_sr = 1.0/44100.0;
else x->r_sr = 1.0/sp[0]->s_sr;
}
static t_int *myObj_perform(t_int *w)
{
t_myObj *x = (t_myObj*)(w[1]);
t_float *out1 = (float *)(w[2]);
t_float *out2 = (float *)(w[3]);
t_float *out3 = (float *)(w[4]);
t_float *out4 = (float *)(w[5]);
int vs = (int)(w[6]);
// Hm... not sure about this member. I don't think we can disable individual
// objects in Pd...
// if (x->x_obj.z_disabled)
// goto out;
t_horse *fourses = x->fourses;
double val, c, hilim, lolim;
int i, n;
c = x->smoother;
hilim = fourses[0].val;
lolim = fourses[5].val;
for(i=0; i<vs; i++)
{
for(n=1; n<=NUMFOURSES; n++) {
// smoother
fourses[n].incy = fourses[n].inc*c + fourses[n].incym1*(1-c);
fourses[n].incym1 = fourses[n].incy;
fourses[n].decy = fourses[n].dec*c + fourses[n].decym1*(1-c);
fourses[n].decym1 = fourses[n].decy;
val = fourses[n].val;
val += fourses[n].adder;
if(val <= fourses[n+1].val || val <= lolim ) {
fourses[n].adder = fourses[n].incy;
}
else if( val >= fourses[n-1].val || val >= hilim ) {
fourses[n].adder = fourses[n].decy;
}
fourses[n].val = val;
}
out1[i] = fourses[1].val;
out2[i] = fourses[2].val;
out3[i] = fourses[3].val;
out4[i] = fourses[4].val;
}
//out:
return w+7;
}
static void myObj_info(t_myObj *x) {
int i;
// only fourses 1 to 4 are used
post("----- fourses.info -------");
for(i=1; i<=NUMFOURSES; i++) {
post("fourses[%ld].val = %f", i, x->fourses[i].val);
post("fourses[%ld].inc = %f", i, x->fourses[i].inc);
post("fourses[%ld].dec = %f", i, x->fourses[i].dec);
post("fourses[%ld].adder = %f", i, x->fourses[i].adder);
}
post("------ end -------");
}
void *myObj_new(t_symbol *s, int argc, t_atom *argv)
{
t_myObj *x = (t_myObj *)pd_new(myObj_class);
// dsp_setup((t_pxobject*)x, 0);
outlet_new((t_object *)x, &s_signal);
outlet_new((t_object *)x, &s_signal);
outlet_new((t_object *)x, &s_signal);
outlet_new((t_object *)x, &s_signal);
x->r_sr = 1.0/sys_getsr();
if(sys_getsr() <= 0)
x->r_sr = 1.0/44100.f;
int i;
for(i=1; i<=NUMFOURSES; i++) {
x->fourses[i].val = 0.;
x->fourses[i].inc = 0.01;
x->fourses[i].dec = -0.01;
x->fourses[i].adder = x->fourses[i].inc;
}
x->fourses[0].val = 1.; // dummy 'horse' only used as high limit for fourses[1]
x->fourses[5].val = -1.; // dummy 'horse' only used as low limit for fourses[4]
x->smoother = 0.01;
return x;
}
//void myObj_assist(t_myObj *x, void *b, long m, long a, char *s) {
// if (m==1) {
// switch(a) {
// case 0: sprintf (s,"message inlet"); break;
// }
// }
// else {
// switch(a) {
// case 0: sprintf (s,"(signal) signal out osc1"); break;
// case 1: sprintf(s, "(signal) signal out osc2"); break;
// case 2: sprintf(s, "(signal) signal out osc3"); break;
// case 3: sprintf(s, "(signal) signal out osc4"); break;
// }
//
// }
//}
PD .48 on Raspberry Pi 3? [EDIT: updated to PD .51]
Tutorial to compile Pure-data 0.51-4 on Raspberry Pi with Jack support:
STEP1. Open Terminal:
Ctrl+Alt+T
STEP2. Creating folder to organize compilation (optional):
mkdir src
STEP3. Enter in src folder / install dependencies / download pd source code / unpack downloaded file:
cd src
sudo apt install build-essential autoconf automake libtool gettext git libasound2-dev libjack-jackd2-dev libfftw3-3 libfftw3-dev tcl tk
wget http://msp.ucsd.edu/Software/pd-0.51-4.src.tar.gz
tar -xzf pd-0.51-4.src.tar.gz
STEP4. Compiling Pd:
cd pd-0.51-4
./autogen.sh
./configure --enable-jack --enable-fftw
make
STEP5. Confirming if compilation are ok:
cd bin
./pd
STEP6. If it run, you can install Pd in your raspbian:
cd ..
sudo make install
It don't install fancy icons with desktop integration, if you need that, you need to do it manually.
hope it help!
Changelog:
2021.05.24
- update to compile newest Pd version (Pd-0.51-4)
2020.09.16
- update to compile newest Pd version (Pd-0.51-2)
2020.06.17
- update tutorial to compile newest Pd version (Pd-0.51-0)
2018.09.25
-
remove clone pure-data git repository step to download Pd-0.49 from miller's site in STEP3.
-
unpack file downlaoded via command line in STEP3
Camomile v1.0.1 - An audio plugin with Pure Data embedded
Thanks for the info @Pierre-Guillot!
@Pierre-Guillot said:
I argue that adding external is just a matter of incorporating them in libpd.dll. Am I right?
Yes but the libpd used by Camomile is the static library (.lib/.so/.a) that why libpd is embedded in Camomile.
- In fact, I guess that some of the external libraries are already compatible with multiinstance support because it depends on what parts of the Pd API the libraries use. But to ensure the multiinstance support you must use the C flags
-DPDINSTANCE=1
(and-DPDTHREAD=1
) while compiling the library or libpd and avoid all the static variables (except if they use thread local storage and you ensure to init them well on each thread). Here is one of the 1st posts by Miller about it: https://lists.puredata.info/pipermail/pd-dev/2017-04/020980.html
So i guess i have to remove directly from the external code all the static variable, so basically remove the "static" keyword from the variable declarations.
How can i compile libpd as a .lib/.so/.a and not .dll?
Should i use those flags in the various makefiles or just as a fleg in the command line? (assuming working with msys2 on Win64)
- The same way you did it for the "standard" approach.
So it's enough to use a x64 compiler and a x64 target?
- Including an external library with libpd is pretty straightforward (as long as, in this case, the library has the multiinstance support). See this: https://github.com/libpd/libpd/wiki/Adding-Pure-Data-external-libraries-to-your-project. And if a library is included in libpd it will also be included in Camomile.
So you also have to compile libpd then Camomile (all the instructions are on the Github repository - I updated it a week ago https://github.com/pierreguillot/Camomile/tree/dev/v1.0.6-lv2#compilation - or just do the same steps as on Travis and Appveyor and I can help if needed).
Cheers
I don't really know what Travis and Appeveyor are. I have to check them out.
How to include the static pthread lib for Win compilation? You mention it the Camomile build process readme.
PS: Another approach would have been to ship the libpd dynamic library next to each plugin. i need to try this but I afraid that, on Windows and Linux, the DAW think that the libpd library is another plugin try to load it.
I guess that most hosts have an avoid list for specific .dll. At least Reaper have a config file where is possible to remove a specific .dll from being scanned as a plugin.
thanks!
Purr Data 2.5.0
Some report after testing Purr Data compiled for Win64.
-
I have a strange bug related to MIDI device. I'll have to check if it exists in PD vanilla 32 bit. I have the same bug in PD vanilla for 64bit compiled by Lucas. I don't think it is a multiclient midi driver issue. But i'll check it better. BTW if i choose a MIDI device and apply so it goes saved for the next start of Purr Data..well Purr Data doesn't start anymore and i have to clean the prefs via regedit because it seems that a command line pd.exe -nomidi does not work for Purr Data as it does with Vanilla
-
zexy library does not work even if the .dll externals files are compiled. I have to check the build log because i remember there were some red warnings about specific zexy externals. So every zexy help file i tried shows red outlined externals because the zexy stuff can't be instantiated.
-
there are minor naming errors in some help files that i guess are in the official Purr Data 32bit release (i.e. linearpan~ in pan lib should be linear_pan~
-
timestretch~ just crash Purr Data and the program quits.
-
moocow folder is empty
-
pixelTango does not work but i guess it has something to do with Gem externals dependencies
-
SMLib help file is not present
-
pmpd loads but does not seem to work
-
Gem and fluidsynth~ don't compile for win64 target (so as you know i removed those from the building process)
TimbreID On Raspberry Pi
Compiling only TimbreId against pd (not compiling pd source).
To load timbreIDLib, list the path to the timbreIDLib library file in Pd's startup dialog (e.g., /home/yourname/pd_libs/timbreID/timbreIDLib).
timbreID version 0.7 requires the FFTW library, available at http://www.fftw.org.
FFTW is included pre-compiled with timbreID's Windows binary package available through deken. It's fine to simply leave libfftw3f-3.dll in the timbreID directory for use as a shared library. For Linux and Macintosh, FFTW is statically linked with the timbreIDLib library file, so there is no need for compiling or obtaining FFTW.
If you are compliling FFTW yourself, it must be compiled in single precision. To do so in Linux, configure FFTW like this:
./configure CFLAGS="-fPIC" --enable-float
and like this on a Macintosh:
./configure CFLAGS="-arch i386 -arch x86_64" --enable-float
Then run:
make
sudo make install
The FFTW library for Windows is available precompiled at:
http://www.fftw.org/install/windows.html
You will need the 32-bit version, and the single precision version specifically. The provided zip file contains several compiled versions of FFTW, but only libfftw3f-3.dll is required for timbreID version 0.7.
On Linux and Macintosh, the FFTW library files should be installed to /usr/local/lib by default. Once FFTW is properly built and installed, you can make timbreID using the included Makefile by running:
make
You must specify the location of your Pure Data source code directory in the Makefile beforehand. Compilation from source on Windows can be done with the same Makefile if you use MinGW: http://www.mingw.org
On Linux and Macintosh, timbreIDLib will statically link the FFTW library. On Windows, you will either have to set up an environment variable to point to the location of libfftw3f-3.dll, or simply put libfftw3f-3.dll directly in the timbreID directory.
Cheers~
[struct] / [pointer] object limitation?
Thanks for chiming in @jancsika. You confirmed what I thought about the "stack overflow" counter. Pondering the issue more, I think what I am trying to get at is the difference between memory overflows and CPU overflows. These seem like very different things, although they are covered by the same error message. I'm going to elaborate my question, because I suspect that you do know the answer, if only I can communicate clearly.
My intuition tells me that the first example I posted uses a lot more memory than the second, precisely because it has to remember the numbers 0-98 before it gets to print anything. If the process continued for long enough, it would lead to a memory overflow, ie. the stack would be required to store more numbers than its capacity allows. This is what the "stack overflow" counter is there to protect against.
In the second example, however, the memory overflow doesn't seem to enter the picture. The number is forwarded to the print object and "forgotten" before it is sent back to the top. So if the second example were run without [moses] or any other safety limit, it would not eat up the memory. It would, of course, lead to a CPU overflow, since the process would never terminate, and the computer would still crash if the "stack overflow" counter failed to intervene. But it would crash for a very different reason than the first example, ie. because of a CPU overflow, not a memory overflow.
Does my reasoning here seem correct? Is there anything I've overlooked?
I'll now give some context to my question, because you're probably wondering why I care so much about these details. The context is Context, the library that I'm building. Context uses a lot of recursive functions similar to the second example that I posted, and I'm trying to decide whether or not it's worth rebuilding them using [until]. This would be a lot of work, but there are two reasons why it might be worth doing: 1: Because it would make Context more efficient, and 2: Because recursion will lead to unwanted error messages, as @ingox pointed out.
I am currently much more interested in 1 than in 2. For whatever reason, unwanted error messages have not been a problem for me so far (perhaps because I haven't reached the limit). As for efficiency, the standard answer seems to be that it doesn't make an appreciable difference on modern computers, but in fact I am finding reasons to care about it. Context has a heavy loading procedure, involving several recursive algorithms of the type I've outlined in the second example. Load time is something I care about because it can lead to audio dropouts, hence I am trying to decide whether or not I need to replace my recursive systems with iterative [until] based systems. I ran a simple test* for one such system and found that the recursive system actually seemed to run faster than the iterative counterpart, contrary to what I had expected. This makes me inclined to stick with recursion, but I'd like to know if there is anything that I have failed to consider.
*I can provide more details about this test you like, but I'm worried that if I do so now it would lead to a memory to overflow!
IAC Driver
I'm going to have to plead myself stumped once more I'm afraid. I really like the concept of MIDI routing without using Audio/MIDI setup, and MidiPatchbay is easy enough to use, but the patch is still not connecting as I had expected it to (somebody only barely understands the basics of computer science if claiming so isn't hubris on my part). My process is as follows:
-
Start MIDIPatchbay, create a single universal MIDI strip with both input and output - name "PD-Input"/"PD-Output" for reference. Allows all notes, allows all messages, clocks in real-time.
-
The patch itself doesn't show up in Audio/MIDI setup. That's fine, as I understand it the MIDI signal is traveling through MIDIPatchbay anyways. IAC is turned off and no software instruments are installed. I can close down Audio/MIDI setup and ignore it.
-
Start Mainstage, make sure that the volume is up, a patch is readied, and that Mainstage recognizes that there is a MIDI input available. Mainstage recognizes "1 MIDI input available"
-
Start PD-Extended and open the Sequencer patch.
-
Go through the process of making sure all components of the patch are functioning (it has a sequence tempo set, all the notes are active, volume is up, all the usual goodies).
-
Check DSP to on (I don't think it's necessary, but I tend to idiot proof my processes).
-
Set MIDI output from PD-Extended to "PD-Input" from MIDIPatchbay.
At this point I have all three pieces of software running, I believe in the correct order, and connected to one another with the only glitch being that I don't get a lick of audio. I'll dump the patch here for reference:
I try to keep things fairly self-explanatory in terms of sends/receives and with comments within the object arrangement, but here's hoping it's legible. If the problem is in the coding of the patch I can take it across to that section of the forum. That said, even making a simple patch to create a note with set number, velocity, and duration on manual bang and send through the midiout doesn't seem to be arriving to Mainstage. I suppose I could use one of my other programs capable of MIDI synthesis, but that seems superfluous.
I really appreciate the help, I've worked with PD less frequently over the past five years or so than when I was first learning the ropes; it always seems like I have to re-learn a few things as well as double check on my knowledge of possible objects to use... Always something new.