私は、音声処理を実行する書き込み中のSSEメソッドに問題があります。私はここでインテルの論文に基づいてSSEランダムな機能を実装しました:SSE組み込み関数は、通常のfloatオペレーションが-1を返すようにします。#INV
次のように私もまた、SSEを使用して、S16にフロートから変換を実行されているメソッドを持っては、変換は非常に単純に行われ
unsigned int Float_S16LE(float *data, const unsigned int samples, uint8_t *dest)
{
int16_t *dst = (int16_t*)dest;
const __m128 mul = _mm_set_ps1((float)INT16_MAX);
__m128 rand;
const uint32_t even = count & ~0x3;
for(uint32_t i = 0; i < even; i += 4, data += 4, dst += 4)
{
/* random round to dither */
FloatRand4(-0.5f, 0.5f, NULL, &rand);
__m128 rmul = _mm_add_ps(mul, rand);
__m128 in = _mm_mul_ps(_mm_load_ps(data),rmul);
__m64 con = _mm_cvtps_pi16(in);
memcpy(dst, &con, sizeof(int16_t) * 4);
}
}
次のようにFloatRand4が定義されている:
static inline void FloatRand4(const float min, const float max, float result[4], __m128 *sseresult = NULL)
{
const float delta = (max - min)/2.0f;
const float factor = delta/(float)INT32_MAX;
...
}
場合結果が返され、result
は未使用です。 これは最初のループで完全に実行されますが、次のループでdelta
は1.0
ではなく-1.#INF
になります。私が__m64 con = _mm_cvtps_pi16(in);
という行をコメントアウトすると、問題は解消されます。
私はFPUが未知の状態になっていると思います。
_mm_cvtps_pi16は悪い考えです。 _mm_cvtps_epi32、_mm_packs_epi32、_mm_store_si128/_mm_storeu_si128の組み合わせを使用して8個の浮動小数点数を8個のint16_tに変換し、問題はなくなりました! –