Esempio n. 1
0
u8 XN297_ReadPayload(u8* msg, int len)
{
    // TODO: if xn297_crc==1, check CRC before filling *msg 
    u8 res = NRF24L01_ReadPayload(msg, len);
    for(u8 i=0; i<len; i++)
      msg[i] = bit_reverse(msg[i])^bit_reverse(xn297_scramble[i+xn297_addr_len]);
    return res;
}
Esempio n. 2
0
uint8_t XN297_ReadPayload(uint8_t* msg, int len)
{
    uint8_t res = NRF24L01_ReadPayload(msg, len);
    uint8_t i;
    for(i = 0; i<len; i++)
        msg[i] = bit_reverse(msg[i]) ^ bit_reverse(xn297_scramble[i+xn297_addr_len]);
    return res;
}
Esempio n. 3
0
void
process_fddi(register u_char *u, register const struct pcap_pkthdr *h,
    register const u_char *p)
{
	register struct fddi_header *fh;
	register struct ether_arp *ea;
	register u_char *sea, *sha;
	register time_t t;
	u_int32_t sia;

	fh = (struct fddi_header *)p;
	ea = (struct ether_arp *)(fh + 1);

	if (!swapped) {
		bit_reverse(fh->src, 6);
		bit_reverse(fh->dst, 6);
	}
	if (!sanity_fddi(fh, ea, h->caplen))
		return;

	/* Source MAC hardware ethernet address */
	sea = (u_char *)fh->src;

	/* Source ARP ethernet address */
	sha = (u_char *)SHA(ea);

	/* Source ARP ip address */
	BCOPY(SPA(ea), &sia, 4);

	/* Watch for bogons */
	if (isbogon(sia)) {
		dosyslog(LOG_INFO, "bogon", sia, sea, sha);
		return;
	}

	/* Watch for ethernet broadcast */
	if (MEMCMP(sea, zero, 6) == 0 || MEMCMP(sea, allones, 6) == 0 ||
	    MEMCMP(sha, zero, 6) == 0 || MEMCMP(sha, allones, 6) == 0) {
		dosyslog(LOG_INFO, "ethernet broadcast", sia, sea, sha);
		return;
	}

	/* Double check ethernet addresses */
	if (MEMCMP(sea, sha, 6) != 0) {
		dosyslog(LOG_INFO, "ethernet mismatch", sia, sea, sha);
		return;
	}

	/* Got a live one */
	t = h->ts.tv_sec;
	can_checkpoint = 0;
	if (!ent_add(sia, sea, t, NULL))
		syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed",
		    intoa(sia), e2str(sea), t);
	can_checkpoint = 1;
}
Esempio n. 4
0
int bit_reverse(unsigned int n, unsigned int k)
{
	if(k==1)return n;
	unsigned int k1,k2,a,b;
	k1 = k/2;
	k2 = k-k1;
	a = n>>k2;
	b = n - (a<<k2);
	a = bit_reverse(a,k1);
	b = bit_reverse(b,k2);
	return (b<<k1)+a;
}
Esempio n. 5
0
bool display_drawLine(int x, int y, uint8_t line)
{
	bool unset = false;
	
	if (!display_inited)
		return unset;
	
	if (y < 0 || y >= DISPLAY_MAX_Y)
		return unset;
	
	line = bit_reverse(line);
	
	while (line) {
		
		if (x < 0 || x >= DISPLAY_MAX_X)
			break;
		
		if (line & 1) {
			if (display_get(x, y))
				unset = true;
			display_toggle(x, y);
		}
		
		x++;
		line >>= 1;
	}
	
	return unset;
}
Esempio n. 6
0
void fft_tobb(fft_direction dir, cpx **in, cpx **out, const int n_threads, const int n)
{
    const int n2 = (n / 2);
    int bit, dist, dist2;
    unsigned int steps;
    cpx *W;
    bit = log2_32(n);    
    const int lead = 32 - bit;

    W = (cpx *)malloc(sizeof(cpx) * n);    
    twiddle_factors(W, dir, n);
    steps = 0;
    dist2 = n;
    dist = n2;
    --bit;
    
    _fft_tbbody(*in, *out, W, bit, steps, dist, dist2, n2);
    while (bit-- > 0) {
        dist2 = dist;
        dist = dist >> 1;
        _fft_tbbody(*out, *out, W, bit, ++steps, dist, dist2, n2);
    }
    bit_reverse(*out, dir, lead, n);
    free(W);
}
static int create_stairstep_page(TIFF *tiff_file)
{
    uint8_t image_buffer[8192];
    int row;
    int start_pixel;
    int i;

    /* TSB-85 STAIRSTEP page. */
    start_pixel = 0;
    for (row = 0;  row < 1728;  row++)
    {
        clear_row(image_buffer, 1728);
        set_pixel_range(image_buffer, 1, start_pixel, start_pixel + 63);
        if (photo_metric != PHOTOMETRIC_MINISWHITE)
        {
            for (i = 0;  i < 1728/8;  i++)
                image_buffer[i] = ~image_buffer[i];
        }
#if 0
        if (fill_order != FILLORDER_LSB2MSB)
            bit_reverse(image_buffer, image_buffer, 1728/8);
#endif
        if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
        {
            printf("Write error at row %d.\n", row);
            exit(2);
        }
        start_pixel += 64;
        if (start_pixel >= 1728)
            start_pixel = 0;
    }
    return 1728;
}
Esempio n. 8
0
void fft(DTYPE X_R[SIZE], DTYPE X_I[SIZE])
{
	
DTYPE temp_R;		/*temporary storage complex variable*/
DTYPE temp_I;		/*temporary storage complex variable*/


int i,j,k;			/* loop indexes */
int i_lower;		/* Index of lower point in butterfly */
int step;

int stage;
int DFTpts;
int numBF;			/*Butterfly Width*/

int N2 = SIZE2;	/* N2=N>>1 */

bit_reverse(X_R, X_I);


/*=======================BEGIN: FFT=========================*/
// Do M stages of butterflies 
step=N2;
DTYPE a, e, c, s;

for(stage=1; stage<= M; stage++)
{
	DFTpts = 1 << stage;		// DFT = 2^stage = points in sub DFT 
	numBF = DFTpts/2; 			// Butterfly WIDTHS in sub-DFT 
	k=0;

	e = -6.283185307178/DFTpts;

	a = 0.0;
	// Perform butterflies for j-th stage 
	butterfly:for(j=0; j<numBF; j++)
	{
	
	c = cos(a);
	s = sin(a);
	a = a + e;

	// Compute butterflies that use same W**k
	DFTpts:for(i=j; i<SIZE; i += DFTpts)
		{	
			
			i_lower = i + numBF;			//index of lower point in butterfly
			temp_R = X_R[i_lower]*c- X_I[i_lower]*s;
			temp_I = X_I[i_lower]*c+ X_R[i_lower]*s;

			X_R[i_lower] = X_R[i] - temp_R;
			X_I[i_lower] = X_I[i] - temp_I;
			X_R[i] = X_R[i] + temp_R;
			X_I[i] = X_I[i] + temp_I;			
		}
		k+=step;
	}
	step=step/2;
	}
}
Esempio n. 9
0
void mlcd_set_lines_with_func(uint8_t (*f)(uint8_t, uint8_t), uint8_t first_line, uint8_t line_number) {
    NRF_SPI_Type *spi_base = (NRF_SPI_Type *)MLCD_SPI;

    uint8_t command = MLCD_WR;
    uint8_t dummy = 0;
    uint8_t line_buffer[MLCD_LINE_BYTES+2];
    uint8_t max_line = first_line + line_number;
  
    /* enable slave (slave select active HIGH) */
    nrf_gpio_pin_set(MLCD_SPI_SS);
  
    spi_master_tx_data_no_cs(spi_base, &command, 1);
  
    line_buffer[MLCD_LINE_BYTES+1] = 0;
    for(uint8_t line = first_line; line < max_line; line++) {
        line_buffer[0] = bit_reverse(line+1);
      
        for(uint8_t i=0; i < MLCD_LINE_BYTES; i++) {
            uint8_t val = 0;
            for(uint8_t bit=0; bit<8; bit++){
                val |= (*f)(i*8+bit, line) << (7-bit);
            }
            line_buffer[i+1] = val;
        }
        spi_master_tx_data_no_cs(spi_base, line_buffer, MLCD_LINE_BYTES+2);
    }
    spi_master_tx_data_no_cs(spi_base, &dummy, 1);

    /* disable slave (slave select active HIGH) */
    nrf_gpio_pin_clear(MLCD_SPI_SS);
}
Esempio n. 10
0
int __main(void)
{
  int store [20];
	volatile unsigned char r;  
	char text [] = "1234";
	char test [] = "hello";
	volatile int result = asciiToBCD(0x30);
	result = asciiToBCD(0x3239);	
	result = BCDToAscii(0x1234);
	result = BCDToAscii(0x0);
	r = cipher('A');
	r = cipher('Z');
	r = ccipher('A', 5);
	result = bit_reverse(0xAAAA0000);
	fib(20, store);
	char_reverse(text, 4);
	
	word_reverse(text, 4);
	word_reverse(test, 5);
	
	word_reverse_compiled(text, 4);
	word_reverse_compiled(test, 5);
		
	return 0;
}
Esempio n. 11
0
unsigned long llz_fft_init(int size)
{
    int i;
    double ang;
    llz_fft_ctx_t *f = NULL;

    f = (llz_fft_ctx_t *)malloc(sizeof(llz_fft_ctx_t));
    memset(f, 0, sizeof(llz_fft_ctx_t));

    f->length = size;
    f->base   = (int)(log(size)/log(2));

    if ((1<<f->base) < size)
        f->base += 1;

    f->bit_rvs  = (int *)malloc(sizeof(int)*size);
    f->fft_work = (double *)malloc(sizeof(double)*size*2);
    f->cos_ang  = (double *)malloc(sizeof(double)*size);
    f->sin_ang  = (double *)malloc(sizeof(double)*size);

    bit_reverse(f->bit_rvs,size);

    for (i = 0 ; i < size ; i++){
        ang = (double)(2*M_PI*i)/size;
        f->cos_ang[i] = (double)cos(ang);
        f->sin_ang[i] = (double)sin(ang);
    }

    return (unsigned long)f;
}
Esempio n. 12
0
uintptr_t fa_fft_init(int size)
{
    int i;
    float ang;
    fa_fft_ctx_t *f = NULL;

    f = (fa_fft_ctx_t *)malloc(sizeof(fa_fft_ctx_t));

    f->length = size;
    f->base   = (int)(log(size)/log(2));

    if ((1<<f->base) < size)
        f->base += 1;

    f->bit_rvs  = (int *)malloc(sizeof(int)*size);
    f->fft_work = (float *)malloc(sizeof(float)*size*2);
    f->cos_ang  = (float *)malloc(sizeof(float)*size);
    f->sin_ang  = (float *)malloc(sizeof(float)*size);

    bit_reverse(f->bit_rvs,size);

    for (i = 0 ; i < size ; i++){
        ang = (float)(2*M_PI*i)/size;
        f->cos_ang[i] = (float)cos(ang);
        f->sin_ang[i] = (float)sin(ang);
    }

    return (uintptr_t)f;
}
Esempio n. 13
0
void fft(double* re,double* im,int32_t     bitsize)
{
    int32_t i;
    int32_t stage;
    int32_t datasize = 1 << bitsize;

    bit_reverse(datasize,re);
    bit_reverse(datasize,im);

    for (stage = 1; stage <= bitsize; stage++)
    {
        int32_t type;
        double  wRe, wIm;
        double  uRe, uIm;
        double  tempwRe,tempwIm;
        double  tempRe, tempIm;
        int32_t butterflydist = 1 << stage;
        int32_t numType       = butterflydist >> 1;
        int32_t butterflysize = butterflydist >> 1;

        wRe = 1.0;
        wIm = 0.0;
        uRe = cos(PI / butterflysize);
        uIm = -sin(PI / butterflysize);

        for (type = 0; type < numType; type++)
        {
            for (i = type; i < datasize; i += butterflydist)
            {
                int32_t ip;
                ip      = i + butterflysize;
                tempRe  = re[ip] * wRe - im[ip] * wIm;
                tempIm  = re[ip] * wIm + im[ip] * wRe;
                re[ip]  = re[i] - tempRe;
                im[ip]  = im[i] - tempIm;
                re[i]  += tempRe;
                im[i]  += tempIm;
            }
            tempwRe = wRe * uRe - wIm * uIm;
            tempwIm = wRe * uIm + wIm * uRe;
            wRe = tempwRe;
            wIm = tempwIm;
        }
    }
}
Esempio n. 14
0
File: fft.c Progetto: egawata/dft
complex fft(int n, int log2n, double *data) 
{
    if ( n < 0 ||  n >= (1 << (log2n) ) ) {
        fprintf(stderr, "_fft() : index no. [%d] is invalid.", n);
        exit(1);
    }

    n = bit_reverse(n, log2n);

    return _fft(n, 0, log2n, data);
}
Esempio n. 15
0
 void FFT::transform(
   std::vector< std::complex<double> > &data
 ) {
   N = data.size();
   f = &data;
   bit_reverse();
   for (int n = 1; n < N; n *= 2)
     Danielson_Lanczos(n);
   for (int i = 0; i < N; ++i)
     (*f)[i] /= std::sqrt(double(N));
 }
Esempio n. 16
0
void fft_fixed(fft_direction dir, cpx **in, cpx **out, const int n_threads, const int n)
{
#ifdef GENERATED_FIXED_SIZE    
    if (fixed_size_fft(dir, *in, *out, GEN_BIT_REVERSE_ORDER, n)) {
        return;
    }
#endif
    cpx *W = (cpx *)malloc(sizeof(cpx) * n);
    twiddle_factors(W, dir, n);
    fft_xn(dir, *in, *out, W, n);
    free(W);
    bit_reverse(*out, dir, 32 - log2_32(n), n);
}
Esempio n. 17
0
static void send_hdlc(void *user_data, const uint8_t *msg, int len)
{
    t38_terminal_state_t *s;

    s = (t38_terminal_state_t *) user_data;
    if (len <= 0)
    {
        s->tx_len = -1;
    }
    else
    {
        bit_reverse(s->tx_buf, msg, len);
        s->tx_len = len;
        s->tx_ptr = 0;
    }
}
Esempio n. 18
0
//-----------------------------------------------------------------------------
// name: cfft()
// desc: complex value fft
//
//   these routines from CARL software, spect.c
//   check out the CARL CMusic distribution for more software
//
//   cfft replaces float array x containing NC complex values (2*NC float 
//   values alternating real, imagininary, etc.) by its Fourier transform 
//   if forward is true, or by its inverse Fourier transform ifforward is 
//   false, using a recursive Fast Fourier transform method due to 
//   Danielson and Lanczos.
//
//   NC MUST be a power of 2.
//
//-----------------------------------------------------------------------------
void cfft( float * x, long NC, unsigned int forward )
{
    float wr, wi, wpr, wpi, theta, scale ;
    long mmax, ND, m, i, j, delta ;
    ND = NC<<1 ;
    bit_reverse( x, ND ) ;
    
    for( mmax = 2 ; mmax < ND ; mmax = delta )
    {
        delta = mmax<<1 ;
        theta = TWOPI/( forward? mmax : -mmax ) ;
        wpr = (float) (-2.*pow( sin( 0.5*theta ), 2. )) ;
        wpi = (float) sin( theta ) ;
        wr = 1. ;
        wi = 0. ;

        for( m = 0 ; m < mmax ; m += 2 )
        {
            register float rtemp, itemp ;
            for( i = m ; i < ND ; i += delta )
            {
                j = i + mmax ;
                rtemp = wr*x[j] - wi*x[j+1] ;
                itemp = wr*x[j+1] + wi*x[j] ;
                x[j] = x[i] - rtemp ;
                x[j+1] = x[i+1] - itemp ;
                x[i] += rtemp ;
                x[i+1] += itemp ;
            }

            wr = (rtemp = wr)*wpr - wi*wpi + wr ;
            wi = wi*wpr + rtemp*wpi + wi ;
        }
    }

    // scale output
    scale = (float)(forward ? 1./ND : 2.) ;
    {
        register float *xi=x, *xe=x+ND ;
        while( xi < xe )
            *xi++ *= scale ;
    }
}
Esempio n. 19
0
static huft_code huft_get_code(
	huft_bits *b,           /* code lengths in bits (all assumed <= B_MAX) */
	int n,                  /* number of codes (assumed <= N_MAX) */
	int k                   /* index */
	)
{
	huft_code code = 0;
	huft_bits bits = b[k];
	int i;

	if (bits == 0)
		return 0;

	for (i = 0; i < n; i++) {
		if (b[i] < bits && b[i] > 0)
			code += 1 << (b[k] - b[i]);
		else if ((i < k) && (b[i] == bits))
			code += 1;
	}

	return bit_reverse(code, bits);
}
Esempio n. 20
0
__inline void _fft_tobb(fft_direction dir, cpx *seq, cpx *W, const int n)
{
    const int n2 = (n / 2);
    int bit, dist, dist2;
    unsigned int steps;

    bit = log2_32(n);
    const int lead = 32 - bit;
    steps = 0;
    dist2 = n;
    dist = n2;
    --bit;

    _fft_tbbody(seq, seq, W, bit, steps, dist, dist2, n2);
    while (bit-- > 0)
    {
        dist2 = dist;
        dist = dist >> 1;
        _fft_tbbody(seq, seq, W, bit, ++steps, dist, dist2, n2);
    }
    bit_reverse(seq, dir, lead, n);
}
	inline void ntt(bool is_inv,VT &in,VT &out,int N){
		int bitlen=std::__lg(N);
		for(int i=0;i<N;++i)out[bit_reverse(i,bitlen)]=in[i];
		for(int step=2,id=1;step<=N;step<<=1,++id){
			T wn=pow_mod(G,(P-1)>>id,P),wi=1,u,t;
			const int mh=step>>1;
			for(int i=0;i<mh;++i){
				for(int j=i;j<N;j+=step){
					u=out[j],t=wi*out[j+mh]%P;
					out[j]=u+t;
					out[j+mh]=u-t;
					if(out[j]>=P)out[j]-=P;
					if(out[j+mh]<0)out[j+mh]+=P;
				}
				wi=wi*wn%P;
			}
		}
		if(is_inv){
			for(int i=1;i<N/2;++i)std::swap(out[i],out[N-i]);
			T invn=pow_mod(N,P-2,P);
			for(int i=0;i<N;++i)out[i]=out[i]*invn%P;
		}
	}
Esempio n. 22
0
u8 XN297_WritePayload(u8* msg, int len)
{
    u8 packet[32];
    u8 res;
    if (is_xn297) {
        res = NRF24L01_WritePayload(msg, len);
    } else {
        int last = 0;
        if (xn297_addr_len < 4) {
            // If address length (which is defined by receive address length)
            // is less than 4 the TX address can't fit the preamble, so the last
            // byte goes here
            packet[last++] = 0x55;
        }
        for (int i = 0; i < xn297_addr_len; ++i) {
            packet[last++] = xn297_tx_addr[xn297_addr_len-i-1] ^ xn297_scramble[i];
        }

        for (int i = 0; i < len; ++i) {
            // bit-reverse bytes in packet
            u8 b_out = bit_reverse(msg[i]);
            packet[last++] = b_out ^ xn297_scramble[xn297_addr_len+i];
        }
        if (xn297_crc) {
            int offset = xn297_addr_len < 4 ? 1 : 0;
            u16 crc = initial;
            for (int i = offset; i < last; ++i) {
                crc = crc16_update(crc, packet[i]);
            }
            crc ^= xn297_crc_xorout[xn297_addr_len - 3 + len];
            packet[last++] = crc >> 8;
            packet[last++] = crc & 0xff;
        }
        res = NRF24L01_WritePayload(packet, last);
    }
    return res;
}
Esempio n. 23
0
uint8_t XN297_WritePayload(uint8_t* msg, int len)
{
    uint8_t buf[32];
    uint8_t res;
    int last = 0;
    if (xn297_addr_len < 4) {
        // If address length (which is defined by receive address length)
        // is less than 4 the TX address can't fit the preamble, so the last
        // byte goes here
        buf[last++] = 0x55;
    }
    int i;
    for (i = 0; i < xn297_addr_len; ++i) {
        buf[last++] = xn297_tx_addr[xn297_addr_len-i-1] ^ xn297_scramble[i];
    }

    for (i = 0; i < len; ++i) {
        // bit-reverse bytes in packet
        uint8_t b_out = bit_reverse(msg[i]);
        buf[last++] = b_out ^ xn297_scramble[xn297_addr_len+i];
    }

    if (xn297_crc) {
        int offset = xn297_addr_len < 4 ? 1 : 0;
        uint16_t crc = initial;
        int i;
        for (i = offset; i < last; ++i) {
            crc = crc16_update(crc, buf[i]);
        }
        crc ^= xn297_crc_xorout[xn297_addr_len - 3 + len];
        buf[last++] = crc >> 8;
        buf[last++] = crc & 0xff;
    }
    res = NRF24L01_WritePayload(buf, last);
    return res;
}
Esempio n. 24
0
int main(int argc, char *argv[])
{
    int i;
    uint32_t x;
    uint8_t ax;
    uint8_t bx;
    uint16_t ax16;
    uint16_t bx16;
    uint32_t ax32;
    uint32_t bx32;

    for (i = 0, x = 0;  i < 100000;  i++)
    {
        ax = top_bit_dumb(x);
        bx = top_bit(x);
        if (ax != bx)
        {
            printf("Test failed: top bit mismatch 0x%" PRIx32 " -> %u %u\n", x, ax, bx);
            exit(2);
        }
        ax = bottom_bit_dumb(x);
        bx = bottom_bit(x);
        if (ax != bx)
        {
            printf("Test failed: bottom bit mismatch 0x%" PRIx32 " -> %u %u\n", x, ax, bx);
            exit(2);
        }
        x = rand();
    }
    for (i = 0;  i < 256;  i++)
    {
        ax = bit_reverse8_dumb(i);
        bx = bit_reverse8(i);
        if (ax != bx)
        {
            printf("Test failed: bit reverse 8 - %02x %02x %02x\n", i, ax, bx);
            exit(2);
        }
    }
    for (i = 0;  i < 1000000;  i++)
        from[i] = rand();
    bit_reverse(to, from, 1000000);
    for (i = 0;  i < 1000000;  i++)
    {
        if (bit_reverse8_dumb(from[i]) != to[i])
        {
            printf("Test failed: bit reverse - at %d, %02x %02x %02x\n", i, from[i], bit_reverse8(from[i]), to[i]);
            exit(2);
        }
    }
    for (i = 0;  i < 256;  i++)
    {
        x = i | (((i + 1) & 0xFF) << 8) | (((i + 2) & 0xFF) << 16) | (((i + 3) & 0xFF) << 24);
        ax32 = bit_reverse_4bytes_dumb(x);
        bx32 = bit_reverse_4bytes(x);
        if (ax32 != bx32)
        {
            printf("Test failed: bit reverse 4 bytes - %" PRIx32 " %" PRIx32 " %" PRIx32 "\n", x, ax32, bx32);
            exit(2);
        }
    }
    for (i = 0;  i < 65536;  i++)
    {
        ax16 = bit_reverse16_dumb(i);
        bx16 = bit_reverse16(i);
        if (ax16 != bx16)
        {
            printf("Test failed: bit reverse 16 - %x %x %x\n", i, ax16, bx16);
            exit(2);
        }
    }
    for (i = 0;  i < 0x7FFFFF00;  i += 127)
    {
        ax32 = bit_reverse32_dumb(i);
        bx32 = bit_reverse32(i);
        if (ax32 != bx32)
        {
            printf("Test failed: bit reverse 32 - %d %" PRIx32 " %" PRIx32 "\n", i, ax32, bx32);
            exit(2);
        }
    }

    for (i = 0;  i < 256;  i++)
    {
        ax = parity8(i);
        bx = parity8_dumb(i);
        if (ax != bx)
        {
            printf("Test failed: parity 8 - %x %x %x\n", i, ax, bx);
            exit(2);
        }
    }

    for (i = -1;  i < 32;  i++)
    {
        ax32 = most_significant_one32(1 << i);
        if (ax32 != (1 << i))
        {
            printf("Test failed: most significant one 32 - %x %" PRIx32 " %x\n", i, ax32, (1 << i));
            exit(2);
        }
        ax32 = least_significant_one32(1 << i);
        if (ax32 != (1 << i))
        {
            printf("Test failed: least significant one 32 - %x %" PRIx32 " %x\n", i, ax32, (1 << i));
            exit(2);
        }
    }

    for (i = 0x80000000;  i < 0x800FFFFF;  i++)
    {
        ax = one_bits32_dumb(i);
        bx = one_bits32(i);
        if (ax != bx)
        {
            printf("Test failed: one bits - %d, %x %x\n", i, ax, bx);
            exit(2);
        }
    }

    printf("Tests passed.\n");
    return 0;
}
Esempio n. 25
0
static int process_rx_data(t38_core_state_t *t, void *user_data, int data_type, int field_type, const uint8_t *buf, int len)
{
    t38_terminal_state_t *s;
    uint8_t buf2[len];
    
    s = (t38_terminal_state_t *) user_data;
#if 0
    /* In termination mode we don't care very much what the data type is. */
    switch (data_type)
    {
    case T38_DATA_V21:
    case T38_DATA_V27TER_2400:
    case T38_DATA_V27TER_4800:
    case T38_DATA_V29_7200:
    case T38_DATA_V29_9600:
    case T38_DATA_V17_7200:
    case T38_DATA_V17_9600:
    case T38_DATA_V17_12000:
    case T38_DATA_V17_14400:
    case T38_DATA_V8:
    case T38_DATA_V34_PRI_RATE:
    case T38_DATA_V34_CC_1200:
    case T38_DATA_V34_PRI_CH:
    case T38_DATA_V33_12000:
    case T38_DATA_V33_14400:
    default:
        break;
    }
#endif

    switch (field_type)
    {
    case T38_FIELD_HDLC_DATA:
        if (s->rx_len + len <= T38_MAX_HDLC_LEN)
        {
            bit_reverse(s->rx_buf + s->rx_len, buf, len);
            s->rx_len += len;
        }
        s->timeout_rx_samples = s->samples + ms_to_samples(MID_RX_TIMEOUT);
        break;
    case T38_FIELD_HDLC_FCS_OK:
        if (len > 0)
        {
            span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK!\n");
            /* The sender has incorrectly included data in this message. It is unclear what we should do
               with it, to maximise tolerance of buggy implementations. */
        }
        /* Don't deal with repeats of the same field type. Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK
           packets, when they have sent no data for the body of the frame. */
        if (t->current_rx_data_type != data_type
            ||
            t->current_rx_field_type != field_type)
        {
            span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK (%s)\n", (s->rx_len >= 3)  ?  t30_frametype(s->rx_buf[2])  :  "???", (s->missing_data)  ?  "missing octets"  :  "clean");
            t30_hdlc_accept(&(s->t30_state), !s->missing_data, s->rx_buf, s->rx_len);
        }
        s->rx_len = 0;
        s->missing_data = FALSE;
        s->timeout_rx_samples = s->samples + ms_to_samples(MID_RX_TIMEOUT);
        break;
    case T38_FIELD_HDLC_FCS_BAD:
        if (len > 0)
        {
            span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD!\n");
            /* The sender has incorrectly included data in this message. We can safely ignore it, as the
               bad FCS means we will throw away the whole message, anyway. */
        }
        /* Don't deal with repeats of the same field type. Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD
           packets, when they have sent no data for the body of the frame. */
        if (t->current_rx_data_type != data_type
            ||
            t->current_rx_field_type != field_type)
        {
            span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad (%s)\n", (s->rx_len >= 3)  ?  t30_frametype(s->rx_buf[2])  :  "???", (s->missing_data)  ?  "missing octets"  :  "clean");
            t30_hdlc_accept(&(s->t30_state), FALSE, s->rx_buf, s->rx_len);
        }
        s->rx_len = 0;
        s->missing_data = FALSE;
        s->timeout_rx_samples = s->samples + ms_to_samples(MID_RX_TIMEOUT);
        break;
    case T38_FIELD_HDLC_FCS_OK_SIG_END:
        if (len > 0)
        {
            span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_OK_SIG_END!\n");
            /* The sender has incorrectly included data in this message. It is unclear what we should do
               with it, to maximise tolerance of buggy implementations. */
        }
        /* Don't deal with repeats of the same field type. Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_OK_SIG_END
           packets, when they have sent no data for the body of the frame. */
        if (t->current_rx_data_type != data_type
            ||
            t->current_rx_field_type != field_type)
        {
            span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC OK, sig end (%s)\n", (s->rx_len >= 3)  ?  t30_frametype(s->rx_buf[2])  :  "???", (s->missing_data)  ?  "missing octets"  :  "clean");
            t30_hdlc_accept(&(s->t30_state), !s->missing_data, s->rx_buf, s->rx_len);
            t30_hdlc_accept(&(s->t30_state), TRUE, NULL, PUTBIT_CARRIER_DOWN);
        }
        s->rx_len = 0;
        s->missing_data = FALSE;
        s->timeout_rx_samples = 0;
        break;
    case T38_FIELD_HDLC_FCS_BAD_SIG_END:
        if (len > 0)
        {
            span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_FCS_BAD_SIG_END!\n");
            /* The sender has incorrectly included data in this message. We can safely ignore it, as the
               bad FCS means we will throw away the whole message, anyway. */
        }
        /* Don't deal with repeats of the same field type. Some T.38 implementations send multiple T38_FIELD_HDLC_FCS_BAD_SIG_END
           packets, when they have sent no data for the body of the frame. */
        if (t->current_rx_data_type != data_type
            ||
            t->current_rx_field_type != field_type)
        {
            span_log(&s->logging, SPAN_LOG_FLOW, "Type %s - CRC bad, sig end (%s)\n", (s->rx_len >= 3)  ?  t30_frametype(s->rx_buf[2])  :  "???", (s->missing_data)  ?  "missing octets"  :  "clean");
            t30_hdlc_accept(&(s->t30_state), FALSE, s->rx_buf, s->rx_len);
            t30_hdlc_accept(&(s->t30_state), TRUE, NULL, PUTBIT_CARRIER_DOWN);
        }
        s->rx_len = 0;
        s->missing_data = FALSE;
        s->timeout_rx_samples = 0;
        break;
    case T38_FIELD_HDLC_SIG_END:
        if (len > 0)
        {
            span_log(&s->logging, SPAN_LOG_WARNING, "There is data in a T38_FIELD_HDLC_SIG_END!\n");
            /* The sender has incorrectly included data in this message, but there seems nothing meaningful
               it could be. There could not be an FCS good/bad report beyond this. */
        }
        /* This message is expected under 2 circumstances. One is as an alternative to T38_FIELD_HDLC_FCS_OK_SIG_END - 
           i.e. they send T38_FIELD_HDLC_FCS_OK, and then T38_FIELD_HDLC_SIG_END when the carrier actually drops.
           The other is because the HDLC signal drops unexpectedly - i.e. not just after a final frame. */
        if (t->current_rx_data_type != data_type
            ||
            t->current_rx_field_type != field_type)
        {
            /* WORKAROUND: At least some Mediatrix boxes have a bug, where they can send this message at the
                           end of non-ECM data. We need to tolerate this. We use the generic receive complete
                           indication, rather than the specific HDLC carrier down. */
            s->rx_len = 0;
            s->missing_data = FALSE;
            s->timeout_rx_samples = 0;
            t30_receive_complete(&(s->t30_state));
        }
        break;
    case T38_FIELD_T4_NON_ECM_DATA:
        if (!s->rx_signal_present)
        {
            t30_non_ecm_put_bit(&(s->t30_state), PUTBIT_TRAINING_SUCCEEDED);
            s->rx_signal_present = TRUE;
        }
        bit_reverse(buf2, buf, len);
        t30_non_ecm_put_chunk(&(s->t30_state), buf2, len);
        s->timeout_rx_samples = s->samples + ms_to_samples(MID_RX_TIMEOUT);
        break;
    case T38_FIELD_T4_NON_ECM_SIG_END:
        if (t->current_rx_data_type != data_type
            ||
            t->current_rx_field_type != field_type)
        {
            if (len > 0)
            {
                if (!s->rx_signal_present)
                {
                    t30_non_ecm_put_bit(&(s->t30_state), PUTBIT_TRAINING_SUCCEEDED);
                    s->rx_signal_present = TRUE;
                }
                bit_reverse(buf2, buf, len);
                t30_non_ecm_put_chunk(&(s->t30_state), buf2, len);
            }
            /* WORKAROUND: At least some Mediatrix boxes have a bug, where they can send HDLC signal end where
                           they should send non-ECM signal end. It is possible they also do the opposite.
                           We need to tolerate this, so we use the generic receive complete
                           indication, rather than the specific non-ECM carrier down. */
            t30_receive_complete(&(s->t30_state));
        }
        s->rx_signal_present = FALSE;
        s->timeout_rx_samples = 0;
        break;
    case T38_FIELD_CM_MESSAGE:
    case T38_FIELD_JM_MESSAGE:
    case T38_FIELD_CI_MESSAGE:
    case T38_FIELD_V34RATE:
    default:
        break;
    }
    return 0;
}
Esempio n. 26
0
static void
bit_reverse_buffer(uint8_t *p, uint8_t *end)
{
	for (; p < end; ++p)
		*p = bit_reverse(*p);
}
Esempio n. 27
0
int t38_terminal_send_timeout(t38_terminal_state_t *s, int samples)
{
    int len;
    int i;
    int previous;
    uint8_t buf[MAX_OCTETS_PER_UNPACED_CHUNK + 50];
    /* Training times for all the modem options, with and without TEP */
    static const int training_time[] =
    {
           0,      0,   /* T38_IND_NO_SIGNAL */
           0,      0,   /* T38_IND_CNG */
           0,      0,   /* T38_IND_CED */
        1000,   1000,   /* T38_IND_V21_PREAMBLE */ /* TODO: 850 should be OK for this, but it causes trouble with some ATAs. Why? */
         943,   1158,   /* T38_IND_V27TER_2400_TRAINING */
         708,    923,   /* T38_IND_V27TER_4800_TRAINING */
         234,    454,   /* T38_IND_V29_7200_TRAINING */
         234,    454,   /* T38_IND_V29_9600_TRAINING */
         142,    367,   /* T38_IND_V17_7200_SHORT_TRAINING */
        1393,   1618,   /* T38_IND_V17_7200_LONG_TRAINING */
         142,    367,   /* T38_IND_V17_9600_SHORT_TRAINING */
        1393,   1618,   /* T38_IND_V17_9600_LONG_TRAINING */
         142,    367,   /* T38_IND_V17_12000_SHORT_TRAINING */
        1393,   1618,   /* T38_IND_V17_12000_LONG_TRAINING */
         142,    367,   /* T38_IND_V17_14400_SHORT_TRAINING */
        1393,   1618,   /* T38_IND_V17_14400_LONG_TRAINING */
           0,      0,   /* T38_IND_V8_ANSAM */
           0,      0,   /* T38_IND_V8_SIGNAL */
           0,      0,   /* T38_IND_V34_CNTL_CHANNEL_1200 */
           0,      0,   /* T38_IND_V34_PRI_CHANNEL */
           0,      0,   /* T38_IND_V34_CC_RETRAIN */
           0,      0,   /* T38_IND_V33_12000_TRAINING */
           0,      0    /* T38_IND_V33_14400_TRAINING */
    };

    if (s->current_rx_type == T30_MODEM_DONE  ||  s->current_tx_type == T30_MODEM_DONE)
        return TRUE;

    s->samples += samples;
    t30_timer_update(&s->t30_state, samples);
    if (s->timeout_rx_samples  &&  s->samples > s->timeout_rx_samples)
    {
        span_log(&s->logging, SPAN_LOG_FLOW, "Timeout mid-receive\n");
        s->timeout_rx_samples = 0;
        t30_receive_complete(&(s->t30_state));
    }
    if (s->timed_step == T38_TIMED_STEP_NONE)
        return FALSE;
    if (s->samples < s->next_tx_samples)
        return FALSE;
    /* Its time to send something */
    switch (s->timed_step)
    {
    case T38_TIMED_STEP_NON_ECM_MODEM:
        /* Create a 75ms silence */
        if (s->t38.current_tx_indicator != T38_IND_NO_SIGNAL)
            t38_core_send_indicator(&s->t38, T38_IND_NO_SIGNAL, s->indicator_tx_count);
        s->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_2;
        s->next_tx_samples += ms_to_samples(75);
        break;
    case T38_TIMED_STEP_NON_ECM_MODEM_2:
        /* Switch on a fast modem, and give the training time to complete */
        t38_core_send_indicator(&s->t38, s->next_tx_indicator, s->indicator_tx_count);
        s->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_3;
        s->next_tx_samples += ms_to_samples(training_time[s->next_tx_indicator << 1]);
        break;
    case T38_TIMED_STEP_NON_ECM_MODEM_3:
        /* Send a chunk of non-ECM image data */
        /* T.38 says it is OK to send the last of the non-ECM data in the signal end message.
           However, I think the early versions of T.38 said the signal end message should not
           contain data. Hopefully, following the current spec will not cause compatibility
           issues. */
        len = t30_non_ecm_get_chunk(&s->t30_state, buf, s->octets_per_data_packet);
        bit_reverse(buf, buf, len);
        if (len >= s->octets_per_data_packet)
        {
            s->next_tx_samples += ms_to_samples(s->ms_per_tx_chunk);
            t38_core_send_data(&s->t38, s->current_tx_data_type, T38_FIELD_T4_NON_ECM_DATA, buf, len, DATA_TX_COUNT);
        }
        else
        {
            t38_core_send_data(&s->t38, s->current_tx_data_type, T38_FIELD_T4_NON_ECM_SIG_END, buf, len, s->data_end_tx_count);
            /* This should not be needed, since the message above indicates the end of the signal, but it
               seems like it can improve compatibility with quirky implementations. */
            t38_core_send_indicator(&s->t38, T38_IND_NO_SIGNAL, s->indicator_tx_count);
            s->timed_step = T38_TIMED_STEP_NONE;
            t30_send_complete(&(s->t30_state));
        }
        break;
    case T38_TIMED_STEP_HDLC_MODEM:
        /* Send HDLC preambling */
        t38_core_send_indicator(&s->t38, s->next_tx_indicator, s->indicator_tx_count);
        s->next_tx_samples += ms_to_samples(training_time[s->next_tx_indicator << 1]);
        s->timed_step = T38_TIMED_STEP_HDLC_MODEM_2;
        break;
    case T38_TIMED_STEP_HDLC_MODEM_2:
        /* Send a chunk of HDLC data */
        i = s->octets_per_data_packet;
        if (i >= (s->tx_len - s->tx_ptr))
        {
            i = s->tx_len - s->tx_ptr;
            s->timed_step = T38_TIMED_STEP_HDLC_MODEM_3;
        }
        t38_core_send_data(&s->t38, s->current_tx_data_type, T38_FIELD_HDLC_DATA, &s->tx_buf[s->tx_ptr], i, DATA_TX_COUNT);
        s->tx_ptr += i;
        s->next_tx_samples += ms_to_samples(s->ms_per_tx_chunk);
        break;
    case T38_TIMED_STEP_HDLC_MODEM_3:
        /* End of HDLC frame */
        previous = s->current_tx_data_type;
        s->tx_ptr = 0;
        s->tx_len = 0;
        t30_send_complete(&s->t30_state);
        if (s->tx_len < 0)
        {
            t38_core_send_data(&s->t38, previous, T38_FIELD_HDLC_FCS_OK_SIG_END, NULL, 0, s->data_end_tx_count);
            /* We have already sent T38_FIELD_HDLC_FCS_OK_SIG_END. It seems some boxes may not like
               us sending a T38_FIELD_HDLC_SIG_END at this point. Just say there is no signal. */
            t38_core_send_indicator(&s->t38, T38_IND_NO_SIGNAL, s->indicator_tx_count);
            s->tx_len = 0;
            t30_send_complete(&s->t30_state);
            if (s->tx_len)
                s->timed_step = T38_TIMED_STEP_HDLC_MODEM;
        }
        else
        {
            t38_core_send_data(&s->t38, previous, T38_FIELD_HDLC_FCS_OK, NULL, 0, DATA_TX_COUNT);
            if (s->tx_len)
                s->timed_step = T38_TIMED_STEP_HDLC_MODEM_2;
        }
        s->next_tx_samples += ms_to_samples(s->ms_per_tx_chunk);
        break;
    case T38_TIMED_STEP_CED:
        /* It seems common practice to start with a no signal indicator, though
           this is not a specified requirement. Since we should be sending 200ms
           of silence, starting the delay with a no signal indication makes sense.
           We do need a 200ms delay, as that is a specification requirement. */
        s->timed_step = T38_TIMED_STEP_CED_2;
        s->next_tx_samples = s->samples + ms_to_samples(200);
        t38_core_send_indicator(&s->t38, T38_IND_NO_SIGNAL, s->indicator_tx_count);
        s->current_tx_data_type = T38_DATA_NONE;
        break;
    case T38_TIMED_STEP_CED_2:
        /* Initial 200ms delay over. Send the CED indicator */
        s->next_tx_samples = s->samples + ms_to_samples(3000);
        s->timed_step = T38_TIMED_STEP_PAUSE;
        t38_core_send_indicator(&s->t38, T38_IND_CED, s->indicator_tx_count);
        s->current_tx_data_type = T38_DATA_NONE;
        break;
    case T38_TIMED_STEP_CNG:
        /* It seems common practice to start with a no signal indicator, though
           this is not a specified requirement. Since we should be sending 200ms
           of silence, starting the delay with a no signal indication makes sense.
           We do need a 200ms delay, as that is a specification requirement. */
        s->timed_step = T38_TIMED_STEP_CNG_2;
        s->next_tx_samples = s->samples + ms_to_samples(200);
        t38_core_send_indicator(&s->t38, T38_IND_NO_SIGNAL, s->indicator_tx_count);
        s->current_tx_data_type = T38_DATA_NONE;
        break;
    case T38_TIMED_STEP_CNG_2:
        /* Initial short delay over. Send the CNG indicator */
        s->timed_step = T38_TIMED_STEP_NONE;
        t38_core_send_indicator(&s->t38, T38_IND_CNG, s->indicator_tx_count);
        s->current_tx_data_type = T38_DATA_NONE;
        break;
    case T38_TIMED_STEP_PAUSE:
        /* End of timed pause */
        s->timed_step = T38_TIMED_STEP_NONE;
        t30_send_complete(&s->t30_state);
        break;
    }
    return FALSE;
}
Esempio n. 28
0
File: iFFT.c Progetto: yuronfu/final
void FFT(double *x_r,double *x_i,double *y_r,double *y_i,int N)
{
     int i,j,k,t,p = 2,M = N;
     double theta,w_r,w_i,temp_r[4],temp_i[4];
     
     bit_reverse(x_r,x_i,y_r,y_i,N);
     
     for(i = 1 ; i < N ; i*=p)
     {
           t = 0;
           
           if(M%2 == 0) p = 2;
           else
           {
               if(M%3 == 0) p =3;
               else p = 5;
           }
           theta = -2*M_PI/(p*i);
           while(t < N)
           {
                   for(j = 0 ; j < i ; j++)
                   {
                         w_r = cos(j*theta);
                         w_i = sin(j*theta);
                         switch(p)
                         {
                                  case 2:
                                       temp_r[0] = w_r*y_r[j+i+t] - w_i*y_i[j+i+t];
                                       temp_i[0] = w_i*y_r[j+i+t] + w_r*y_i[j+i+t];
                                       y_r[j+i+t] = y_r[j+t] - temp_r[0];
                                       y_i[j+i+t] = y_i[j+t] - temp_i[0];
                                       y_r[j+t]+=temp_r[0];
                                       y_i[j+t]+=temp_i[0];
                                       break;
                                  case 3:
                                       temp_r[0] = w_r*y_r[j+i+t] - w_i*y_i[j+i+t];
                                       temp_i[0] = w_i*y_r[j+i+t] + w_r*y_i[j+i+t];
                                       temp_r[1] = (w_r*w_r - w_i*w_i)*y_r[j+2*i+t] - 2*w_r*w_i*y_i[j+2*i+t];
                                       temp_i[1] = 2*w_r*w_i*y_r[j+2*i+t] + (w_r*w_r - w_i*w_i)*y_i[j+i+t];
                                       y_r[j+2*i+t] = y_r[j+t] - 0.5*(temp_r[0] + temp_r[1]) - 0.86602540378443864676372317075294*(temp_i[0] - temp_i[1]);
                                       y_i[j+2*i+t] = y_i[j+t] - 0.5*(temp_i[0] + temp_i[1]) + 0.86602540378443864676372317075294*(temp_r[0] - temp_r[1]);
                                       y_r[j+i+t] = y_r[j+t] - 0.5*(temp_r[0] + temp_r[1]) + 0.86602540378443864676372317075294*(temp_i[0] - temp_i[1]);
                                       y_i[j+i+t] = y_i[j+t] - 0.5*(temp_i[0] + temp_i[1]) - 0.86602540378443864676372317075294*(temp_r[0] - temp_r[1]);
                                       y_r[j+t] = y_r[j+t] + temp_r[0] + temp_r[1];
                                       y_i[j+t] = y_i[j+t] + temp_i[0] + temp_i[1];
                                       break;
                                  case 5:
                                       temp_r[0] = w_r*y_r[j+i+t] - w_i*y_i[j+i+t];
                                       temp_i[0] = w_i*y_r[j+i+t] + w_r*y_i[j+i+t];
                                       for(k = 2 ; k < 5 ; k++)
                                       {
                                             temp_r[k-1] = cos(j*k*theta)*y_r[j+k*i+t] - sin(j*k*theta)*y_i[j+k*i+t];
                                             temp_i[k-1] = sin(j*k*theta)*y_r[j+k*i+t] + cos(j*k*theta)*y_i[j+k*i+t];
                                       }
                                       y_r[j+4*i+t] = y_r[j+t] + 0.30901699437494745126286943559535*(temp_r[0]+temp_r[3]) - 0.95105651629515353118193843329209*(temp_i[0]-temp_i[3]) - 0.80901699437494734024056697307969*(temp_r[1]+temp_r[2]) - 0.58778525229247324812575925534475*(temp_i[1]-temp_i[2]);
                                       y_i[j+4*i+t] = y_i[j+t] + 0.30901699437494745126286943559535*(temp_i[0]+temp_i[3]) + 0.95105651629515353118193843329209*(temp_r[0]-temp_r[3]) - 0.80901699437494734024056697307969*(temp_i[1]+temp_i[2]) + 0.58778525229247324812575925534475*(temp_r[1]-temp_r[2]);
                                       y_r[j+3*i+t] = y_r[j+t] - 0.80901699437494734024056697307969*(temp_r[0]+temp_r[3]) - 0.58778525229247324812575925534475*(temp_i[0]-temp_i[3]) + 0.30901699437494745126286943559535*(temp_r[1]+temp_r[2]) + 0.95105651629515353118193843329209*(temp_i[1]-temp_i[2]);
                                       y_i[j+3*i+t] = y_i[j+t] - 0.80901699437494734024056697307969*(temp_i[0]+temp_i[3]) + 0.58778525229247324812575925534475*(temp_r[0]-temp_r[3]) + 0.30901699437494745126286943559535*(temp_i[1]+temp_i[2]) - 0.95105651629515353118193843329209*(temp_r[1]-temp_r[2]);
                                       y_r[j+2*i+t] = y_r[j+t] - 0.80901699437494734024056697307969*(temp_r[0]+temp_r[3]) + 0.58778525229247324812575925534475*(temp_i[0]-temp_i[3]) + 0.30901699437494745126286943559535*(temp_r[1]+temp_r[2]) - 0.95105651629515353118193843329209*(temp_i[1]-temp_i[2]);
                                       y_i[j+2*i+t] = y_i[j+t] - 0.80901699437494734024056697307969*(temp_i[0]+temp_i[3]) - 0.58778525229247324812575925534475*(temp_r[0]-temp_r[3]) + 0.30901699437494745126286943559535*(temp_i[1]+temp_i[2]) + 0.95105651629515353118193843329209*(temp_r[1]-temp_r[2]);
                                       y_r[j+i+t] = y_r[j+t] + 0.30901699437494745126286943559535*(temp_r[0]+temp_r[3]) + 0.95105651629515353118193843329209*(temp_i[0]-temp_i[3]) - 0.80901699437494734024056697307969*(temp_r[1]+temp_r[2]) + 0.58778525229247324812575925534475*(temp_i[1]-temp_i[2]);
                                       y_i[j+i+t] = y_i[j+t] + 0.30901699437494745126286943559535*(temp_i[0]+temp_i[3]) - 0.95105651629515353118193843329209*(temp_r[0]-temp_r[3]) - 0.80901699437494734024056697307969*(temp_i[1]+temp_i[2]) - 0.58778525229247324812575925534475*(temp_r[1]-temp_r[2]);
                                       y_r[j+t] = y_r[j+t] + temp_r[0] + temp_r[1] + temp_r[2] + temp_r[3];
                                       y_i[j+t] = y_i[j+t] + temp_i[0] + temp_i[1] + temp_i[2] + temp_i[3];
                                       break;
                                       
                         }
                   }
                   t = t + p*i;
           }
           M = M/p;
     }
     
     
     return;
}
Esempio n. 29
0
void
zn_array_mul_fft_dft (ulong* res,
                      const ulong* op1, size_t n1,
                      const ulong* op2, size_t n2,
                      unsigned lgT, const zn_mod_t mod)
{
   ZNP_ASSERT (mod->m & 1);
   ZNP_ASSERT (n2 >= 1);
   ZNP_ASSERT (n1 >= n2);
   
   if (lgT == 0)
   {
      // no layers of DFT; just call usual FFT routine
      int sqr = (op1 == op2) && (n1 == n2);
      ulong x = zn_array_mul_fft_fudge (n1, n2, sqr, mod);
      zn_array_mul_fft (res, op1, n1, op2, n2, x, mod);
      return;
   }

   unsigned lgM, lgK;

   // number of pmf_t coefficients for each input poly
   ulong m1, m2;

   // figure out how big the transform needs to be
   mul_fft_params (&lgK, &lgM, &m1, &m2, n1, n2);

   // number of pmf_t coefficients for output poly
   ulong m = m1 + m2 - 1;

   ulong M = 1UL << lgM;
   ulong K = 1UL << lgK;
   ptrdiff_t skip = M + 1;

   size_t n3 = n1 + n2 - 1;

   // Split up transform into length K = U * T, i.e. U columns and T rows.
   if (lgT >= lgK)
      lgT = lgK;
   unsigned lgU = lgK - lgT;
   ulong U = 1UL << lgU;
   ulong T = 1UL << lgT;
   
   // space for two input rows, and one partial row
   pmfvec_t in1, in2, part;
   pmfvec_init (in1, lgU, skip, lgM, mod);
   pmfvec_init (in2, lgU, skip, lgM, mod);
   pmfvec_init (part, lgU, skip, lgM, mod);

   // the virtual pmfvec_t that we use for the column DFTs
   virtual_pmfvec_t col;
   virtual_pmfvec_init (col, lgT, lgM, mod);

   // zero the output
   zn_array_zero (res, n3);
   
   long i, j, k;
   int which;

   // Write m = U * mT + mU, where 0 <= mU < U
   ulong mU = m & (U - 1);
   ulong mT = m >> lgU;

   // for each row (beginning with the last partial row if it exists)....
   for (i = mT - (mU == 0); i >= 0; i--)
   {
      ulong i_rev = bit_reverse (i, lgT);
      
      // for each input array....
      for (which = 0; which < 2; which++)
      {
         pmfvec_struct* in = which ? in2 : in1;
         const ulong* op = which ? op2 : op1;
         size_t n = which ? n2 : n1;

         pmf_t p = in->data;

         for (j = 0; j < U; j++, p += in->skip)
         {
            // compute the i-th row of the j-th column as it would look after
            // the column FFTs, using naive DFT
            pmf_zero (p, M);
            ulong r = i_rev << (lgM - lgT + 1);
            
            for (k = 0; k < T; k++)
            {
               merge_chunk_to_pmf (p, op, n, (k * U + j) << (lgM - 1), M, mod);
               pmf_rotate (p, -r);
            }
            
            pmf_rotate (p, (i_rev * j) << (lgM - lgK + 1));
         }
         
         // Now we've got the whole row; run FFT on the row
         pmfvec_fft (in, (i == mT) ? mU : U, U, 0);
      }

      if (i == mT)
      {
         // pointwise multiply the two partial rows
         pmfvec_mul (part, in1, in2, mU, i == 0);
         // remove fudge factor
         pmfvec_scalar_mul (part, mU, pmfvec_mul_fudge (lgM, 0, mod));

         // zero remainder of the partial row; we will subsequently add
         // in contributions from the vertical IFFTs when we process the other
         // rows.
         for (j = mU; j < U; j++)
            pmf_zero (part->data + part->skip * j, M);
      }
      else
      {
         // pointwise multiply the two rows
         pmfvec_mul (in1, in1, in2, U, i == 0);
         // remove fudge factor
         pmfvec_scalar_mul (in1, U, pmfvec_mul_fudge (lgM, 0, mod));
         
         // horizontal IFFT this row
         pmfvec_ifft (in1, U, 0, U, 0);

         // simulate vertical IFFTs with DFTs
         for (j = 0; j < U; j++)
         {
            virtual_pmfvec_reset (col);
            virtual_pmf_import (col->data[i], in1->data + in1->skip * j);
            virtual_pmfvec_ifft (col, mT + (j < mU), (j >= mU) && mU,
                                 j << (lgM + 1 - lgK));
            
            if ((j >= mU) && mU)
            {
               // add contribution to partial row (only for rightmost columns)
               pmf_t src = virtual_pmf_export (col->data[mT]);
               if (src)
                  pmf_add (part->data + part->skip * j, src, M, mod);
            }

            // add contributions to output
            for (k = 0; k < mT + (j < mU); k++)
               merge_chunk_from_pmf (res, n3,
                                     virtual_pmf_export (col->data[k]),
                                     (k * U + j) * M/2, M, mod);
         }
      }
   }

   // now finish off the partial row
   if (mU)
   {
      // horizontal IFFT partial row
      pmfvec_ifft (part, mU, 0, U, 0);

      // simulate leftmost vertical IFFTs
      for (j = 0; j < mU; j++)
      {
         virtual_pmfvec_reset (col);
         virtual_pmf_import (col->data[mT], part->data + part->skip * j);
         virtual_pmfvec_ifft (col, mT + 1, 0, j << (lgM + 1 - lgK));
                         
         // add contributions to output
         for (k = 0; k <= mT; k++)
            merge_chunk_from_pmf (res, n3,
                                  virtual_pmf_export (col->data[k]),
                                  (k * U + j) * M/2, M, mod);
      }
   }
   
   // normalise result
   zn_array_scalar_mul (res, res, n3, zn_mod_pow2 (-lgK, mod), mod);

   virtual_pmfvec_clear (col);
   pmfvec_clear (part);
   pmfvec_clear (in2);
   pmfvec_clear (in1);
}