AIMP Forum

AIMP для Windows => Дополнения (Plugins / Skins) => Разработка => Topic started by: Moshi0 on September 08, 2018, 03:59:55

Title: Data filtering in custom music library
Post by: Moshi0 on September 08, 2018, 03:59:55
So ive been trying to enable data filtering in my custom music library but I cant get it to work.

If I use AIMPML_DATASTORAGE_CAP_FILTERING flag I cant get the "quick search" string, it is always null.
I assume i just do
Code: [Select]
Filter->GetValueAsObject(AIMPML_FILTER_SEARCHSTRING, IID_IAIMPString, ...); in IAIMPMLDataProvider::GetData?
Or is this only used for smart playlists?

Preferably everything should be done by aimp, so i tried not using AIMPML_DATASTORAGE_CAP_FILTERING flag but then song list is always empty, event tho I get proper call to IAIMPMLDataProvider::GetData and return valid data. Is this a bug or am I missing something?
Title: Re: Data filtering in custom music library
Post by: Artem on September 08, 2018, 09:20:18
It must works correctly, because filtering works correctly in MyClouds and Podcasts plugins.
Please, can you provide a sample for me? I will check what goes wrong on AIMP's side
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 08, 2018, 14:31:19
aimp_ml_sample_with_flag.zip: Has AIMPML_DATASTORAGE_CAP_FILTERING capability flag set and im trying to get the "quick search" string in IAIMPMLDataProvider::GetData but its always null.
aimp_ml_sample_without_flag.zip: Has capabilities set to 0, the same data is returned but its not visible in the list.

Thanks for help.
Title: Re: Data filtering in custom music library
Post by: Artem on September 08, 2018, 21:54:32
Your plugins required debug versions of VS Runtime libraries - MSVCP140D.dll and VCRUNTIME140D.dll. I cannot run the plugin because I have VS2012 on my PC
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 08, 2018, 22:58:21
You plugins required debug versions of VS Runtime libraries - MSVCP140D.dll and VCRUNTIME140D.dll. I cannot run the plugin because I have VS2012 on my PC

Hmm, well I am on vs2017 and it seems you cant drop to lower toolkit without installing older visual studio.
I recompiled as release, i assume you have non-debug v140 redist.
Title: Re: Data filtering in custom music library
Post by: Artem on September 08, 2018, 23:27:08
in 1st case, looks like I have found a bugs in C++ version of SDK, following constants must be:

Quote
const int AIMPML_FILTER_LIMIT           = 11;
const int AIMPML_FILTER_OFFSET          = 12;
const int AIMPML_FILTER_SORTBY          = 13;
const int AIMPML_FILTER_SORTDIRECTION   = 14; // Refer to the AIMPML_SORTDIRECTION_XXX
const int AIMPML_FILTER_SEARCHSTRING    = 20; // optional
const int AIMPML_FILTER_ALPHABETICINDEX = 21; // optional

in 2nd case, AIMP tries to filter content by NodeID field from grouping tree, but content for table returns items with different NodeId values. So, player have find no matches. I think, will be better to introduce the ParentID field (internal), that will bind grouping tree items with table items.
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 09, 2018, 01:40:14
in 1st case, looks like I have found a bugs in C++ version of SDK, following constants must be:

Yup, that was the fix.

in 2nd case, AIMP tries to filter content by NodeID field from grouping tree, but content for table returns items with different NodeId values. So, player have find no matches. I think, will be better to introduce the ParentID field (internal), that will bind grouping tree items with table items.

So I just set NodeId in table items to be equal to the parent id in tree as I dont really need it since I can use TrackId field for identification.
But that does seem to only work for root grouping node, children still have empty table. Do I have to build a full path to the grouping tree node?
Attached sample.
Title: Re: Data filtering in custom music library
Post by: Artem on September 10, 2018, 08:15:53
Do I have to build a full path to the grouping tree node?

Or try to set the AIMPML_GROUPINGTREENODE_FLAG_STANDALONE flag for grouping tree items (refer to the IAIMPMLGroupingTreeDataProviderSelection article)
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 10, 2018, 13:46:58
Or try to set the AIMPML_GROUPINGTREENODE_FLAG_STANDALONE flag for grouping tree items (refer to the IAIMPMLGroupingTreeDataProviderSelection article)

Hmm, this will work, but I need full path for each grouping tree item ("root\child1\child12"). So I can only have the root nodes as standalone. Otherwise the selection will only contain the selected item id.
So how would I use full path as "NodeId"? "root\child1" or "root/child1" does not work.
Title: Re: Data filtering in custom music library
Post by: Artem on September 10, 2018, 22:57:54
Hmm, this will work, but I need full path for each grouping tree item ("root\child1\child12"). So I can only have the root nodes as standalone. Otherwise the selection will only contain the selected item id.
So how would I use full path as "NodeId"? "root\child1" or "root/child1" does not work.

Filtering like FilePath is available FileName field types only. I suggest you to introduce parentID field instead
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 10, 2018, 23:34:14
Filtering like FilePath is available FileName field types only. I suggest you to introduce parentID field instead

And what do I put in that ParentId field?

If I have a tree:

If I click on "child2" tree item, I need the selection to be [root, child2]. The selection can only work like that if the only standalone tree item is "root".
But what you are saying is, I cant set the "ParentId" field of list items to be equal to "child2" because "child2" tree node is not standalone and that will cause the filtering system to not show items in the list.

If I set all tree items as standalone, the filtering system works but the selection only contains the clicked tree item.

So it seems you can either have all tree items as standalone and filtering system, or if some items are not standalone you need to write your own filtering.
Am I understanding this correctly?
Title: Re: Data filtering in custom music library
Post by: Artem on September 11, 2018, 08:32:32
If I set all tree items as standalone, the filtering system works but the selection only contains the clicked tree item.

This is because you are filtering by NodeID, not ParentID, so it displays only current node.

So it seems you can either have all tree items as standalone and filtering system, or if some items are not standalone you need to write your own filtering.
Am I understanding this correctly?

If you want to use data from grouping tree as file name - you should use filename field type, because only in this case engine combines node path like file name path - root\child1\ and etc, for all other field types it build filter like: (nodeId = 'root') AND (nodeId = 'child1'), as you can see this filter make no sense.
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 11, 2018, 19:19:54
This is because you are filtering by NodeID, not ParentID, so it displays only current node.

I mean that if I set all nodes as standalone I wont get the full path in the selection, as in help:
"First element in the Selection is focused node. If current node does not have the AIMPML_GROUPINGTREENODE_FLAG_STANDALONE flag - the parent node will be added to Selection. Algorithm running until root or node with the AIMPML_GROUPINGTREENODE_FLAG_STANDALONE flag."

So I can only have the root node to be standalone, otherwise the selection will not be [root, child1, child12, ...], and will only contain the focused node.

Also, if I introduce another field "ParentId" what do I put there in IAIMPMLDataProviderSelection? How would it be different than just using "NodeId"?
It does not matter if the field is "NodeId" or "ParentId", I still have to put the grouping node id there. And it seems like the builtin filtering only works when the id I use is for standalone node.

If you want to use data from grouping tree as file name - you should use filename field type, because only in this case engine combines node path like file name path - root\child1\ and etc, for all other field types it build filter like: (nodeId = 'root') AND (nodeId = 'child1'), as you can see this filter make no sense.

But I thought I have to build the filter in GroupingTreeDataProvider::AppendFilter based on selection? Or you are talking internally?
Since I am the one creating the filter and then using it in DataProvider::GetData it shouldn't matter how the filter is constructed.
I am mainly talking about what data to return for "NodeId"/"ParentId" fields in IAIMPMLDataProviderSelection. 


IMHO the builtin filtering system should work with non-standalone grouping tree nodes and its a bug.
The AIMPML_GROUPINGTREENODE_FLAG_STANDALONE flag should only change how the selection is created, not how the filtering system works.

But I also think we might be misunderstanding each other here.
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 13, 2018, 02:57:35
So I still cant figure this out.

I need to point "NodeId" field in DataProviderSelection to a grouping tree node that is not standalone, and have the internal filtering system work.
It seems that this cant be done, and I think that is a bug.

I also dont quite understand how would another "ParentId" field help here.
So I use "NodeId" in GroupingTreeDataProviderSelection::GetValue, but then use "ParentId" in DataProviderSelection?
And what value do I put in "NodeId" in DataProviderSelection?

Can you provide a sample? It can be pascal or even pseudo code.
Title: Re: Data filtering in custom music library
Post by: Artem on September 14, 2018, 22:05:17
Ok, I will try to explain.

Default ML engine working with a big single table that contains all required data, engine provides an ability to group that data by specified fields. Imagine, we have a big table with our data that we want to display in music library:

Code: [Select]
DataColumn1|DataColumn2|..

We want to group our data by custom way (not simply by data column), so, will add two internal columns that will contain data for grouping - these columns are NodeID and ParentNodeID. NodeID is a ID of record in the table. ParentNodeID is an ID of record that will be a parent for current record. For example:

Code: [Select]
|NodeID|ParentNodeID|DataColumn1|DataColumn2|..
|    0    |      -1         |   Text 1
|    1    |      -1         |   Text 2
|    2    |       1         |   Text 3

It be translated to a simple tree using ParentNodeID + NodeID:

Code: [Select]
<Root>
    +  <NodeID=0>
    +  <NodeID=1>
             +  <NodeID=2>

Now, in GroupingTreeDataProviderSelection your should return ParentNodeID and Display Names for it, in IAIMPMLDataProviderSelection - table as it is
Title: Re: Data filtering in custom music library
Post by: Moshi0 on September 15, 2018, 02:42:19
Oooh, I just understood why you said that my filters made no sense. I didnt know that the filter I create is also used internally by aimp.
I corrected the filter and it works now just fine, but I cheated a bit and used AIMPML_FIELDFILTER_VALUE2 for custom data.

Regarding your latest reply.
It seems that using additional "ParentNodeId" field is unnecessary? Doesnt aimp internally match the current grouping tree selection and the returned GroupingTreeDataProviderSelection list?
Because Ive always used only "NodeId" field and the grouping was working just fine. I bet I could even use AIMPML_RESERVED_FIELD_ID field.

Also I dont quite understand how are you setting both "NodeId" and "ParentNodeId" here:
Code: [Select]
|NodeID|ParentNodeID|DataColumn1|DataColumn2|..
|    0    |      -1         |   Text 1
|    1    |      -1         |   Text 2
|    2    |       1         |   Text 3

As you can only return one field from GroupingTreeDataProviderSelection.


Anyway, thanks for help!
This explained a lot about inner workings of music libraries.
Title: Re: Data filtering in custom music library
Post by: Artem on September 16, 2018, 20:01:31
I put the ParentNodeID to GroupingTreeDataProviderSelection and filter table's content by this field.