mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-12-22 19:26:30 +01:00
alsabat: align the data type on float
Aligning the data type of fftw analyzer, sample converter and other components on float, because: 1. avoid unnecessary data type conversion; 2. using float is more efficient than using double; 3. the extra double accuracy is not required. Signed-off-by: Lu, Han <han.lu@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
4157528808
commit
09cb66f40c
7 changed files with 41 additions and 40 deletions
|
@ -26,10 +26,11 @@
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "bat-signal.h"
|
||||||
|
|
||||||
static void check_amplitude(struct bat *bat, double *buf)
|
static void check_amplitude(struct bat *bat, float *buf)
|
||||||
{
|
{
|
||||||
double sum, average, amplitude;
|
float sum, average, amplitude;
|
||||||
int i, percent;
|
int i, percent;
|
||||||
|
|
||||||
/* calculate average value */
|
/* calculate average value */
|
||||||
|
@ -39,7 +40,7 @@ static void check_amplitude(struct bat *bat, double *buf)
|
||||||
|
|
||||||
/* calculate peak-to-average amplitude */
|
/* calculate peak-to-average amplitude */
|
||||||
for (i = 0, sum = 0.0; i < bat->frames; i++)
|
for (i = 0, sum = 0.0; i < bat->frames; i++)
|
||||||
sum += abs(buf[i] - average);
|
sum += fabsf(buf[i] - average);
|
||||||
amplitude = sum / bat->frames * M_PI / 2.0;
|
amplitude = sum / bat->frames * M_PI / 2.0;
|
||||||
|
|
||||||
/* calculate amplitude percentage against full range */
|
/* calculate amplitude percentage against full range */
|
||||||
|
@ -71,9 +72,9 @@ int check_peak(struct bat *bat, struct analyze *a, int end, int peak, float hz,
|
||||||
float tolerance = (delta_rate > delta_HZ) ? delta_rate : delta_HZ;
|
float tolerance = (delta_rate > delta_HZ) ? delta_rate : delta_HZ;
|
||||||
|
|
||||||
fprintf(bat->log, _("Detected peak at %2.2f Hz of %2.2f dB\n"), hz_peak,
|
fprintf(bat->log, _("Detected peak at %2.2f Hz of %2.2f dB\n"), hz_peak,
|
||||||
10.0 * log10(a->mag[peak] / mean));
|
10.0 * log10f(a->mag[peak] / mean));
|
||||||
fprintf(bat->log, _(" Total %3.1f dB from %2.2f to %2.2f Hz\n"),
|
fprintf(bat->log, _(" Total %3.1f dB from %2.2f to %2.2f Hz\n"),
|
||||||
10.0 * log10(p / mean), start * hz, end * hz);
|
10.0 * log10f(p / mean), start * hz, end * hz);
|
||||||
|
|
||||||
if (hz_peak < DC_THRESHOLD) {
|
if (hz_peak < DC_THRESHOLD) {
|
||||||
fprintf(bat->err, _(" WARNING: Found low peak %2.2f Hz,"),
|
fprintf(bat->err, _(" WARNING: Found low peak %2.2f Hz,"),
|
||||||
|
@ -161,7 +162,7 @@ static int check(struct bat *bat, struct analyze *a, int channel)
|
||||||
|
|
||||||
static void calc_magnitude(struct bat *bat, struct analyze *a, int N)
|
static void calc_magnitude(struct bat *bat, struct analyze *a, int N)
|
||||||
{
|
{
|
||||||
double r2, i2;
|
float r2, i2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 1; i < N / 2; i++) {
|
for (i = 1; i < N / 2; i++) {
|
||||||
|
@ -176,36 +177,36 @@ static void calc_magnitude(struct bat *bat, struct analyze *a, int N)
|
||||||
static int find_and_check_harmonics(struct bat *bat, struct analyze *a,
|
static int find_and_check_harmonics(struct bat *bat, struct analyze *a,
|
||||||
int channel)
|
int channel)
|
||||||
{
|
{
|
||||||
fftw_plan p;
|
fftwf_plan p;
|
||||||
int err = -ENOMEM, N = bat->frames;
|
int err = -ENOMEM, N = bat->frames;
|
||||||
|
|
||||||
/* Allocate FFT buffers */
|
/* Allocate FFT buffers */
|
||||||
a->in = (double *) fftw_malloc(sizeof(double) * bat->frames);
|
a->in = (float *) fftwf_malloc(sizeof(float) * bat->frames);
|
||||||
if (a->in == NULL)
|
if (a->in == NULL)
|
||||||
goto out1;
|
goto out1;
|
||||||
|
|
||||||
a->out = (double *) fftw_malloc(sizeof(double) * bat->frames);
|
a->out = (float *) fftwf_malloc(sizeof(float) * bat->frames);
|
||||||
if (a->out == NULL)
|
if (a->out == NULL)
|
||||||
goto out2;
|
goto out2;
|
||||||
|
|
||||||
a->mag = (double *) fftw_malloc(sizeof(double) * bat->frames);
|
a->mag = (float *) fftwf_malloc(sizeof(float) * bat->frames);
|
||||||
if (a->mag == NULL)
|
if (a->mag == NULL)
|
||||||
goto out3;
|
goto out3;
|
||||||
|
|
||||||
/* create FFT plan */
|
/* create FFT plan */
|
||||||
p = fftw_plan_r2r_1d(N, a->in, a->out, FFTW_R2HC,
|
p = fftwf_plan_r2r_1d(N, a->in, a->out, FFTW_R2HC,
|
||||||
FFTW_MEASURE | FFTW_PRESERVE_INPUT);
|
FFTW_MEASURE | FFTW_PRESERVE_INPUT);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
goto out4;
|
goto out4;
|
||||||
|
|
||||||
/* convert source PCM to doubles */
|
/* convert source PCM to floats */
|
||||||
bat->convert_sample_to_double(a->buf, a->in, bat->frames);
|
bat->convert_sample_to_float(a->buf, a->in, bat->frames);
|
||||||
|
|
||||||
/* check amplitude */
|
/* check amplitude */
|
||||||
check_amplitude(bat, a->in);
|
check_amplitude(bat, a->in);
|
||||||
|
|
||||||
/* run FFT */
|
/* run FFT */
|
||||||
fftw_execute(p);
|
fftwf_execute(p);
|
||||||
|
|
||||||
/* FFT out is real and imaginary numbers - calc magnitude for each */
|
/* FFT out is real and imaginary numbers - calc magnitude for each */
|
||||||
calc_magnitude(bat, a, N);
|
calc_magnitude(bat, a, N);
|
||||||
|
@ -213,14 +214,14 @@ static int find_and_check_harmonics(struct bat *bat, struct analyze *a,
|
||||||
/* check data */
|
/* check data */
|
||||||
err = check(bat, a, channel);
|
err = check(bat, a, channel);
|
||||||
|
|
||||||
fftw_destroy_plan(p);
|
fftwf_destroy_plan(p);
|
||||||
|
|
||||||
out4:
|
out4:
|
||||||
fftw_free(a->mag);
|
fftwf_free(a->mag);
|
||||||
out3:
|
out3:
|
||||||
fftw_free(a->out);
|
fftwf_free(a->out);
|
||||||
out2:
|
out2:
|
||||||
fftw_free(a->in);
|
fftwf_free(a->in);
|
||||||
out1:
|
out1:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
16
bat/bat.c
16
bat/bat.c
|
@ -37,7 +37,7 @@
|
||||||
#include "alsa.h"
|
#include "alsa.h"
|
||||||
#endif
|
#endif
|
||||||
#include "convert.h"
|
#include "convert.h"
|
||||||
#ifdef HAVE_LIBFFTW3
|
#ifdef HAVE_LIBFFTW3F
|
||||||
#include "analyze.h"
|
#include "analyze.h"
|
||||||
#endif
|
#endif
|
||||||
#include "latencytest.h"
|
#include "latencytest.h"
|
||||||
|
@ -68,7 +68,7 @@ static int get_duration(struct bat *bat)
|
||||||
|
|
||||||
if (bat->frames <= 0 || bat->frames > MAX_FRAMES) {
|
if (bat->frames <= 0 || bat->frames > MAX_FRAMES) {
|
||||||
fprintf(bat->err, _("Invalid duration. Range: (0, %d(%fs))\n"),
|
fprintf(bat->err, _("Invalid duration. Range: (0, %d(%fs))\n"),
|
||||||
MAX_FRAMES, (double)MAX_FRAMES / bat->rate);
|
MAX_FRAMES, (float)MAX_FRAMES / bat->rate);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ static void set_defaults(struct bat *bat)
|
||||||
bat->sample_size = 2;
|
bat->sample_size = 2;
|
||||||
bat->format = BAT_PCM_FORMAT_S16_LE;
|
bat->format = BAT_PCM_FORMAT_S16_LE;
|
||||||
bat->convert_float_to_sample = convert_float_to_int16;
|
bat->convert_float_to_sample = convert_float_to_int16;
|
||||||
bat->convert_sample_to_double = convert_int16_to_double;
|
bat->convert_sample_to_float = convert_int16_to_float;
|
||||||
bat->frames = bat->rate * 2;
|
bat->frames = bat->rate * 2;
|
||||||
bat->target_freq[0] = 997.0;
|
bat->target_freq[0] = 997.0;
|
||||||
bat->target_freq[1] = 997.0;
|
bat->target_freq[1] = 997.0;
|
||||||
|
@ -576,19 +576,19 @@ static int bat_init(struct bat *bat)
|
||||||
switch (bat->sample_size) {
|
switch (bat->sample_size) {
|
||||||
case 1:
|
case 1:
|
||||||
bat->convert_float_to_sample = convert_float_to_uint8;
|
bat->convert_float_to_sample = convert_float_to_uint8;
|
||||||
bat->convert_sample_to_double = convert_uint8_to_double;
|
bat->convert_sample_to_float = convert_uint8_to_float;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
bat->convert_float_to_sample = convert_float_to_int16;
|
bat->convert_float_to_sample = convert_float_to_int16;
|
||||||
bat->convert_sample_to_double = convert_int16_to_double;
|
bat->convert_sample_to_float = convert_int16_to_float;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
bat->convert_float_to_sample = convert_float_to_int24;
|
bat->convert_float_to_sample = convert_float_to_int24;
|
||||||
bat->convert_sample_to_double = convert_int24_to_double;
|
bat->convert_sample_to_float = convert_int24_to_float;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
bat->convert_float_to_sample = convert_float_to_int32;
|
bat->convert_float_to_sample = convert_float_to_int32;
|
||||||
bat->convert_sample_to_double = convert_int32_to_double;
|
bat->convert_sample_to_float = convert_int32_to_float;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(bat->err, _("Invalid PCM format: size=%d\n"),
|
fprintf(bat->err, _("Invalid PCM format: size=%d\n"),
|
||||||
|
@ -669,7 +669,7 @@ int main(int argc, char *argv[])
|
||||||
test_loopback(&bat);
|
test_loopback(&bat);
|
||||||
|
|
||||||
analyze:
|
analyze:
|
||||||
#ifdef HAVE_LIBFFTW3
|
#ifdef HAVE_LIBFFTW3F
|
||||||
if (!bat.standalone)
|
if (!bat.standalone)
|
||||||
err = analyze_capture(&bat);
|
err = analyze_capture(&bat);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -211,7 +211,7 @@ struct bat {
|
||||||
FILE *log;
|
FILE *log;
|
||||||
FILE *err;
|
FILE *err;
|
||||||
|
|
||||||
void (*convert_sample_to_double)(void *, double *, int);
|
void (*convert_sample_to_float)(void *, float *, int);
|
||||||
void (*convert_float_to_sample)(float *, void *, int, int);
|
void (*convert_float_to_sample)(float *, void *, int, int);
|
||||||
|
|
||||||
void *buf; /* PCM Buffer */
|
void *buf; /* PCM Buffer */
|
||||||
|
@ -221,9 +221,9 @@ struct bat {
|
||||||
|
|
||||||
struct analyze {
|
struct analyze {
|
||||||
void *buf;
|
void *buf;
|
||||||
double *in;
|
float *in;
|
||||||
double *out;
|
float *out;
|
||||||
double *mag;
|
float *mag;
|
||||||
};
|
};
|
||||||
|
|
||||||
void prepare_wav_info(struct wav_container *, struct bat *);
|
void prepare_wav_info(struct wav_container *, struct bat *);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void convert_uint8_to_double(void *buf, double *val, int samples)
|
void convert_uint8_to_float(void *buf, float *val, int samples)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ void convert_uint8_to_double(void *buf, double *val, int samples)
|
||||||
val[i] = ((uint8_t *) buf)[i];
|
val[i] = ((uint8_t *) buf)[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert_int16_to_double(void *buf, double *val, int samples)
|
void convert_int16_to_float(void *buf, float *val, int samples)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ void convert_int16_to_double(void *buf, double *val, int samples)
|
||||||
val[i] = ((int16_t *) buf)[i];
|
val[i] = ((int16_t *) buf)[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert_int24_to_double(void *buf, double *val, int samples)
|
void convert_int24_to_float(void *buf, float *val, int samples)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int32_t tmp;
|
int32_t tmp;
|
||||||
|
@ -48,7 +48,7 @@ void convert_int24_to_double(void *buf, double *val, int samples)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert_int32_to_double(void *buf, double *val, int samples)
|
void convert_int32_to_float(void *buf, float *val, int samples)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void convert_uint8_to_double(void *, double *, int);
|
void convert_uint8_to_float(void *, float *, int);
|
||||||
void convert_int16_to_double(void *, double *, int);
|
void convert_int16_to_float(void *, float *, int);
|
||||||
void convert_int24_to_double(void *, double *, int);
|
void convert_int24_to_float(void *, float *, int);
|
||||||
void convert_int32_to_double(void *, double *, int);
|
void convert_int32_to_float(void *, float *, int);
|
||||||
void convert_float_to_uint8(float *, void *, int, int);
|
void convert_float_to_uint8(float *, void *, int, int);
|
||||||
void convert_float_to_int16(float *, void *, int, int);
|
void convert_float_to_int16(float *, void *, int, int);
|
||||||
void convert_float_to_int24(float *, void *, int, int);
|
void convert_float_to_int24(float *, void *, int, int);
|
||||||
|
|
|
@ -75,7 +75,7 @@ float sin_generator_next_sample(struct sin_generator *sg)
|
||||||
sg->state_real = sr * pr - si * pi;
|
sg->state_real = sr * pr - si * pi;
|
||||||
sg->state_imag = sr * pi + pr * si;
|
sg->state_imag = sr * pi + pr * si;
|
||||||
/* return the input value so sine wave starts at exactly 0.0 */
|
/* return the input value so sine wave starts at exactly 0.0 */
|
||||||
return sr;
|
return (float)sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fills a vector with a sine wave */
|
/* fills a vector with a sine wave */
|
||||||
|
|
|
@ -91,7 +91,7 @@ if test x$bat = xtrue; then
|
||||||
FFTW_CFLAGS=""
|
FFTW_CFLAGS=""
|
||||||
dnl Check for libfftw3
|
dnl Check for libfftw3
|
||||||
have_libfftw3="yes"
|
have_libfftw3="yes"
|
||||||
AC_CHECK_LIB([fftw3], [fftw_malloc], , [have_libfftw3="no"])
|
AC_CHECK_LIB([fftw3f], [fftwf_malloc], , [have_libfftw3="no"])
|
||||||
dnl Check for libtinyalsa
|
dnl Check for libtinyalsa
|
||||||
have_libtinyalsa=
|
have_libtinyalsa=
|
||||||
if test x$alsabat_backend_tiny = xtrue; then
|
if test x$alsabat_backend_tiny = xtrue; then
|
||||||
|
|
Loading…
Reference in a new issue