Загрузка данных


#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;
}