ref: 784f11d5e684bd50c0c0c98f5e552740a0e6ea86
parent: 866192e9213de1cf6a1a21942a4b816a3f9db7f7
author: cbagwell <cbagwell>
date: Thu Sep 2 14:56:08 EDT 2004
synth bugfix for generating brown noise.
--- a/Changelog
+++ b/Changelog
@@ -14,6 +14,8 @@
block when there wasn't.
o Restructured directory layout so that source code is in
a seperate directory.
+ o Benedikt Zeyen found a bug in synth effect when generating
+ brown noise that could cause clipping.
sox-12.17.5
--- a/README
+++ b/README
@@ -82,7 +82,7 @@
History:
-This is release 12.17.3 of SoX and its companion library Sound Tools.
+This is release 12.17.6 of SoX and its companion library Sound Tools.
SoX was originally written and maintained by Lance Norskog but is
currently maintained by Chris Bagwell (cbagwell@users.sourceforge.net).
--- a/src/synth.c
+++ b/src/synth.c
@@ -70,9 +70,9 @@
/* Calculate pseudo-random 32 bit number based on linear congruential method. */
static unsigned long GenerateRandomNumber( void )
{
- static unsigned long randSeed = 22222; /* Change this for different random sequences. */
- randSeed = (randSeed * 196314165) + 907633515;
- return randSeed;
+ static unsigned long randSeed = 22222; /* Change this for different random sequences. */
+ randSeed = (randSeed * 196314165) + 907633515;
+ return randSeed;
}
#define PINK_MAX_RANDOM_ROWS (30)
@@ -90,59 +90,59 @@
/* Setup PinkNoise structure for N rows of generators. */
void InitializePinkNoise( PinkNoise *pink, int numRows )
{
- int i;
- long pmax;
- pink->pink_Index = 0;
- pink->pink_IndexMask = (1<<numRows) - 1;
+ int i;
+ long pmax;
+ pink->pink_Index = 0;
+ pink->pink_IndexMask = (1<<numRows) - 1;
/* Calculate maximum possible signed random value. Extra 1 for white noise always added. */
- pmax = (numRows + 1) * (1<<(PINK_RANDOM_BITS-1));
- pink->pink_Scalar = 1.0f / pmax;
+ pmax = (numRows + 1) * (1<<(PINK_RANDOM_BITS-1));
+ pink->pink_Scalar = 1.0f / pmax;
/* Initialize rows. */
- for( i=0; i<numRows; i++ ) pink->pink_Rows[i] = 0;
- pink->pink_RunningSum = 0;
+ for( i=0; i<numRows; i++ ) pink->pink_Rows[i] = 0;
+ pink->pink_RunningSum = 0;
}
/* Generate Pink noise values between -1.0 and +1.0 */
float GeneratePinkNoise( PinkNoise *pink )
{
- long newRandom;
- long sum;
- float output;
+ long newRandom;
+ long sum;
+ float output;
/* Increment and mask index. */
- pink->pink_Index = (pink->pink_Index + 1) & pink->pink_IndexMask;
+ pink->pink_Index = (pink->pink_Index + 1) & pink->pink_IndexMask;
/* If index is zero, don't update any random values. */
- if( pink->pink_Index != 0 )
- {
- /* Determine how many trailing zeros in PinkIndex. */
- /* This algorithm will hang if n==0 so test first. */
- int numZeros = 0;
- int n = pink->pink_Index;
- while( (n & 1) == 0 )
- {
- n = n >> 1;
- numZeros++;
- }
+ if( pink->pink_Index != 0 )
+ {
+ /* Determine how many trailing zeros in PinkIndex. */
+ /* This algorithm will hang if n==0 so test first. */
+ int numZeros = 0;
+ int n = pink->pink_Index;
+ while( (n & 1) == 0 )
+ {
+ n = n >> 1;
+ numZeros++;
+ }
- /* Replace the indexed ROWS random value.
- * Subtract and add back to RunningSum instead of adding all the random
- * values together. Only one changes each time.
- */
- pink->pink_RunningSum -= pink->pink_Rows[numZeros];
- newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
- pink->pink_RunningSum += newRandom;
- pink->pink_Rows[numZeros] = newRandom;
- }
-
+ /* Replace the indexed ROWS random value.
+ * Subtract and add back to RunningSum instead of adding all the random
+ * values together. Only one changes each time.
+ */
+ pink->pink_RunningSum -= pink->pink_Rows[numZeros];
+ newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
+ pink->pink_RunningSum += newRandom;
+ pink->pink_Rows[numZeros] = newRandom;
+ }
+
/* Add extra white noise value. */
- newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
- sum = pink->pink_RunningSum + newRandom;
+ newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
+ sum = pink->pink_RunningSum + newRandom;
/* Scale to range of -1.0 to 0.9999. */
- output = pink->pink_Scalar * sum;
+ output = pink->pink_Scalar * sum;
- return output;
+ return output;
}
/**************** end of pink noise stuff */
@@ -192,20 +192,20 @@
double f;
if(*s=='%'){
- f = strtod(s+1,h);
- if ( *h == s+1 ){
- /* error*/
- return -1.0;
- }
- f=calc_note_freq(f);
+ f = strtod(s+1,h);
+ if ( *h == s+1 ){
+ /* error*/
+ return -1.0;
+ }
+ f=calc_note_freq(f);
}else{
- f=strtod(s,h);
- if(*h==s){
- return -1.0;
- }
+ f=strtod(s,h);
+ if(*h==s){
+ return -1.0;
+ }
}
if( f < 0.0 )
- return -1.0;
+ return -1.0;
return f;
}
@@ -218,7 +218,7 @@
sy->type[d]=sy->type[s];
sy->mix[d]=sy->mix[s];
for(i=0;i<PCOUNT;i++){
- sy->par[d][i]=sy->par[s][i];
+ sy->par[d][i]=sy->par[s][i];
}
}
@@ -244,157 +244,157 @@
synth->length_str = 0;
synth->max = ST_SAMPLE_MAX;
for(c=0;c<MAXCHAN;c++){
- synth->freq[c] = 440.0;
- synth->freq2[c] = 440.0;
- synth->type[c]=SYNTH_SINE;
- synth->mix[c] = SYNTH_CREATE;
+ synth->freq[c] = 440.0;
+ synth->freq2[c] = 440.0;
+ synth->type[c]=SYNTH_SINE;
+ synth->mix[c] = SYNTH_CREATE;
- for(i=0;i<PCOUNT;i++)
- synth->par[c][i]= -1.0;
-
- synth->par[c][0]= 0.0; /* offset */
- synth->par[c][1]= 0.0; /* phase */;
+ for(i=0;i<PCOUNT;i++)
+ synth->par[c][i]= -1.0;
+
+ synth->par[c][0]= 0.0; /* offset */
+ synth->par[c][1]= 0.0; /* phase */;
}
argn=0;
if ( n<0){
- st_fail(usstr);
- return(ST_EOF);
+ st_fail(usstr);
+ return(ST_EOF);
}
if(n==0){
- /* no arg, use default*/
- return(ST_SUCCESS);
+ /* no arg, use default*/
+ return(ST_SUCCESS);
}
/* read length if given ( if first par starts with digit )*/
if( isdigit((int)argv[argn][0])) {
- synth->length_str = malloc(strlen(argv[argn])+1);
- if (!synth->length_str)
- {
- st_fail("Could not allocate memeory");
- return(ST_EOF);
- }
- strcpy(synth->length_str,argv[argn]);
- /* Do a dummy parse of to see if it will fail */
- if (st_parsesamples(0, synth->length_str, &synth->length, 't') !=
- ST_SUCCESS)
- {
- st_fail(usstr);
- return (ST_EOF);
- }
- argn++;
+ synth->length_str = malloc(strlen(argv[argn])+1);
+ if (!synth->length_str)
+ {
+ st_fail("Could not allocate memeory");
+ return(ST_EOF);
+ }
+ strcpy(synth->length_str,argv[argn]);
+ /* Do a dummy parse of to see if it will fail */
+ if (st_parsesamples(0, synth->length_str, &synth->length, 't') !=
+ ST_SUCCESS)
+ {
+ st_fail(usstr);
+ return (ST_EOF);
+ }
+ argn++;
}
/* for one or more channel */
/* type [mix] [f1[-f2]] [p0] [p1] [p2] [p3] [p4] */
for(c=0;c<MAXCHAN;c++){
- if(n > argn){
- /* next par must be type */
- if( strcasecmp(argv[argn],"sine")==0){
- synth->type[c]=SYNTH_SINE;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"square")==0){
- synth->type[c]=SYNTH_SQUARE;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"sawtooth")==0){
- synth->type[c]=SYNTH_SAWTOOTH;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"triangle")==0){
- synth->type[c]=SYNTH_TRIANGLE;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"exp")==0){
- synth->type[c]=SYNTH_EXP;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"trapetz")==0){
- synth->type[c]=SYNTH_TRAPETZ;
- argn++;
- }else if( strcasecmp(argv[argn],"whitenoise")==0){
- synth->type[c]=SYNTH_WHITENOISE;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"noise")==0){
- synth->type[c]=SYNTH_WHITENOISE;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"pinknoise")==0){
- synth->type[c]=SYNTH_PINKNOISE;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"brownnoise")==0){
- synth->type[c]=SYNTH_BROWNNOISE;
- argn++; /* 1 */
- }else if( strcasecmp(argv[argn],"voicenoise")==0){
- synth->type[c]=SYNTH_VOICENOISE;
- argn++; /* 1 */
- }else{
- /* type not given, error */
- st_warn("synth: no type given");
- st_fail(usstr);
- return(ST_EOF);
- }
- if(n > argn){
- /* maybe there is a mix-type in next arg */
- if(strcasecmp(argv[argn],"create")==0){
- synth->mix[c]=SYNTH_CREATE;
- argn++;
- }else if(strcasecmp(argv[argn],"mix")==0){
- synth->mix[c]=SYNTH_MIX;
- argn++;
- }else if(strcasecmp(argv[argn],"amod")==0){
- synth->mix[c]=SYNTH_AMOD;
- argn++;
- }else if(strcasecmp(argv[argn],"fmod")==0){
- synth->mix[c]=SYNTH_FMOD;
- argn++;
- }
- if(n > argn){
- /* read frequency's if given */
- synth->freq[c]= StringToFreq(argv[argn],&hlp);
- synth->freq2[c] = synth->freq[c];
- if(synth->freq[c] < 0.0){
- st_warn("synth: illegal freq");
- st_fail(usstr);
- return(ST_EOF);
- }
- if(*hlp=='-') {
- /* freq2 given ! */
- char *hlp2;
- synth->freq2[c]=StringToFreq(hlp+1,&hlp2);
- if(synth->freq2[c] < 0.0){
- st_warn("synth: illegal freq2");
- st_fail(usstr);
- return(ST_EOF);
- }
- }
- argn++;
- i=0;
- /* read rest of parameters */
- while(n > argn){
- if( ! isdigit((int)argv[argn][0]) ){
- /* not a digit, must be type of next channel */
- break;
- }
- if( i >= PCOUNT) {
- st_warn("synth: too many parameters");
- st_fail(usstr);
- return(ST_EOF);
-
- }
- synth->par[c][i]=strtod(argv[argn],&hlp);
- if(hlp==argv[argn]){
- /* error in number */
- st_warn("synth: parameter error");
- st_fail(usstr);
- return(ST_EOF);
- }
- i++;
- argn++;
- }/* .. while */
- if(n > argn){
- /* got here by 'break', scan parms for next chan */
- }else{
- break;
- }
- }
- }
- } /* if n > argn */
+ if(n > argn){
+ /* next par must be type */
+ if( strcasecmp(argv[argn],"sine")==0){
+ synth->type[c]=SYNTH_SINE;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"square")==0){
+ synth->type[c]=SYNTH_SQUARE;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"sawtooth")==0){
+ synth->type[c]=SYNTH_SAWTOOTH;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"triangle")==0){
+ synth->type[c]=SYNTH_TRIANGLE;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"exp")==0){
+ synth->type[c]=SYNTH_EXP;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"trapetz")==0){
+ synth->type[c]=SYNTH_TRAPETZ;
+ argn++;
+ }else if( strcasecmp(argv[argn],"whitenoise")==0){
+ synth->type[c]=SYNTH_WHITENOISE;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"noise")==0){
+ synth->type[c]=SYNTH_WHITENOISE;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"pinknoise")==0){
+ synth->type[c]=SYNTH_PINKNOISE;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"brownnoise")==0){
+ synth->type[c]=SYNTH_BROWNNOISE;
+ argn++; /* 1 */
+ }else if( strcasecmp(argv[argn],"voicenoise")==0){
+ synth->type[c]=SYNTH_VOICENOISE;
+ argn++; /* 1 */
+ }else{
+ /* type not given, error */
+ st_warn("synth: no type given");
+ st_fail(usstr);
+ return(ST_EOF);
+ }
+ if(n > argn){
+ /* maybe there is a mix-type in next arg */
+ if(strcasecmp(argv[argn],"create")==0){
+ synth->mix[c]=SYNTH_CREATE;
+ argn++;
+ }else if(strcasecmp(argv[argn],"mix")==0){
+ synth->mix[c]=SYNTH_MIX;
+ argn++;
+ }else if(strcasecmp(argv[argn],"amod")==0){
+ synth->mix[c]=SYNTH_AMOD;
+ argn++;
+ }else if(strcasecmp(argv[argn],"fmod")==0){
+ synth->mix[c]=SYNTH_FMOD;
+ argn++;
+ }
+ if(n > argn){
+ /* read frequency's if given */
+ synth->freq[c]= StringToFreq(argv[argn],&hlp);
+ synth->freq2[c] = synth->freq[c];
+ if(synth->freq[c] < 0.0){
+ st_warn("synth: illegal freq");
+ st_fail(usstr);
+ return(ST_EOF);
+ }
+ if(*hlp=='-') {
+ /* freq2 given ! */
+ char *hlp2;
+ synth->freq2[c]=StringToFreq(hlp+1,&hlp2);
+ if(synth->freq2[c] < 0.0){
+ st_warn("synth: illegal freq2");
+ st_fail(usstr);
+ return(ST_EOF);
+ }
+ }
+ argn++;
+ i=0;
+ /* read rest of parameters */
+ while(n > argn){
+ if( ! isdigit((int)argv[argn][0]) ){
+ /* not a digit, must be type of next channel */
+ break;
+ }
+ if( i >= PCOUNT) {
+ st_warn("synth: too many parameters");
+ st_fail(usstr);
+ return(ST_EOF);
+
+ }
+ synth->par[c][i]=strtod(argv[argn],&hlp);
+ if(hlp==argv[argn]){
+ /* error in number */
+ st_warn("synth: parameter error");
+ st_fail(usstr);
+ return(ST_EOF);
+ }
+ i++;
+ argn++;
+ }/* .. while */
+ if(n > argn){
+ /* got here by 'break', scan parms for next chan */
+ }else{
+ break;
+ }
+ }
+ }
+ } /* if n > argn */
}/* for .. */
/* make some intelligent parameter initialization for channels
@@ -405,13 +405,13 @@
* - if parm for 3 channels were given, copy 2->4
*/
if(c == 0 || c >= MAXCHAN){
- for(c=1;c<MAXCHAN;c++)
- parmcopy(synth,0,c);
+ for(c=1;c<MAXCHAN;c++)
+ parmcopy(synth,0,c);
}else if(c == 1){
- parmcopy(synth,0,2);
- parmcopy(synth,1,3);
+ parmcopy(synth,0,2);
+ parmcopy(synth,1,3);
}else if(c == 2){
- parmcopy(synth,1,3);
+ parmcopy(synth,1,3);
}
return (ST_SUCCESS);
@@ -431,12 +431,12 @@
if (synth->length_str)
{
- if (st_parsesamples(effp->ininfo.rate, synth->length_str,
- &synth->length, 't') != ST_SUCCESS)
- {
- st_fail(usstr);
- return(ST_EOF);
- }
+ if (st_parsesamples(effp->ininfo.rate, synth->length_str,
+ &synth->length, 't') != ST_SUCCESS)
+ {
+ st_fail(usstr);
+ return(ST_EOF);
+ }
}
synth->samples_done=0;
@@ -443,72 +443,72 @@
synth->rate = effp->ininfo.rate;
for(i=0;i< MAXCHAN; i++){
- synth->h[i]=0.0;
+ synth->h[i]=0.0;
}
/* parameter adjustment for all channels */
for(c=0;c<MAXCHAN;c++){
- /* adjust parameter 0 - 100% to 0..1 */
- for(i=0;i<PCOUNT;i++){
- synth->par[c][i] /= 100.0;
- }
+ /* adjust parameter 0 - 100% to 0..1 */
+ for(i=0;i<PCOUNT;i++){
+ synth->par[c][i] /= 100.0;
+ }
- /* give parameters nice defaults for the different 'type' */
+ /* give parameters nice defaults for the different 'type' */
- switch(synth->type[c]){
- case SYNTH_SINE:
- break;
- case SYNTH_SQUARE:
- /* p2 is pulse width */
- if(synth->par[c][2] < 0.0){
- synth->par[c][2] = 0.5; /* default to 50% duty cycle */
- }
- break;
- case SYNTH_TRIANGLE:
- /* p2 is position of maximum*/
- if(synth->par[c][2] < 0.0){
- /* default : 0 */
- synth->par[c][2]=0.5;
- }
- break;
- case SYNTH_SAWTOOTH:
- /* no parameters, use TRIANGLE to create no-default-sawtooth */
- break;
- case SYNTH_TRAPETZ:
- /* p2 is length of rising slope,
- * p3 position where falling slope begins
- * p4 position of end of falling slope
- */
- if(synth->par[c][2] < 0.0 ){
- synth->par[c][2]= 0.1;
- synth->par[c][3]= 0.5;
- synth->par[c][4]= 0.6;
- }else if(synth->par[c][3] < 0.0){
- /* try a symetric waveform
- */
- if(synth->par[c][2] <= 0.5){
- synth->par[c][3] = (1.0-2.0*synth->par[c][2])/2.0;
- synth->par[c][4] = synth->par[c][3] + synth->par[c][2];
- }else{
- /* symetric is not possible, fall back to asymetrical
- * triangle
- */
- synth->par[c][3]=synth->par[c][2];
- synth->par[c][4]=1.0;
- }
- }else if(synth->par[c][4] < 0.0){
- /* simple falling slope to the end */
- synth->par[c][4]=1.0;
- }
- break;
- case SYNTH_PINKNOISE:
- /* Initialize pink noise signals with different numbers of rows. */
- InitializePinkNoise( &(synth->pinkn[c]),10+2*c);
- break;
- default:
- break;
- }
- }
+ switch(synth->type[c]){
+ case SYNTH_SINE:
+ break;
+ case SYNTH_SQUARE:
+ /* p2 is pulse width */
+ if(synth->par[c][2] < 0.0){
+ synth->par[c][2] = 0.5; /* default to 50% duty cycle */
+ }
+ break;
+ case SYNTH_TRIANGLE:
+ /* p2 is position of maximum*/
+ if(synth->par[c][2] < 0.0){
+ /* default : 0 */
+ synth->par[c][2]=0.5;
+ }
+ break;
+ case SYNTH_SAWTOOTH:
+ /* no parameters, use TRIANGLE to create no-default-sawtooth */
+ break;
+ case SYNTH_TRAPETZ:
+ /* p2 is length of rising slope,
+ * p3 position where falling slope begins
+ * p4 position of end of falling slope
+ */
+ if(synth->par[c][2] < 0.0 ){
+ synth->par[c][2]= 0.1;
+ synth->par[c][3]= 0.5;
+ synth->par[c][4]= 0.6;
+ }else if(synth->par[c][3] < 0.0){
+ /* try a symetric waveform
+ */
+ if(synth->par[c][2] <= 0.5){
+ synth->par[c][3] = (1.0-2.0*synth->par[c][2])/2.0;
+ synth->par[c][4] = synth->par[c][3] + synth->par[c][2];
+ }else{
+ /* symetric is not possible, fall back to asymetrical
+ * triangle
+ */
+ synth->par[c][3]=synth->par[c][2];
+ synth->par[c][4]=1.0;
+ }
+ }else if(synth->par[c][4] < 0.0){
+ /* simple falling slope to the end */
+ synth->par[c][4]=1.0;
+ }
+ break;
+ case SYNTH_PINKNOISE:
+ /* Initialize pink noise signals with different numbers of rows. */
+ InitializePinkNoise( &(synth->pinkn[c]),10+2*c);
+ break;
+ default:
+ break;
+ }
+ }
return (ST_SUCCESS);
}
@@ -524,24 +524,24 @@
double t,dt ;
if(synth->length<=0){
- /* there is no way to change the freq. without knowing the length
- * use startfreq all the time ...
- */
- f = synth->freq[c];
+ /* there is no way to change the freq. without knowing the length
+ * use startfreq all the time ...
+ */
+ f = synth->freq[c];
}else{
- f = synth->freq[c] *
- exp( (log(synth->freq2[c])-log(synth->freq[c]))*
- synth->samples_done/synth->length );
+ f = synth->freq[c] *
+ exp( (log(synth->freq2[c])-log(synth->freq[c]))*
+ synth->samples_done/synth->length );
}
om = 1.0 / f; /* periodendauer inn sec */
t = synth->samples_done / (double)synth->rate; /* zeit seit start in sec */
dt = t - synth->h[c]; /* seit seitdem letzte periode um war. */
if( dt < om){
- /* wir sind noch in der periode.. */
+ /* wir sind noch in der periode.. */
}else{
- /* schon in naechste periode */
- synth->h[c]+=om;
- dt=t-synth->h[c];
+ /* schon in naechste periode */
+ synth->h[c]+=om;
+ dt=t-synth->h[c];
}
sd= dt/om; /* position in der aktuellen periode; 0<= sd < 1*/
sd = fmod(sd+synth->par[c][1],1.0); /* phase einbauen */
@@ -548,139 +548,140 @@
switch(synth->type[c]){
- case SYNTH_SINE:
- r = sin(2.0 * M_PI * sd);
- break;
- case SYNTH_SQUARE:
- /* |_______ | +1
- * | | |
- * |_______|__________| 0
- * | | |
- * | |__________| -1
- * | |
- * 0 p2 1
+ case SYNTH_SINE:
+ r = sin(2.0 * M_PI * sd);
+ break;
+ case SYNTH_SQUARE:
+ /* |_______ | +1
+ * | | |
+ * |_______|__________| 0
+ * | | |
+ * | |__________| -1
+ * | |
+ * 0 p2 1
*/
- if(sd < synth->par[c][2]){
- r = -1.0;
- }else{
- r = +1.0;
- }
- break;
- case SYNTH_SAWTOOTH:
- /* | __| +1
- * | __/ |
- * |_______/_____| 0
- * | __/ |
- * |_/ | -1
- * | |
- * 0 1
+ if(sd < synth->par[c][2]){
+ r = -1.0;
+ }else{
+ r = +1.0;
+ }
+ break;
+ case SYNTH_SAWTOOTH:
+ /* | __| +1
+ * | __/ |
+ * |_______/_____| 0
+ * | __/ |
+ * |_/ | -1
+ * | |
+ * 0 1
*/
- r = -1.0 + 2.0 * sd;
- break;
- case SYNTH_TRIANGLE:
- /* | _ | +1
- * | / \ |
- * |__/___\__| 0
- * | / \ |
- * |/ \| -1
- * | |
- * 0 p2 1
+ r = -1.0 + 2.0 * sd;
+ break;
+ case SYNTH_TRIANGLE:
+ /* | _ | +1
+ * | / \ |
+ * |__/___\__| 0
+ * | / \ |
+ * |/ \| -1
+ * | |
+ * 0 p2 1
*/
- if( sd < synth->par[c][2]){ /* in rising Part of period */
- r = -1.0 + 2.0 * sd / synth->par[c][2];
- }else{ /* falling part */
- r = 1.0 - 2.0 *
- (sd-synth->par[c][2])/(1-synth->par[c][2]);
- }
- break;
- case SYNTH_TRAPETZ:
- /* | ______ |+1
- * | / \ |
- * |__/________\___________| 0
- * | / \ |
- * |/ \_________|-1
- * | |
- * 0 p2 p3 p4 1
+ if( sd < synth->par[c][2]){ /* in rising Part of period */
+ r = -1.0 + 2.0 * sd / synth->par[c][2];
+ }else{ /* falling part */
+ r = 1.0 - 2.0 *
+ (sd-synth->par[c][2])/(1-synth->par[c][2]);
+ }
+ break;
+ case SYNTH_TRAPETZ:
+ /* | ______ |+1
+ * | / \ |
+ * |__/________\___________| 0
+ * | / \ |
+ * |/ \_________|-1
+ * | |
+ * 0 p2 p3 p4 1
*/
- if( sd < synth->par[c][2]){ /* in rising part of period */
- r = -1.0 + 2.0 * sd / synth->par[c][2];
- }else if( sd < synth->par[c][3]){ /* in constant Part of period */
- r=1.0;
- }else if( sd < synth->par[c][4] ){ /* falling part */
- r = 1.0 - 2.0 *
- (sd - synth->par[c][3])/(synth->par[c][4]-synth->par[c][3]);
- }else{
- r = -1.0;
- }
- break;
+ if( sd < synth->par[c][2]){ /* in rising part of period */
+ r = -1.0 + 2.0 * sd / synth->par[c][2];
+ }else if( sd < synth->par[c][3]){ /* in constant Part of period */
+ r=1.0;
+ }else if( sd < synth->par[c][4] ){ /* falling part */
+ r = 1.0 - 2.0 *
+ (sd - synth->par[c][3])/(synth->par[c][4]-synth->par[c][3]);
+ }else{
+ r = -1.0;
+ }
+ break;
- case SYNTH_EXP:
- /* | | | +1
- * | | | |
- * | _| |_ | 0
- * | __- -__ |
- * |____--- ---____ | f(p3)
- * | |
- * 0 p2 1
+ case SYNTH_EXP:
+ /* | | | +1
+ * | | | |
+ * | _| |_ | 0
+ * | __- -__ |
+ * |____--- ---____ | f(p3)
+ * | |
+ * 0 p2 1
*/
- move=exp( - synth->par[c][3] * LOG_10_20 * 100.0 ); /* 0 .. 1 */
- if ( sd < synth->par[c][2] ) {
- r = move * exp(sd * log(1.0/move)/synth->par[c][2]);
- }else{
- r = move *
- exp( (1-sd)*log(1.0/move)/
- (1.0-synth->par[c][2]));
- }
+ move=exp( - synth->par[c][3] * LOG_10_20 * 100.0 ); /* 0 .. 1 */
+ if ( sd < synth->par[c][2] ) {
+ r = move * exp(sd * log(1.0/move)/synth->par[c][2]);
+ }else{
+ r = move *
+ exp( (1-sd)*log(1.0/move)/
+ (1.0-synth->par[c][2]));
+ }
- /* r in 0 .. 1 */
- r = r * 2.0 - 1.0; /* -1 .. +1 */
- break;
- case SYNTH_WHITENOISE:
- r= 2.0* rand()/(double)RAND_MAX - 1.0;
- break;
- case SYNTH_PINKNOISE:
- r = GeneratePinkNoise( &(synth->pinkn[c]) );
- break;
- case SYNTH_BROWNNOISE:
- /* no idea if this algorithm is good enough.. */
- move = 2.0* rand()/(double)RAND_MAX - 1.0;
- move *= BROWNNOISE_FAC;
- synth->h[c] += move;
- if( fabs(synth->h[c]) > 1.0 ){
- synth->h[c] -= 2.0*move;
- }
- r=synth->h[c];
- break;
- default:
- st_warn("synth: internal error 1");
- break;
+ /* r in 0 .. 1 */
+ r = r * 2.0 - 1.0; /* -1 .. +1 */
+ break;
+ case SYNTH_WHITENOISE:
+ r= 2.0* rand()/(double)RAND_MAX - 1.0;
+ break;
+ case SYNTH_PINKNOISE:
+ r = GeneratePinkNoise( &(synth->pinkn[c]) );
+ break;
+ case SYNTH_BROWNNOISE:
+ /* no idea if this algorithm is good enough.. */
+ move = 2.0* rand()/(double)RAND_MAX - 1.0;
+ move *= BROWNNOISE_FAC;
+ synth->h[c] += move;
+ if ((synth->h[c]) > 1.0)
+ synth->h[c] -= 2.0*move;
+ if ((synth->h[c]) < -1.0)
+ synth->h[c] += 2.0*move;
+ r=synth->h[c];
+ break;
+ default:
+ st_warn("synth: internal error 1");
+ break;
}
/* add offset, but prevent clipping */
om = fabs(synth->par[c][0]);
if( om <= 1.0 ){
- r *= 1.0 - om; /* reduce amp, prevent clipping */
- r += om;
+ r *= 1.0 - om; /* reduce amp, prevent clipping */
+ r += om;
}
switch(synth->mix[c]){
- case SYNTH_CREATE:
- ov = synth->max * r;
- break;
- case SYNTH_MIX:
- ov = iv/2 + r*synth->max/2;
- break;
- case SYNTH_AMOD:
- ov = (st_sample_t)(0.5*(r+1.0)*(double)iv);
- break;
- case SYNTH_FMOD:
- ov = iv * r ;
- break;
- default:
- st_fail("synth: internel error 2");
- break;
+ case SYNTH_CREATE:
+ ov = synth->max * r;
+ break;
+ case SYNTH_MIX:
+ ov = iv/2 + r*synth->max/2;
+ break;
+ case SYNTH_AMOD:
+ ov = (st_sample_t)(0.5*(r+1.0)*(double)iv);
+ break;
+ case SYNTH_FMOD:
+ ov = iv * r ;
+ break;
+ default:
+ st_fail("synth: internel error 2");
+ break;
}
return ov;
@@ -701,35 +702,35 @@
int chan=effp->ininfo.channels;
if(chan > MAXCHAN ){
- st_fail("synth: can not operate with more than %d channels",MAXCHAN);
- return(ST_EOF);
+ st_fail("synth: can not operate with more than %d channels",MAXCHAN);
+ return(ST_EOF);
}
len = ((*isamp > *osamp) ? *osamp : *isamp) / chan;
for(done = 0; done < len ; done++){
- for(c=0;c<chan;c++){
- /* each channel is independent, but the algorithm is the same */
+ for(c=0;c<chan;c++){
+ /* each channel is independent, but the algorithm is the same */
- obuf[c] = do_synth(ibuf[c],synth,c);
- }
- ibuf+=chan;
- obuf+=chan;
- synth->samples_done++;
- if(synth->length > 0 ){
- if( synth->samples_done > synth->length){
- /* break 'nul' file fileter when enough samples
- * are produced. the actual number of samples
- * will be a little bigger, depends on when the
- * signal gets to the plugin
- */
- raise(SIGINT); /* only once */
- *osamp = done*chan;
- break;
+ obuf[c] = do_synth(ibuf[c],synth,c);
+ }
+ ibuf+=chan;
+ obuf+=chan;
+ synth->samples_done++;
+ if(synth->length > 0 ){
+ if( synth->samples_done > synth->length){
+ /* break 'nul' file fileter when enough samples
+ * are produced. the actual number of samples
+ * will be a little bigger, depends on when the
+ * signal gets to the plugin
+ */
+ raise(SIGINT); /* only once */
+ *osamp = done*chan;
+ break;
- }
+ }
}
-
+
}
return (ST_SUCCESS);
}
@@ -740,13 +741,13 @@
int st_synth_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp)
{
- *osamp = 0;
- return (ST_SUCCESS);
+ *osamp = 0;
+ return (ST_SUCCESS);
}
/*
* Do anything required when you stop reading samples.
- * (free allocated memory, etc.)
+ * (free allocated memory, etc.)
*/
int st_synth_stop(eff_t effp)
{