← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
audio_stft_mag_phase_checked.c File Reference
#include "ckernel_tts.h"
#include "checked_float_buffer.h"
#include <math.h>
#include <stdint.h>
#include <string.h>

Go to the source code of this file.

Functions

int audio_stft_mag_phase_checked_f32 (const float *samples, size_t samples_capacity, const float *window, size_t window_capacity, const float *cos_table, const float *sin_table, size_t table_capacity, float *output, size_t output_capacity, size_t output_stride, float *scratch, size_t scratch_capacity, size_t samples_count, size_t n_fft, size_t hop, size_t frames)
 
int audio_stft_mag_phase_plan_f32 (size_t samples, size_t n_fft, size_t hop, size_t *frames, size_t *spectral_elements)
 
int audio_stft_mag_phase_trace_checked_f32 (const float *samples, size_t samples_capacity, const float *window, size_t window_capacity, const float *cos_table, const float *sin_table, size_t table_capacity, float *output, size_t output_capacity, size_t output_stride, float *scratch, size_t scratch_capacity, size_t samples_count, size_t n_fft, size_t hop, size_t frames, double *complex_trace, size_t complex_trace_capacity)
 
static int stft_mag_phase_impl (const float *samples, size_t samples_capacity, const float *window, size_t window_capacity, const float *cos_table, const float *sin_table, size_t table_capacity, float *output, size_t output_capacity, size_t output_stride, float *scratch, size_t scratch_capacity, size_t samples_count, size_t n_fft, size_t hop, size_t frames, double *complex_trace, size_t complex_trace_capacity)
 
static int stft_trace_overlaps (const double *trace, size_t elements, const float *other, size_t other_elements)
 
static int stft_trace_region (const double *trace, size_t elements)
 

Function Documentation

◆ audio_stft_mag_phase_checked_f32()

int audio_stft_mag_phase_checked_f32 ( const float *  samples,
size_t  samples_capacity,
const float *  window,
size_t  window_capacity,
const float *  cos_table,
const float *  sin_table,
size_t  table_capacity,
float *  output,
size_t  output_capacity,
size_t  output_stride,
float *  scratch,
size_t  scratch_capacity,
size_t  samples_count,
size_t  n_fft,
size_t  hop,
size_t  frames 
)

Definition at line 133 of file audio_stft_mag_phase_checked.c.

138 {
139 return stft_mag_phase_impl(samples, samples_capacity, window,
140 window_capacity, cos_table, sin_table, table_capacity, output,
141 output_capacity, output_stride, scratch, scratch_capacity,
142 samples_count, n_fft, hop, frames, NULL, 0);
143}
static int stft_mag_phase_impl(const float *samples, size_t samples_capacity, const float *window, size_t window_capacity, const float *cos_table, const float *sin_table, size_t table_capacity, float *output, size_t output_capacity, size_t output_stride, float *scratch, size_t scratch_capacity, size_t samples_count, size_t n_fft, size_t hop, size_t frames, double *complex_trace, size_t complex_trace_capacity)

References stft_mag_phase_impl().

◆ audio_stft_mag_phase_plan_f32()

int audio_stft_mag_phase_plan_f32 ( size_t  samples,
size_t  n_fft,
size_t  hop,
size_t *  frames,
size_t *  spectral_elements 
)

Definition at line 8 of file audio_stft_mag_phase_checked.c.

9 {
10 if (!frames || !spectral_elements || n_fft < 2 || (n_fft & 1) ||
11 !hop || samples <= n_fft / 2 || samples > INT64_MAX / 2 ||
12 n_fft > INT64_MAX / 2 || samples > SIZE_MAX / sizeof(float) ||
13 n_fft > SIZE_MAX / sizeof(float)) return CK_AUDIO_EXTENT_INVALID;
14 const size_t count = samples / hop + 1;
15 const size_t bins = n_fft / 2 + 1;
16 if (count > SIZE_MAX / (2 * bins) ||
17 count * (2 * bins) > SIZE_MAX / sizeof(float))
19 *frames = count;
20 *spectral_elements = count * 2 * bins;
21 return CK_AUDIO_EXTENT_OK;
22}
@ CK_AUDIO_EXTENT_INVALID
Definition ckernel_tts.h:42
@ CK_AUDIO_EXTENT_OVERFLOW
Definition ckernel_tts.h:44
@ CK_AUDIO_EXTENT_OK
Definition ckernel_tts.h:41
const uint8_t size_t count
Definition true_bpe.h:209

References CK_AUDIO_EXTENT_INVALID, CK_AUDIO_EXTENT_OK, CK_AUDIO_EXTENT_OVERFLOW, and count.

Referenced by stft_mag_phase_impl().

◆ audio_stft_mag_phase_trace_checked_f32()

int audio_stft_mag_phase_trace_checked_f32 ( const float *  samples,
size_t  samples_capacity,
const float *  window,
size_t  window_capacity,
const float *  cos_table,
const float *  sin_table,
size_t  table_capacity,
float *  output,
size_t  output_capacity,
size_t  output_stride,
float *  scratch,
size_t  scratch_capacity,
size_t  samples_count,
size_t  n_fft,
size_t  hop,
size_t  frames,
double *  complex_trace,
size_t  complex_trace_capacity 
)

Definition at line 147 of file audio_stft_mag_phase_checked.c.

153 {
154 if (!complex_trace) return CK_AUDIO_EXTENT_INVALID;
155 return stft_mag_phase_impl(samples, samples_capacity, window,
156 window_capacity, cos_table, sin_table, table_capacity, output,
157 output_capacity, output_stride, scratch, scratch_capacity,
158 samples_count, n_fft, hop, frames, complex_trace,
159 complex_trace_capacity);
160}

References CK_AUDIO_EXTENT_INVALID, and stft_mag_phase_impl().

◆ stft_mag_phase_impl()

static int stft_mag_phase_impl ( const float *  samples,
size_t  samples_capacity,
const float *  window,
size_t  window_capacity,
const float *  cos_table,
const float *  sin_table,
size_t  table_capacity,
float *  output,
size_t  output_capacity,
size_t  output_stride,
float *  scratch,
size_t  scratch_capacity,
size_t  samples_count,
size_t  n_fft,
size_t  hop,
size_t  frames,
double *  complex_trace,
size_t  complex_trace_capacity 
)
static

Definition at line 40 of file audio_stft_mag_phase_checked.c.

46 {
47 size_t required_frames, spectral_elements, span, bins, table_need;
48 const int planned = audio_stft_mag_phase_plan_f32(samples_count, n_fft,
49 hop, &required_frames, &spectral_elements);
50 if (planned != CK_AUDIO_EXTENT_OK) return planned;
51 if (frames != required_frames || output_stride < frames ||
52 n_fft > SIZE_MAX / (n_fft / 2 + 1)) return CK_AUDIO_EXTENT_INVALID;
53 bins = n_fft / 2 + 1;
54 table_need = bins * n_fft;
55 if (!ck_checked_span(2 * bins, frames, output_stride, &span))
57 if (samples_capacity < samples_count || window_capacity < n_fft ||
58 table_capacity < table_need || output_capacity < span ||
59 scratch_capacity < spectral_elements) return CK_AUDIO_EXTENT_LIMIT;
60 if (!ck_checked_region(samples, samples_count) ||
61 !ck_checked_region(window, n_fft) ||
62 !ck_checked_region(cos_table, table_need) ||
63 !ck_checked_region(sin_table, table_need) ||
64 !ck_checked_region(output, span) ||
65 !ck_checked_region(scratch, spectral_elements) ||
66 ck_checked_overlap(output, span, samples, samples_count) ||
67 ck_checked_overlap(output, span, window, n_fft) ||
68 ck_checked_overlap(output, span, cos_table, table_need) ||
69 ck_checked_overlap(output, span, sin_table, table_need) ||
70 ck_checked_overlap(output, span, scratch, spectral_elements) ||
71 ck_checked_overlap(scratch, spectral_elements, samples, samples_count) ||
72 ck_checked_overlap(scratch, spectral_elements, window, n_fft) ||
73 ck_checked_overlap(scratch, spectral_elements, cos_table, table_need) ||
74 ck_checked_overlap(scratch, spectral_elements, sin_table, table_need))
76 if (!ck_checked_finite(samples, samples_count) ||
77 !ck_checked_finite(window, n_fft) ||
78 !ck_checked_finite(cos_table, table_need) ||
79 !ck_checked_finite(sin_table, table_need))
81 if (complex_trace) {
82 if (complex_trace_capacity < spectral_elements)
84 if (!stft_trace_region(complex_trace, spectral_elements) ||
85 stft_trace_overlaps(complex_trace, spectral_elements, samples, samples_count) ||
86 stft_trace_overlaps(complex_trace, spectral_elements, window, n_fft) ||
87 stft_trace_overlaps(complex_trace, spectral_elements, cos_table, table_need) ||
88 stft_trace_overlaps(complex_trace, spectral_elements, sin_table, table_need) ||
89 stft_trace_overlaps(complex_trace, spectral_elements, output, span) ||
90 stft_trace_overlaps(complex_trace, spectral_elements, scratch, spectral_elements))
92 } else if (complex_trace_capacity) return CK_AUDIO_EXTENT_INVALID;
93 const size_t center = n_fft / 2;
94 for (size_t frame = 0; frame < frames; ++frame) {
95 for (size_t bin = 0; bin < bins; ++bin) {
96 double real = 0.0, imag = 0.0;
97 for (size_t tap = 0; tap < n_fft; ++tap) {
98 /* samples_count > center guarantees one reflection suffices. */
99 const int64_t unreflected = (int64_t)(frame * hop + tap) -
100 (int64_t)center;
101 size_t source;
102 if (unreflected < 0) source = (size_t)(-unreflected);
103 else if ((uint64_t)unreflected >= samples_count)
104 source = 2 * (samples_count - 1) - (size_t)unreflected;
105 else source = (size_t)unreflected;
106 const double value = (double)samples[source] * window[tap];
107 real += value * cos_table[bin * n_fft + tap];
108 imag += value * sin_table[bin * n_fft + tap];
109 }
110 /* The Nyquist bin of a real-input even FFT has exactly zero
111 * imaginary part. Trig-table roundoff otherwise flips +pi to
112 * -pi, which is not interchangeable for downstream convolutions. */
113 if (bin == bins - 1) imag = 0.0;
114 const float magnitude = (float)hypot(real, imag);
115 const float phase = (float)atan2(imag, real);
116 if (!isfinite(magnitude) || !isfinite(phase))
118 if (complex_trace) {
119 const size_t index = 2 * (bin * frames + frame);
120 complex_trace[index] = real;
121 complex_trace[index + 1] = imag;
122 }
123 scratch[bin * frames + frame] = magnitude;
124 scratch[(bins + bin) * frames + frame] = phase;
125 }
126 }
127 for (size_t row = 0; row < 2 * bins; ++row)
128 memcpy(output + row * output_stride, scratch + row * frames,
129 frames * sizeof(float));
130 return CK_AUDIO_EXTENT_OK;
131}
int audio_stft_mag_phase_plan_f32(size_t samples, size_t n_fft, size_t hop, size_t *frames, size_t *spectral_elements)
static int stft_trace_region(const double *trace, size_t elements)
static int stft_trace_overlaps(const double *trace, size_t elements, const float *other, size_t other_elements)
static int ck_checked_finite(const float *ptr, size_t n)
static int ck_checked_span(size_t rows, size_t width, size_t stride, size_t *span)
static int ck_checked_region(const float *ptr, size_t n)
static int ck_checked_overlap(const float *a, size_t na, const float *b, size_t nb)
@ CK_AUDIO_EXTENT_LIMIT
Definition ckernel_tts.h:43

References audio_stft_mag_phase_plan_f32(), CK_AUDIO_EXTENT_INVALID, CK_AUDIO_EXTENT_LIMIT, CK_AUDIO_EXTENT_OK, CK_AUDIO_EXTENT_OVERFLOW, ck_checked_finite(), ck_checked_overlap(), ck_checked_region(), ck_checked_span(), stft_trace_overlaps(), and stft_trace_region().

Referenced by audio_stft_mag_phase_checked_f32(), and audio_stft_mag_phase_trace_checked_f32().

◆ stft_trace_overlaps()

static int stft_trace_overlaps ( const double *  trace,
size_t  elements,
const float *  other,
size_t  other_elements 
)
static

Definition at line 34 of file audio_stft_mag_phase_checked.c.

35 {
36 return (uintptr_t)trace < (uintptr_t)other + other_elements * sizeof(float) &&
37 (uintptr_t)other < (uintptr_t)trace + elements * sizeof(double);
38}

Referenced by stft_mag_phase_impl().

◆ stft_trace_region()

static int stft_trace_region ( const double *  trace,
size_t  elements 
)
static

Definition at line 28 of file audio_stft_mag_phase_checked.c.

28 {
29 return trace && (uintptr_t)trace % _Alignof(double) == 0 &&
30 elements <= SIZE_MAX / sizeof(double) &&
31 (uintptr_t)trace <= UINTPTR_MAX - elements * sizeof(double);
32}

Referenced by stft_mag_phase_impl().