#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/**
* Ресемплинг 8000 -> 16000 Гц
* @param input - указатель на входной массив (размер n)
* @param output - указатель на выходной массив (размер 2n)
* @param n - количество входных сэмплов (должно быть кратно 8)
*/
void resample_8to16_asm(const int16_t* input, int16_t* output, int n) {
const int16_t* in_ptr = input;
int16_t* out_ptr = output;
int iterations = n / 8;
if (iterations <= 0) return;
asm volatile (
"1: \n\t"
// 1. Загружаем 8 сэмплов: [s0, s1, s2, s3, s4, s5, s6, s7]
"ld1 {v0.8h}, [%[in]], #16 \n\t"
// 2. Создаем смещенный регистр для интерполяции [s1, s2...s7, s7]
// Используем EXT, чтобы сдвинуть V0 на 2 байта (один элемент h)
"ext v1.16b, v0.16b, v0.16b, #2 \n\t"
// 3. Считаем среднее: V2 = (V0 + V1 + 1) >> 1
// Инструкция SRHADD делает это атомарно для знаковых чисел
"srhadd v2.8h, v0.8h, v1.8h \n\t"
// 4. Перемешиваем оригиналы (V0) и средние (V2)
// zip1 соберет [s0, m0, s1, m1, s2, m2, s3, m3]
// zip2 соберет [s4, m4, s5, m5, s6, m6, s7, m7]
"zip1 v3.8h, v0.8h, v2.8h \n\t"
"zip2 v4.8h, v0.8h, v2.8h \n\t"
// 5. Сохраняем 16 сэмплов (32 байта) в выходной буфер
"st1 {v3.8h, v4.8h}, [%[out]], #32 \n\t"
// 6. Цикл
"subs %w[count], %w[count], #1 \n\t"
"b.ne 1b \n\t"
: [in] "+r" (in_ptr), [out] "+r" (out_ptr), [count] "+r" (iterations)
:
: "v0", "v1", "v2", "v3", "v4", "cc", "memory"
);
}
int main() {
const int N = 8; // входных сэмплов
int16_t input[8] = {0, 100, 200, 300, 400, 500, 600, 700};
int16_t output[16];
resample_8to16_asm(input, output, N);
printf("In (8kHz) -> Out (16kHz):\n");
for (int i = 0; i < 16; i++) {
printf("%d ", output[i]);
}
printf("\n");
return 0;
}