From the original SynthMaker forum (2004–2014), with its members’ names and dates.
theod ·
Hello to all! I have downloaded the free version of SM in order to get a "feel" of the program and see what I can create with it. I'm fairly imaginative (lol) but have absolutely no knowledge of C++ so I thought SM would be a cool place for me to start. I have in the past created a few things, mainly for personal use, in MaxForLive and I can pretty much do a lot of maths to process data so Im not a complete "alien" to the software.
I have also spent a LOT of hours, reading topics in this very forum in order to avoid asking the same boring questions that some of you guys might have seen like 1000 times.
I started creating a VST effect in SM in order to get a feel of the program - sort of like doing my own tutorial, gathered a lot of usefull info and modules from this forum and the Wiki. I even found a software to automatically create animated knobs (imagine the patience I had, to manually create in photoshop a 61 frames animated knob before discovering the automated program)
So on to my questions:
1. I managed to create a host-synced LFO, meaning I was able to translate values of a knob to BPM divisions of my host's BPM so I can have an LFO cycle of 1/32, 1/64 and so on. I have seen a lot of posts about SM's bad timing accuracy and Im not sure how I can check that as it will play a part in my decision to buy the program.
Specifically Im getting the tempo of the host and divide it to get Hz (tempo/7.5=32nds in Hz, tempo/15=16ths in Hz and so on) and then use "Hz to 0-1" to "feed" the LFO's frequency input. Would you say this method is accurate?
2. Even though with the above process the LFO seems to be synced to host, how can I also hard-sync its phase, meaning what if I want to start my sine LFO at precisely the start of a bar? I did notice some related modules but I have no clue how these are used.
3.If the two above can be achieved correctly, could I perhaps use some sort of synced LFO to drive a midi sequencer (I ve seen all the posts saying that midi timing in SM is very poor) so Im wondering
More general questions:
4.I wont deny the fact that Im flirting with the idea of creating commercial plug ins with SM (of course this would take me time but I dont mind). If that would be the case, Id prefer if the end user could never find out what I used to make the plug ins. As I 've noticed, the mouse cursor over the knobs is a straight give-away. is there any way to define a custom cursor for when over the knobs or other "clickable" elements?
5. I want to deeply comprehend how the data is manipulated by some primitives and modules of the program. For example a switch is outputing 0 and 1s depending on its state - logical. Why isnt a trigger outputing 1s when pressed, 0s when released?
6. Can any change of Integer be used as a trigger? (perhaps these questions come from a MaxForLive way of working)
EDIT: Nevermind, stupid question, I tested ot and saw the results - any change of integer or float value can be interpreted as trigger indeed
7. In some case after some weird maths with floats, I noticed the float showing a value of 0.001364e594 or something like that....What does that e stand for?
8.I tried to export a VST with the PPQ primitive and a poly readout to just see what data it spits out....Got nothing...why is that?
9. Seems to me like the manual has been left behind - it covers some of the basics and thats that. Also in some sections it obviously reffers to things in the program which must have been in previous versions and not the current one. What gives?
10. Is there a primitive I havent discovered that can do a conversion of a float range to another float range - for example take a range of -1 to 1 and "map" (sorry, MaxForLive again) it to a range of 0 to 1?
I do know the maths to do it* but it seems to me like an ommision to not have such a primitive.
11. finally, could someone help me comprehend the "essence" of what a stream is, what a "mono" stream is and what a "poly" stream is. Not the description from the manual but the pure essence - perhaps. I mean, if someone asked me what float and float array difference is Id say float is a "number" and "float array" is a series of lots of numbers.
Thanks in advance for your patience reading all the above! 😉
trogluddite ·
Hello theod, welcome to the forum.
Good to see you have been reading up - intelligent questions are so much easier to answer!
I'll try to answer what I can as briefly as possible, and give a few pointers for further research...
1) As long as your LFO is all in streams (blue or white), it will be pretty accurate - you should mostly get to the end of a song before noticing even the tiniest bit of drift. It's only when you use the triggered (green) data types that the timing becomes (very!) slack.
2) The key to phase lock is to use the PPQ Position and/or Bar Position primitives - they output a number indicating the host's precise cursor position, with whole numbers representing beats (or bars). If you search "PPQ" you will find a few examples on the forum.
3) This is where the timing problems will take effect. MIDI events can only be generated by using the green triggering, which has a maximum "sample rate" of around 60Hz, and terrible timing jitter. You can sample a stream PPQ into a green signal to prevent long term drift, but the event timing will still be pretty awful.
Sequencing a self-contained sound source (i.e. within the SM plugin) can be done accurately, but not a sequencer for controlling other plugins or hardware via MIDI.
4) No, the cursor graphics are set in stone - you can hide the cursor when dragging, but that's about it. There are also other tell-tale signs that you may have used SM (e.g. size of the plugin .dll)
5) All 'green' data includes a trigger whenever the value changes - this enables the data to only be processed when something 'happens' - thus saving CPU power when there is no user interaction via the plugin's GUI.
As you have found, some controls and modules send only triggers, with no attached data - these are used by modules with a 'Do it now' trigger input to set a task in motion.
6) see (5). This applies to everything except the blue and white stream data types - all of the other kinds of connection use triggers.
7) This is a maths convention for indicating very large or small numbers. It is known as scientific (or exponential) notation - the Wikipedia article HERE has a good description.
8) You will need to use a mono readout rather than poly for this - see (11) for why this is...
9) No argument there - the documentation is absolute pants!
10) Like the documentation, the toolbox also has many glaring omissions! However, once you have created a module to do your maths, you can drag it into your toolbox and re-use it as often as you like (custom toolbox modules are 'global'; i.e. not specific to a particular .osm file)
11) A stream is basically 'real-time' data - i.e. any signal that is calculated at the sample rate of your soundcard. It's best to think of it that way rather than thinking of it as 'audio', as many other signals (e.g. modulation sources) might also be running at sample rate. This is in contrast to the 'Green' triggered data, which is only processed when required.
The difference between mono and poly has to do with synthesiser voices...
A mono signal will be running at all times - even if there is no audio actually present and no MIDI notes playing. This is used mostly for programming effects and processing audio from a soundcard input or sequencer audio track.
in contrast a poly signal is used by a synth to generate sound only when notes are played via MIDI input, under the control of the MIDI to Voices module. They use a primitive form of parallel processing to create multiple instances of any poly sections of a schematic, so that those parts are duplicated once for each note that is playing. That means that poly sections only use as much CPU as is needed for the number of notes currently held.
This is why your poly readout from your PPQ primitive didn't work - without a MIDI to Voices module or any MIDI notes playing, poly sections effectively don't exist.
The majority of stream components will auto-detect whether they should be poly or mono according to how you use them - there are toolbox modules to convert between the two when required. Note that turning a poly signal into a mono one will sum together the poly values from all currently playing notes - thus, 'mixing down' all the notes into a single stream ready for adding effects or sending to the plugin output.
Happy Synthmaking!
nix ·
Hello, and welcome!
HGope u have have a lot of fun with SM.
I will have a go at answering ur questions, maybe someone else can expand and correct me.
1. Your LFO would be quite accurate. The mono and poly streams operate at samplerate. Using an oscillator as an LFO, I imagine the timing would be accurate enough for say a 5 min track. It may actually be sample accurate. If you used a float array with the sine,triangle etc. plotted and a counter to read it, it would be sample accurate.
2.If you make your LFO in mono(blue) it will be free running. If you make it poly(white) it will retrigger from the same place on MIDI note on. If you use the counter method you can reset the counter whenever you like. You can use the sync input on the osc, if using an osc prim.
3.Internal timing can be sample accurate, as you can use the streams, but if you want to go to MIDI, the 'MIDI event' prim needs a green trigger to trigger it. Essentially u can only run at an uneven 100hz with green tick trigger sadly.
4.Yes, I think so.
5.The trigger doesn't actually output a number, only a trigger.
6.Yes, there is 'integer changed trigger' module
7. Sorry, I don't know how to read these values. They are very small figures though.
8.The poly readout needs a MIDI note on connected to it before it will display the value. Perhaps that is why it didn't. You could try with 'mono readout', just make sure your host is active, ie. press play.
9.Try the Wiki man, maybe better, but still some omissions.
10. You could build that module urself, I haven't seen it before.
11.mono is an ordinary audio stream, except values can be DC and beyond -1 to 1.
poly is polyphonic stream containing note data for chords. It transmits more than one number at a time.
Cheers chap, happy to try and answer further
edit-I see trog has answered, I'll post anyway, maybe more information is better
Honestly, this is simple math. Expect more complicated stuff if you want to do any programming, be it Max or SM.
If you have Max, don't bother with SM; you already have more that we do.
theod ·
Wow! Thanks for the fast replies guys.
at Trogludite:
Thanks a lot for the info and food for thought. See, in my mind I was conceptualising green data as triggers (I was right in that) but I couldnt quite conceptualize the different between poly and mono due to the fact that I just interpreted them as "audio signals". Your no11 answer eally put things into perspective and solved half my questions.
I do understand the need to differentiate poly and mono when working with synths (VSTi) - or I think I do, but I want to focus on the VST effect side of things, so this means, as I ve understood,processing mono or packed mono4 signals.
So, I was wondering why the hell my LFO's grey stream output would become mono when connected to a SV3 which has mono in and out - in other words the SVF3 became blue the minute I used it as a filter VST (blue in - out) but I couldnt figure out why the hell should the "freq" input and the "resonance" input would go blue. I mean, my mentality was, hey this should be green (float data).
So I guess the reason is that since we want to manipulate a mono stream - even with our own float data- they have to be in mono in order to say ermmmmm keep up with the job (being sample accurate)? But then again, couldnt "poly" keep up with the job instead of turning it to a mono which (as I read) eats CPU regardless of the signal passing thorugh or not? But can I interpret the signal of an LFO as poly - it really isnt a "polyphonic stream" of data, is it?
Ok, ok an example, the below VST effect works when exported.....I really cant figure out the difference and which way is the best (referring to the data manipulation difference between channel 1 and channel 2)
Any clues? If they both are correct, which one is, theoretically, lighter in CPU?
*EDIT for clarification: I created the above simple effect only to test and try to discover answers to my questions, I know I should have packed the mono ins into a mono4*
Yup, as dictated by the equation I posted in asterisk. Not to be a smartass however, I had googled to find a solution because I too thought it's simple math and a bit of ashamed I couldnt figure it out without googling and I surely know you need to manipulate more complicated stuff to code quality stuff. Im having a "one step at a time" mentality right now! 😉
As far as MaxForLive goes, it is quite powerful, and a different kind of projects can be done with it,(mainly interactional stuff the way I see it) but the end product requires from the users to have MaxForLive too. I wanted to ermmm lets say start to create simple VSTs of some ideas I have that I could also share with others, mainly VST FX - for free just for the process of learning and IF (a big IF) they were ever valued to be paid, then why not? Anyways...
Again thanks for all your replies! Digging back in....
trogluddite ·
Hi again,
For an effect, your top schematic would be the correct one to use - as you say, there is no need to use poly unless you want to make a polyphonic synth.
The colour changing is perfectly normal.
The basic code used inside most modules etc. is 'universal' - they will often work with poly or mono as the situation demands - but there are sufficient differences between poly and mono that stream modules need to be strictly one or the other. Hence, until they are linked up, they will have 'undecided' grey connectors. As soon as you make some links, they will look at what is at the other end of the link, and take on the appropriate colour and data type.
Due to the underlying code being so similar, you can force poly links into mono connections and vice versa - but this is not advisable, as the results are very unpredictable!
The issue with floats is kind of complicated by the terminology used!
A float (floating point) is simply a number that can have any numerical value - i.e. possibly with stuff after the decimal point; as opposed to integers (only whole numbers), boolean (on=1/off=0) and strings (text characters). In SM, 'float' is usually used to mean the 'Green' triggered float data.
However, in reality, the numbers in a stream are also float numbers - exactly the same number format, the only difference is in the speed of operation (stream = sample rate, always running : green = slow rate, only runs when triggered).
Because of this, you can always plug a green float into a stream input - poly or mono - to get your control values into a stream module. In fact you can also plug integers and booleans into streams, due to SM's clever automatic format conversion.
In your case, the LFO is a stream components - if it were to use green floats, the waveform coming out of it would not be 'smooth', and the modulation of the filter would be noticably 'lumpy'. therefore, the maths modules between the LFO and filter must also be stream components in order to keep the 'processing speed' consistent for the whole signal chain.
BTW) Infuzion's comment about the scaling, and your answer, provide one reason why there is not a scaling module. Most often, the situation is like your example, where the maths factorises down to a much simpler equation.
If there were a general purpose module, it would far too tempting to use it in places where is would be using more CPU power than is really necessary.
The extra thinking involved in finding a more optimum solution is very valuable training for the kinds of problems that you will have to solve regularly when making SM schematics.
theod ·
However, in reality, the numbers in a stream are also float numbers - exactly the same number format, the only difference is in the speed of operation (stream = sample rate, always running : green = slow rate, only runs when triggered).
Exactly what was confusing me, but with your replies, I fully comprehend now.
I am totally covered. Couldnt expect more spot-on info, thank you very much.....taking it all in, doing further research, and probably will be back with my OSMs.
Thanks a lot!
EDIT
Oh, oh one last thing: I know that when developing such things, its not only the operation that counts, but also how heavy it is for the CPU. So I'd like to learn the "correct" way, and not the "just make it work, waste 80% CPU" way so I need to ask one last thing:
As far CPU usage is concerned, I assume the more the calculations the more the usage. If the insertion-creation of an object in the schematic "saves" calculations that means we save CPU usage, correct? How does the size of the dll resulting affects performance? I mean is there a point where one could argue "hey you 've gone too far with all those trigger blockers and whatnot to minimize calculations but all these object aditions affect performance"?
I swear, this was my last question..........................................
................................................................................................for this week! 😀
trogluddite ·
The effect on CPU usage is very different for mono, poly, and green parts, to summarise...
mono (and mono4)
These parts are always running, so yes, reducing the component count (and optimising any code and assembly components) will almost always reduce the CPU hit. Most of the optimisations are not SM specific, they apply to any kind of programming 'language'. - e.g. Divides are most costly than multiplies, subtracts more costly than adding etc.
A big CPU saver is to use mono4 where the same effect is used on multiple channels (e.g. processing stereo audio) - you can process four channels for the price of one!
The other big CPU saver is to disconnect (with selectors) the outputs of any modules that are 'bypassed'. A stream module with its outputs disconnected will go to sleep and use no CPU at all. This also applies to any long chain of modules that all feed to the same disconnected parts. But note - disconnecting inputs to a module doesn't have this effect - only the outputs!
When making stream parts, it's always worth having a good think about what sections might be better off done using green triggered data. For example, say you have an effect where you need to divide values by the current sample rate - you know that the sample rate is only going to be changed very very rarely, and also that dividing is a relatively costly calculation. So you could calculate "1/sample rate" in green parts, and then use this value to multiply in the stream sections - the .dll would be a little bigger, but you'd save CPU because the divide is done only once when a change in sample rate triggers your green section.
poly
These only run when the MIDI to Voices module is actually playing notes - they use the same kind of processing as mono4, so four notes of polyphony consumes the same CPU as one note. Restricting the number of voices in the properties can be a good CPU saver with e.g. long release pad sounds - though probably best to make that a GUI option so that the end user can decide for themselves what compromises to make.
In other respects, the 'optimising' rules are the same as for mono.
triggered data
Slightly different - sometimes adding more components (e.g. trigger blockers, sample and hold) can reduce the CPU load by limiting the number of triggers, or the number of modules through which the triggers pass. This is particularly true of GUI elements - SM's screen redrawing is unusually inefficient, so anything that reduces screen updates, or the size of updated areas, is always welcome - even if it makes a schematic more complex. If you search 'GUI CPU load', you will find several threads with good tips for this.
There are some triggered parts that you do need to be careful with - for instance the 'integer loop' and 'draw loop' send out rapid flurries of triggers when they are started; and manipulating very large arrays (particularly string arrays) will always be rather greedy.
The main rule is that the CPU load is only due to what parts of the schematic are running at the time - for example, you could have an effects rack with a choice of a dozen or more effects - but if in real use, most of them would be turned off, the bypassed effects will not consume any CPU.
Note that SM will always produce large .dll sizes, and SM VST's will generally load slower than regular ones - this is because the .dll actually contains a copy of the schematic, plus a 'run-time' version of the SM environment. This is to enable the plugin to be compiled 'in-situ' to allow for some optimisation for specific CPU's, the 'trigger tracking' engine, and to allow the 'disconnected outputs' behaviour to work.
As you can probably tell from the forum, I could go on from here for many many pages - there are so many different optimisation 'tricks', and everyone here has their particular favourites. Your best bet, is to apply the general principles as best you can, check out forum examples, and then post up any designs that you are still unsure of - you can be sure of plenty of help, as there is always a friendly 'rivalry' between the forum guru's for the 'optimisation king' crown!
PS) I am on a promise to generate some tutorials about trigger optimisation - progress is rather slow as I'm in the middle of some 'home improvements' at the moment (hard to SM when you have to keep disconnecting the electricity!) - but keep your eyes peeled, lesson one should be complete some time this weekend, I hope.
theod ·
Great thanks a lot for all the info!
I'll be definitely on the lookout for your tutorials. 🙂
infuzion ·
theod wrote: As far as MaxForLive goes, it is quite powerful, and a different kind of projects can be done with it,(mainly interactional stuff the way I see it) but the end product requires from the users to have MaxForLive too. I wanted to ermmm lets say start to create simple VSTs of some ideas I have that I could also share with others, mainly VST FX - for free just for the process of learning and IF (a big IF) they were ever valued to be paid, then why not?
Well, my target market is DJs using Live (& other hosts). I would say here in Denver 90-95% DJs who actually buy stuff use Macs. SM will never be Mac compatible. In fact, SM may never be 64bit either; either OS or audio. Also expect about 90% the people will bootleg your software. If you are fine with SM's present limitations, & want to make VSTs for yourself & maybe make a small bit of side-money or give away free VSTs, go for it. If you really want to sell lots of VSTs; C++ is your best bet right now.
I have no idea how much DSK makes, but I know other bigger SM VST creators end up earning about /hour if that.
theod ·
Well, my target market is DJs using Live (& other hosts). I would say here in Denver 90-95% DJs who actually buy stuff use Macs. SM will never be Mac compatible. In fact, SM may never be 64bit either; either OS or audio. Also expect about 90% the people will bootleg your software. If you are fine with SM's present limitations, & want to make VSTs for yourself & maybe make a small bit of side-money or give away free VSTs, go for it. If you really want to sell lots of VSTs; C++ is your best bet right now.
I have no idea how much DSK makes, but I know other bigger SM VST creators end up earning about /hour if that.
Hear ya and that's what I 've gathered so far: you need to be a coder and designing in C++ in order to have your imagination only as a limit. I'm not sure I can find the time, or to be sincere, give priority to learningC++.....Maybe I'll invest in Synthmaker to make some small plugs for personal use-freebies for my gigs - dj sets. Still checking it out!
Wrote something here? To have a post removed or your name hidden, write to [email protected].