feat(audio): tone_gen sinus pur + test host
Composant tone_gen : generation sinus stereo entrelace (L==R), sans dependance IDF, teste en host TDD (4/4 assertions OK). Build IDF vert : libtone_gen.a compile en [1321/1335].
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
idf_component_register(
|
||||
SRCS "tone_gen.c"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Fill `buf` with n_frames stereo frames (L == R) of a sine wave.
|
||||
* buf must hold n_frames*2 int16_t. *phase is the running mono sample index,
|
||||
* advanced by n_frames. amplitude is the peak amplitude in int16 units. */
|
||||
void tone_gen_fill_stereo(int16_t *buf, int n_frames, uint32_t *phase,
|
||||
float freq_hz, float amplitude, uint32_t sample_rate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Test host pur (compilé avec cc, hors IDF) pour tone_gen_fill_stereo. */
|
||||
#include "tone_gen.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int16_t buf[8 * 2];
|
||||
uint32_t phase = 0;
|
||||
|
||||
/* 1. À phase 0, sin(0) = 0 → premier échantillon nul, L == R. */
|
||||
tone_gen_fill_stereo(buf, 8, &phase, 440.0f, 8000.0f, 16000);
|
||||
assert(buf[0] == 0);
|
||||
assert(buf[1] == 0);
|
||||
for (int i = 0; i < 8; i++) assert(buf[i*2] == buf[i*2+1]); /* L == R */
|
||||
|
||||
/* 2. La phase a avancé de 8 échantillons. */
|
||||
assert(phase == 8);
|
||||
|
||||
/* 3. Amplitude bornée par l'amplitude crête demandée (+1 d'arrondi). */
|
||||
uint32_t ph2 = 0;
|
||||
int16_t buf2[64 * 2];
|
||||
tone_gen_fill_stereo(buf2, 64, &ph2, 440.0f, 8000.0f, 16000);
|
||||
for (int i = 0; i < 64; i++) {
|
||||
assert(buf2[i*2] <= 8001 && buf2[i*2] >= -8001);
|
||||
}
|
||||
|
||||
/* 4. Valeur conforme au sinus attendu à un index connu (phase=4, 440Hz/16k). */
|
||||
float expected = 8000.0f * sinf(2.0f * (float)M_PI * 440.0f * 4.0f / 16000.0f);
|
||||
/* buf2[4] correspond à phase==4 (rempli depuis phase 0). */
|
||||
int16_t got = buf2[4 * 2];
|
||||
assert(fabsf((float)got - expected) < 2.0f);
|
||||
|
||||
printf("tone_gen: 4/4 assertions OK\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "tone_gen.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
void tone_gen_fill_stereo(int16_t *buf, int n_frames, uint32_t *phase,
|
||||
float freq_hz, float amplitude, uint32_t sample_rate)
|
||||
{
|
||||
for (int i = 0; i < n_frames; i++) {
|
||||
float s = amplitude * sinf(2.0f * (float)M_PI * freq_hz *
|
||||
(float)(*phase) / (float)sample_rate);
|
||||
int16_t v = (int16_t)s;
|
||||
buf[i * 2] = v; /* L */
|
||||
buf[i * 2 + 1] = v; /* R */
|
||||
(*phase)++;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user