nuttx-apps/audioutils/fmsynth/test/opfunc_test.c
Takayoshi Koizumi 40c506f3a0 audioutils/fmsynth: Add FM synthesizer library
Add simple FM synthesizer library in audioutils.
2022-08-25 20:29:55 +09:00

166 lines
4.8 KiB
C

/****************************************************************************
* apps/audioutils/fmsynth/test/opfunc_test.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <audioutils/fmsynth_op.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define FS (48000)
#define DUMP_PERIOD (FS * 3 / 2000)
#define ACCURACY_TEST_PERIOD (FS * 3)
#define HZ (4186)
/****************************************************************************
* Private Data
****************************************************************************/
static opfunc_t func_sin;
static opfunc_t func_tri;
static opfunc_t func_saw;
static opfunc_t func_sqa;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* name: prepare_opfuncs
****************************************************************************/
static void prepare_opfuncs(void)
{
fmsynth_op_t *op;
op = fmsynthop_create();
fmsynthop_select_opfunc(op, FMSYNTH_OPFUNC_SIN);
func_sin = op->wavegen;
fmsynthop_select_opfunc(op, FMSYNTH_OPFUNC_TRIANGLE);
func_tri = op->wavegen;
fmsynthop_select_opfunc(op, FMSYNTH_OPFUNC_SAWTOOTH);
func_saw = op->wavegen;
fmsynthop_select_opfunc(op, FMSYNTH_OPFUNC_SQUARE);
func_sqa = op->wavegen;
fmsynthop_delete(op);
}
/****************************************************************************
* name: wavegen_dump
****************************************************************************/
static void wavegen_dump(void)
{
int t;
float deltaact;
deltaact = (float)FMSYNTH_PI * 2. * (float)HZ / (float)FS;
printf("===== Wave generator Dump ====\n");
printf("SIN, TRIANGLE, SAWTOOTH, SQUARE\n");
for (t = 0; t < DUMP_PERIOD; t++)
{
printf("%d, %d, %d, %d\n",
func_sin((int)(deltaact * t)),
func_tri((int)(deltaact * t)),
func_saw((int)(deltaact * t)),
func_sqa((int)(deltaact * t))
);
}
printf("\n");
}
/****************************************************************************
* name: sin_accuracy_test
****************************************************************************/
static void sin_accuracy_test(void)
{
int t;
float delta;
float deltaact;
float max_diff = 0.f;
float ref_sin;
int sin_val;
float norm_sin;
float diff;
delta = M_PI * 2. * (float)HZ / (float)FS;
deltaact = (float)FMSYNTH_PI * 2. * (float)HZ / (float)FS;
printf("===== Local SIN function ACCURACY TEST ====\n");
for (t = 0; t < ACCURACY_TEST_PERIOD; t++)
{
sin_val = func_sin((int)(deltaact * t));
ref_sin = sinf(delta * t);
norm_sin = (float)sin_val / (float)SHRT_MAX;
printf("t=%d, operator-sin(%d)=%d, norm_sin=%f, sinf(%f)=%f ",
t, (int)(deltaact * t), sin_val, norm_sin, delta * t, ref_sin);
diff = fabsf(norm_sin - ref_sin);
max_diff = max_diff < diff ? diff : max_diff;
if (diff >= 0.005)
{
printf(" BIG-DIFF : %f\n", diff);
}
else
{
printf("\n");
}
}
printf("\n\nMAX DIFF = %f\n\n", max_diff);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* name: main
****************************************************************************/
int main(void)
{
prepare_opfuncs();
sin_accuracy_test();
wavegen_dump();
return 0;
}