Changeset 1376

Show
Ignore:
Timestamp:
10/26/08 15:01:00 (12 years ago)
Author:
ppalmers
Message:

fix clipping and float->int conversion. optimize this a bit. fix SSE code.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/libffado-2.0/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r1344 r1376  
    3939#include <cstring> 
    4040 
    41 #define AMDTP_FLOAT_MULTIPLIER 2147483392.0 
    42  
     41#define AMDTP_FLOAT_MULTIPLIER (1.0f * ((1<<23) - 1)) 
    4342namespace Streaming 
    4443{ 
     
    516515 
    517516#ifdef __SSE2__ 
    518 //#if 0 
    519517#include <emmintrin.h> 
    520518#warning SSE2 build 
     
    544542 
    545543    const __m128i label = _mm_set_epi32 (0x40000000, 0x40000000, 0x40000000, 0x40000000); 
     544    const __m128i mask = _mm_set_epi32 (0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF); 
    546545    const __m128 mult = _mm_set_ps(AMDTP_FLOAT_MULTIPLIER, AMDTP_FLOAT_MULTIPLIER, AMDTP_FLOAT_MULTIPLIER, AMDTP_FLOAT_MULTIPLIER); 
    547546 
     
    571570        // the base event for this position 
    572571        target_event = (quadlet_t *)(data + i); 
    573  
    574572        // process the events 
    575573        for (j=0;j < nevents; j += 1) 
     
    597595            // convert to signed integer 
    598596            v_int = _mm_cvttps_epi32( v_float ); 
    599             // shift right 8 bits 
    600             v_int = _mm_srli_epi32( v_int, 8 ); 
     597            // mask 
     598            v_int = _mm_and_si128( v_int, mask ); 
    601599            // label it 
    602600            v_int = _mm_or_si128( v_int, label ); 
     
    607605            // do second swap 
    608606            v_int = _mm_or_si128( _mm_slli_epi32( v_int, 16 ), _mm_srli_epi32( v_int, 16 ) ); 
    609  
    610607            // store the packed int 
    611608            // (target misalignment is assumed since we don't know the m_dimension) 
     
    655652                v_float = _mm_min_ps(v_float, v_max); 
    656653#endif 
    657  
    658654                // multiply 
    659655                v_float = _mm_mul_ps(v_float, mult); 
    660656                // convert to signed integer 
    661657                v_int = _mm_cvttps_epi32( v_float ); 
    662                 // shift right 8 bits 
    663                 v_int = _mm_srli_epi32( v_int, 8 ); 
     658                // mask 
     659                v_int = _mm_and_si128( v_int, mask ); 
    664660                // label it 
    665661                v_int = _mm_or_si128( v_int, label ); 
     
    689685                float *in = (float *)buffer; 
    690686#if AMDTP_CLIP_FLOATS 
    691                 if(*in > 1.0) *in=1.0; 
    692                 if(*in < -1.0) *in=-1.0; 
    693 #endif 
     687                // clip directly to the value of a maxed event 
     688                if(*in > 1.0) { 
     689                    *target_event = CONDSWAPTOBUS32_CONST(0x407FFFFF); 
     690                } else if(*in < -1.0) { 
     691                    *target_event = CONDSWAPTOBUS32_CONST(0x40800001); 
     692                } else { 
     693                    float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
     694                    unsigned int tmp = ((int) v); 
     695                    tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
     696                    *target_event = CondSwapToBus32((quadlet_t)tmp); 
     697                } 
     698#else 
    694699                float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
    695700                unsigned int tmp = ((int) v); 
    696                 tmp = ( tmp >> 8 ) | 0x40000000; 
     701                tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
    697702                *target_event = CondSwapToBus32((quadlet_t)tmp); 
     703#endif 
    698704                buffer++; 
    699705                target_event += m_dimension; 
     
    938944                float *in = (float *)buffer; 
    939945#if AMDTP_CLIP_FLOATS 
    940                 if(*in > 1.0) *in=1.0; 
    941                 if(*in < -1.0) *in=-1.0; 
     946                // clip directly to the value of a maxed event 
     947                if(*in > 1.0) { 
     948                    *target_event = CONDSWAPTOBUS32_CONST(0x407FFFFF); 
     949                } else if(*in < -1.0) { 
     950                    *target_event = CONDSWAPTOBUS32_CONST(0x40800001); 
     951                } else { 
     952                    float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
     953                    unsigned int tmp = ((int) v); 
     954                    tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
     955                    *target_event = CondSwapToBus32((quadlet_t)tmp); 
     956                } 
     957#else 
     958                float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
     959                unsigned int tmp = ((int) v); 
     960                tmp = ( tmp & 0x00FFFFFF ) | 0x40000000; 
     961                *target_event = CondSwapToBus32((quadlet_t)tmp); 
    942962#endif 
    943                 float v = (*in) * AMDTP_FLOAT_MULTIPLIER; 
    944                 unsigned int tmp = ((int) lrintf(v)); 
    945  
    946                 tmp = ( tmp >> 8 ) | 0x40000000; 
    947                 *target_event = CondSwapToBus32((quadlet_t)tmp); 
    948963                buffer++; 
    949964                target_event += m_dimension;