From the original SynthMaker forum (2004–2014), with its members’ names and dates.
nmakinen ·
Hello!
I'm new to this forum, but I've been working with SynthMaker for the past couple of months and it works like a dream!
What I'm looking for is something that would measure all the samples of an input signal for a given amount of time, say 5ms, and calculate which one of the samples has the greatest value. Then it would reset and start all over again for the next 5ms and so on. So it would constantly measure 5ms blocks of signal and output the max value within every block.
I'd really appreciate your help because I've been trying hard to make this work but I'm out of ideas. I'm new to coding so if there's a built in solution for this that I have missed, please let me know. Although, if you can provide me a code on this forum, I'd be really glad to work with that. Thanks!
- nmakinen
oddson ·
Here's a coded solution...
streamin x;
streamin r; // reset in samples
streamout y;
float i,max; // index and temp var for max
//reset i, max and y every r samples
i = i - (i>=r & i);
max = max - (i==0 & max);
//set max to x if x is new current max
max = max + ((x>=max) & (x - max));
// set y to current max
y = y + (i==0 & (max - y));
//increment i
i = i + 1;
nmakinen ·
Thank you! That's really close to what I need, but for me it seems it doesn't output the max values accurately all the time. I tried changing this line, just for the heck of it:
y = y + (i==0 & (max - y));
to simply
y = max;
and it seems to output the correct max values, but the lengths of the blocks now seem pretty random as you can see from the attached pictures (the one below is after the code change).
infuzion ·
Good testing nmakinen! & welcome to SM!
martinvicanek ·
Oddson's code works with a slight change in order:
streamin x;
streamin r; // reset in samples
streamout y;
float i,max; // index and temp var for max
// update y and reset max if i == 0
y = y + (i==0 & (max - y));
max = max&(i > 0);
//set max to x if x is new current max
max = max + (x>max) & (x - max);
//increment i if i < r, else reset
i = (i + 1)&(i < r);
stw ·
yes,
or if you don't want to mess variable names with code syntax (max) it could look like this:
streamin x;
streamin r; // reset in samples
streamout y;
float i,temp; // index and temp var for max
//reset i, max and y every r samples
i = i - (i>=r & i);
y = y+(i==0 & (temp-y));
//set temp to x if x is new current max
temp = (i>0)& max(temp,x); // use abs(x) to get absolute max
//increment i
i = i + 1;
lesobrod ·
Good job, guys!
What about MovingExtremum? Hope it may be helpfull...
streamin x;
streamin r; // reset in samples
streamout y;
float i,temp; // index and temp var for max
//reset i, max and y every r samples
i = i - (i>=r & i);
y = y+(i==0 & (temp-y));
//set temp to x if x is new current extremum
temp = (x<=0)& min(temp,x) +
(x>0)& max(temp,x);
//increment i
i = i + 1;
infuzion ·
lesobrod wrote: Good job, guys!
What about MovingExtremum? Hope it may be helpfull...
Neat, but seems to need tweaking. It rapidly updates some changes, but other changes it takes a few cycles? Slope seems to have some effect, but some slopes that look visually the same may or may not be quickly updated?
Xtinct ·
It seems like oddsons original post is the closest to the solution to the problem, but instead of sample and holding the value for 5ms it needs to readthe values find the max then hold for 5ms which means it will always look wrong on the dual scope as the output wll always be 5ms behind the input
oddson ·
Sorry for screwing this up... I think I had it working and then tried to simplify and comment the code but broke it in the process... using max for a variable was a bad idea too...
infuzion ·
?
So what is the correct method then?
This is mine from months ago.
streamin inA;streamin countMax;
streamout outMaxWindow;
float count=0;
float F1=1;
movaps xmm0,inA;
//reset oldMax every countMax
movaps xmm2,count;
movaps xmm3,xmm2;
cmpps xmm2,countMax,1;
addps xmm3,F1;
andps xmm3,xmm2;
movaps count,xmm3;
andps xmm2,outMaxWindow; //reset if over countMax
maxps xmm0,xmm2;
//movaps oldMax,xmm0;
movaps outMaxWindow,xmm0;
bootsy ·
you might also simply consider the AHR envelope follower function which is floating here around somewhere, depending what the overall goal is.
lesobrod ·
infuzion wrote: ?
So what is the correct method then?
This is mine from months ago.
Hmmm And what does vol mean? When I set vol=1, here the result
and it looks not very exact....
lesobrod ·
Here's another point. (^__^) (Something wrong with my prev extremums, thanx infuzion!)
I see that topic-starter requested MAX. OK, but how about PEAK?
Look at the picture, please. In some sense, on range [A..B] function F(x) has maximum -
F(B) at the x=B. For rigorous math it's correct; but for sound rather said that
there is no maximum on [A..B], only on range [B..C] ! The same is for minimums.
Here is the code for peaks (both + and -) scanning and the result.
I'm afraid that's a kinda off this topic, just for thoughts..
nmakinen ·
Thank you all so much! I'm going to look into all solutions that have been posted / discussed so far and take influences of them. I'm trying to make an effective but clean tool for dynamics processing (I guess it's "good luck with that" but I'm full of ideas and at least I want to give them a try).
This forum seems really great, and the people very nice 🙂
- nmakinen
nmakinen ·
EDIT: Some kind of moving average filter seems to be just what I need here. Sorry for being such a newbie 🙂
Original post:
Apparently the AHR envelope follower is exactly what I needed, but these solutions have been really useful for learning purposes.
Now I've been looking for a good filter for the follower. I need something.. umm.. symmetric (?) and something that doesn't effect the maximum volume on any given frequency, at least above 20Hz (I do understand that this requires equivalent hold times so the filter gets enough time to react before reaching the max). By symmetry I mean that after filtering, the point of the maximum level should be right in the middle of the hold time.
So ideally I need a filter that can turn square wave into sine wave without any change in the maximum volume. How hard would it be to achieve this?
Wrote something here? To have a post removed or your name hidden, write to [email protected].