130 lines
2.8 KiB
C
130 lines
2.8 KiB
C
#include<ctype.h>
|
|
#include<fcntl.h>
|
|
#include<math.h>
|
|
#include<portaudio.h>
|
|
#include<stdbool.h>
|
|
#include<stdint.h>
|
|
#include<stdio.h>
|
|
#include<stdlib.h>
|
|
#include<string.h>
|
|
#include<time.h>
|
|
#include<unistd.h>
|
|
#include"audio.h"
|
|
|
|
/*******
|
|
* Create new Audio struct
|
|
*******/
|
|
Audio aud_new(size_t samplerate,size_t nsamples,size_t channels)
|
|
{
|
|
Audio aud=(Audio){0};
|
|
aud.samplerate=samplerate;
|
|
aud.nsamples=nsamples;
|
|
aud.channels=channels;
|
|
aud.data=malloc(nsamples*sizeof(uint16_t));
|
|
return aud;
|
|
}
|
|
|
|
/*******
|
|
* Free Audio struct resources
|
|
*******/
|
|
void aud_free(Audio*aud)
|
|
{
|
|
if(!aud)return;
|
|
if(aud->data)
|
|
free(aud->data);
|
|
aud->data=0;
|
|
*aud=(Audio){0};
|
|
}
|
|
|
|
/*******
|
|
* Convolver (low-pass filter)
|
|
*******/
|
|
void aud_avg(Audio*aud,size_t blocksize)
|
|
{
|
|
if(!aud->data||!aud->nsamples||!aud->channels||!aud->samplerate||!blocksize)return;
|
|
for(size_t i=blocksize-1;i<aud->nsamples;++i)
|
|
{
|
|
uint16_t sum=0;
|
|
for(size_t j=0;j<blocksize&&(i+j)<aud->nsamples;++j)
|
|
sum+=aud->data[i+j];
|
|
/* for(size_t ch=0;ch<aud->channels;++ch,++i) */
|
|
aud->data[i]=sum/blocksize;
|
|
}
|
|
}
|
|
|
|
/*******
|
|
* Randomize data
|
|
*******/
|
|
void aud_rnd(Audio*aud,size_t mode)
|
|
{
|
|
if(!aud->data||!aud->nsamples||!aud->samplerate||!aud->channels)return;
|
|
|
|
for(size_t i=0;i<aud->nsamples;++i)
|
|
{
|
|
/* for(size_t ch=0;ch<aud->channels;++ch,++i) */
|
|
uint16_t sample=rand();
|
|
if(mode==GEN)
|
|
aud->data[i]=sample;
|
|
else if(mode==ADD)
|
|
aud->data[i]=(aud->data[i]+sample)/2;
|
|
}
|
|
}
|
|
|
|
/*******
|
|
* Zero all data
|
|
*******/
|
|
void aud_zero(Audio*aud)
|
|
{
|
|
if(!aud->data||!aud->nsamples||!aud->channels)return;
|
|
memset(aud->data,0,aud->nsamples*sizeof(uint16_t));
|
|
}
|
|
|
|
/*******
|
|
* Naïve amplitude envelope
|
|
*******/
|
|
void aud_env(Audio*aud)
|
|
{
|
|
if(!aud)return;
|
|
if(!aud->data)return;
|
|
size_t range=aud->nsamples/8;
|
|
for(size_t i=0;i<range;++i)
|
|
aud->data[i]*=(float)i/range;
|
|
for(size_t i=0;i<aud->nsamples/8;++i)
|
|
aud->data[aud->nsamples-1-i]*=(float)i/range;
|
|
}
|
|
|
|
/*******
|
|
* Sine waveform generator
|
|
*******/
|
|
void aud_sine(Audio*aud,double freq,size_t mode)
|
|
{
|
|
if(!aud->data||!aud->nsamples||!aud->samplerate||!aud->channels)return;
|
|
for(size_t i=0;i<aud->nsamples;++i)
|
|
{
|
|
/* for(size_t ch=0;ch<aud->channels;++ch,++i) */
|
|
uint16_t sample=sin((2*PI)/(aud->samplerate/freq)*i)*8000;
|
|
if(mode==GEN)
|
|
aud->data[i]=sample;
|
|
else if(mode==ADD)
|
|
aud->data[i]=(aud->data[i]+sample)/2;
|
|
}
|
|
}
|
|
|
|
/*******
|
|
* Triangle waveform generator
|
|
*******/
|
|
void aud_tri(Audio*aud,double freq,size_t mode)
|
|
{
|
|
if(!aud->data||!aud->nsamples||!aud->samplerate||!aud->channels)return;
|
|
for(size_t i=0;i<aud->nsamples;++i)
|
|
{
|
|
/* for(size_t ch=0;ch<aud->channels;++ch,++i) */
|
|
//aud->data[i]=sin(i);
|
|
uint16_t sample=(i%(int)(aud->samplerate/freq))*7;
|
|
if(mode==GEN)
|
|
aud->data[i]=sample;
|
|
else if(mode==ADD)
|
|
aud->data[i]=(aud->data[i]+sample)/2;
|
|
}
|
|
}
|