Filter löschen
Filter löschen

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

2 Ansichten (letzte 30 Tage)
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?

Akzeptierte Antwort

Kaustubha Govind
Kaustubha Govind am 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 Kommentare
Andreas Prokopiou
Andreas Prokopiou am 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 am 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);

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (3)

Andreas Prokopiou
Andreas Prokopiou am 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 Kommentar
Kaustubha Govind
Kaustubha Govind am 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.

Melden Sie sich an, um zu kommentieren.


Andreas Prokopiou
Andreas Prokopiou am 1 Mär. 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 Kommentare
Kaustubha Govind
Kaustubha Govind am 1 Mär. 2011
Did you try by specifying all relevant inputs: dt and OMEfilters as constant inputs using emlcoder.egc?
Andreas Prokopiou
Andreas Prokopiou am 1 Mär. 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?

Melden Sie sich an, um zu kommentieren.


Fred Smith
Fred Smith am 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!

Translated by