SynthMaker

buffer

Archive · 2005 22 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

lalo ·

hi guys!

just to share my humble trying to build some basic buffer stuff...

you have a buffer loader...you can click on it with mouse and open the wave file..

then you have a couple of slider to change the start and the end point of the buffer loop...inside the buffer read there's some logic to protect value ranges

you can choose to loop (1) or not to loop (0)

http://www.nusic.org/temps/buffer_bricks.rar

todos

1. a switch to reverse the sample (i have to figure out if i can do all in the same code component or just do another code component to read reverse...suggestions? )

2. interpolation code (i'll need to study the mathematics involved..and 'cause i'm so ignorant in math..it may require ages)

3. find a way to have an option to have clickless start and end of samples (zero crossing finding?...little ramp at start and end points? )

4. add trigger outputs that sends their 'bang' when the sample start and when it arrive to the end

and many other...

known issue to solve

1. if in 'not looped mode' (aka single shot) at the momnet the buffer is played from the 'start' to its very end..not the end specified by the relevant 'end' inlet...i have to find the right boolean mask logic i guess

another issue : the wave compnent only load the first half of the .wav file...i guess is a little bug in jorge's code for that module...we'll see 🙂 lemme know what you think

lalo

sambean ·

Nice one!

Beginnings of a proper sampler..

To get the buffer to loop backwards add

counter = counter + ( counter < 0) & (loop > 0) & duration ;

into the code, this basically loops any play values that are below zero, then you can set increment to -1 (you can remove the float max as well as you are safe with decreasing values)

Stopping the clicking of samples can be achieved later I'd say when you implement proper controls with an ADSR envelop, unless of course you wanted to envelope the whole sample (say multiply the output by sin1(length/position)) hmmm... granular synthesis....

like the sample too!

lalo ·

thanx sambean 🙂

i'm trying to rebuild the max/msp and pd objects like buffer~ groove~ record~ play~ etc...

i'll be happy to work in a collective fashion 🙂

lalo

infuzion ·

thanks lalo 😇 helps me understand how the buffer thing works

Shifrin ·

Cheers lalo,

I need to get my SM machine back up and running (doing a format/reinstall of it ATM) so I can check all this new stuff!!!

Shif.

lalo ·

thanx infuzion 🙂

i did this work just to learn ..to teach myself 🙂 it's nice is useful for other people 🙂

😍

lalo

lalo ·

sambean wrote: Nice one!

Beginnings of a proper sampler..

To get the buffer to loop backwards add

counter = counter + ( counter < 0) & (loop > 0) & duration ;

into the code, this basically loops any play values that are below zero, then you can set increment to -1 (you can remove the float max as well as you are safe with decreasing values)

Stopping the clicking of samples can be achieved later I'd say when you implement proper controls with an ADSR envelop, unless of course you wanted to envelope the whole sample (say multiply the output by sin1(length/position)) hmmm... granular synthesis....

like the sample too!

thanx for your suggestions sambean 🙂 the reverse trick is smart 🙂

a little thing is...can you explain the concept behind the sin1(length/position) ...wich in my example could be sin1(duration/index).. argh i wish not to be so bad at math 🙂 well i konw what's sin is..in plain trigonometry..but i can't grasp why you choose (length/position) as an argument

lalo

lalo ·

now with reverse code line as suggested by sambean... just type a negative value in the speed float data field....

i'll make a proper button for testing it...

feel free to make suggestions/changes....

i have a lot of features in mind for the buffer read module 🙂

http://www.nusic.org/temps/buffer_bricks.rar

lalo

sambean ·

Glad to help..

Sorry it should have been sin1(0.5 *index/duration).. (i think)

The sin1(0.5 * index/duration) is a very simple way to envelope a sound.. It probably would'nt be useful for a sampler as the shape of the envelope is too shallow.. the sound would gradually fade in and out..

By dividing index by duration and multipying by 0.5, you rescale the index to a number between 0 and 0.5, instead of say going between 0 and 44100 for a 1 second sample..

Between 0 and 0.5 on the sin1 function is the first 'bump' so by multiplying the signal by this, as the index loops, the signal will be enveloped by the 'bump'..

I'll try to post an example later

sambean ·

Here's a quick example with the sine envelope..

http://freespace.virgin.net/cc.lai/buff ... velope.osm

I've set the play speed 0.1 and added a 'peeker' so you can see the envelope value in numbers..

No clicks, but not really useful for sample playing..

Try making the loop length really short.. Thats why I mentioned granular synthesis earlier, you could have a read buffer that plays an enveloped short section of the memory, and the position of the read buffer gradually scans through the sample..

Lots to do..

Nu Audio Science ·

You guys are kickin it 🙂

lalo ·

sambean wrote: Here's a quick example with the sine envelope..

http://freespace.virgin.net/cc.lai/buff ... velope.osm

I've set the play speed 0.1 and added a 'peeker' so you can see the envelope value in numbers..

No clicks, but not really useful for sample playing..

Try making the loop length really short.. Thats why I mentioned granular synthesis earlier, you could have a read buffer that plays an enveloped short section of the memory, and the position of the read buffer gradually scans through the sample..

Lots to do..

thanx sam 🙂 ..yes i know the granular synthesis paradigm 🙂

it will definitely a project to investigate when i'll have more SM experience

lalo

lalo ·

hi guys!

i'm back at work on this stuff.... i have to solve one problem....

if the buffer reading is not looped i'd like to have the code component 'mute' itself when the the buffer reading has reached the end....to spare cpu....otherwise the counter will continue increment itself..cpu wasting i think... any solution? a kind of IS_LOOPED and IS_OVER flags outputs from the module that controls a switcher with 2 inputs..one frome the code component and the other from a dummy one ?

lalo

lalo ·

solved i guess 🙂

mdk ·

hello, this might be more appropriate in a thread about general code, but as i was looking through the code in this example i thought it would be ok to ask here.

basically im trying to convert my normal programming understanding into understanding SM code and im a bit confused as to how these lines work :

counter = counter - ( counter > duration) & (loop > 0) & duration ; counter = counter + ( counter < 0) & (loop > 0) & duration ;

I understand that comparisons generate bit masks which are then 'applied' with the bitwise & operator, but i just cant quite follow the logic here which resets the counter back to 0.

from the first line it translates into my head something like this :

if(loop > 0 && duration > 0) { counter = counter - ( counter > duration ? 1 : 0); }

but im sure that cant be what is happening.

is it that the result of (counter > duration) is actually the value of counter?

any explanations would be great....i've got a lot of catching up to do 🙂

stefan ·

You seem to be missing that both lines end with "& duration"

counter = counter - ( counter > duration) & (loop > 0) & duration ; counter = counter + ( counter < 0) & (loop > 0) & duration ;

would translate into:

if(counter > duration && loop > 0) counter = counter - duration;

if(counter < 0 && loop > 0) counter = counter + duration;

mdk ·

ok, it was the double & in each line that was really the source of my confusion, i've seen it in quite a few places and i was struggling to make sense of what it was doing.

I thought that the & duration at the end was just another application of using the bitmask as a yes / no type operation.. i.e. it was a check the duration was greater than zero and just produced a result of zero or one..

its a lot clearer now..i just need to get the patterns for some basic code constructions figured out...

many thanks. 🙂

angstrom ·

I was wondering, why you SM Dev guys didn't choose to use

&& to represent logical And

|| to represent logical OR

in the SM code module, but instead went for the single character versions? especially with & operating as the mask.

stefan ·

angstrom wrote: I was wondering, why you SM Dev guys didn't choose to use

&& to represent logical And

|| to represent logical OR

in the SM code module, but instead went for the single character versions? especially with & operating as the mask.

Because bitwise and logical is the same thing? 🙂

angstrom ·

I thought that would be the answer 😉 , it's my unfamiliarity with masking that makes it troublesome to comprehend. I manage to use the mask system by the use of chants and spells and cautious trial right now.

so the distinction between a mask and a logical AND as used in the rest of the conditional, is that the mask simply is the last '&' in the line?

It seems odd to me that & is the mask, semantically in the code it seems to equate to 'then'

counter = counter - ( counter > duration) & (loop > 0) & duration;

Translated : if (the counter is greater than the duration, and the loop is above 0) THEN counter = counter - duration.

so why is the mask a bitwise AND (&) ? Because that implies: if (the counter is greater than the duration and the loop is above 0 ) AND counter = counter - duration.

I can't see how AND makes sense there, although it quite obviously does. 😕 feel free to point me at a microsoft dev doc, rather than typing out an explanation of SSE masks for the baffled 😉

stefan ·

Comparisons result in a bitmask. If the result of the comparison is true, all bits in the bitmask is set to one, if the result of the comparison is false, all bits are set to zero.

If you do an bitwise & with a bitmask and a value, you will get the value out if the bitmask is "true" and you will get 0.0 out if the bitmask is "false".

Hence

a = b > c & d -> mask = b > c; a = mask & d;

where & is a bitwise AND operation. in the code earlier in the thread, there's a "double" comparison, which in reality is using a logical AND operation. Here's how it works:

a = b > c & d > e & f; -> mask1 = b > c; mask2 = d > e; mask3 = mask1 & mask2; a = mask3 & f;

Everyone with me? 🙂

mdk ·

yeah, i got it 🙂

this would be a good example to add to the docs because the example currently provided is very simple and only uses 1's so I basically understood it the wrong way round 😕

even just changing the example from :

x = x - (x >= 1.0) & 1.0

to something like :

x = x - (x >= 4.0) & 2.0

is equivalent to the following C / C++ code :

if(x >= 4.0) x = x - 2.0;

could be more instructive.

anyway, thanks again...theres no stopping me now 🙂

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.