Skip to content

Commit 9b1e6ee

Browse files
committed
More work on FloatVectorOperations
1 parent 61b5bee commit 9b1e6ee

File tree

3 files changed

+72
-5
lines changed

3 files changed

+72
-5
lines changed

modules/yup_audio_basics/buffers/yup_FloatVectorOperations.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ struct BasicOps32
8383

8484
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { _mm_storeu_ps (dest, a); }
8585

86+
static forcedinline void storeU (int* dest, ParallelType a) noexcept { _mm_storeu_si128 (reinterpret_cast<__m128i*> (dest), _mm_castps_si128 (a)); }
87+
88+
static forcedinline void storeA (int* dest, ParallelType a) noexcept { _mm_store_si128 (reinterpret_cast<__m128i*> (dest), _mm_castps_si128 (a)); }
89+
8690
static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return _mm_add_ps (a, b); }
8791

8892
static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return _mm_sub_ps (a, b); }
@@ -335,6 +339,10 @@ struct BasicOps32
335339

336340
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { vst1q_f32 (dest, a); }
337341

342+
static forcedinline void storeU (int* dest, ParallelType a) noexcept { vst1q_f32 (reinterpret_cast<float*> (dest), a); }
343+
344+
static forcedinline void storeA (int* dest, ParallelType a) noexcept { vst1q_f32 (reinterpret_cast<float*> (dest), a); }
345+
338346
static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return vaddq_f32 (a, b); }
339347

340348
static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return vsubq_f32 (a, b); }
@@ -1509,12 +1517,37 @@ void convertFixedToFloat (float* dest, const int* src, float multiplier, Size nu
15091517
vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier),
15101518
YUP_LOAD_NONE,
15111519
YUP_INCREMENT_SRC_DEST, )
1512-
#else
1520+
#elif YUP_USE_SSE_INTRINSICS
15131521
YUP_PERFORM_VEC_OP_SRC_DEST (dest[i] = (float) src[i] * multiplier,
15141522
Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 (reinterpret_cast<const __m128i*> (src)))),
15151523
YUP_LOAD_NONE,
15161524
YUP_INCREMENT_SRC_DEST,
15171525
const Mode::ParallelType mult = Mode::load1 (multiplier);)
1526+
#else
1527+
for (Size i = 0; i < num; ++i)
1528+
dest[i] = (float) src[i] * multiplier;
1529+
#endif
1530+
}
1531+
1532+
template <typename Size>
1533+
void convertFloatToFixed (int* dest, const float* src, float multiplier, Size num) noexcept
1534+
{
1535+
#if YUP_USE_ARM_NEON
1536+
YUP_PERFORM_VEC_OP_SRC_DEST (dest[i] = (int) (src[i] * multiplier),
1537+
vreinterpretq_f32_s32 (vcvtq_s32_f32 (vmulq_n_f32 (vld1q_f32 (src), multiplier))),
1538+
YUP_LOAD_NONE,
1539+
YUP_INCREMENT_SRC_DEST, )
1540+
1541+
#elif YUP_USE_SSE_INTRINSICS
1542+
YUP_PERFORM_VEC_OP_SRC_DEST (dest[i] = (int) (src[i] * multiplier),
1543+
_mm_castsi128_ps (_mm_cvtps_epi32 (_mm_mul_ps (_mm_loadu_ps (src), mult))),
1544+
YUP_LOAD_NONE,
1545+
YUP_INCREMENT_SRC_DEST,
1546+
const Mode::ParallelType mult = Mode::load1 (multiplier);)
1547+
1548+
#else
1549+
for (Size i = 0; i < num; ++i)
1550+
dest[i] = (int) (src[i] * multiplier);
15181551
#endif
15191552
}
15201553

@@ -1829,6 +1862,16 @@ void YUP_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, const
18291862
FloatVectorHelpers::convertFixedToFloat (dest, src, multiplier, num);
18301863
}
18311864

1865+
void YUP_CALLTYPE FloatVectorOperations::convertFloatToFixed (int* dest, const float* src, float multiplier, size_t num) noexcept
1866+
{
1867+
FloatVectorHelpers::convertFloatToFixed (dest, src, multiplier, num);
1868+
}
1869+
1870+
void YUP_CALLTYPE FloatVectorOperations::convertFloatToFixed (int* dest, const float* src, float multiplier, int num) noexcept
1871+
{
1872+
FloatVectorHelpers::convertFloatToFixed (dest, src, multiplier, num);
1873+
}
1874+
18321875
//==============================================================================
18331876

18341877
intptr_t YUP_CALLTYPE FloatVectorOperations::getFpStatusRegister() noexcept

modules/yup_audio_basics/buffers/yup_FloatVectorOperations.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,13 @@ struct NameForwarder : public Bases...
220220
class YUP_API FloatVectorOperations : public detail::NameForwarder<FloatVectorOperationsBase<float, int>, FloatVectorOperationsBase<float, size_t>, FloatVectorOperationsBase<double, int>, FloatVectorOperationsBase<double, size_t>>
221221
{
222222
public:
223-
/** */
224-
static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept;
223+
/** Convert fixed integer signal to float applying a multiplier. */
224+
static void YUP_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept;
225+
static void YUP_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, size_t num) noexcept;
225226

226-
/** */
227-
static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, size_t num) noexcept;
227+
/** Convert float signal to int applying a multiplier. */
228+
static void YUP_CALLTYPE convertFloatToFixed (int* dest, const float* src, float multiplier, int num) noexcept;
229+
static void YUP_CALLTYPE convertFloatToFixed (int* dest, const float* src, float multiplier, size_t num) noexcept;
228230

229231
/** This method enables or disables the SSE/NEON flush-to-zero mode. */
230232
static void YUP_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept;

tests/yup_audio_basics/yup_FloatVectorOperations.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,28 @@ class FloatVectorOperationsTests : public ::testing::Test
154154
FloatVectorOperations::fill (data1, (ValueType) 18, num);
155155
FloatVectorOperations::divide (data2, data1, (ValueType) 6, num);
156156
EXPECT_TRUE (areAllValuesEqual (data2, num, (ValueType) 3));
157+
158+
fillRandomly (random, int1, num);
159+
const ValueType multiplier = (ValueType) (1.0 / (1 << 16));
160+
161+
if constexpr (std::is_same_v<ValueType, float>)
162+
{
163+
convertFixed (data1, int1, multiplier, num);
164+
FloatVectorOperations::convertFixedToFloat (data2, int1, multiplier, num);
165+
EXPECT_TRUE (buffersMatch (data1, data2, num));
166+
167+
convertFloatToFixed (int1, data1, 1.0f / multiplier, num);
168+
HeapBlock<int> int2 (num + 16);
169+
#if YUP_ARM
170+
int* const intData = int2;
171+
#else
172+
int* const intData = addBytesToPointer (int2.get(), random.nextInt (16));
173+
#endif
174+
FloatVectorOperations::convertFloatToFixed (intData, data1, 1.0f / multiplier, num);
175+
176+
for (int i = 0; i < num; ++i)
177+
EXPECT_EQ (int1[i], intData[i]);
178+
}
157179
}
158180

159181
static void fillRandomly (Random& random, ValueType* d, int num)

0 commit comments

Comments
 (0)