Author Topic: Tags Library  (Read 62659 times)

3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #325 on: 24 Apr '15 - 12:46 »
How would you solve this cover issue?

APEv2 and MP4 tags don't have a 'cover type'. With my solution if you load an MP4 tag with cover art and then you save it to an MP3, it will be cover type 3 (most common). Doing this is 4 lines of code. If I give back -1 as cover type, the saving will write a type -1 which is completely invalid. The coder has to parse the cover art data, TagsLibrary_GetCoverArt() (for Ogg Vorbis and Opus this will mean to decode and copy the whole cover art picture data to the memory), set the cover type field, then set it with TagsLibrary_SetCoverArt() (which again copies to whole picture data from memory pointer to a TMemoryStream - which can be avoided if there's a new function for just setting the cover art parameters ::)) and then save the tag. And the question remains: how would the code know what kind is the cover art?

Quote
if i want use for MusePack or WavePck Front And  Back Cover what your think is return then?

As I wrote already, there is no cover type for MusePack and WavPack. You can not set it.
It will return 3 as now.

Code: [Select]
what i can do
upload a EXE with and without Free the Lib if your want.
then you can debug for the Trouble.

Tried without freeing still seems working here. So yes, please upload a test app. which can show this problem.

Thank you!

EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #326 on: 24 Apr '15 - 13:07 »
Quote
As I wrote already, there is no cover type for MusePack and WavPack. You can not set it.
It will return 3 as now.

ok is your projekt ;)
i mean that is wrong.
if the Tags not used CoverArt then i should not set any.
and return should allways nothing. (my opinion)

FreeLib also
Code: [Select]
   private void CleanUp()
    {
      ListView1.Items.Clear();
      ListView2.Items.Clear();
      lvThumb.Items.Clear();
      ImageListThumbs.Images.Clear();
      txtArtist.Text = "";
      txtTitle.Text = "";
      txtAlbum.Text = "";
      txtChannels.Text = "";
      txtSamplesPerSec.Text = "";
      txtBitsPerSample.Text = "";
      txtPlayTime.Text = "";
      txtSampleCount.Text = "";
      txtBitRate.Text = "";
      rbCoverfront.Checked = false;
      rbLabel.Checked = false;
      rbCoverback.Checked = false;
      rbBand.Checked = false;
      rbArtist.Checked = false;
      rbConductor.Checked = false;
      rbComposer.Checked = false;
      rbBandLogo.Checked = false;
      rbOther.Checked = false;
      rbPerformance.Checked = false;

      // Free TagsLib
      if (Tags.HTags != IntPtr.Zero)
      {
        TagsLib.TagsLibrary_Free(Tags);
        Tags.HTags = IntPtr.Zero;
      }

    }


and load again..

Code: [Select]
   private void LoadTag(int Index)
    {
      CleanUp();

      if (!TagsLib.TagsLibrary_Loaded(Tags, TTagType.ttAutomatic))
      {
        Tags = TagsLib.TagsLibrary_Create();
      }


greets
« Last Edit: 24 Apr '15 - 15:06 by EWeiss »

3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #327 on: 24 Apr '15 - 14:03 »
For APEv2 tags there is one field used by apps.: 'Cover Art (Front)' so the cover art in APEv2 tags is always type 3.

I could change this for example to write 'Cover Art (Back)' or 'Leaflet page' but this will not be compatible with other software.
If you wish you can always specify this name with TCoverArtData.Name when adding/setting cover arts to whatever you like.

Regarding the attributes, the app. you attached doesn't set the flags to parse the MusePack and WavPack audio attributes, so here they are always all 0.

Enable these before creating the tag object:

Code: [Select]
   TagsLibrary_SetConfig(nil, Pointer(1), TAGSLIBRARY_PARSE_WAVPACK_AUDIO_ATTRIBUTES, ttAutomatic);
    TagsLibrary_SetConfig(nil, Pointer(1), TAGSLIBRARY_PARSE_MUSEPACK_AUDIO_ATTRIBUTES, ttAutomatic);
    TagsLibrary_SetConfig(nil, Pointer(1), TAGSLIBRARY_DEEP_OPUS_BITRATE_SCAN, ttAutomatic);
    //* Create a Tags Library instance
    Tags := TagsLibrary_Create;
    ... load and display...

While debugging I also noticed that you query an atMPEG audio attributes for MusePack and WavPack too. That's probably not needed.

Latest beta: TagsLib.zip

EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #328 on: 24 Apr '15 - 14:19 »
Quote
For APEv2 tags there is one field used by apps.: 'Cover Art (Front)' so the cover art in APEv2 tags is always type 3.
Ok that is better then 0 ;)
i have Change it.

Quote
Enable these before creating the tag object:
ops..
is see have added SetConfig on the wrong place sorry..

Code: [Select]
     txtFilename.Text = OpenFileDialog1.FileName;
      if (txtFilename.Text != "")
      {
        SetConfig(OpenFileDialog1.FilterIndex);
        FilterIndex = OpenFileDialog1.FilterIndex;
        LoadTag(FilterIndex);
      }
i have also use SetConfig before FreeLib is called..

Change it to now
Code: [Select]
     // Free TagsLib
      if (Tags.HTags != IntPtr.Zero)
      {
        TagsLib.TagsLibrary_Free(Tags);
        Tags.HTags = IntPtr.Zero;
        SetConfig(FilterIndex);
      }
      else
      {
        // First start of Application
        SetConfig(FilterIndex);
      }

Code: [Select]
   private void SetConfig(int Index)
    {
      switch (Index)
      {
        case 2:
          {
            TagsLib.TagsLibrary_SetConfig(Tags, (IntPtr)1, TConfigFlags.TAGSLIBRARY_PARSE_OGG_PLAYTIME, TTagType.ttAutomatic);
            break;
          }
        case 4:
          {
            TagsLib.TagsLibrary_SetConfig(Tags, (IntPtr)1, TConfigFlags.TAGSLIBRARY_DEEP_OPUS_BITRATE_SCAN, TTagType.ttAutomatic);
            TagsLib.TagsLibrary_SetConfig(Tags, (IntPtr)1, TConfigFlags.TAGSLIBRARY_PARSE_OGG_PLAYTIME, TTagType.ttAutomatic);
            break;
          }
        case 5:
          {
            TagsLib.TagsLibrary_SetConfig(Tags, (IntPtr)1, TConfigFlags.TAGSLIBRARY_PARSE_MUSEPACK_AUDIO_ATTRIBUTES, TTagType.ttAutomatic);
            break;
          }
        case 6:
          {
            TagsLib.TagsLibrary_SetConfig(Tags, (IntPtr)1, TConfigFlags.TAGSLIBRARY_PARSE_WAVPACK_AUDIO_ATTRIBUTES, TTagType.ttAutomatic);
            break;
          }
      }
    }

works.. also no BUG
thank you!

greets
« Last Edit: 24 Apr '15 - 14:40 by EWeiss »

EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #329 on: 24 Apr '15 - 15:09 »
Quote
While debugging I also noticed that you query an atMPEG audio attributes for MusePack and WavPack too. That's probably not needed.
i think not..

Code: [Select]
               Dim MusePackAttributes As New TMusePackAttributes()

                lblAttrib.Text = "MusePack AudioAttributes"
                TagsLib.TagsLibrary_GetAudioAttributes(Tags, TAudioType.atMusePack, MusePackAttributes)

Code: [Select]
               Dim WavePackAttributes As New TWAVPackAttributes()

                lblAttrib.Text = "WavePack AudioAttributes"
                TagsLib.TagsLibrary_GetAudioAttributes(Tags, TAudioType.atWAVPack, WavePackAttributes)

and later also.. (your mean this?)
Code: [Select]
       Dim AudioAttributes As New TAudioAttributes

        TagsError = TagsLib.TagsLibrary_GetAudioAttributes(Tags, TAudioType.atAutomatic, AudioAttributes)
        If TagsError = TTagError.TAGSLIBRARY_SUCCESS Then
            txtChannels.Text = AudioAttributes.Channels.ToString()
            txtSamplesPerSec.Text = AudioAttributes.SamplesPerSec.ToString()
            txtBitsPerSample.Text = AudioAttributes.BitsPerSample.ToString()
            txtPlayTime.Text = Utils.GetTimeString(AudioAttributes.PlayTime)
            txtSampleCount.Text = AudioAttributes.SampleCount.ToString()
            txtBitRate.Text = AudioAttributes.Bitrate.ToString()
        End If

Add all Attributes, testing and Cover Art also.
everything works. :)

Attach last source code and binary.

greets
« Last Edit: 24 Apr '15 - 16:49 by EWeiss »

3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #330 on: 24 Apr '15 - 15:52 »
Ok. Thanks!

Download link in the first post, updates:

  • Fixed loading of big endian unicode ID3v2 tags
  • Fixed APEv2 and MP4 cover arts are now classified as cover type 3 (front cover)
  • Fixes and improvements for the .NET wrapper and tutorial
  • Fixed missing 'atWAVPack' and 'atMusePack' enums from the VB header

3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #331 on: 24 Apr '15 - 15:59 »
I think I know what the problem is... I select a WavPack or MusePack in the file browser, but not selecting file type *.mpc or .*wv but enter *.* in the file name edit - this lists all files.
You are probably checking the filter index, which will stay at *.mp3. :)

EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #332 on: 24 Apr '15 - 16:20 »
I think I know what the problem is... I select a WavPack or MusePack in the file browser, but not selecting file type *.mpc or .*wv but enter *.* in the file name edit - this lists all files.
You are probably checking the filter index, which will stay at *.mp3. :)

not understand correctly FilterIndex for MusePack are 5 and WavPack are 6
so i not use atMPEG :)

atMPEG is used for FilterIndex 1

Quote
but enter *.* in the file name edit - this lists all files.
yes that is wrong then i can not checking for FilterIndex

the FilterIndex then is allways 1..
that is you call atMPEG instead of atMusePack or atWAVPack
also no error by me.  only a design Problem ..

Quote
MP4 cover arts are now classified as cover type 3
why MP4 also?
i have not add the FilterIndex to Radio Button so my Sample is wrong now wth mp4 Tags.

Fixed MP4 Cover so you can only select Cover Front now.
Attach last source code and binary.

i hope you has not more Change ;)
do not forgot fix C++ Header and LIB also :)

greets
« Last Edit: 25 Apr '15 - 12:50 by EWeiss »

3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #333 on: 24 Apr '15 - 22:54 »
It's ok, it's not common to do such thing.
You shouldn't use filter index for file format identification with open dialog, only with the save dialog, I would suggest TagsLibrary_GetAudioFormat() instead.

I updated the package again, sorry I messed up the unicode ID3v2 tag reading with the last update: :-[

  • Fixed infinite loop for unicode tags in ID3v2 GetUnicodeUserDefinedTextInformation() introduced with the previous update
  • Fixed loading of (type 2) big endian unicode ID3v2 tags
  • Fixes and improvements for the .NET wrapper .dll and tutorial

Download link in the first post.

EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #334 on: 25 Apr '15 - 00:16 »
Quote
I would suggest TagsLibrary_GetAudioFormat() instead.

i think is a good idea :)

greets

AussieOldTimer

  • Posts: 18
Re: NEW: Tags Library
« Reply #335 on: 25 Apr '15 - 08:37 »
Hi guys,

Just wondering if you have actually tried to play a song yet?  ???

I use 64 bit Windows 8.1, which means I have to use the 64 bit version of Bass.dll and the Bass.Net and TagsLibraryDefs.net libraries.
(Incidentally I had to rebuild the TagsLibraryDefs.dll to suit my Framework - AnyCPU and .Net Framework 4).

I do the following Imports:

Imports TagsLib_API
Imports TagsLib_API.Utils
Imports Un4seen.Bass


and initialize Bass like this:

        BassNet.Registration("address", "code")
        If False = Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, Me.Handle) Then
            MsgBox("BASS Init Error!")
        End If


When I go to Debug I get the following error:

'Utils' is ambiguous, imported from the namespaces or types 'Un4seen.Bass, TagsLib_API.Utils'.

This is in the code twice, in the btnAttribute_Mousedown event

txtPlayTime.Text = utils.(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))

and in the

AddCover Sub-routine

Dim imagePtr As IntPtr = Utils.GetPointerfromByteArray(openFile)

Seems that there is a clash with between the libraries using the same terminology (?).

Just thought you might want to give playing a song a go and see what you get  ;)
Other than that, it works really, really well.  ;D

Cheers,

AussieOldTimer
(Brisbane, Australia)


EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #336 on: 25 Apr '15 - 11:11 »
Quote
Seems that there is a clash
no is a Developer Problem :)

Code: [Select]
remove Imports TagsLib_API.Utils
then change this
Code: [Select]
txtPlayTime.Text = utils.(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))
to
Code: [Select]
txtPlayTime.Text = TagsLib_API.Utils.(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))
you have two Namespace of "Utils" Compiler not found the right one.
so use instead of Utils the full Namespace Path TagsLib_API.Utils

the same for GetPointerfromByteArray

that should fix your Problem.

PS:
i see txtPlayTime is wrong by you.
Code: [Select]
txtPlayTime.Text = TagsLib_API.Utils.GetTimeString(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))
greets
« Last Edit: 25 Apr '15 - 11:41 by EWeiss »

AussieOldTimer

  • Posts: 18
Re: NEW: Tags Library
« Reply #337 on: 25 Apr '15 - 12:09 »
Hey,

thanks for the prompt reply.  :)

Well I have done what you said, but I get the following problems . . .





Any advice?

AussieOldTimer

AussieOldTimer

  • Posts: 18
Re: NEW: Tags Library
« Reply #338 on: 25 Apr '15 - 12:22 »
Never mind, I figured it out.

Instead of

txtPlayTime.Text = utils.(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))

or

txtPlayTime.Text = TagsLib_API.Utils.GetTimeString(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))

it should be

txtPlayTime.Text = TagsLib_API.Utils.Utils.GetTimeString(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))

Same with the GetPointerfromByteArray . . .

Dim imagePtr As IntPtr = TagsLib_API.Utils.Utils.GetPointerfromByteArray(openFile)

Cheers

AussieOldTimer


EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #339 on: 25 Apr '15 - 12:45 »
Never mind, I figured it out.

Instead of

txtPlayTime.Text = utils.(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))

or

txtPlayTime.Text = TagsLib_API.Utils.GetTimeString(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))

it should be

txtPlayTime.Text = TagsLib_API.Utils.Utils.GetTimeString(TagsLib.TagsLibrary_GetAudioAttribute(Tags, TAudioAttribute.aaPlayTime))

Same with the GetPointerfromByteArray . . .

Dim imagePtr As IntPtr = TagsLib_API.Utils.Utils.GetPointerfromByteArray(openFile)

Cheers

AussieOldTimer



Yes while your have remove Imports TagsLib_API.Utils
so that TagsLib_API.Utils.Utils should be correctly

Quote
I use 64 bit Windows 8.1, which means I have to use the 64 bit Version
i hope your use 64 Bit from TagsLib.dll also.

Attach last source code and binary.

Changed Samples from FilterIndex to  TagsLibrary_GetAudioFormat (3delite has no time select the right FilterIndex) :)
Fixed TagsLibrary_GetAudioFormat also in TagsLibraryDefs.NET

greets
« Last Edit: 25 Apr '15 - 13:09 by EWeiss »

AussieOldTimer

  • Posts: 18
Re: NEW: Tags Library
« Reply #340 on: 25 Apr '15 - 13:41 »
Cool.  8)

Thanks again - great job!  ;D

EWeiss

  • Posts: 342
Re: NEW: Tags Library
« Reply #341 on: 25 Apr '15 - 18:20 »
Cool.  8)

Thanks again - great job!  ;D

no Problem :)

if you find other mistake please tell me.
so i can fix it.

greets

JeremyB

  • Guest
Re: NEW: Tags Library
« Reply #342 on: 26 Jun '15 - 07:38 »
I'm trying to get this working in a .NET project. However when I try adding a reference to the 64-bit DLL from the Bin\Win64 folder it is failing.

When I open the .NET solution and run the tutorial projects, it compiles & runs but then tells me I'm missing TagsLib.DLL on selecting a file:

Additional information: Unable to load DLL 'TagsLib.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Any advice appreciated.

radio42

  • Posts: 4574
Re: NEW: Tags Library
« Reply #343 on: 26 Jun '15 - 08:45 »
What native 64-bit DLL are you trying to add as a reference.
Note, that you can not add a native (unmanaged) C/C++ DLL as a reference to a managed .Net project!

I don't know what the 'TagsLib.dll' is for. It is not part of Bass.Net - so it must be something you or another lib is adding/referencing!

3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #344 on: 26 Jun '15 - 08:52 »
As far as I know you have to build a Win64 version of 'TagsLibraryDefs.Net.dll' (it's in the '\.NET\TagsLibraryDefs.NET\' folder) and add this built 'TagsLibraryDefs.Net.dll' reference to your project. Then copy the '\Bin\Win64\TagsLib.dll' beside your .exe.

JeremyB

  • Guest
Re: NEW: Tags Library
« Reply #345 on: 26 Jun '15 - 08:59 »
As far as I know you have to build a Win64 version of 'TagsLibraryDefs.Net.dll' (it's in the '\.NET\TagsLibraryDefs.NET\' folder) and add this built 'TagsLibraryDefs.Net.dll' reference to your project. Then copy the '\Bin\Win64\TagsLib.dll' beside your .exe.

Thanks, I'll give that a go.

frytech

  • Posts: 11
Re: NEW: Tags Library
« Reply #346 on: 1 Sep '15 - 02:22 »
A little clarification requested if I may.  I am a novice VB6 programmer working on an MP3 player.  It is only for MP3's for pretty much personal use so I don't intend to support other formats.  I'm having a problem reading ID3v2 tags.  I downloaded the latest copy of the tags library only 3 days ago with all the latest VB6 declarations although I did have to add 'save' into the class module.  

According to what I have been able to gleen from the latest documentation, ttAutomatic when reading a tag gives priority to reading the ID3v2 tag structure if the tag exists else it reads the ID3v1 tag if it exists.  These 2 statements -should- give the same results on the same file if my understanding is correct.

    ID3TagV2.SetTag "TITLE", txtTitle(0).text, ttAutomatic
    ID3TagV2.SetTag "TITLE", txtTitle(0).text, ttID3v2


If I read the tag in automatic, it will not catch the tag saved as id3v2 and vice versa.

Saving tags in the the above way also renders different results.


« Last Edit: 1 Sep '15 - 03:17 by frytech »

3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #347 on: 1 Sep '15 - 11:21 »
Yes, by default the tag load priority should be as fallows:

    TagsLibraryDefaultTagLoadPriority[0] := ttFlac;
    TagsLibraryDefaultTagLoadPriority[1] := ttOpusVorbis;
    TagsLibraryDefaultTagLoadPriority[2] := ttMP4;
    TagsLibraryDefaultTagLoadPriority[3] := ttWMA;
    TagsLibraryDefaultTagLoadPriority[4] := ttID3v2;
    TagsLibraryDefaultTagLoadPriority[5] := ttAPEv2;
    TagsLibraryDefaultTagLoadPriority[6] := ttWAV;
    TagsLibraryDefaultTagLoadPriority[7] := ttID3v1;

So ID3v1 has the lowest priority.

This order can be changed with the TagsLibrary_SetTagLoadPriority() function.

The save function first checks if a tag type is loaded, if yes, saves that tag format, in case of MP3 if no ID3v2 is in the file but there is ID3v1 then only ID3v1 will be saved. This probably should be changed, I think about this. It's a little bit unclear to me how to determine the save format.

For now to save an ID3v2 tag explicitly use 'ttID3v2' with the save function.

Please tell me if you still have problems with it!

EDIT: There's no use to set a tag value with for example 'ttID3v2' and then use 'ttAutomatic' when saving as 'ttAutomatic' for saving means to set the ID3v2 tag values from those added (existing from loading) with 'ttAutomatic' - in other words they will be replaced before saving.

The library has two layers: the particular tags (ID3v2) and a "global" tags. When loading the ID3v2 is loaded then according to tag load priority it is parsed into the "global" array. If ttID3v2 is used when setting a tag the ID3v2 tag is changed, when using 'ttAutomatic' the "global" array is changed. When saving the tags with 'ttAutomatic' the global tags are copied into ID3v2 and then this ID3v2 is saved. So if you changed an ID3v2 tag value it will be replaced on save with the "global" value.
« Last Edit: 1 Sep '15 - 11:43 by 3delite »

frytech

  • Posts: 11
Re: NEW: Tags Library
« Reply #348 on: 1 Sep '15 - 20:01 »
Yes, by default the tag load priority should be as fallows:
...
  
The save function first checks if a tag type is loaded, if yes, saves that tag format, in case of MP3 if no ID3v2 is in the file but there is ID3v1 then only ID3v1 will be saved. This probably should be changed, I think about this. It's a little bit unclear to me how to determine the save format.
...
 this ID3v2 is saved. So if you changed an ID3v2 tag value it will be replaced on save with the "global" value.

I see where my mistake is, I thought the library created an ID3v2 tag if it did not already exist.  I have some weird files that have an ID3v1 tag only but it is located in the front of the file, not the last 128 bytes of the file.  I thought these were part of the header for a v2 tag. Your library reads these tags as v1 without a problem.  I have not seen any issues with reading an actual v2 tag.

I am assuming that if a file has both tag types and I read as ttautomatic, modify the tag and save as ttautomatic, that both tag types will be modified?


3delite

  • Posts: 895
Re: NEW: Tags Library
« Reply #349 on: 2 Sep '15 - 14:25 »
Yes, that's the way it should work. But if you have any issues with it please post it!

ID3v1 must be at the file end, the library won't read it if it is at the beginning. If the file starts with 'ID3' then that's an ID3v2 tag.

EDIT: The package has been updated with the fix for the "if no ID3v2 in the file but there is ID3v1 no ID3v2 will be written".
Please download (link) in the first post.
« Last Edit: 2 Sep '15 - 21:44 by 3delite »