convotest/sy.c
2024-06-15 16:56:16 -05:00

177 lines
2.7 KiB
C

#include"sy.h"
void nois(float*a,size_t n)
{
int amp=2;
for(size_t i=0;i<n;++i)
a[i]=frand()*amp-amp/2;
}
// triangle oscillator
void tri(float*a,int n,int freq)
{
int period=44100.0/freq;
int amp=2;
float ratio=amp/((float)period/2);
for(int j=0;j<n;++j)
{
int i=j+period/4; // adjust phase
if(i%period<period/2)
a[j]=i%period;
else
a[j]=period-(i%period);
// a[i] is half of a ratio
// and needs to be adjusted
// for amplitude
a[j]*=ratio;
a[j]-=amp/2;
}
}
// square oscillator
void sq(float*a,int n,int freq)
{
int period=44100.0/freq;
for(int i=0;i<n;++i)
{
if(i%period<period/2)
a[i]=1;
else
a[i]=-1;
}
}
// sine oscillator
void sn(float*a,int n,int freq)
{
int period=44100.0/freq;
for(int i=0;i<n;++i)
a[i]=sin(2*(M_PI)*((float)i/period));
}
void atk(float*a,size_t n,size_t t)
{
if(!a)return;
for(size_t i=0;i<t&&i<n;++i)
a[i]*=i/((float)t);
}
void rel(float*a,size_t n,size_t t)
{
if(!a)return;
for(size_t i=1;i<t&&i<n;++i)
a[n-i]*=i/((float)t);
}
// Convolving average lowpass filter
// Smooth high frequencies
// samplerate: 44100 Hz
// cutoff: 440 Hz
// window: 44100/440=100
void avgwindow(float*a,int n,int windowsize)
{
if(!a)return;
for(int k=0;k<n;++k)
{
int i=k-windowsize/2;
float sum=0;
while(i<0)i+=n;
for(int j=0;j<windowsize;++j)
{
sum+=a[i];
i=(i+1)%n;
}
a[k]=sum/windowsize;
}
}
/* void avg(float*a,size_t n,float w) */
/* { */
/* if(!w)return; */
/* if(!a)return; */
/* w=ceil(w)+1; */
/* for(size_t i=0;i<n;++i) */
/* { */
/* if(i<w) */
/* for(size_t j=0;j<w;++j) */
/* { */
/* if(j<i)a[i]+=a[j]; */
/* } */
/* else */
/* for(size_t j=i-w+1;j<i&&j<n;++j) */
/* a[i]+=a[j]; */
/* a[i]/=w; */
/* } */
/* } */
void printwindow(float*a,int n,int windowsize)
{
if(!a)return;
int i=n-windowsize/2;
if(i<0)i+=n;
for(int j=0;j<windowsize;++j)
{
printf("%f",a[i]);
if(j<windowsize-1)
printf(", ");
i=(i+1)%n;
}
printf("\n");
}
void printwindowall(float*a,int n,int windowsize)
{
if(!a)return;
for(int k=0;k<n;++k)
{
int i=k-windowsize/2;
while(i<0)i+=n;
printf("(");
for(int j=0;j<windowsize;++j)
{
printf("%f",a[i]);
if(j<windowsize-1)
printf(", ");
i=(i+1)%n;
}
printf(")\n");
}
}
// Insert integer into correct place
// starting from 0 to n
void sort(float*a,size_t n)
{
float t;
if(!a)return;
for(size_t i=0;i<n-1;++i)
for(size_t j=i+1;j<n;++j)
if(a[i]>a[j])
t=a[i],
a[i]=a[j],
a[j]=t;
}
void shuf(float*a,size_t n)
{
float t;
for(size_t i=0;i<n;++i)
{
size_t sw=rand()%n;
t=a[i],
a[i]=a[sw],
a[sw]=t;
}
}
void rotl(float*a,size_t n)
{
if(!a)return;
float t=a[0];
for(size_t i=1;i<n;++i)
a[i-1]=a[i];
a[n-1]=t;
}