Clear Filters
Clear Filters

Using emlc to generate C code - function within a function problem

2 views (last 30 days)
Hello fellow Matlab users,
Ive been trying to convert a massive code from matlab to c and implement it for real time signal processing on a DSP processor.
So far ive been succesfull and emlc is an amazing function! The problem i have reached now is that I need to compile a code that has the function "butter" inside (gives out butterworth filter coefficients.)
The problem is that the compilation report complains about butter`s input arguments are not constant.
To make things a bit more clear:
C_generating_script.m => Function_1.m => butter.m
Now my question is:
How can I define/declare the inputs of the butter function as constants which is within another function and allow it to compile?

Accepted Answer

Kaustubha Govind
Kaustubha Govind on 24 Feb 2011
Have you tried specifying constant inputs using emlcoder.egc: http://www.mathworks.com/help/toolbox/eml/ug/bq2wkmb-47.html#brl11_g-1
  2 Comments
Andreas Prokopiou
Andreas Prokopiou on 25 Feb 2011
yes but im not quite sure where i need to make this declaration.
The function that complains about constant inputs (butter.m) is within another function (ParamGen.m) and ParamGen.m is the one I want to compile to C
Kaustubha Govind
Kaustubha Govind on 25 Feb 2011
Could you give a simple example of what you are doing? I tried the following, and it compiled without using emlcoder.egc:
-------- mytest.m ----------
function [b, a] = mytest
%#codegen
n = 4; Wn = 0.5;
a = zeros(1,5);
b = zeros(1,5);
[b a] = subfun(n,Wn);
-------- subfun.m ----------
function [b a] = subfun(n, Wn)
%#codegen
[b a] = butter(n, Wn);

Sign in to comment.

More Answers (3)

Andreas Prokopiou
Andreas Prokopiou on 27 Feb 2011
I have changed a bit the organization of the code but I still get the same problem. Here`s the section of the code that doesn`t get converted to C:
The function call is:
parameters = MAP_ParamGen(dt,fasterdt,CF_of_channel,audiotimeofblock);
takes in as input 4 double floats and gives out a struct with around 150 entries
This is the c-generating code im using:
emlc -eg {dt,fasterdt,CF_of_channel,audiotimeofblock } MAP_ParamGen.m -c -T RTW -report
the error comes from:
function [PARAMS] = MAP_ParamGen(dt,fasterdt,CF_of_channel,audiotimeofblock) %#eml
.
.
.
cutOffFrequency = 100;
order = 1;
sampleRate=1/dt;
Nyquist=sampleRate/2;
[PARAMS.OME_b_low,PARAMS.OME_a_low] = butter(order, cutOffFrequency/Nyquist, 'low');
.
.
.
  1 Comment
Kaustubha Govind
Kaustubha Govind on 28 Feb 2011
You should use:
emlc -eg {emlcoder.egc(dt),fasterdt,CF_of_channel,audiotimeofblock } MAP_ParamGen.m -c -T RTW -report
To specify that 'dt' as a constant, since this determines one of the inputs to butter.

Sign in to comment.


Andreas Prokopiou
Andreas Prokopiou on 1 Mar 2011
It works! Thank you! I finally understand how the constant declaration works.
I have another problem now though:
.
.
.
OMEfilters = [0 900 1;2 800 2;0 900 3;2 800 4];
sampleRate=1/dt;
Nyquist=sampleRate/2;
[nFilters nValues]=size(OMEfilters);
for i=1:nFilters
gaindB(i)=OMEfilters(i,1);
lowCutOff=OMEfilters(i,2);
filterOrder(i)=OMEfilters(i,3);
if nValues>3
highCutOff=filters(i,4);
else
highCutOff=sampleRate/3;
end
[b_high,a_high] = butter(filterOrder(i), [lowCutOff highCutOff] /Nyquist);
for j = 1:filterOrder(i)*2+1
OME_b_high(i,j) = b_high(j);
OME_a_high(i,j) = a_high(j);
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
All of the sizes of arrays are well defined and there is no problem there. Again it complains about constant inputs. Is it because the input value to the function changes per for loop iteration? if yes,Is there a way to resolve this without unravelling the for loop?
  2 Comments
Kaustubha Govind
Kaustubha Govind on 1 Mar 2011
Did you try by specifying all relevant inputs: dt and OMEfilters as constant inputs using emlcoder.egc?
Andreas Prokopiou
Andreas Prokopiou on 1 Mar 2011
Yes, In fact OMEfilters is contained within the MAP_ParamGen.m file which im compiling so emlc should be able to "see" that that parameter will not change.
As far as I can tell is exactly the same situation as before with the only difference the for loop and the if statement.
I tried fixing the highCutOff so it doesnt go through the if statement thus not allowing it two execution paths but there is still an error.
The error seems to be because the inputs to the 'butter' function change at every for loop iteration even though they are defined within the same function as a constant value. Is this something that is not possible to convert to C?
Is there a way to define within the compiled function that a certain parameter might change value but not type?

Sign in to comment.


Fred Smith
Fred Smith on 14 Jul 2011
Try using eml.unroll on the for-loop. That will cause the loop to be unrolled in the generated code.
This may or may not be acceptable depending on how many iterations the loop has. If it is not acceptable then you need a butter function that supports non-constant inputs. That capability is not available today.
If that is what you need, could you explain your use case and we'll create an enhancement request to add this capability to the product.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!