Resampling based on FFT

Vashishth December 16, 20102 comments Coded in Matlab
% FFTRESAMPLE Resample a real signal by the ratio p/q
function y = fftResample(x,p,q)

% --- take FFT of signal ---
f = fft(x);

% --- resize in the FFT domain ---
% add/remove the highest frequency components such that len(f) = len2
len1 = length(f);
len2 = round(len1*p/q);
lby2 = 1+len1/2;
if len2 < len1
  % remove some high frequency samples
  d = len1-len2;
  f = f(:);
  f(floor(lby2-(d-1)/2:lby2+(d-1)/2)) = [];
elseif len2 > len1
  % add some high frequency zero samples
  d = len2-len1;
  lby2 = floor(lby2);
  f = f(:);
  f = [f(1:lby2); zeros(d,1); f(lby2+1:end)];
end

% --- take the IFFT ---
% odd number of sample removal/addition may make the FFT of a real signal
% asymmetric and artificially introduce imaginary components - we take the
% real value of the IFFT to remove these, at the cost of not being able to
% reample complex signals
y = real(ifft(f));

2-D Ping Pong Game.

Vashishth December 16, 2010 Coded in Matlab
%By vkc
function RunGame

    hMainWindow = figure(...
        'Color', [1 1 1],...
        'Name', 'Game Window',...
        'Units', 'pixels',...
        'Position',[100 100 800 500]);

    
    
    img = imread('ball.bmp','bmp');
    [m,n,c] = size(img);
    hBall = axes(...
        'parent', hMainWindow,...
        'color', [1 1 1],...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [345, 280, n, m] );
    hBallImage = imshow( img );
    set(hBallImage, 'parent', hBall, 'visible', 'off' );
    ballSpeed = 3;
    ballDirection = 0;
    hTempBall = axes( ...
        'parent', hMainWindow,...
        'units', 'pixels',...
        'color', 'none',...
        'visible', 'off',...
        'position', get(hBall, 'position' ) );
    
    
    img = imread('paddle.bmp','bmp');
    [m,n,c] = size(img);
    
    hRightPaddle = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [650 - 10, 250 - 50, n, m] );
    hRightPaddleImage = imshow( img );
    set(hRightPaddleImage, 'parent', hRightPaddle, 'visible', 'off' );
    targetY = 200;
    t = timer(  'TimerFcn', @UpdateRightPaddleAI,...
                'StartDelay', 10 );
            start(t)
    
    

    hLeftPaddle = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [50, 250 - 50, n, m] );
    hLeftPaddleImage = imshow( img );
    set(hLeftPaddleImage, 'parent', hLeftPaddle, 'visible', 'off' );

    hBottomWall = axes(...
        'parent', hMainWindow,...
        'color', [1 1 1],...
        'units', 'pixels',...
        'visible', 'off',...
        'position', [0 40 700 10] );
    patch( [0 700 700 0], [0 0 10 10], 'b' );    
    
    hTopWall = axes(...
        'parent', hMainWindow,...
        'color', [1 1 1],...
        'units', 'pixels',...
        'visible', 'off',...
        'position', [0 450 700 10] );
    patch( [0 700 700 0], [0 0 10 10], 'b' );
    
    rightScore = 0;
    leftScore = 0;
    hRightScore = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [650 485 50 10] );
    hLeftScore = axes(...
        'parent', hMainWindow,...
        'color', 'none',...
        'visible', 'off',...
        'units', 'pixels',...
        'position', [30 485 50 10] );
    hRightScoreText = text( 0, 0, '0', 'parent', hRightScore,...
        'visible', 'on', 'color', [1 1 1] );
    hLeftScoreText = text( 0, 0, '0', 'parent', hLeftScore,...
        'visible', 'on', 'color', [1 1 1] );
    
    
    
    hQuitButton = uicontrol(...
        'string', 'Quit',...
        'position', [325 475 50 20],...
        'Callback', @QuitButton_CallBack );
    
    hStartButton = uicontrol(...
        'string', 'Start',...
        'position', [325 240 50 20],...
        'Callback',@StartButton_CallBack );

    playing = true; 
    

    while playing == true
        

        UpdateBall()
        UpdateLeftPaddle()
        UpdateRightPaddle()

        CheckForScore()

        pause( 0.01 )
    end
    stop(t)
    close( hMainWindow )
    
    
    
    
    
    
    
    

    
    
    function UpdateBall
        
       pos = get( hBall, 'position' );
       ballX = pos(1,1);
       ballY = pos(1,2);
       
       ballDirection = NormalizeAngle( ballDirection );
      
       
       % check for collisions with the walls
       if ( ballY > 450 - 10 ) && ( ballDirection > 0 ) && ( ballDirection < 180 )
            if ( ballDirection > 90 )
                ballDirection = ballDirection + 2 * ( 180 - ballDirection );
            else
                ballDirection = ballDirection - 2 * ballDirection;
            end
       elseif ( ballY < 50 ) && ( ballDirection > 180 ) && ( ballDirection < 360 )
            if ( ballDirection > 270 )
                ballDirection = ballDirection + 2 * ( 360 - ballDirection );
            else
                ballDirection = ballDirection - 2 * ( ballDirection - 180 );
            end
       end
       
       % check for collisions with the paddles
       
       if ( ballDirection > 90 && ballDirection < 270 )
           
            leftPaddlePos = get( hLeftPaddle, 'position' );
            leftX = leftPaddlePos(1,1);
            leftY = leftPaddlePos(1,2);
          
            if(     (ballX < leftX + 10)...
                &&  (ballX > leftX + 5)...
                &&  (ballY + 10 > leftY)...
                &&  (ballY < leftY + 100)     )
                
                if ( ballDirection < 180 )
                    ballDirection = 180 - ballDirection;
                elseif( ballDirection > 180 )
                    ballDirection = 180 - ballDirection;
                end
            end
       else
            rightPaddlePos = get( hRightPaddle, 'position' );
            rightX = rightPaddlePos(1,1);
            rightY = rightPaddlePos(1,2);
            
            if(     (ballX + 10 > rightX)...
                &&  (ballX + 10 < rightX + 5)...
                &&  (ballY > rightY)...
                &&  (ballY < rightY + 100)  )
                
                if ( ballDirection < 90 )
                    ballDirection = 180 - ballDirection;
                elseif( ballDirection > 270 )
                    ballDirection = 180 - ballDirection;
                end
            end
       end
           
       MoveObject( hBall, ballSpeed, ballDirection );
        
    end

    
    function UpdateRightPaddle()

         
         speed = 5;
         pos = get( hRightPaddle, 'position' );
         rightY = pos(1,2);
         
         
         
         if( rightY + 5 < targetY - 50 && rightY < 400 - 50 )
             MoveObject( hRightPaddle, speed, 90 )
         elseif( rightY - 5 > targetY - 50 && rightY > 50 )
             MoveObject( hRightPaddle, speed, 270 )
         end
      
         pos = get( hRightPaddle, 'position' );
         rightY = pos( 1,2);
         if( rightY > 400 - 50 )
             rightY = 350;
         elseif( rightY < 50 )
             rightY = 50;
         end
         
         
        if( strcmp( get( t, 'Running' ), 'off' ) )
            start(t)
        end
    
    end

    function UpdateRightPaddleAI( ob, data )
        
        % calculate where the ball will colide.
        tempBallDirection = NormalizeAngle( ballDirection ); 
        if( tempBallDirection < 90 || tempBallDirection > 270 && ballSpeed > 0 )
           
            ballPos = get( hBall, 'position' );
            set( hTempBall, 'position', ballPos );
            ballX = ballPos(1,1);            
            while( ballX < 650 - 10  )
                
                ballPos = get( hTempBall, 'position' );
                ballX = ballPos(1,1); 
                ballY = ballPos(1,2);
                MoveObject( hTempBall, 20, tempBallDirection )

               % check for temp ball collision with walls.
               if ( ballY > 450 - 10 ) 
                   if ( tempBallDirection > 0 ) 
                       if ( tempBallDirection < 180 )    
                            tempBallDirection = 360 - tempBallDirection;
                       end
                   end
               elseif ( ballY < 60 ) 
                   if( tempBallDirection > 180 ) 
                       if( tempBallDirection < 360 )
                            tempBallDirection = 360 - tempBallDirection;
                       end
                   end
               end

%                     line( 0, 0, 'marker', '*', 'parent', hTempBall )
%                     pause( 0.0005 )
            end

            pos = get( hTempBall, 'position' );
            ballY = pos(1,2);
            targetY = ballY + ( rand * 150 ) - 75;
            
        end
    end

    function UpdateLeftPaddle()    
        scr = get( hMainWindow, 'position' );
        screenX = scr(1,1);
        screenY = scr(1,2);
        screenH = scr(1,4);
        
        mouse = get(0, 'PointerLocation' );
        y = mouse(1,2) - screenY;
        
        if( y > 100 && y < 400 )
            paddlePos = get( hLeftPaddle, 'position' ); 
            paddlePos(1,2) = y - 50; 
            set( hLeftPaddle, 'position', paddlePos );
        elseif( y > 400 )
            paddlePos = get( hLeftPaddle, 'position' ); 
            paddlePos(1,2) = 400 - 50; 
            set( hLeftPaddle, 'position', paddlePos ); 
        elseif( y < 100 )
            paddlePos = get( hLeftPaddle, 'position' ); 
            paddlePos(1,2) = 100 - 50; 
            set( hLeftPaddle, 'position', paddlePos );
        end
        
    end

    function CheckForScore()
        
       pos = get( hBall, 'position' );
       xpos = pos(1,1);
       ypos = pos(1,2);
       
       if ( xpos < 5 )
           set( hBallImage, 'visible', 'off' )
           rightScore = rightScore + 1;
           set ( hRightScoreText, 'string', num2str( rightScore ) )
           pause( .5 )
           ResetBall()
       elseif ( xpos + 10 > 695 )
           set( hBallImage, 'visible', 'off' )
           leftScore = leftScore + 1;
           set ( hLeftScoreText, 'string', num2str( leftScore ) )
           pause( .5 )
           ResetBall()
       end
       
    end
        
    function ResetBall
        
        pos = get( hBall, 'position' );
        pos(1,1) = 345;
        pos(1,2) = 255 + floor( rand*100 ) - 50;
        set( hBall, 'position', pos )
        ballSpeed = 4;
        ballDirection =  ( (rand(1) < 0.5) * 180 ) ...          % 0 or 180
                       + ( 45 + (rand(1) < 0.5) * -90 ) ...     % + 45 or - 45
                       + ( floor( rand * 40 ) - 20 );           % + -20 to 20
        set( hBallImage, 'visible', 'on' )
        pause(1)
        
    end
    

    function MoveObject( hInstance, speed, direction )

        p = get( hInstance, 'position' );

        x = p( 1, 1 );
        y = p( 1, 2 );
        
        x = x + cosd( direction ) * speed;
        y = y + sind( direction ) * speed;

        p( 1, 1 ) = x;
        p( 1, 2 ) = y;

        set( hInstance, 'position', p )

    end

    function SetObjectPosition( hObject, x, y )
       
       pos = get( hObject, 'position' );
       pos(1,1) = x;
       pos(1,2) = y;
       set( hObject, 'position', pos )
        
    end

    function a = NormalizeAngle( angle )
        
        while angle > 360
            angle = angle - 360;
        end
        
        while angle < 0
            angle = angle + 360;
        end
        a = angle;

    end

    function QuitButton_CallBack( hObject, eventData )
        playing = false;
    end

    function StartButton_CallBack( hObject, eventData )
        set( hObject, 'visible', 'off' );
        set( hLeftPaddleImage, 'visible', 'on' )
        set( hRightPaddleImage, 'visible', 'on' )
        ResetBall();
    end

end

Constant complexity rectangular QAM demodulator

Vashishth November 14, 2010 Coded in C for the TI C67x
% N is the size of the constellation.
% v is the input data.
% For details email me.
void function_qam()
{

co=0;
 m=0;

for(q=0; q<N; q++)

        {

 a=v[m];// a holds the real part
 b=v[m+1];// b holds the imaginary part

 d=a-onern[max];  %onern stores the negative real axis points and onein stores the negative imag axis points. eg for 256 QAM, each will store 0 to -8 as an array.
 l=d;         //l stores the distance
 s=(d-l);
 if(l<max-1) % max is the maximum value that the 1-d coordinate can take.
       {

if(d>0){
 if(s<=.5)
       {
 hi=max-l;
 flagtwo=1;
       }
 else
 {
 hi=max-l-1;
 flagtwo=1;
 }
      }
	  else
	  {
	  hi=max;
	  flagtwo=1;
	  }
        
      }

 if(l==max-1)
 {
 hi=1;
 flagtwo=1;
 }
 if(l==max)//
 {
 flagone=1;
 hi=1;
 } 

 if(l>max)
        {
		if(d<2*max)
		{

 if(s<=.5)
 {
 hi=l-max;
 flagone=1;
 }
 else
 {
 hi=l-max+1;
 flagone=1;
 }
        }
		else
		{
		hi=max;
		flagone=1;
		}
       
          
        }

 de=b-onein[max];
 le=de;         //l stores the distance
 se=(de-le);

 if(le<max-1)
      {

	  if(de>0)
	  {
 if(se<=.5)
 {
 hm=max-le;
 flagfour=1;
 }
 else
 {
 hm=max-le-1;
 flagfour=1;
 }
      
      }
	  else
	  {
	  hm=max;
	  flagfour=1;
      }
      
      
      }

 if(le==max-1)
 {
 hm=1;
 flagfour=1;
 }
 if(le==max)
 {
 flagthree=1;
 hm=1;
 }

 if(le>max)
     {

if(de<2*max){

 if(se<=.5)
 {
 hm=le-max;
 flagthree=1;
 }
 else
 {
 hm=le-max+1;
 flagthree=1;
 }
    }
	else
	{
	hm=max;
	flagthree=1;
	}
    
       
    
    }

 if(flagone==1)
 {
  vv[m]=hi;  // now v[m] holds one x coordinate of the qam mapping and v[m+1] holds the y coordinate
 }
 
 else
 {
 vv[m]= 100-hi;
 }

 
 if(flagthree==1)
  {
 vv[m+1]=hm;  
  }
		else
		{
 vv[m+1]= 100-hm;
        }

flagone=0;
flagtwo=0;
flagthree=0;
flagfour=0;
        r=0;
        
        
          
           output[co]= valuetable[ vv[m] ][ vv[m+1] ] ;
       
       
          
          
                        
      m = m+ 2;
	  
	  co = co+ 1;
                
                
                 }

  for(t=0;t<(N/2);t++)
  {
   p[t] = (output[t]);
 
  }

 

}