14#if defined(__AVX2__) && defined(__FMA__)
18#define CK_AUDIO_PI_F 3.14159265358979323846f
19#define CK_AUDIO_PI_D 3.14159265358979323846264338327950288
23 while (index < 0 || index >= length) {
27 index = 2 * length - index - 2;
35 return (uint16_t)p[0] | ((uint16_t)p[1] << 8);
40 return (uint32_t)p[0] | ((uint32_t)p[1] << 8) |
41 ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
49 if (bytes == NULL || info == NULL) {
52 if (byte_count < 12 || memcmp(bytes,
"RIFF", 4) != 0 ||
53 memcmp(bytes + 8,
"WAVE", 4) != 0) {
56 const size_t riff_end = (size_t)
read_u32_le(bytes + 4) + 8u;
57 if (riff_end < 12 || riff_end > byte_count) {
60 memset(info, 0,
sizeof(*info));
64 while (offset + 8 <= riff_end) {
65 const uint8_t *chunk = bytes + offset;
66 const uint32_t chunk_bytes =
read_u32_le(chunk + 4);
67 const size_t payload = offset + 8;
68 if ((
size_t)chunk_bytes > riff_end - payload) {
71 if (!found_format && memcmp(chunk,
"fmt ", 4) == 0) {
72 if (chunk_bytes < 16) {
80 }
else if (!found_data && memcmp(chunk,
"data", 4) == 0) {
85 const size_t padded = (size_t)chunk_bytes + ((
size_t)chunk_bytes & 1u);
86 if (padded > SIZE_MAX - payload) {
89 offset = payload + padded;
91 if (!found_format || !found_data || info->
format_tag != 1 ||
96 const size_t bytes_per_frame = (size_t)info->
channels * 2u;
97 if (bytes_per_frame == 0 || info->
data_bytes % bytes_per_frame != 0 ||
98 info->
data_bytes / bytes_per_frame > (
size_t)INT_MAX) {
102 return info->
frames > 0 ? 0 : -6;
106 const uint8_t *bytes,
112 if (bytes == NULL || info == NULL || mono == NULL) {
116 info->
channels <= 0 || info->
frames <= 0 || mono_capacity < info->frames ||
121 const float scale = 1.0f / 32768.0f;
122 for (
int frame = 0; frame < info->
frames; ++frame) {
124 for (
int channel = 0; channel < info->
channels; ++channel) {
125 const size_t index = ((size_t)frame * info->
channels + channel) * 2u;
128 mono[frame] = (sum / (float)info->
channels) * scale;
134 const uint8_t *bytes,
141 bytes, byte_count, 0, mono, mono_capacity, info);
145 const uint8_t *bytes,
156 if (start_frame < 0 || start_frame >= info->
frames || mono_capacity <= 0) {
159 const int available = info->
frames - start_frame;
160 const int decoded = available < mono_capacity ? available : mono_capacity;
162 const float scale = 1.0f / 32768.0f;
163 for (
int frame = 0; frame < decoded; ++frame) {
165 const size_t source_frame = (size_t)start_frame + (
size_t)frame;
166 for (
int channel = 0; channel < info->
channels; ++channel) {
168 (source_frame * (size_t)info->
channels + (
size_t)channel) * 2u;
171 mono[frame] = (sum / (float)info->
channels) * scale;
177 const int16_t *interleaved,
182 if (interleaved == NULL || mono == NULL) {
185 if (n_frames <= 0 || n_channels <= 0) {
188 const float scale = 1.0f / 32768.0f;
189 for (
int frame = 0; frame < n_frames; ++frame) {
191 for (
int channel = 0; channel < n_channels; ++channel) {
192 sum += (float)interleaved[(
size_t)frame * n_channels + channel];
194 mono[frame] = (sum / (float)n_channels) * scale;
204 if (input_frames <= 0 || input_rate <= 0 || output_rate <= 0) {
207 return 1 + (int)(((
long long)(input_frames - 1) * output_rate) / input_rate);
218 if (input == NULL || output == NULL) {
222 if (expected <= 0 || output_frames != expected) {
225 for (
int frame = 0; frame < output_frames; ++frame) {
226 const long long numerator = (
long long)frame * input_rate;
227 const int left = (int)(numerator / output_rate);
229 const float fraction = (float)(numerator % output_rate) / (float)output_rate;
230 output[frame] = fmaf(input[
right] - input[
left], fraction, input[
left]);
244 if (input == NULL || output == NULL) {
248 if (expected <= 0 || output_frames != expected || radius < 2 || radius > 128) {
251 const double ratio = (double)output_rate / (
double)input_rate;
252 const double cutoff = ratio < 1.0 ? ratio : 1.0;
253 for (
int frame = 0; frame < output_frames; ++frame) {
254 const double source = (double)frame * (
double)input_rate / (double)output_rate;
255 const int center = (int)floor(source);
256 double weighted = 0.0;
257 double weight_sum = 0.0;
258 for (
int tap = center - radius + 1; tap <= center + radius; ++tap) {
259 if (tap < 0 || tap >= input_frames) {
262 const double distance = source - (double)tap;
263 const double scaled = cutoff * distance;
264 const double sinc = fabs(scaled) < 1.0e-12 ? 1.0 :
266 const double window_x = distance / (double)radius;
267 if (fabs(window_x) >= 1.0) {
270 const double window = 0.5 * (1.0 + cos(
CK_AUDIO_PI_D * window_x));
271 const double weight = cutoff * sinc * window;
272 weighted += (double)input[tap] * weight;
273 weight_sum += weight;
275 output[frame] = weight_sum != 0.0 ? (float)(weighted / weight_sum) : 0.0f;
286 if (input == NULL || output == NULL) {
289 if (input_frames <= 0 || output_frames <= 0) {
292 const int copied = input_frames < output_frames ? input_frames : output_frames;
293 memmove(output, input, (
size_t)copied *
sizeof(
float));
294 if (copied < output_frames) {
298 (
size_t)(output_frames - copied) *
sizeof(
float));
309 if (input == NULL || output == NULL) {
312 if (frames <= 0 || !isfinite(coefficient)) {
315 if (input == output) {
316 for (
int frame = frames - 1; frame > 0; --frame) {
317 output[frame] = input[frame] - coefficient * input[frame - 1];
320 output[0] = input[0];
321 for (
int frame = 1; frame < frames; ++frame) {
322 output[frame] = input[frame] - coefficient * input[frame - 1];
335 if (input == NULL || output == NULL) {
338 if (channels <= 0 || frames <= 0 || !isfinite(epsilon) || epsilon < 0.0f) {
341 const int denominator = frames > 1 ? frames - 1 : 1;
342 for (
int channel = 0; channel < channels; ++channel) {
344 double sum_squared_difference = 0.0;
345 for (
int frame = 0; frame < frames; ++frame) {
346 sum += (double)input[(
size_t)frame * channels + channel];
348 const double mean = sum / (double)frames;
349 for (
int frame = 0; frame < frames; ++frame) {
350 const double difference =
351 (double)input[(
size_t)frame * channels + channel] - mean;
352 sum_squared_difference += difference * difference;
354 float standard_deviation = sqrtf(
355 (
float)(sum_squared_difference / (
double)denominator));
356 if (isnan(standard_deviation)) {
357 standard_deviation = 0.0f;
359 const float inverse_standard_deviation =
360 1.0f / (standard_deviation + epsilon);
361 for (
int frame = 0; frame < frames; ++frame) {
362 const size_t index = (size_t)frame * channels + channel;
363 output[index] = (float)((
double)input[index] - mean) *
364 inverse_standard_deviation;
376 if (window == NULL || cos_table == NULL || sin_table == NULL) {
379 if (n_fft <= 0 || (n_fft & 1) != 0) {
382 const int bins = n_fft / 2 + 1;
383 for (
int sample = 0; sample < n_fft; ++sample) {
384 window[sample] = 0.5f - 0.5f * cosf(
387 for (
int bin = 0; bin < bins; ++bin) {
388 for (
int sample = 0; sample < n_fft; ++sample) {
390 (float)(bin * sample) / (float)n_fft;
391 const size_t index = (size_t)bin * n_fft + sample;
392 cos_table[index] = cosf(angle);
393 sin_table[index] = sinf(angle);
402 return hz / (200.0 / 3.0);
404 return 15.0 + log(hz / 1000.0) / (log(6.4) / 27.0);
410 return (200.0 / 3.0) * mel;
412 return 1000.0 * exp((log(6.4) / 27.0) * (mel - 15.0));
421 if (mel_filters == NULL) {
424 if (sample_rate <= 0 || n_fft <= 0 || (n_fft & 1) != 0 || n_mels <= 0) {
427 const int bins = n_fft / 2 + 1;
430 for (
int mel = 0; mel < n_mels; ++mel) {
431 const double left_mel =
432 mel_min + (mel_max - mel_min) * (
double)mel / (double)(n_mels + 1);
433 const double center_mel =
434 mel_min + (mel_max - mel_min) * (
double)(mel + 1) / (
double)(n_mels + 1);
435 const double right_mel =
436 mel_min + (mel_max - mel_min) * (
double)(mel + 2) / (
double)(n_mels + 1);
440 const double normalization = 2.0 / (
right -
left);
441 for (
int bin = 0; bin < bins; ++bin) {
443 ((double)sample_rate / 2.0) * (double)bin / (
double)(bins - 1);
444 const double lower = (hz -
left) / (center -
left);
445 const double upper = (
right - hz) / (
right - center);
446 const double triangle = fmax(0.0, fmin(lower, upper));
447 mel_filters[(size_t)mel * bins + bin] =
448 (
float)(triangle * normalization);
455 const float *samples,
458 const float *cos_table,
459 const float *sin_table,
465 if (samples == NULL || window == NULL || cos_table == NULL ||
466 sin_table == NULL || power == NULL) {
469 if (n_fft <= 0 || hop_length <= 0 || n_samples <= n_fft / 2 ||
470 (n_fft & 1) != 0 || n_frames <= 0) {
473 if (n_frames != n_samples / hop_length) {
476 const int bins = n_fft / 2 + 1;
477 const int center = n_fft / 2;
478 for (
int frame = 0; frame < n_frames; ++frame) {
479 for (
int bin = 0; bin < bins; ++bin) {
480 const float *cos_row = cos_table + (size_t)bin * n_fft;
481 const float *sin_row = sin_table + (size_t)bin * n_fft;
484 for (
int sample = 0; sample < n_fft; ++sample) {
486 frame * hop_length + sample - center, n_samples);
487 const float value = samples[source] * window[sample];
488 real = fmaf(value, cos_row[sample], real);
489 imag = fmaf(value, sin_row[sample], imag);
491 power[(size_t)frame * bins + bin] =
492 fmaf(real, real, imag * imag);
499 const float *samples,
503 const float *cos_table,
504 const float *sin_table,
511 if (samples == NULL || window == NULL || cos_table == NULL ||
512 sin_table == NULL || power == NULL) {
515 if (n_samples <= 0 || window_length <= 0 || n_fft <= 0 ||
516 window_length > n_fft || (n_fft & 1) != 0 || hop_length <= 0 ||
517 n_frames <= 0 || (reflect_padding != 0 && reflect_padding != 1)) {
520 if (n_frames != n_samples / hop_length + 1) {
524 const int bins = n_fft / 2 + 1;
525 const int center = n_fft / 2;
526 const int window_start = (n_fft - window_length) / 2;
527 for (
int frame = 0; frame < n_frames; ++frame) {
528 for (
int bin = 0; bin < bins; ++bin) {
529 const float *cos_row = cos_table + (size_t)bin * n_fft;
530 const float *sin_row = sin_table + (size_t)bin * n_fft;
533 for (
int sample = 0; sample < window_length; ++sample) {
534 const int fft_sample = window_start + sample;
535 int source = frame * hop_length + fft_sample - center;
536 if (source < 0 || source >= n_samples) {
537 if (!reflect_padding) {
542 const float value = samples[source] * window[sample];
543 real = fmaf(value, cos_row[fft_sample], real);
544 imag = fmaf(value, sin_row[fft_sample], imag);
546 power[(size_t)frame * bins + bin] =
547 fmaf(real, real, imag * imag);
555 const float *mel_filters,
562 if (power == NULL || mel_filters == NULL || log_mel == NULL) {
565 if (frames <= 0 || bins <= 0 || channels <= 0 || epsilon <= 0.0f) {
568 for (
int frame = 0; frame < frames; ++frame) {
569 const float *spectrum = power + (size_t)frame * bins;
570 float *output = log_mel + (size_t)frame * channels;
571 for (
int channel = 0; channel < channels; ++channel) {
572 const float *filter = mel_filters + (size_t)channel * bins;
574 for (
int bin = 0; bin < bins; ++bin) {
575 sum = fmaf(spectrum[bin], filter[bin], sum);
577 output[channel] = logf(sum + epsilon);
584 const float *samples,
588 const float *cos_table,
589 const float *sin_table,
594 const float *samples,
597 const float *cos_table,
598 const float *sin_table,
605 if (samples == NULL || window == NULL || cos_table == NULL ||
606 sin_table == NULL || power == NULL || fft_scratch == NULL) {
610 n_samples <= n_fft / 2 || n_frames <= 0 ||
611 n_frames != n_samples / hop_length) {
614 for (
int frame = 0; frame < n_frames; ++frame) {
629 const float *samples,
633 const float *cos_table,
634 const float *sin_table,
638 const int radix = 20;
640 float *stage_real = fft_scratch;
642 for (
int p = 0; p < radix; ++p) {
643 for (
int k = 0; k < radix; ++k) {
646 for (
int q = 0; q < radix; ++q) {
647 const int sample = p + radix * q;
651 const float value = samples[source] * window[sample];
652 const size_t twiddle =
654 real = fmaf(value, cos_table[twiddle], real);
655 imag = fmaf(value, sin_table[twiddle], imag);
657 stage_real[p * radix + k] = real;
658 stage_imag[p * radix + k] = imag;
661 for (
int frequency = 0;
664 const int k = frequency % radix;
667 for (
int p = 0; p < radix; ++p) {
668 const float a = stage_real[p * radix + k];
669 const float b = stage_imag[p * radix + k];
670 const size_t twiddle =
672 const float c = cos_table[twiddle];
673 const float s = sin_table[twiddle];
674 real = fmaf(a, c, fmaf(-b, s, real));
675 imag = fmaf(a, s, fmaf(b, c, imag));
677 power[frequency] = fmaf(real, real, imag * imag);
682 const uint8_t *bytes,
685 int target_sample_rate,
687 const float *cos_table,
688 const float *sin_table,
689 const float *mel_filters,
694 if (bytes == NULL || window == NULL || cos_table == NULL ||
695 sin_table == NULL || mel_filters == NULL || log_mel == NULL) {
704 n_mels <= 0 || output_frames <= 0) {
707 float *samples = (
float *)malloc((
size_t)info.
frames *
sizeof(float));
708 if (samples == NULL) {
712 bytes, byte_count, &info, samples, info.
frames);
713 if (decoded != info.
frames) {
721 (
size_t)n_mels * (
size_t)output_frames *
sizeof(
float));
724 float maximum = -INFINITY;
727 for (
int frame = 0; frame < global_frames; ++frame) {
737 for (
int mel = 0; mel < n_mels; ++mel) {
738 const float *filter =
742 sum = fmaf(filter[bin], power[bin], sum);
744 const float value = log10f(fmaxf(sum, 1.0e-10f));
745 maximum = fmaxf(maximum, value);
746 const int output_frame = frame - start_feature;
747 if (output_frame >= 0 && output_frame < output_frames) {
748 log_mel[(size_t)mel * output_frames + output_frame] = value;
753 if (!isfinite(maximum)) {
757 const int available = global_frames - start_feature;
758 const int valid_frames =
759 available < output_frames ? (available > 0 ? available : 0) : output_frames;
760 const float floor = maximum - 8.0f;
761 for (
int mel = 0; mel < n_mels; ++mel) {
762 float *output = log_mel + (size_t)mel * output_frames;
763 for (
int frame = 0; frame < valid_frames; ++frame) {
764 output[frame] = (fmaxf(output[frame], floor) + 4.0f) / 4.0f;
782 int use_stride2_contiguous;
783} ck_audio_conv1d_f32_args_t;
785#if defined(__AVX2__) && defined(__FMA__)
786static inline __m256 ck_audio_load_stride2_8(
const float *input)
788 const __m256i select_even = _mm256_setr_epi32(0, 2, 4, 6, 0, 0, 0, 0);
789 const __m256 lo = _mm256_permutevar8x32_ps(
790 _mm256_loadu_ps(input), select_even);
791 const __m256 hi = _mm256_permutevar8x32_ps(
792 _mm256_loadu_ps(input + 8), select_even);
793 return _mm256_insertf128_ps(
794 _mm256_castps128_ps256(_mm256_castps256_ps128(lo)),
795 _mm256_castps256_ps128(hi), 1);
805 const ck_audio_conv1d_f32_args_t *args =
806 (
const ck_audio_conv1d_f32_args_t *)opaque;
807 for (
int out_channel = ith; out_channel < args->output_channels;
808 out_channel += nth) {
809 const float *weight_channel = args->weight +
810 (size_t)out_channel * args->input_channels * args->kernel_size;
811 float *output_channel = args->output +
812 (size_t)out_channel * args->output_frames;
814 const int interior_begin =
815 (args->padding + args->stride - 1) / args->stride;
816 for (; out_frame < interior_begin && out_frame < args->output_frames;
818 float sum = args->bias != NULL ? args->bias[out_channel] : 0.0f;
819 for (
int in_channel = 0; in_channel < args->input_channels;
821 const float *input_channel = args->input +
822 (size_t)in_channel * args->input_frames;
823 const float *weight_row = weight_channel +
824 (size_t)in_channel * args->kernel_size;
825 for (
int kernel = 0; kernel < args->kernel_size; ++kernel) {
827 out_frame * args->stride + kernel - args->padding;
828 if (in_frame >= 0 && in_frame < args->input_frames) {
829 sum = fmaf(input_channel[in_frame], weight_row[kernel], sum);
833 output_channel[out_frame] = sum;
835#if defined(__AVX2__) && defined(__FMA__)
836 for (; out_frame + 7 < args->output_frames &&
837 (out_frame + 7) * args->stride + args->kernel_size - 1 -
838 args->padding < args->input_frames;
840 __m256 sums = _mm256_set1_ps(
841 args->bias != NULL ? args->bias[out_channel] : 0.0f);
842 for (
int in_channel = 0; in_channel < args->input_channels;
844 const float *input_channel = args->input +
845 (size_t)in_channel * args->input_frames;
846 const float *weight_row = weight_channel +
847 (size_t)in_channel * args->kernel_size;
848 for (
int kernel = 0; kernel < args->kernel_size; ++kernel) {
850 out_frame * args->stride + kernel - args->padding;
852 if (args->stride == 1) {
853 samples = _mm256_loadu_ps(input_channel + base);
854 }
else if (args->stride == 2 &&
855 args->use_stride2_contiguous &&
856 base + 15 < args->input_frames) {
857 samples = ck_audio_load_stride2_8(input_channel + base);
858 }
else if (args->stride == 2) {
859 const __m256i indices = _mm256_setr_epi32(
860 base, base + 2, base + 4, base + 6,
861 base + 8, base + 10, base + 12, base + 14);
862 samples = _mm256_i32gather_ps(input_channel, indices, 4);
864 samples = _mm256_setr_ps(
866 input_channel[base + args->stride],
867 input_channel[base + 2 * args->stride],
868 input_channel[base + 3 * args->stride],
869 input_channel[base + 4 * args->stride],
870 input_channel[base + 5 * args->stride],
871 input_channel[base + 6 * args->stride],
872 input_channel[base + 7 * args->stride]);
874 sums = _mm256_fmadd_ps(
875 samples, _mm256_set1_ps(weight_row[kernel]), sums);
878 _mm256_storeu_ps(output_channel + out_frame, sums);
881 for (; out_frame < args->output_frames; ++out_frame) {
882 float sum = args->bias != NULL ? args->bias[out_channel] : 0.0f;
883 for (
int in_channel = 0; in_channel < args->input_channels;
885 const float *input_channel = args->input +
886 (size_t)in_channel * args->input_frames;
887 const float *weight_row = weight_channel +
888 (size_t)in_channel * args->kernel_size;
889 for (
int kernel = 0; kernel < args->kernel_size; ++kernel) {
891 out_frame * args->stride + kernel - args->padding;
892 if (in_frame >= 0 && in_frame < args->input_frames) {
893 sum = fmaf(input_channel[in_frame], weight_row[kernel], sum);
897 output_channel[out_frame] = sum;
915 if (input == NULL || weight == NULL || output == NULL) {
918 if (input_channels <= 0 || output_channels <= 0 || input_frames <= 0 ||
919 kernel_size <= 0 || stride <= 0 || padding < 0 || output_frames <= 0) {
922 const int expected = (input_frames + 2 * padding - kernel_size) / stride + 1;
923 if (output_frames != expected) {
926 const char *disable_stride2 =
927 getenv(
"CK_DISABLE_AUDIO_CONV_STRIDE2_CONTIGUOUS");
928 ck_audio_conv1d_f32_args_t args = {
933 .input_channels = input_channels,
934 .output_channels = output_channels,
935 .input_frames = input_frames,
936 .kernel_size = kernel_size,
939 .output_frames = output_frames,
940 .use_stride2_contiguous = !(
941 disable_stride2 && disable_stride2[0] &&
942 strcmp(disable_stride2,
"0") != 0),
946 if (active > output_channels) active = output_channels;
947 if (pool != NULL && active > 1) {
974} ck_audio_conv2d_whc_f32_args_t;
981 const ck_audio_conv2d_whc_f32_args_t *args =
982 (
const ck_audio_conv2d_whc_f32_args_t *)opaque;
983 const int outputs_per_channel = args->output_width * args->output_height;
984 const int input_channels_per_group = args->input_channels / args->groups;
985 const int output_channels_per_group = args->output_channels / args->groups;
986 for (
int index = begin; index <
end; ++index) {
987 const int output_channel = index / outputs_per_channel;
988 const int spatial = index - output_channel * outputs_per_channel;
989 const int output_y = spatial / args->output_width;
990 const int output_x = spatial - output_y * args->output_width;
991 const int group = output_channel / output_channels_per_group;
992 const int input_channel_begin = group * input_channels_per_group;
993 float sum = args->bias != NULL ? args->bias[output_channel] : 0.0f;
994 for (
int input_channel_offset = 0;
995 input_channel_offset < input_channels_per_group;
996 ++input_channel_offset) {
997 const int input_channel = input_channel_begin + input_channel_offset;
998 for (
int kernel_y = 0; kernel_y < args->kernel_height; ++kernel_y) {
999 const int input_y = output_y * args->stride_height + kernel_y -
1000 args->padding_height;
1001 if (input_y < 0 || input_y >= args->input_height) {
1004 for (
int kernel_x = 0; kernel_x < args->kernel_width; ++kernel_x) {
1005 const int input_x = output_x * args->stride_width + kernel_x -
1006 args->padding_width;
1007 if (input_x < 0 || input_x >= args->input_width) {
1010 const size_t input_index =
1011 ((size_t)input_channel * args->input_height + input_y) *
1012 args->input_width + input_x;
1013 const size_t weight_index =
1014 (((size_t)output_channel * input_channels_per_group +
1015 input_channel_offset) * args->kernel_height + kernel_y) *
1016 args->kernel_width + kernel_x;
1017 sum = fmaf(args->input[input_index], args->weight[weight_index], sum);
1021 args->output[index] = sum;
1027 const float *weight,
1033 int output_channels,
1044 if (input == NULL || weight == NULL || output == NULL) {
1047 if (input_width <= 0 || input_height <= 0 || input_channels <= 0 ||
1048 output_channels <= 0 || kernel_width <= 0 || kernel_height <= 0 ||
1049 stride_width <= 0 || stride_height <= 0 || padding_width < 0 ||
1050 padding_height < 0 || groups <= 0 || output_width <= 0 ||
1051 output_height <= 0 || input_channels % groups != 0 ||
1052 output_channels % groups != 0) {
1055 const int expected_width =
1056 (input_width + 2 * padding_width - kernel_width) / stride_width + 1;
1057 const int expected_height =
1058 (input_height + 2 * padding_height - kernel_height) / stride_height + 1;
1059 if (output_width != expected_width || output_height != expected_height) {
1062 ck_audio_conv2d_whc_f32_args_t args = {
1067 .input_width = input_width,
1068 .input_height = input_height,
1069 .input_channels = input_channels,
1070 .output_channels = output_channels,
1071 .kernel_width = kernel_width,
1072 .kernel_height = kernel_height,
1073 .stride_width = stride_width,
1074 .stride_height = stride_height,
1075 .padding_width = padding_width,
1076 .padding_height = padding_height,
1078 .output_width = output_width,
1079 .output_height = output_height,
1081 const int output_elements = output_channels * output_height * output_width;
1084 if (active > output_elements) {
1085 active = output_elements;
1087 if (pool != NULL && active > 1) {
1088 const int grain = output_width > 0 ? output_width : 1;
1090 pool, active, 0, output_elements, grain,
1102} ck_audio_glu_split_f32_args_t;
1106 const ck_audio_glu_split_f32_args_t *args =
1107 (
const ck_audio_glu_split_f32_args_t *)opaque;
1108 for (
int index = begin; index <
end; ++index) {
1109 const float gate = args->gate[index];
1110 const float sigmoid = 1.0f / (1.0f + expf(-gate));
1111 args->output[index] = args->value[index] * sigmoid;
1121 if (input == NULL || output == NULL) {
1124 if (channels <= 0 || frames <= 0) {
1127 const int elements = channels * frames;
1128 ck_audio_glu_split_f32_args_t args = {
1130 .gate = input + elements,
1135 if (active > elements) {
1138 if (pool != NULL && active > 1) {
1140 pool, active, 0, elements, 256,
1149 const float *raw_scores;
1153} ck_audio_relative_shift_f32_args_t;
1156 int begin,
int end,
void *opaque)
1158 const ck_audio_relative_shift_f32_args_t *args =
1159 (
const ck_audio_relative_shift_f32_args_t *)opaque;
1160 const int frames = args->query_frames;
1161 const int raw_frames = args->raw_key_frames;
1162 for (
int row = begin; row <
end; ++row) {
1163 const int query = row % frames;
1164 const float *raw = args->raw_scores + (size_t)row * raw_frames;
1165 float *output = args->scores + (size_t)row * frames;
1166 const int origin = frames - 1 - query;
1167 for (
int key = 0; key < frames; ++key) {
1168 output[key] = raw[origin + key];
1174 const float *raw_scores,
1179 if (raw_scores == NULL || scores == NULL) {
1182 if (heads <= 0 || query_frames <= 0) {
1185 const int rows = heads * query_frames;
1186 ck_audio_relative_shift_f32_args_t args = {
1187 .raw_scores = raw_scores,
1189 .query_frames = query_frames,
1190 .raw_key_frames = 2 * query_frames - 1,
1194 if (active > rows) {
1197 if (pool != NULL && active > 1) {
1199 pool, active, 0, rows, 1,
1213 if (input == NULL || output == NULL) {
1216 if (channels <= 0 || frames <= 0) {
1219 for (
int frame = 0; frame < frames; ++frame) {
1220 for (
int channel = 0; channel < channels; ++channel) {
1221 output[(size_t)frame * channels + channel] =
1222 input[(
size_t)channel * frames + frame];
1229 const float *samples,
1234 if (samples == NULL || power == NULL) {
1245 for (
int frame = 0; frame < n_frames; ++frame) {
1253 const float window = 0.5f - 0.5f * cosf(
1256 const float value = samples[source] * window;
1259 real = fmaf(value, cosf(angle), real);
1260 imag = fmaf(value, sinf(angle), imag);
1263 fmaf(real, real, imag * imag);
1271 const float *mel_filters,
1276 if (power == NULL || mel_filters == NULL || log_mel == NULL) {
1279 if (n_mels <= 0 || n_frames <= 0) {
1283 float maximum = -INFINITY;
1284 for (
int mel = 0; mel < n_mels; ++mel) {
1286 float *output = log_mel + (size_t)mel * n_frames;
1287 for (
int frame = 0; frame < n_frames; ++frame) {
1291 sum = fmaf(filter[bin], spectrum[bin], sum);
1293 const float value = log10f(fmaxf(sum, 1.0e-10f));
1294 output[frame] = value;
1295 maximum = fmaxf(maximum, value);
1299 const float floor = maximum - 8.0f;
1300 for (
int mel = 0; mel < n_mels; ++mel) {
1301 float *output = log_mel + (size_t)mel * n_frames;
1302 for (
int frame = 0; frame < n_frames; ++frame) {
1303 output[frame] = (fmaxf(output[frame], floor) + 4.0f) / 4.0f;
1310 const float *samples,
1312 const float *mel_filters,
1314 float *power_scratch,
1319 samples, n_samples, power_scratch, n_frames);
1320 if (stft_status != 0) {
1324 power_scratch, mel_filters, n_mels, n_frames, log_mel);
int audio_whisper_mel_filters_slaney_f32(int sample_rate, int n_fft, int n_mels, float *mel_filters)
int audio_whisper_log_mel_reference_f32(const float *samples, int n_samples, const float *mel_filters, int n_mels, float *power_scratch, float *log_mel, int n_frames)
int audio_stft_power_precomputed_f32(const float *samples, int n_samples, const float *window, const float *cos_table, const float *sin_table, int n_fft, int hop_length, float *power, int n_frames)
int audio_resample_linear_f32(const float *input, int input_frames, int input_rate, float *output, int output_frames, int output_rate)
int audio_wav_parse_memory(const uint8_t *bytes, size_t byte_count, CKAudioWavInfo *info)
int audio_conv2d_whc_grouped_f32(const float *input, const float *weight, const float *bias, float *output, int input_width, int input_height, int input_channels, int output_channels, int kernel_width, int kernel_height, int stride_width, int stride_height, int padding_width, int padding_height, int groups, int output_width, int output_height)
int audio_log_mel_time_major_f32(const float *power, const float *mel_filters, float *log_mel, int frames, int bins, int channels, float epsilon)
static void ck_audio_relative_shift_f32_range(int begin, int end, void *opaque)
int audio_wav_decode_pcm16_mono_f32(const uint8_t *bytes, size_t byte_count, const CKAudioWavInfo *info, float *mono, int mono_capacity)
int audio_whisper_log_mel_window_wav_pcm16_f32(const uint8_t *bytes, size_t byte_count, int start_frame, int target_sample_rate, const float *window, const float *cos_table, const float *sin_table, const float *mel_filters, int n_mels, int output_frames, float *log_mel)
static uint16_t read_u16_le(const uint8_t *p)
static int reflect_index(int index, int length)
int audio_preemphasis_f32(const float *input, float *output, int frames, float coefficient)
int audio_relative_shift_f32(const float *raw_scores, float *scores, int heads, int query_frames)
int audio_whisper_stft_power_reference_f32(const float *samples, int n_samples, float *power, int n_frames)
int audio_stft_power_centered_window_f32(const float *samples, int n_samples, const float *window, int window_length, const float *cos_table, const float *sin_table, int n_fft, int hop_length, int reflect_padding, float *power, int n_frames)
int audio_stft_precompute_tables_f32(int n_fft, float *window, float *cos_table, float *sin_table)
static void audio_stft_power_fft400_frame_f32(const float *samples, int n_samples, int frame, const float *window, const float *cos_table, const float *sin_table, float *power, float *fft_scratch)
static double audio_hz_to_mel_slaney(double hz)
int audio_glu_split_channel_major_f32(const float *input, float *output, int channels, int frames)
static void ck_audio_conv1d_channel_major_f32_work(int ith, int nth, void *opaque)
int audio_pcm_s16_to_mono_f32(const int16_t *interleaved, int n_frames, int n_channels, float *mono)
int audio_transpose_channel_to_token_f32(const float *input, float *output, int channels, int frames)
static double audio_mel_to_hz_slaney(double mel)
int audio_whisper_log_mel_from_power_reference_f32(const float *power, const float *mel_filters, int n_mels, int n_frames, float *log_mel)
int audio_feature_normalize_per_feature_f32(const float *input, float *output, int channels, int frames, float epsilon)
static uint32_t read_u32_le(const uint8_t *p)
int audio_pad_or_truncate_f32(const float *input, int input_frames, float *output, int output_frames)
int audio_conv1d_channel_major_f32(const float *input, const float *weight, const float *bias, float *output, int input_channels, int output_channels, int input_frames, int kernel_size, int stride, int padding, int output_frames)
int audio_resample_windowed_sinc_f32(const float *input, int input_frames, int input_rate, float *output, int output_frames, int output_rate, int radius)
int audio_wav_decode_memory_pcm16_mono_window_f32(const uint8_t *bytes, size_t byte_count, int start_frame, float *mono, int mono_capacity, CKAudioWavInfo *info)
int audio_stft_power_fft400_f32(const float *samples, int n_samples, const float *window, const float *cos_table, const float *sin_table, int hop_length, float *power, int n_frames, float *fft_scratch)
static void ck_audio_glu_split_f32_range(int begin, int end, void *opaque)
int audio_resampled_frame_count(int input_frames, int input_rate, int output_rate)
static void ck_audio_conv2d_whc_grouped_f32_range(int begin, int end, void *opaque)
int audio_wav_decode_memory_pcm16_mono_f32(const uint8_t *bytes, size_t byte_count, float *mono, int mono_capacity, CKAudioWavInfo *info)
Persistent pthread thread pool for CK-Engine inference.
void ck_threadpool_parallel_for_n(ck_threadpool_t *pool, int active_threads, int begin, int end, int grain_size, ck_range_fn_t fn, void *args)
void ck_threadpool_dispatch_n(ck_threadpool_t *pool, int active_threads, ck_work_fn_t fn, void *args)
ck_threadpool_t * ck_threadpool_global(void)
int ck_threadpool_n_threads(const ck_threadpool_t *pool)
#define CK_AUDIO_WHISPER_N_FFT
#define CK_AUDIO_WHISPER_HOP_LENGTH
#define CK_AUDIO_WHISPER_SAMPLE_RATE
#define CK_AUDIO_WHISPER_POWER_BINS
const char const char * right