Я использую звуковой микшер, он отлично работает без SIMD-инструкций, но с трудом выясняет, как извлекать мои звуковые данные на отдельные каналы.Переключить аудиоканалы с помощью SIMD-команд
Мои данные поступают в чередующемся формате: L0R0 L1R1 L2R2 L3R3 ... Я загружаю их в __m128i в том же формате, поэтому у меня есть 4 образца в регистре.
Я хотел бы, чтобы они были в разных каналах: L0L1L2L3 R0R1R2R3. Это та часть, которую мне не хватает.
Таким образом, вход: 8 x i16 (4xi32 чередующийся) Я хотел бы, чтобы выход как left = 4 x f32 и right = 4 x f32, затем выполните смешение.
После смешивания, я могу чередовать каналы, и я получаю L0R0 L1R1 L2R2 ...:
__m128 *src0 = mixed_channel0;
__m128 *src1 = mixed_channel1;
__m128 *dest = (__m128i *)buffer;
for (u32 sample_index = 0; sample_index < sample_chunk_count; ++sample_index)
{
__m128 s0 = _mm_load_ps((f32 *)src0++);
__m128 s1 = _mm_load_ps((f32 *)src1++);
__m128i l = _mm_cvtps_epi32(s0);
__m128i r = _mm_cvtps_epi32(s1);
__m128i lr0 = _mm_unpacklo_epi32(l, r);
__m128i lr1 = _mm_unpackhi_epi32(l, r);
*dest++ = _mm_packs_epi32(lr0, lr1);
}
В принципе мне нужно сделать наоборот:
__m128i input = [L0R0, L1R1, L2R2, L3R3] packed pairs of 16bit ints
// magic happens, then
__m128 left = [L0, L1, L2, L3] packed 32bit floats
__m128 right = [R0, R1, R2, R3] packed 32bit floats
Даже если я маскировать младший/высокий порядок i16-s, то как я могу преобразовать их в f32-s? После маскировки я хотел бы получить:
__m128i right = [xx, R0, xx, R1, xx, R2, xx, R3]
__m128i left = [L0, xx, L1, xx, L2, xx, L3, xx]
Если бы я мог преобразовать их в 4 х i32-х, то было бы легко преобразовать их в f32-s с _mm_cvtepi32_ps и я бы сделал.
Спасибо.
Я думаю, что ваш лучший выбор для преобразования низких/высоких 'i16' с бит-сдвигами. 'high_halves = _mm_srai_epi32 (упакованный, 16);'.Поскольку ваши значения подписаны, вам, вероятно, нужно подписать - продлить низкие половинки с помощью сдвига влево и затем использовать арифметический сдвиг вправо. Я не могу думать о лучшем банкомате, но это кажется неуклюжим. –
Некоторые наборы инструкций SIMD (например, ARM NEON/ARMv8) содержат больше инструкций с двумя входами или двумя выводами, и я думаю, что это можно было бы распаковать с помощью одной команды. (Возможно, распакуйте, IIRC). Поэтому важно сказать конкретно с Intel SSE, а не только с SIMD. –
Может потребоваться [SSE3] (https://blogs.msdn.microsoft.com/chuckw/2012/09/11/directxmath-sse3-and-ssse3/)? Хотя это не «требуется» [SSE/SSE2] (https://blogs.msdn.microsoft.com/chuckw/2012/09/11/directxmath-sse-sse2-and-arm-neon/) для современных ПК, это очень часто (для геймеров Steam это 91%). '' _mm_moveldup_ps'' и '' _mm_movehdup_ps'' весьма полезны. –