This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Speech processing with TMS320VC5505 eZdsp USB stick - linking error

Other Parts Discussed in Thread: TMS320VC5505

Hello

I am doing MFCC extraction from a speech signal on the TMS320VC5505 eZdsp USB stick, i am using CCSv4, and i have the following error msg: "Linking failed. Check the Console window for details." and in the console window it says:  INTERNAL ERROR: Space required for local variables exceeds maximum in _main.

For this i am using rfft given in the Dsplib for this microcontroller that i downloaded from TI website (and log10 and pow from the same file for use on my 2D arrays in the calculations).

In the next file you can see the source code i have written for this:

8407.main.txt
/*
 *  Copyright 2009 by Spectrum Digital Incorporated.
 *  All rights reserved. Property of Spectrum Digital Incorporated.
 */

#include "stdio.h"
#include "usbstk5505.h"

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  Testing Function                                                        *
 *                                                                          *
 * ------------------------------------------------------------------------ */
void TEST_execute( Int16 ( *funchandle )( ), char *testname, Int16 testid )
{
    Int16 status;

    /* Display test ID */
    printf( "%02d  Testing %s...\n", testid, testname );

    /* Call test function */
    status = funchandle( );

    /* Check for test fail */
    if ( status != 0 )
    {
        /* Print error message */
        printf( "     FAIL... error code %d... quitting\n", status );

        /* Software Breakpoint to Code Composer */
        SW_BREAKPOINT;
    }
    else
    {
        /* Print error message */
        printf( "    PASS\n" );
    }
}

extern Int16 aic3204_test( );

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  main( )                                                                 *
 *                                                                          *
 * ------------------------------------------------------------------------ */
void main( void )
{
    /* Initialize BSL */
    USBSTK5505_init( );

    printf("EXBUSSEL = %02x\n", SYS_EXBUSSEL);
    
    TEST_execute( aic3204_test, "AIC3204", 1 );

    printf( "\n***ALL Tests Passed***\n" );
    SW_BREAKPOINT;
}

 

I tried to remove all the unnecessary variables so i don't have any more maneuvering space there. I tried to comment a part of the code and only if i comment everything from the rfft call to the end (including the rfft), i don't get the linking error msg.

 

I am new in programing microcontrollers so i ask if you could make your answer simple to understand.

I hope you can help me solve this problem, any suggestions are welcome.

 

thank you in advance.

  • Under Build Options --> Runtime Model Options, what do you have under "Specify memory model"?

  • The memory model is specified as Huge. And I think that there is no other option because i expect to have very big matrices during the MFCC extraction.

    I checked the allocated memory and the whole memory is used.

    By my calculations the biggest matrix used would be a little smaller then 40 kB (assuming that maybe the space required for 1 float sample is 2 bytes), is that too much?

    I tried to make it smaller - reduce it to [1200][10] but i still got the same error msg pointing me to look at the console output. Here is the console output, it may help to understand what's wrong:

    **** Build of configuration Debug for project MFCC ****

    C:\Program Files\Texas Instruments\ccsv4\utils\gmake\gmake -k all
    'Building file: ../main.c'
    'Invoking: C5500 Compiler'
    "C:/Program Files/Texas Instruments/ccsv4/tools/compiler/c5500/bin/cl55" -v5505 -g --include_path="C:/Program Files/Texas Instruments/ccsv4/tools/compiler/c5500/include" --diag_warning=225 --sat_reassoc=off --ptrdiff_size=32 --fp_reassoc=off --memory_model=huge --asm_source=mnemonic  --preproc_with_compile --preproc_dependency="main.pp" "../main.c"
    >> INTERNAL ERROR: Space required for local variables exceeds maximum in _main

    This may be a serious problem.  Please contact customer support with a
    description of this problem and a sample of the source files that caused this
    INTERNAL ERROR message to appear.


    >> Compilation failure
    Cannot continue compilation - ABORTING!

    C:\Program Files\Texas Instruments\ccsv4\utils\gmake\gmake: *** [main.obj] Error 1
    C:\Program Files\Texas Instruments\ccsv4\utils\gmake\gmake: Target `all' not remade because of errors.
    Build complete for project MFCC

  • Oh, I just realized i put the wrong code last time. Here is the code I am using:

    8867.MFCC main.txt
    
    #include "stdio.h"
    #include "usbstk5505.h"
    #include "math.h"
    #include "Dsplib.h"
    extern Int16 AIC3204_rset( Uint16 regnum, Uint16 regval);
    #define XmitL 0x10
    #define XmitR 0x20
    #define RcvR 0x08
    #define RcvL 0x04
    #define pi 3.1415926535897932384626433832795028841971693993751
    #define nfilt 40
    
    void main( void )
    {
    	void *za_obradu, *obrada, *pom;
        Int16 i, j, p, whichfilt, freq;
        Int16 sample, data4;
        float novi_desni[1200], za_obraditi_desni[1200][100], pomocna[1200], mfcc[100][13];		//wlen=0.0256, upperf i lowerf 3 x veci
        float ncep=13,lowerf=400, upperf=20566.4928, samprate=48000, nfft=256, win[1200], dfreq;
        float filters[1200][40], melmax, melmin, dmelbw, arange[42], filt_edge[42], leftfr, centerfr, rightfr, fwidth, height, leftslope, rightslope;
        int S, time= 1, wlen=1200;
        
        /* Initialize BSL */
        USBSTK5505_init( );
    	printf("EXBUSSEL = %02x\n", SYS_EXBUSSEL);
        
        /* izvodenje*/
        printf("izvodenje je pocelo");
        
        /* program MFCC */
      
        /* Configure Serial Bus */
        SYS_EXBUSSEL |= 0x0100;  // Configure Serial bus 0 for I2S0
     
         
        /* Configure AIC3204 */
        AIC3204_rset( 0, 0 );      // Select page 0
        AIC3204_rset( 1, 1 );      // Reset codec
        AIC3204_rset( 0, 1 );      // Select page 1
        AIC3204_rset( 1, 8 );      // Disable crude AVDD generation from DVDD
        AIC3204_rset( 2, 1 );      // Enable Analog Blocks, use LDO power
        AIC3204_rset( 0, 0 );
        /* PLL and Clocks config and Power Up  */
        AIC3204_rset( 27, 0x0d );  // BCLK and WCLK are set as o/p; AIC3204(Master)
        AIC3204_rset( 28, 0x00 );  // Data ofset = 0
        AIC3204_rset( 4, 3 );      // PLL setting: PLLCLK <- MCLK, CODEC_CLKIN <-PLL CLK
        AIC3204_rset( 6, 7 );      // PLL setting: J=7
        AIC3204_rset( 7, 0x06 );   // PLL setting: HI_BYTE(D=1680)
        AIC3204_rset( 8, 0x90 );   // PLL setting: LO_BYTE(D=1680)
        AIC3204_rset( 30, 0x88 );  // For 32 bit clocks per frame in Master mode ONLY
                                   // BCLK=DAC_CLK/N =(12288000/8) = 1.536MHz = 32*fs
        AIC3204_rset( 5, 0x91 );   // PLL setting: Power up PLL, P=1 and R=1
        AIC3204_rset( 13, 0 );     // Hi_Byte(DOSR) for DOSR = 128 decimal or 0x0080 DAC oversamppling
        AIC3204_rset( 14, 0x80 );  // Lo_Byte(DOSR) for DOSR = 128 decimal or 0x0080
        AIC3204_rset( 20, 0x80 );  // AOSR for AOSR = 128 decimal or 0x0080 for decimation filters 1 to 6
        AIC3204_rset( 11, 0x82 );  // Power up NDAC and set NDAC value to 2
        AIC3204_rset( 12, 0x87 );  // Power up MDAC and set MDAC value to 7
        AIC3204_rset( 18, 0x87 );  // Power up NADC and set NADC value to 7
        AIC3204_rset( 19, 0x82 );  // Power up MADC and set MADC value to 2
        /* DAC ROUTING and Power Up */
        AIC3204_rset( 0, 1 );      // Select page 1
        AIC3204_rset( 0x0c, 8 );   // LDAC AFIR routed to HPL
        AIC3204_rset( 0x0d, 8 );   // RDAC AFIR routed to HPR
        AIC3204_rset( 0, 0 );      // Select page 0
        AIC3204_rset( 64, 2 );     // Left vol=right vol
        AIC3204_rset( 65, 0 );     // Left DAC gain to 0dB VOL; Right tracks Left
        AIC3204_rset( 63, 0xd4 );  // Power up left,right data paths and set channel
        AIC3204_rset( 0, 1 );      // Select page 1
        AIC3204_rset( 0x10, 00 );  // Unmute HPL , 0dB gain
        AIC3204_rset( 0x11, 00 );  // Unmute HPR , 0dB gain
        AIC3204_rset( 9, 0x30 );   // Power up HPL,HPR
        AIC3204_rset( 0, 0 );      // Select page 0
        USBSTK5505_wait( 100 );    // wait
        /* ADC ROUTING and Power Up */
        AIC3204_rset( 0, 1 );      // Select page 1
        AIC3204_rset( 0x34, 0x30 );// STEREO 1 Jack
    		                       // IN2_L to LADC_P through 40 kohm
        AIC3204_rset( 0x37, 0x30 );// IN2_R to RADC_P through 40 kohmm
        AIC3204_rset( 0x36, 3 );   // CM_1 (common mode) to LADC_M through 40 kohm
        AIC3204_rset( 0x39, 0xc0 );// CM_1 (common mode) to RADC_M through 40 kohm
        AIC3204_rset( 0x3b, 0 );   // MIC_PGA_L unmute
        AIC3204_rset( 0x3c, 0 );   // MIC_PGA_R unmute
        AIC3204_rset( 0, 0 );      // Select page 0
        AIC3204_rset( 0x51, 0xc0 );// Powerup Left and Right ADC
        AIC3204_rset( 0x52, 0 );   // Unmute Left and Right ADC
        
        
        AIC3204_rset( 0, 0 );    
        USBSTK5505_wait( 100 );  // Wait
        /* I2S settings */
        I2S0_SRGR = 0x0;     
        I2S0_CR = 0x8010;    // 16-bit word, slave, enable I2C
        I2S0_ICMR = 0x3f;    // Enable interrupts
        /* Play Tone */
    	
    	//Postavljanje elemenata matrica na 0
    	for ( sample = 0 ; sample < 1200 ; sample++ ){
                	novi_desni[sample]=0;
                	pomocna[sample]=0;
        	for ( i = 0 ; i < 100 ; i++ ){
                za_obraditi_desni[sample][i]=0;
        	}
        }	
                
    //Ono sa neta
               //Matrica Mel filtara
               for(i=0 ; i < 1200 ; i++){
               		for(j=0 ; j < 40 ; j++){
               		filters[i][j]=0;      //inicijalizacija na nule
               		}
               }
               
               dfreq = samprate / nfft;	 // nfft je sto je bio N u MATLAB-u															//Ovo sam kopirao samo reda radi,
    /*           if (upperf > samprate/2){	// upperf i lowerf se moraju modificirati po�to je sad samprate 3 x veci pa moraju i oni biti														//jer ce uvjet nece nikada biti ispunjen
               	printf("\nGornja frekvencija %f je veca od Nyquistove %f" , upperf, samprate/2);	//
               }*/   //nemoe� printat nesto na screen ako nema screena
    	
    			melmax = 2595 * log10(1 + upperf / 700);
    			melmin = 2595 * log10(1 + lowerf / 700);
    			dmelbw = (melmax - melmin) / (nfilt + 1);
    			
    			//Rubovi filtara u Hz
    			for(i=0 ; i < 42 ; i++){
    				arange[i]=i;
    			}
    			for(i=0 ; i < 42 ; i++){
    			filt_edge[i]=700. * (pow(10., (melmin+dmelbw*arange[i]) / 2595.) - 1.);
    			}
    			for(whichfilt=0 ; whichfilt < nfilt ; whichfilt++){
    				//Filter trokuti u DFT tockama
    				leftfr = filt_edge[whichfilt]/dfreq;
    				centerfr = _nround(filt_edge[whichfilt + 1] / dfreq);
    				rightfr = _nround(filt_edge[whichfilt + 2] / dfreq);
    				fwidth = (rightfr - leftfr) * dfreq;
    				height = 2. / fwidth;
    				if (centerfr != leftfr) 
                      leftslope = height / (centerfr - leftfr); 
                  	else
                      leftslope = 0;
    				freq = leftfr + 1;
    				while (freq < centerfr){ 
                       filters[freq][whichfilt] = (freq - leftfr) * leftslope; 
                       freq = freq + 1;
    				}
    				if (freq == centerfr){ // This is always true 
                       filters[freq][whichfilt] = height; 
                       freq = freq + 1;
    				}
    				if (centerfr != rightfr){ 
                       rightslope = height / (centerfr - rightfr);
    				}
    				while (freq < rightfr){ 
                       filters[freq][whichfilt] = (freq - rightfr) * rightslope; 
                       freq = freq + 1;
    				}				
    			}
    
    	//Snimanje i spremanje u matricu
    	//for(i=0 ; i < 5 ; i++)
    	while(1)
    	{
    		for(i=0 ; i < time ; i++) // snimanje naredbe 1 sec
    		{
                for ( sample = 0 ; sample < samprate ; sample++ )
                {
    				/* Read Digital audio input */
          	        while((RcvR & I2S0_IR) == 0);  // Wait for receive interrupt to be pending
    //                data3 = I2S0_W0_MSW_R;  // 16 bit left channel received audio data
          	        data4 = I2S0_W1_MSW_R;  // 16 bit right channel received audio data
    
    				novi_desni[sample]=data4;
    
    				/* Write Digital audio input */
                    while((XmitR & I2S0_IR) == 0); // Wait for transmit interrupt to be pending
    //				I2S0_W0_MSW_W = data3;  // 16 bit left channel transmit audio data
          	        I2S0_W1_MSW_W = data4;  // 16 bit right channel transmit audio data
    
                }
    		}
    //ne posto se snima blok od 1 sec.        
    /*            //stavljanje zadnjih 10 ms sa prethodnog
                for ( sample = 720 ; sample < 1200 ; sample++ )
                {
                	za_obraditi_desni[sample-720]=stari_desni[sample];
                }
               
                //stavljanje prvih 15 ms sa novog
                for ( sample = 0 ; sample < 720 ; sample++ )
                {
                	za_obraditi_desni[sample+720]=novi_desni[sample];
                }
                
                //kopiranje novi_desni-->stari_desni
                for ( sample = 0 ; sample < 1200 ; sample++ )
                {
                	stari_desni[sample]=novi_desni[sample];
                }*/
                
               
               	S=0; //brojac dijelova audio signala
       			for (j=0; j <(samprate*time) ; j=j+480)
        		{
        			for(i=0; i<1200 ; i++){
        				za_obraditi_desni[i][S]=novi_desni[j+i];
        			}
            		S=S++;
                }
    			S=S--;
    			za_obradu = &za_obraditi_desni[0][0];
    			
    		
               //Izgradnja Hammingovog prozora
     //          wlen = wlen * samprate; //fali (int)
               
               for (i=0 ; i < wlen ; i++){ // wlen =1200
               		win[i]=0.54-0.46*pi*cos(2*(i-1)/(wlen-1));
               }
               
               //Mno�enje uzoraka sa Hammingovim prozorom
               for (i = 0 ; i < S ; i++){
               	for (j = 0 ; j < wlen ; j++){
               		za_obraditi_desni[j][i]=za_obraditi_desni[j][i]*win[i];
               	}
               }
    // ovdje bio komad koda za filtere racunat sad je prije while petlje
    			
    			//Izrada DCT matrice
    			//mo�da najbolje iz onog naseg iz MATLAB-a pod pretpostavkom da je matrica filtera ovdje filters
    			
    			// FFT
    			rfft(za_obradu, nfft, NOSCALE);
    
    			//apsolutna vrijednost i kvadrat svakog elementa matrice
    			for(i=0; i < S; i++){
    				for(j=0; j < wlen; j++){
    					 za_obraditi_desni[i][j] = pow(fabs(za_obraditi_desni[i][j]),2);
    				} // koristim iste 2 matrice za cijelu obradu zbog ogranicenja memorije na MCU
    			}
    			// mnozenje spektra snage sa svakim trokutastim filtrom zasebno
    			for(j=0; j < S; j++){
        			for(i=0; i < nfilt; i++){
        				for(p=0; p < wlen; p++){
        					//ove dve matrice monozit u petlji
            				pomocna[p] = pomocna[p]+(za_obraditi_desni[j][p]*filters[i][p]);
        				}
        			}
       // vidi dal ces tu koristiti pointere ili bas te matrice - MATRICE??!!
        			for(p=0; p < wlen; p++){
     	  				za_obraditi_desni[j][p]= pomocna[p];
        				pomocna[p] = 0;
     	  			}
    			}
    			
    			// Diskretna kosinusna transformacija DCT
    			for(i=0; i < S; i++){
    				for(j=0; j < ncep; j++){
    					mfcc[i][j] = 0;
    				}
    			}
    			pom=&pomocna[0];
    			for(j=0; j < S; j++){
    				obrada=&za_obraditi_desni[j][0];
    				logn(obrada,pom,wlen);
        			for(p=0; p < ncep; p++){
            			for(i=0; i < wlen; i++){
                			if(za_obraditi_desni[i][j] != 0){
                				mfcc[p][j]=mfcc[p][j] +pomocna[i] * cos(pi*(p-1)/2/wlen*(2*(i-1)+1));
                			}
        			    }
       			 	}
    			}
    	}
    	  
    }
    

     

    I hope you can help solve my problem.

    Thank you.

  • floats are 32 bit long, so array 1200x100 alone takes 480kB of memory - more than whole on-chip memory. I don't even mention that there are  other big arrays in code.

     

    regards

    MS

  • Oh, thank you for pointing that out. Now I've corrected for the problem and the code build ok, but still a new problem appears when running that is when i run debug. i get the following when starting the debugger:

    "55xx: Loader: One or more sections of your program falls into a memory region that is not writable.  These regions will not actually be written to the target.  Check your linker configuration and/or memory map."

    And when i run the program it stops right away, and this is probably the reason.

    Here is the new code:

    2376.MFCC main.txt
    #include "stdio.h"
    #include "usbstk5505.h"
    #include "aic3204.h"
    #include "PLL.h"
    #include "stereo.h"
    #include "Dsplib.h"
    #include "math.h"
    
    Int16 left_input;
    Int16 right_input;
    Int16 left_output;
    Int16 right_output;
    Int16 mono_input;
    
    
    #define SAMPLES_PER_SECOND 16000
    #define pi 3.1415926535897932384626433832795028841971693993751
    #define nfilt 40
    
    void *za_obradu, *obrada, *pom;
    Int16 i, j, p, whichfilt, freq;
    Int16 sample;
    Int16 novi_desni[8000], za_obraditi_desni[400][48], pomocna[400], mfcc[48][13];		//wlen=0.0256, upperf i lowerf 3 x veci
    Uint16 ncep=13,lowerf=133.3333, upperf=6855.4976, wlen=400, melmax, melmin, dmelbw, samprate=16000, nfft=256, dfreq, leftfr, centerfr, rightfr, fwidth, height, leftslope, rightslope;
    Int16 filters[400][40], win[400],  arange[42], filt_edge[42];
    Uint16 S=48, time= 1;
    
    
    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  main( )                                                                 *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    void main( void ) 
    {
        /* Initialize BSL */
        USBSTK5505_init( );
    	
    	/* Initialize PLL */
    	pll_frequency_setup(100);
    
        /* Initialise hardware interface and I2C for code */
        aic3204_hardware_init();
        
        /* Initialise the AIC3204 codec */
    	aic3204_init(); 
    
        /* izvodenje*/
        printf("izvodenje je pocelo");
    	
    	/* Setup sampling frequency and 0dB gain for microphone */
        set_sampling_frequency_and_gain(SAMPLES_PER_SECOND, 0);	
      
        //asm(" bclr XF");
        
       //Postavljanje elemenata matrica na 0
    	for ( sample = 0 ; sample < wlen ; sample++ ){
                	novi_desni[sample]=0;
                	pomocna[sample]=0;
        	for ( i = 0 ; i < S ; i++ ){
                za_obraditi_desni[sample][i]=0;
        	}
        }	
       
    //Ono sa neta
               //Matrica Mel filtara
               for(i=0 ; i < wlen ; i++){
               		for(j=0 ; j < nfilt ; j++){
               		filters[i][j]=0;      //inicijalizacija na nule
               		}
               }
               
               dfreq = samprate / nfft;	 // nfft je sto je bio N u MATLAB-u															//Ovo sam kopirao samo reda radi,
    /*           if (upperf > samprate/2){	// upperf i lowerf se moraju modificirati po�to je sad samprate 3 x veci pa moraju i oni biti														//jer ce uvjet nece nikada biti ispunjen
               	printf("\nGornja frekvencija %f je veca od Nyquistove %f" , upperf, samprate/2);	//
               }*/   //nemoe� printat nesto na screen ako nema screena
    	
    			melmax = 2595 * log10(1 + upperf / 700);
    			melmin = 2595 * log10(1 + lowerf / 700);
    			dmelbw = (melmax - melmin) / (nfilt + 1);
    			
    			//Rubovi filtara u Hz
    			for(i=0 ; i < 42 ; i++){
    				arange[i]=i;
    			}
    			for(i=0 ; i < 42 ; i++){
    			filt_edge[i]=700. * (pow(10., (melmin+dmelbw*arange[i]) / 2595.) - 1.);
    			}
    			for(whichfilt=0 ; whichfilt < nfilt ; whichfilt++){
    				//Filter trokuti u DFT tockama
    				leftfr = filt_edge[whichfilt]/dfreq;
    				centerfr = _nround(filt_edge[whichfilt + 1] / dfreq);
    				rightfr = _nround(filt_edge[whichfilt + 2] / dfreq);
    				fwidth = (rightfr - leftfr) * dfreq;
    				height = 2. / fwidth;
    				if (centerfr != leftfr) 
                      leftslope = height / (centerfr - leftfr); 
                  	else
                      leftslope = 0;
    				freq = leftfr + 1;
    				while (freq < centerfr){ 
                       filters[freq][whichfilt] = (freq - leftfr) * leftslope; 
                       freq = freq + 1;
    				}
    				if (freq == centerfr){ // This is always true 
                       filters[freq][whichfilt] = height; 
                       freq = freq + 1;
    				}
    				if (centerfr != rightfr){ 
                       rightslope = height / (centerfr - rightfr);
    				}
    				while (freq < rightfr){ 
                       filters[freq][whichfilt] = (freq - rightfr) * rightslope; 
                       freq = freq + 1;
    				}				
    			}
    
    	//Snimanje i spremanje u matricu
    	//for(i=0 ; i < 5 ; i++)
    	while(1)
    	{
    			//Snima se 0.5 sekunda -> 0.5L
        	for ( i = 0  ; i < SAMPLES_PER_SECOND * 0.5L  ;i++  )
     		{
    
         	aic3204_codec_read(&left_input, &right_input); // Configured for one interrupt per two channels.
       
         	mono_input = stereo_to_mono(left_input, right_input);
         	
         	novi_desni[i]= mono_input;
     		}
    
              	S=0; //brojac dijelova audio signala
       			for (j=0; j <(samprate-320) ; j=j+160)
        		{
        			for(i=0; i<wlen ; i++){
        				za_obraditi_desni[i][S]=novi_desni[j+i];
        			}
            		S=S++;
                }
    			S=S--;
    			za_obradu = &za_obraditi_desni[0][0];
    			
    		
               //Izgradnja Hammingovog prozora
     //          wlen = wlen * samprate; //fali (int)
               
               for (i=0 ; i < wlen ; i++){
               		win[i]=0.54-0.46*pi*cos(2*(i-1)/(wlen-1));
               }
               
               //Mno�enje uzoraka sa Hammingovim prozorom
               for (i = 0 ; i < S ; i++){
               	for (j = 0 ; j < wlen ; j++){
               		za_obraditi_desni[j][i]=za_obraditi_desni[j][i]*win[i];
               	}
               }
    // ovdje bio komad koda za filtere racunat sad je prije while petlje
    			
    			//Izrada DCT matrice
    			//mo�da najbolje iz onog naseg iz MATLAB-a pod pretpostavkom da je matrica filtera ovdje filters
    			
    			// FFT
    			rfft(za_obradu, nfft, NOSCALE);
    
    			//apsolutna vrijednost i kvadrat svakog elementa matrice
    			for(i=0; i < S; i++){
    				for(j=0; j < wlen; j++){
    					 za_obraditi_desni[i][j] = pow(fabs(za_obraditi_desni[i][j]),2);
    				} // koristim iste 2 matrice za cijelu obradu zbog ogranicenja memorije na MCU
    			}
    			// mnozenje spektra snage sa svakim trokutastim filtrom zasebno
    			for(j=0; j < S; j++){
        			for(i=0; i < nfilt; i++){
        				for(p=0; p < wlen; p++){
        					//ove dve matrice monozit u petlji
            				pomocna[p] = pomocna[p]+(za_obraditi_desni[j][p]*filters[i][p]);
        				}
        			}
       // vidi dal ces tu koristiti pointere ili bas te matrice - MATRICE??!!
        			for(p=0; p < wlen; p++){
     	  				za_obraditi_desni[j][p]= pomocna[p];
        				pomocna[p] = 0;
     	  			}
    			}
    			
    			// Diskretna kosinusna transformacija DCT
    			for(i=0; i < S; i++){
    				for(j=0; j < ncep; j++){
    					mfcc[i][j] = 0;
    				}
    			}
    
    			for(j=0; j < S; j++){
    				obrada=&za_obraditi_desni[j][0];
    				pom=&pomocna[0];
    				logn(obrada,pom,wlen);
        			for(p=0; p < ncep; p++){
            			for(i=0; i < wlen; i++){
                			if(za_obraditi_desni[i][j] != 0){
                				mfcc[p][j]=mfcc[p][j] +pomocna[i] * cos(pi*(p-1)/2/wlen*(2*(i-1)+1));
                			}
        			    }
       			 	}
    			}
    	}
    
    }
    
    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  End of main.c                                                           *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    

    Oh and I didn't modify the linkx.cmd file becouse it already allocates everything like i want it to. And in the current state all of my matrices take up only 86,54 kB. I hope that the extra functions don't take up all the remaining space. That's one thing I'll try to remove all the unnecessary files because i based this program on the getting started (section 1) program from the C5000 Teaching ROM.

     

    Thanks again

  •  Right after starting or in some particular place in code? I guess you haven't try to debug step by step to find line which cause error? I can only suppose that linker file should be modified to use FFT from dsplib. Add to linker file that line:

    .data:twiddle : > SARAM2, align(2048)

    Of course  in align put number that fit to your code.

    regards

    MS

  • I tried to add the line

    .data: twiddle: > SARAM2, align (256)

    to the lnkx.cmd file, but still got the error message. Then I just put the following line

    .fftcode  >  SARAM2

    to the lnkx.cmd file, and the problem was solved. No error message. Why is that? Why didn't CCS automatically allocate the memory for the RFFT?

    This is the whole lnkx.cmd file:

    8741.lnkx.txt
    /******************************************************************************/
    /* LNKX.CMD - COMMAND FILE FOR LINKING C PROGRAMS IN LARGE/HUGE MEMORY MODEL  */
    /*                                                                            */
    /* Usage:                                                                     */
    /*  cl55 <src files> -z -o<out file> -m<map file> lnkx.cmd -l<RTS library>   */
    /*                                                                            */
    /* Description: This file is a sample command file that can be used for       */
    /*              linking programs built with the C Compiler.  Use it as a      */
    /*              guideline; you  may want to change the allocation scheme      */
    /*              according to the size of your program and the memory layout   */
    /*              of your target system.                                        */
    /*                                                                            */
    /*   Notes: (1) You must specify the directory in which <RTS library> is      */
    /*              located.  Either add a "-i<directory>" line to this file      */
    /*              file, or use the system environment variable C55X_C_DIR to    */
    /*              specify a search path for the libraries.                      */
    /*                                                                            */
    /******************************************************************************/
    
    -stack    0x2000      /* Primary stack size   */
    -sysstack 0x1000      /* Secondary stack size */
    -heap     0x2000      /* Heap area size       */
    
    -c                    /* Use C linking conventions: auto-init vars at runtime */
    -u _Reset             /* Force load of reset interrupt handler                */
    
    /* SPECIFY THE SYSTEM MEMORY MAP */
    
    MEMORY
    {
     PAGE 0:  /* ---- Unified Program/Data Address Space ---- */
    
      MMR    (RWIX): origin = 0x000000, length = 0x0000c0  /* MMRs */
      DARAM0 (RWIX): origin = 0x0000c0, length = 0x00ff40  /*  64KB - MMRs */
      SARAM0 (RWIX): origin = 0x010000, length = 0x010000  /*  64KB */
      SARAM1 (RWIX): origin = 0x020000, length = 0x020000  /* 128KB */
      SARAM2 (RWIX): origin = 0x040000, length = 0x00FE00  /*  64KB */
      VECS   (RWIX): origin = 0x04FE00, length = 0x000200  /*  512B */
      PDROM   (RIX): origin = 0xff8000, length = 0x008000  /*  32KB */
      
     PAGE 1: 
     
      EXTERNAL (RWIX): origin = 0xc00000, length = 0x200000
    
     PAGE 2:  /* -------- 64K-word I/O Address Space -------- */
    
      IOPORT (RWI) : origin = 0x000000, length = 0x020000
    }
     
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
    
    SECTIONS
    {
       .text     >> SARAM1|SARAM2|SARAM0  /* Code                        */
    
       /* Both stacks must be on same physical memory page               */
       .stack    >  DARAM0                /* Primary system stack        */
       .sysstack >  DARAM0                /* Secondary system stack      */
    
       .data     >> DARAM0|SARAM0|SARAM1  /* Initialized vars            */
       /*.data: twiddle: > SARAM2, align (256)*/
       .bss      >> DARAM0|SARAM0|SARAM1  /* Global & static vars        */
       .const    >> DARAM0|SARAM0|SARAM1  /* Constant data               */
       .sysmem   >  DARAM0|SARAM0|SARAM1  /* Dynamic memory (malloc)     */
       .switch   >  SARAM2                /* Switch statement tables     */
       .cinit    >  SARAM2                /* Auto-initialization tables  */
       .pinit    >  SARAM2                /* Initialization fn tables    */
       .cio      >  SARAM2                /* C I/O buffers               */
       .args     >  SARAM2                /* Arguments to main()         */
       .fftcode  >  SARAM2
       
    
        vectors  >  VECS                  /* Interrupt vectors           */
    
       .ioport   >  IOPORT PAGE 2         /* Global & static ioport vars */
    }

    I've also reduced the sampling rate to 16kHz in order to save memory space, but I will probably need more later, since I will have to use FLOAT and DOUBLE format for the functions.. The TSM320VC5505 is supposed to have a total of 16 MB of memory.  So how do I use all of this memory other than the on chip memory  ~320 kB?

    There is another problem. When I try to build the Hamming window with

    for (i=0 ; i < wlen ; i++){

           win[i]=0.54-0.46*cos((double)(2*(i-1)/(wlen-1)));

    }

     All the values in win[] are 0. It's like CCS recognizes 0.54 and 0.46 as  0. I also tried it with

     for (i=0 ; i < wlen ; i++){

            win[i]=ham1-ham2*cos((double)(2*(i-1)/(wlen-1)));

               }

    Where ham1 and ham2 are defined

    float ham1=0.54, ham2=0.46;

    but i get the same. Is this because of the fixed – point arithmetics, and how do I solve this?

    Also, the cos() function returns incorrect values (i checked it with my calculator for rad and deg).

    This the whole code:

    3173.MFCmain.txt
    #include "stdio.h"
    #include "usbstk5505.h"
    #include "aic3204.h"
    #include "PLL.h"
    #include "stereo.h"
    #include "Dsplib.h"
    #include "math.h"
    
    Int16 left_input;
    Int16 right_input;
    Int16 left_output;
    Int16 right_output;
    Int16 mono_input;
    
    
    #define SAMPLES_PER_SECOND 16000
    #define pi 3.1415926535897932384626433832795028841971693993751
    #define nfilt 40
    
    void *za_obradu, *obrada, *pom;
    Uint16 i, j, p, whichfilt, freq,sample, S;
    float ham1=0.54, ham2=0.46;
    float novi_desni[4000], pomocna[400], mfcc[23][13],za_obraditi_desni[400][23];
    float ncep=13,lowerf=133.3333, upperf=6855.4976, wlen=400, melmax, melmin, dmelbw, samprate=16000, nfft=256, dfreq, leftfr, centerfr, rightfr, fwidth, height, leftslope, rightslope;
    float filters[400][40], win[400],  arange[42], filt_edge[42];
    double time= 1;
    
    
    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  main( )                                                                 *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    void main( void ) 
    {
        /* Initialize BSL */
        USBSTK5505_init( );
    	
    	/* Initialize PLL */
    	pll_frequency_setup(100);
    
        /* Initialise hardware interface and I2C for code */
        aic3204_hardware_init();
        
        /* Initialise the AIC3204 codec */
    	aic3204_init(); 
    
        /* izvodenje*/
        printf("izvodenje je pocelo \n");
    	
    	/* Setup sampling frequency and 0dB gain for microphone */
        set_sampling_frequency_and_gain(SAMPLES_PER_SECOND, 0);	
      
        //asm(" bclr XF");
        
       //Postavljanje elemenata matrica na 0
    	for ( sample = 0 ; sample < wlen ; sample++ ){
                	pomocna[sample]=0;
        	for ( i = 0 ; i < S ; i++ ){
                za_obraditi_desni[sample][i]=0;
        	}
        }
        for(sample = 0 ; sample < 8000 ; sample++){
        	novi_desni[sample]=0;}
       
    //Ono sa neta
               //Matrica Mel filtara
               for(i=0 ; i < wlen ; i++){
               		for(j=0 ; j < nfilt ; j++){
               		filters[i][j]=0;      //inicijalizacija na nule
               		}
               }
               
               dfreq = samprate / nfft;	 // nfft je sto je bio N u MATLAB-u															//Ovo sam kopirao samo reda radi,
    /*           if (upperf > samprate/2){	// upperf i lowerf se moraju modificirati po�to je sad samprate 3 x veci pa moraju i oni biti														//jer ce uvjet nece nikada biti ispunjen
               	printf("\nGornja frekvencija %f je veca od Nyquistove %f" , upperf, samprate/2);	//
               }*/   //nemoe� printat nesto na screen ako nema screena
    	
    			melmax = 2595 * log10(1 + upperf / 700);
    			melmin = 2595 * log10(1 + lowerf / 700);
    			dmelbw = (melmax - melmin) / (nfilt + 1);
    			
    			//Rubovi filtara u Hz
    			for(i=0 ; i < 42 ; i++){
    				arange[i]=i;
    			}
    			for(i=0 ; i < 42 ; i++){
    			filt_edge[i]=700. * (pow(10., (melmin+dmelbw*arange[i]) / 2595.) - 1.);
    			}
    			for(whichfilt=0 ; whichfilt < nfilt ; whichfilt++){
    				//Filter trokuti u DFT tockama
    				leftfr = filt_edge[whichfilt]/dfreq;
    				centerfr = _nround(filt_edge[whichfilt + 1] / dfreq);
    				rightfr = _nround(filt_edge[whichfilt + 2] / dfreq);
    				fwidth = (rightfr - leftfr) * dfreq;
    				height = 2. / fwidth;
    				if (centerfr != leftfr) 
                      leftslope = height / (centerfr - leftfr); 
                  	else
                      leftslope = 0;
    				freq = leftfr + 1;
    				while (freq < centerfr){ 
                       filters[freq][whichfilt] = (freq - leftfr) * leftslope; 
                       freq = freq + 1;
    				}
    				if (freq == centerfr){ // This is always true 
                       filters[freq][whichfilt] = height; 
                       freq = freq + 1;
    				}
    				if (centerfr != rightfr){ 
                       rightslope = height / (centerfr - rightfr);
    				}
    				while (freq < rightfr){ 
                       filters[freq][whichfilt] = (freq - rightfr) * rightslope; 
                       freq = freq + 1;
    				}				
    			}
    
    	//Snimanje i spremanje u matricu
    	//for(i=0 ; i < 5 ; i++)
    	while(1)
    	{
    		printf("petlja radi\n");
    			//Snima se 0.5 sekunda -> 0.5L
        	for ( i = 0  ; i < SAMPLES_PER_SECOND * 0.25L  ;i++  )
     		{
    
         	aic3204_codec_read(&left_input, &right_input); // Configured for one interrupt per two channels.
       
         	mono_input = stereo_to_mono(left_input, right_input);
         	
         	novi_desni[i]= mono_input;
     		}
    
              	S=0; //brojac dijelova audio signala
       			for (j=0; j <(8000-320) ; j=j+160)
        		{
        			for(i=0; i<wlen ; i++){
        				za_obraditi_desni[i][S]=novi_desni[j+i];
        			}
            		S++;
                }
    			S--;
    			za_obradu = &za_obraditi_desni[0][0];
    			
    		
               //Izgradnja Hammingovog prozora
     //          wlen = wlen * samprate; //fali (int)
               
               for (i=0 ; i < wlen ; i++){
               		win[i]=ham1-ham2*cos((double)2*(i-1)/(wlen-1));
               }
               time=cos((double)(2*(250-1)/(wlen-1)));
               
               //Mno�enje uzoraka sa Hammingovim prozorom
               for (i = 0 ; i < S ; i++){
               	for (j = 0 ; j < wlen ; j++){
               		za_obraditi_desni[j][i]=za_obraditi_desni[j][i]*win[i];
               	}
               }
    // ovdje bio komad koda za filtere racunat sad je prije while petlje
    			
    			//Izrada DCT matrice
    			//mo�da najbolje iz onog naseg iz MATLAB-a pod pretpostavkom da je matrica filtera ovdje filters
    			
    			// FFT
    			rfft(za_obradu, nfft, SCALE);
    			printf("petlja POSLJE FFT\n");
    
    			//apsolutna vrijednost i kvadrat svakog elementa matrice
    			for(i=0; i < S; i++){
    				for(j=0; j < wlen; j++){
    					 za_obraditi_desni[i][j] = pow(fabs(za_obraditi_desni[i][j]),2);
    				} // koristim iste 2 matrice za cijelu obradu zbog ogranicenja memorije na MCU
    			}
    			// mnozenje spektra snage sa svakim trokutastim filtrom zasebno
    			for(j=0; j < S; j++){
        			for(i=0; i < nfilt; i++){
        				for(p=0; p < wlen; p++){
        					//ove dve matrice monozit u petlji
            				pomocna[p] = pomocna[p]+(za_obraditi_desni[j][p]*filters[i][p]);
        				}
        			}
       // vidi dal ces tu koristiti pointere ili bas te matrice - MATRICE??!!
        			for(p=0; p < wlen; p++){
     	  				za_obraditi_desni[j][p]= pomocna[p];
        				pomocna[p] = 0;
     	  			}
    			}
    			
    			// Diskretna kosinusna transformacija DCT
    			for(i=0; i < S; i++){
    				for(j=0; j < ncep; j++){
    					mfcc[i][j] = 0;
    				}
    			}
    
    			for(j=0; j < S; j++){
    				obrada=&za_obraditi_desni[j][0];
    				pom=&pomocna[0];
    				logn(obrada,pom,wlen);
        			for(p=0; p < ncep; p++){
            			for(i=0; i < wlen; i++){
                			if(za_obraditi_desni[i][j] != 0){
                				mfcc[p][j]=mfcc[p][j] +pomocna[i] * cos(pi*(p-1)/2/wlen*(2*(i-1)+1));
                			}
        			    }
       			 	}
    			}
    	}
    
    }
    
    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  End of main.c                                                           *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    


    Thank you in advance.

  • ok, I have figured some of these things out. but now i have a new question.

    As you saw i use rfft from Dsplib. And now I get  to the rfft with no problem but the rfft gives me on output the value -1.#QNAN for some samples and of course that interferes  with the following calculations so that the program gets stuck/fails. I am wondering what is the reason so i went into the command with the debugger and it gave me this message:

    Source not found.

    and at the opened tab was the name: 0 $cfft_noscale.asm:90:681$() at cfft_noscale.asm:90 0x0433ac

     

    If this means that it can't find the function why does it give any output at all. I have in my project the library that should support. the header file dsplib.h says: Header file for DSPLIB library on the TMS320VC5505 USB Stick.

    and i have these librarys:

    55xdsph.lib

    CSLc55x5h.lib

     

    thanks again.