Browse Source

Implement automatic gain control

master
Gavan Fantom 17 years ago
parent
commit
5d93c3ba74
  1. 87
      src/lsi/beatdetect.c

87
src/lsi/beatdetect.c

@ -32,6 +32,16 @@
#define CHISTSIZE 512 #define CHISTSIZE 512
#define SHISTSIZE 200
#define CLIPDELTA (20)
#define SMAXMIN (24576)
#define SMAXMAX (31129)
#define DOWNDELTA (3)
#define UPDELTA (1)
#define VOLMIN (1)
#define VOLMAX (255)
double outputslist[NOUTPUTS] = { double outputslist[NOUTPUTS] = {
1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023
}; };
@ -67,14 +77,17 @@ int minp, maxp;
double lastsum[NOUTPUTS]; double lastsum[NOUTPUTS];
double history[NOUTPUTS][HISTSIZE]; double history[NOUTPUTS][HISTSIZE];
double chistory[NOUTPUTS][CHISTSIZE]; double chistory[NOUTPUTS][CHISTSIZE];
int shistory[SHISTSIZE];
int histptr; int histptr;
int chistptr; int chistptr;
int shistptr;
char buffer[BUFSIZE]; char buffer[BUFSIZE];
char *bufptr; char *bufptr;
int bufleft; int bufleft;
double phase; double phase;
double confidence; double confidence;
int audio_initialised = 0; int audio_initialised = 0;
int volume;
#define HISTORY(i, x) (history[i][((histptr+(x) >= HISTSIZE) ? histptr+(x)-HISTSIZE : histptr+(x))]) #define HISTORY(i, x) (history[i][((histptr+(x) >= HISTSIZE) ? histptr+(x)-HISTSIZE : histptr+(x))])
@ -96,6 +109,16 @@ int audio_initialised = 0;
chistptr = 0; \ chistptr = 0; \
} while (0) } while (0)
#define SHISTORY(x) (shistory[((shistptr+(x) >= SHISTSIZE) ? shistptr+(x)-SHISTSIZE : shistptr+(x))])
#define SHISTWRITE(x) shistory[shistptr] = (x)
#define SHISTNEXT do { \
shistptr++; \
if (shistptr >= SHISTSIZE) \
shistptr = 0; \
} while (0)
#define SUMSQ(a, b) ((a) * (a) + (b) * (b)) #define SUMSQ(a, b) ((a) * (a) + (b) * (b))
#define MAGSQ(i) SUMSQ(freqs[2*(i)], freqs[2*(i)+1]) #define MAGSQ(i) SUMSQ(freqs[2*(i)], freqs[2*(i)+1])
@ -131,7 +154,7 @@ int beatdetect_init(void)
info.record.channels = 1; info.record.channels = 1;
info.record.precision = 16; info.record.precision = 16;
info.record.encoding = AUDIO_ENCODING_SLINEAR; info.record.encoding = AUDIO_ENCODING_SLINEAR;
info.record.gain = oinfo.record.gain; volume = info.record.gain = oinfo.record.gain;
info.record.port = oinfo.record.port; info.record.port = oinfo.record.port;
info.record.balance = oinfo.record.balance; info.record.balance = oinfo.record.balance;
@ -160,6 +183,24 @@ int beatdetect_init(void)
return 1; return 1;
} }
void beatdetect_volume(int vol)
{
audio_info_t info;
if (audiofd < 0)
return;
if (ioctl(audiofd, AUDIO_GETINFO, &info) < 0) {
printf("ERROR: can't get audio info\n");
return;
}
info.record.gain = vol;
/* printf("Set record gain to %d\n", vol); */
if (ioctl(audiofd, AUDIO_SETINFO, &info) < 0) {
printf("ERROR: can't set audio info\n");
return;
}
}
int beatdetect_read(void) int beatdetect_read(void)
{ {
#if 0 #if 0
@ -168,6 +209,8 @@ int beatdetect_read(void)
int i, j, n, p; int i, j, n, p;
int rv; int rv;
int clip; int clip;
int smax, smaxh;
int changevol;
double localsum[NOUTPUTS]; double localsum[NOUTPUTS];
fft_type *freqs; fft_type *freqs;
int count; int count;
@ -179,6 +222,7 @@ int beatdetect_read(void)
double cmax; double cmax;
int mi, mj, mp; int mi, mj, mp;
int cmi, cmj, cmp; int cmi, cmj, cmp;
int ovolume;
if (!audio_initialised) if (!audio_initialised)
return 0; return 0;
@ -216,14 +260,55 @@ int beatdetect_read(void)
fft_data_signed16((int16_t *)buffer); fft_data_signed16((int16_t *)buffer);
clip = 0; clip = 0;
smax = 0;
/* Check for clip and compute rms */ /* Check for clip and compute rms */
for (i = 0; i < BUFSIZE/2; i++) { for (i = 0; i < BUFSIZE/2; i++) {
int sample = ((int16_t *)buffer)[i]; int sample = ((int16_t *)buffer)[i];
if (abs(sample) > smax)
smax = abs(sample);
if ((sample == INT16_MAX) || (sample == (-1 - INT16_MAX))) if ((sample == INT16_MAX) || (sample == (-1 - INT16_MAX)))
clip = 1; clip = 1;
} }
SHISTWRITE(smax);
SHISTNEXT;
smaxh = 0;
changevol = 0;
for (i = 0; i < SHISTSIZE; i++) {
if (SHISTORY(i) > smaxh)
smaxh = SHISTORY(i);
}
/* Ideal smax range is between 75% and 95% of full signal */
ovolume = volume;
if (clip) {
volume = volume - CLIPDELTA;
changevol = 1;
} else {
if (smax > SMAXMAX) {
volume = volume - DOWNDELTA;
changevol = 1;
}
if (smaxh < SMAXMIN) {
volume = volume + UPDELTA;
changevol = 1;
}
}
if (changevol) {
if (volume < VOLMIN)
volume = 1;
if (volume > VOLMAX)
volume = VOLMAX;
if (volume != ovolume)
beatdetect_volume(volume);
}
fft_window(); fft_window();
fft_compute(); fft_compute();
freqs = fft_getresult(); freqs = fft_getresult();

Loading…
Cancel
Save