-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
topology: Fix dmic nhlt blob building, and fix $[] attribute value resolving #250
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good and all changes work perfectly for me. Thanks for fixing these!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One potential issue in first patch, see inline.
Also, a bit more clarification where the second patch is needed would help. I get this is needed to simply the dmic rules. Maybe a reference to a PR that would be using this PR would help?
@@ -853,8 +853,12 @@ static int configure_registers(struct intel_dmic_params *dmic, struct dmic_calc_ | |||
MIC_CONTROL_PDM_EN_A(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo in commit: clock diver -> clock divider
/* | ||
* Here we have to check the both FIRs if they are | ||
* configured as the later configured DAI may have changed | ||
* the configuration of the DAI configurer earlier. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typoe: configurer -> configured
ret = pre_process_find_variable(dst, var, conf_defines); | ||
free(var); | ||
return ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we "snd_config_delete(*dst)" also in this case won L1623...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I don't think so. The *dst is passed to the caller and it should do what is necessary (however a string value in $[] is probably an error). The reason why I have to delete *dst here is because I reuse *dst to store the result of the defines search and the pointer holding the result of object attribute search may be lost.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then again a paranoid programmer would check strdup() result and return -ENOMEM in case its NULL. But since this is a commmand line tool, and there is probably some out of memory error produced by libc, I do not think its necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could this be a recursive case like
channels $CHANNELS
sample_bits $channel * 4
frame_bits "$[$channels * $sample_bits]"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe someone may look, if tplg_evaluate_config_string
can be replaced with snd_config_evaluate_string
implementation from alsa-lib.
EDIT: My point was that tplg_evaluate_config_string
may be used here recursively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I think about it, I guess it could be that the object attribute is an expression of form $ [channels * 4] , plain $channels *4 should not be allowed. But yes, a recursive call to snd_config_evaluate_string() should do it.
About @perexg 's question, there is a functional difference in tplg_evaluate_config_string() and snd_config_evaluate_string(). tplg_evaluate_config_string() expands $ VAR_NAME occurrences in the middle of the string, unlike plain snd_config_evaluate_string(). However, the functionality could probably be moved to snd_config_evaluate_string().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be also more elegant to use snd_config_remove
+ snd_config_delete
combo rather than duplicating the already allocated string.
snd_config_t *tmp = *dst;
snd_config_remove(*tmp); // detach from the configuration tree
snd_config_evaluate_string(dst, val, ....);
snd_config_delete(*tmp);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not yet too fluent with snd_config_* -functions, but is the remove necessary in this case, where the *dst is already a product of snd_config_copy()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I have read the code back and forth a bit, I am pretty sure the remove is unnecessary for a node, that has just been copied with snd_config_copy(). However, @perexg if you still think that it is good coding practice to add it there, then certainly I will.
The dmic configuration functions are called for each dmic DAI (or FIFO) separately, and each dmic DAI is configured in their own configuration rounds. However, the later configured dmic FIFO may change the common clock divider and thus affect the FIR configuration of the first configured DAI. However, the first configured FIR blob is not touched after it is configured for the first time. To overcome this problem always check the both FIR configurations, no matter which DAI we are configuring. Suggested-by: Seppo Ingalsuo <[email protected]> Signed-off-by: Jyri Sarha <[email protected]>
Its needed for example when $ DMIC0_RATE is used in audio_format topology object's in_rate attribute. That is because the attribute is also used in ibs attrbute in $[] expression: Without this change its not possible to put DMIC sample rate completely behind a single define. |
Changed since previous version. Make a receive call to snd_config_evaluate_string(), instead of just checking for a global define reference. |
80cb9aa
to
ef6a5b0
Compare
Yet one more version that expands also $-expressions found from defines, e.g. this allows:
Where Object.Base.foo_bar.bar would get value 2 * 2 * 2 * 2 = 16. However, its worth mentioning that our nhlt code, which what we were working on when this need was recognized, is not able to handle $-expressions found from behind a define. This is fixable thou, and I have hackish code to do it, but I am not sure the added complexity is justified just for the sake of completeness. At least I would need to clean it up first. |
@@ -1589,6 +1589,7 @@ pre_process_object_variables_expand_fcn(snd_config_t **dst, const char *str, voi | |||
snd_config_t *object_cfg = tplg_pp->current_obj_cfg; | |||
snd_config_t *conf_defines; | |||
const char *object_id; | |||
const char *val; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jsarha will this still work if you had the object defined like this instead?
Object.Base.foo {
channels $CHANNELS
frame_bits "$[$channels * $sample_bits]"
sample_bits $BIT_DEPTH
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that works after this change.
This is the original problem the "topology: Expand attribute references inside $[] expressions"-commit is fixing. E.g. allow Object.Base.input_audio_format.in_rate be defined as $DMIC0_RATE
, without breaking input_audio_format.ibs "$[($in_channels * ($[($in_rate + 999)] / 1000)) * ($in_bit_depth / 8)]"
.
@jsarha The 2ch DMIC config can't work, on 4ch, do you know why ? |
Sorry, I do not follow. Some problem in 2ch DMIC nhlt blob generation in a topology that has 4ch DMIC? Can you explain how exactly can trigger this problem? And if the issue is not directly related to this PR, then it would probably be best to create a SOF issue to track it. |
Sorry, I meant that 2ch DMIC blob can't work. The generated DMIC blob is still 4ch case |
I find the reason, thanks. Need to disable ENABLE_A & ENABLE_B for PDM1 |
if (ret < 0) | ||
SNDERR("Failed to find definition for attribute %s in '%s' object\n", | ||
str, object_id); | ||
/* the extracted value may contain a nested $-expression */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can happen only in the case of a variable that points to a object attribute right? So can we move this block inside the previous if block after like 1612?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 , is there any reason for us to forbid $[]
-expressions in the global definitions? I can imagine that could be handy sometimes. If we allow that then we need to check for $[]
-strings also in the global definitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jarsha its not that we want to forbid but it's not really useful isn't it? The global definitions are all known prior to building all objects. So, having references to other globals is the only option and that seems futile isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 , I don't think the preprocessor works that way. The top level definitions are never resolved for $
-expression on their own, but only when references to them are found in object attribute values. And when they are resolved there, they can in turn refer to other object attributes found in the same object. E.g. I can define
Define {
MY_OBS_DEF "$[($out_channels * ($[($out_rate + 999)] / 1000)) * ($out_bit_depth / 8)]"
}
And then in
Class.Base."audio_format" {
...
obs "$MY_OBS_DEF"
}
I tested that this work.
I can imagine that there could be some use for some common expressions defined at top-level, relying on generic object attributes, and used in several objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but does that even make sense. Have a global definition that uses a local attribute definition? The other way around makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see some sense in that, but if you don't, that is good enough. We can very well live without this "feature". I'll disable it.
Properly expand referred object attributes inside $[] expression. This allows for example this simplified case: Define { CHANNELS 2 BIT_DEPTH 16 } Object.Base.foo { channels $CHANNELS sample_bits $BIT_DEPTH frame_bits "$[$channels * $sample_bits]" } Reported-by: Seppo Ingalsuo <[email protected]> Signed-off-by: Jyri Sarha <[email protected]>
Signed-off-by: Jyri Sarha <[email protected]>
In the latest version I:
|
@kv2019i @ranj063 @RanderWang Please re-review this. We can't merge patches to SOF without having these issues fixed. |
i'm good with this one. Thanks @jsarha |
We now have the relevant approvals from Intel people. I think this could be ready for merge. @perexg , what do you think? |
Properly expand referred object attributes inside $[] expression. This allows for example this simplified case: Define { CHANNELS 2 BIT_DEPTH 16 } Object.Base.foo { channels $CHANNELS sample_bits $BIT_DEPTH frame_bits "$[$channels * $sample_bits]" } Closes: #250 Reported-by: Seppo Ingalsuo <[email protected]> Signed-off-by: Jyri Sarha <[email protected]> Signed-off-by: Jaroslav Kysela <[email protected]>
Closes: #250 Signed-off-by: Jyri Sarha <[email protected]> Signed-off-by: Jaroslav Kysela <[email protected]>
This PR fixes two issues. FIrst it fixes thesofproject/sof#8670 and then it adds to $[] expressions define handling in object attribute, so that we can use DMIC frequency defines in format objects, wihout ibs and obs attributes referring to those attributes breaking it.