[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!
Commands in a colored window
@andrea63
example.zip
The patch (coloured canvas and objects) needs to be used as an abstraction...... then placed in a parent patch..... ***or as a sub-patch. Examples of both in the zip above.
Any connection lines, and all objects outside the "window" (GOP), even partially, will not appear in the parent.
The abstraction or sub-patch "canvas"...... is created and coloured to fit the "window" of the gop, and placed to create a background for the objects. In my example they are not quite the same size, but that can be corrected in their "properties".
In the abstraction example the colours are set by a message (using the first argument of the abstraction). Again, this is not necessary. The colour can be set in the canvas properties, as it has been in the sub-patch.
It's not easy to understand or explain, but I hope that helps.
David.
Maximo (Guitar Rack) - 6 slots with 1 of 60 effects per slot (using "abs_effects_router" + an OSC controller (MobMuPlat)
Maximo (Guitar Rack) - 6 slots with 1 of 60 effects per slot (using "abs_effects_router" + an OSC controller (MobMuPlat)
The app is "maximo-help.pd".
maximo is an effects-chain giving the user 6 slots each one of which may be used to select from 1 of 60 effects (the first being "unchanged").
Check her for details about how to use the "abs_effects_router", http://forum.pdpatchrepo.info/topic/10693/abs_effects_router-60-effects-in-one-abstraction-router-from-diy2-stamp-album-my-abs/1 .
It also includes
- a "maximo/admin.pd" abstraction to control:
dsp, bypass (all), reset (to set all effects to "unchanged"), and 9 presets (0 reserved for program usage) and both save-to-file and load-from-file preset buttons
- an Open Sound Control (OSC) mapper ("maximo/osc_control.pd") for sending values (0 thru 1) to controls /cc/1 thru /cc/34 (see the patch for details).
and
- an example OSC (MobMuPlat) controller at "./maximo-osc.mmp" and "./maximo-osc-mmp.pd"
MAXIMO EXAMPLE
MOBMUPLAT INTERFACE
PAGE 1
PAGE 2
PAGE 3
All of this was contingent on the foundation and resources laid out in the DIY2 and Stamp Album collections and actually this was largely an example of persistence not any real insight and the largest percentage of the success goes to their creators for being so diligent about standardizing their abstractions.
I DO however hope you find it useful.
My GOAL was to eliminate what is often the case with effect stacks (I have seen) of having to connect all the effects. This eliminates that and makes it much cleaner: only having to select from the (tof/pmenu POPUP_LIST button) or navigate to the desired effect with the standard "first, previous, next, last" controls.
I hope you find the work useful and capable of helping you to manifest all those wonderful sounds you have in your head.
Peace and only Love,
Scott
The List of Effects per slot is:
Matrices and reallocating memory
Yes, I understand. Perhaps we can create a new thread about C optimizations for real time audio. Anyway, here are some of things I do when I try to optimize my code (because I also do it sometimes ):
-
Create local variables on the stack of the perform function. For example if I need to read (usually several times) the member value of my object like this
x->f_value
, I prefer to use a local variablefloat value = x->f_value
and to use this newvalue
variable. -
Declare the variable only when they are necessary. For example, if I need to use a temporary float value at the middle of the perform method , I will declare it just before using it. But in fact, I mostly use this in C++ because in C, I encountered compilers without the C99 support and it was awful to debug and now I declare everything at the beginning of the function...
-
Avoid memory access and especially to non-adjacent memory. For example, the matrix approach that I explained is also better because you can read all the matrix by using and incrementing a single pointer (the first cell of the next row is just after the last cell of the previous one). Another example about memory access can be the use of trigonometric functions that seems to be more efficient nowadays than to create a buffer and to interpolate. Last example, if you have for example a buffer and you want to read at specific location and to write in another instead of doinf something like that:
for(...) {
val1?? = *read_ptr++;
*write_ptr++ = val2??;
}
sometimes it's better to have two loops because the memory access is adjacent
for(...) {
val1?? = *read_ptr++;
}
for(...) {
*write_ptr++ = val2??;
}
- Unroll the loop (but normally the modern compilers can do it automatically). Miller Puckette uses it a lot for basic arithmetic objects (+, -, etc.). In the dsp method, he checks if the number of samples is a multiple of 8 and if so, he uses a specific method where the loops are optimized by increment the pointers by 8 samples. That allows to optimize the code because the processors have specific instructions for this kind of approach (see SMID).
I'll try to publish an optimized version of my perform function if you want.
Small comment: you should pay attention to the precision of the floating-point numbers. After a while, you can have bad results because you increment and decrement the avg
value instead of calculating the average at each block. With a computer, something like a + b + c - a
is not necessarily equal to b + c
because a - a
can be not null. And after a lot of time, you equation looks like a1 + a2 + a3 + ... + a10009 + a10010 - a1 - a2 - a3 - ... - a10000
, so you can encounter a lot of approximations.
send list to outlet in external
Thanks for your advise about the clock method. As this is quite important, this information should be given somewhere (In externs/dspobj~.c which comes with pd for example)
That's the difficulty with Pd, sometimes the information are scattered between this forum, puredata.info, the mailing list, facebook, etc. But you already have an example in d_misc.c with the object [bang~] (and it seems that I did a mistake, you should use clock_delay instead of clock_set. I don't know if it really matters, I'll investigate the code).
What are own inlets? Is a second inlet~ already an own inlet?
Can you point me to the source of [pack]? (Couldn't find a file "pack.c" or similar in pd's repository on github.)
No, in fact inlets' pointers are pretty useless that's why almost nobody use them in their objects. But the second arguments of the inlet_new methods can be necessary (pointerinlet_new, floatinlet_new, etc.). For example, when you create a floatinlet_new, you give the adress of the float value to set. If you need to allocate memory for this, you need to free it at the destruction of your object (see [pack] in x_connective.c). But you can also use another class as an intermediary between the "real" inlet and your object, I call this a "proxy" like in Max. In the function
EXTERN t_inlet *inlet_new(t_object *owner, t_pd *dest, t_symbol *s1,
t_symbol *s2);
owner is your object, dest can be the proxy, s1 is the symbol expected by your object and s2 is the symbol that will be used for the proxy.
If you want an example, you can have a look at [clone] in g_clone.c or this example I made.
Do I have to free memory I allocated myself with malloc?
(I just started with C (coming from Python), so I'm still unsure about how things work exactly.)
Yes of course. And you can use t_getbytes and t_freebytes if you only want to include m_pd.h
[NEWBIE] How convert txt file in sound?
Hello lovely Community!
I am PD newbie and this is my first topic here!
So, I ask mercy in advance for my stupid questions
Prologue:
I am working with inertial sensors(Xsens, more precisely) and I'd like to convert in real time in sound the movement acquired by the sensors. As first step, I am doing some trial in offline, so I saved the processed data in a txt file.
Now the question:
How I can read the data from a txt file? I tried the example that I found in this tutorial
Tutorial link
Example Link
patch image
But I think that is a good solution if the txt file is not so big or have only few data...
I tried to follow also the instruction reported here:
http://forum.pdpatchrepo.info/topic/10039/how-do-i-produce-audio-using-text-files/2
But, again, I don't understand very well how to do...
Someone could help me or give me some more suggestions?
Thanks in advance
P.s. Sorry, if I use the same thread for another question...Is it possible to use pure data for converting in real time data acquired by inertial sensors?
Thanks again
Anna
How to create multiple objects at once? Many objects with increasing arguments?
@lacuna I am about to be away without internet for 3 days...... so...... I will describe how it works and post another example....
Each object that you create in the subpatch has a reference within Pd...... a number... which depends on the order in which they are created..... so.....
Your 123 objects will have numbers 1-123..........
But you want to add some other objects. If you add an [outlet~] or [*~ 0.3] before you add your abstractions then that will be object 1 and your abstractions will be objects 2-124. You must be rigorous about the order in which you place the objects.
In this example......... example.pd There are already 3 objects placed in the sub-patch...... open [pd mixer_final] to have a look.
The patch then builds the objects and connects them.....
There is a [loadbang] to say how many of each object should be created, and that creates a [matrix~] with the correct number of inputs and outputs.
Lots of error messages appear in the terminal because the rest of the patches are missing... it does not matter for this example.
The [connect( messages are formatted like this..... [connect "object number" "outlet number" "object number" "inlet number"( and the inlet and outlet numbers are counted from 0-n...... first one "0"......
I do hope that is all makes sense!
Hit the bang at the top of the patch to see everything created in the sub-patch......
David.
Pitch control for engine sound
If you're just looking to get the job done rather than learn the ins and outs of PD, then you should consider finding a pre-made sample player and adapting it to suit your needs. There are several examples in the help files: Help Browser --> 3. audio examples --> B09 to B14.
You should also check out Johannes Kreidler's tutorial, which will walk you through most of what you need to know and has more examples: http://pd-tutorial.com/english/ch03s04.html
PS. I don't think that there's an object called [soundtouch~], but pitch control can be achieved just by speeding up and slowing down the [phasor~] or [line~] that you're using to control the sample playback. By "recfiler~" you probably mean [writesf~].
Special requests
I was looking at Mike Moser-Booth's website (excellent) tutorial about FM synthesis. Here's the link :
http://www.moser-booth.com/sound2/index … =synthesis
However, what interests me is to have a few explanations, or a quick tutorial, on placements of the binary signal operators - [*~] [+~] etc. In the above tutorial(s) from .mmb the explanations are simple and easy to understand. What's interesting (for me) is when you move an [osc~] around to the other side of a operator and so notice the difference in signal, and sometimes how it effects the sound and so the waveform.
In other examples found - on the web - such as in Loadbang from Johannes Kreidler the examples are generally easy to understand, again it's interesting to notice that the operators seem to have a logic in the way they 'should' be placed, but what is it?
Anyone out there with a simple explanation or little tutorial that could clear up this grey area would be much appreciated.
Thanks in advance.
p.s. On the other hand a maths operator [+], [/],[*],[pow] etc is more logical in it's placement, which saves some confusion.
MIDI/QWERTY to DMX
Yes, it is kind of raw programming packaged with a few graphical boxes and some string, that's what is nice about it, you can do whatever you like.
But there is a lot more documentation besides the wiki, you can start here maybe:
or here
http://en.flossmanuals.net/PureData
Also on the program itself if you press ctrl+b you get lots of example patches and every object (graphical box) has a help file showing how to use it and giving some example, just right-click and choose help.
If you prefer video there are some nice tutorials on youtube like this one:
Good luck.