Author Topic: Tags Library  (Read 63396 times)

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #100 on: 11 Feb '15 - 07:33 »
This was raised on vbForums - I don't know if it is important or if there are others we have missed. - Steve.

Quote Originally Posted by LaVolpe:
Some UDT's members are not in the original order. Don't know if this is on purpose or fixed later by you & her.

Quote Originally Posted by Bonnie West:
In the original TagsLibraryDefs.pas Delphi unit, the TDSFAudioAttributes record was declared as:

Code: [Select]
type
    PDSFAudioAttributes = ^TDSFAudioAttributes;
    TDSFAudioAttributes = record
        FormatVersion: DWord;
        FormatID: DWord;
        ChannelType: TDSFChannelType;
        ChannelNumber: DWord;
        SamplingFrequency: DWord;
        BitsPerSample: DWord;
        BlockSizePerChannel: DWord;
        PlayTime: Double;
        SampleCount: UInt64; <<<<<
        Bitrate: Integer;
    end;

Meanwhile, in the accompanying TagsLibraryDefs.h C++ header file, the TDSFAudioAttributes structure was declared as:

Code: [Select]
typedef struct {
    DWORD FormatVersion;
    DWORD FormatID;
    TDSFChannelType ChannelType;
    DWORD ChannelNumber;
    DWORD SamplingFrequency;
    DWORD BitsPerSample;
    QWORD SampleCount; <<<<<
    DWORD BlockSizePerChannel;
    double PlayTime;
    int Bitrate;
} *PTDSFAudioAttributes, TDSFAudioAttributes;

Since the author wrote the DLL in Delphi, I decided to "fix" the VB6 module by following his Delphi declaration. I haven't tried verifying if it works correctly, though.

Steve, you might want to contact the author of that DLL again regarding this matter.

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #101 on: 12 Feb '15 - 01:09 »
So it's working now? :)
Sorry I can't help with VB stuff. :-X

Ooops, sorry the C++ header was wrong, trust the Delphi .pas header, the .dll is built with the Delphi header, so it should be the one actually used in the build process of the .dll.

Regarding the cover art problem: trying here with an APEv2 to MP4 conversion seems working. The cover art gets transfered. So again, I can only ask for a sample source file (with the problematic tag format, eg. APEv2), tell me the destination format, and I try here the conversion, so I can see what the problem is (download link please as always).

If you manage to make a working VB header file, please share it, it would be very useful.

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #102 on: 12 Feb '15 - 14:48 »
I think I have it now. I was calling TagsLibrary_Free Tags after the GetTags call.

Sorry for the bother.

Steve.

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #103 on: 12 Feb '15 - 19:52 »
No problem. Thank you for your help in improving the component.

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #104 on: 16 Feb '15 - 12:30 »
I have come across another small problem.

If I convert a file to wav using the Bass Encoder and DON'T tag it, I can drop it onto any command line encoder and it will encode to that format.

However, if I convert and TAG, some of the encoders error with the error shown attached. Tagged, or not, the wav files play ok in Foobar, VLC, Bass.

List of encoders that don't work with a tagged file:
fdkaac.exe
mppenc.exe
opusenc.exe

List of encoders that do work with a tagged file:
flac.exe
oggenc2.exe
wavpack.exe

Steve.



3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #105 on: 16 Feb '15 - 20:03 »
If some encoders work, then it's a problem with ones that don't. It's probably the WAV LIST INFO chunk at the file start that's confusing them.

Please try explicitly telling Tag Library to write an ID3v2 tag to the WAV files, that doesn't change the WAV chunks at the file start and see what happens:

Code: [Select]
    TagsLibrary_Save(Tags, PWideChar(FileName.wav), ttID3v2);

Some encoders even fail on WAV files with a JUNK chunk that's generated by BASSEnc with the BASS_ENCODE_RF64 flag.

If you still have problems with only an ID3v2 tag in the WAV file, please post a download link so I can check it, but I'm afraid not much can be done if the encoder doesn't parse the WAV chucks correctly.

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #106 on: 16 Feb '15 - 21:46 »
OK tagging wav with ID3v2 has completely cured the problem. Many thanks.

With regard to GetAttributes. If I copy/paste the tagging code from my main programme into a new empty session of VB6 and simply pass it a filename, it and the Tags work 100% reliably. Within my main programme, the tagging works 100% reliably but the attributes do not work at all! Within my main programme I have subclassed controls, a timer, and other things going on. I wonder if there is something in GetAttributes that could be upset by this. It is almost like it is not receiving the filename?? (I get the attributes with the same Load_Library call that calls the tags);

Code: [Select]
   
    Public Declare Function TagsLibrary_GetAudioAttributes Lib "TagsLib.dll" (ByVal Tags As Long, ByVal AudioType As TAudioType, ByRef Attributes As Long) As Long
    
Dim TagAtts as TAudioAttributes
    If TagsLibrary_Loaded(Tags, ttAutomatic) = False Then Tags = TagsLibrary_Create
    TagsLibrary_Load Tags, StrPtr(FileName), ttAutomatic, True
    TagsLibrary_GetAudioAttributes Tags, atAutomatic, VarPtr(TagAtts)

As GetTags is 100% reliable, I wonder if it would be possible for you to internally call GetAttributes and present the data just as you do the tags, something like;

GetDuration
GetBitrate
GetBitDepth
GetSamplefreq
GetsampleCount
GetChannels

The 'Get' implying that the data is read only and cannot be written back to the file. I know this is asking a lot but feel we are so close now (VB wise) that it might be worth the effort. What do you think? e.g.

Code: [Select]
MyTags.AUDIOBitrate = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("GetBitRate"), ttAutomatic))
Best Regards - Steve.

« Last Edit: 16 Feb '15 - 21:52 by Steve Grant »

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #107 on: 17 Feb '15 - 17:19 »
Ok, please try it: TagsLib.zip

Add 2 things to your working VB header (please translate):

Code: [Select]
type
    TAudioAttribute = (aaChannels, aaSamplesPerSec, aaBitsPerSample, aaPlayTime, aaSampleCount, aaBitRate);

TagsLibrary_GetAudioAttribute     = function (Tags: HTags; Attribute: TAudioAttribute): Double;

Not tested, tell me whether it's ok or not!

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #108 on: 17 Feb '15 - 22:23 »
Ok I tried it with the structure as a new Type, but couldn't get it to work. Then I changed the structure to an Enum. Same as TAudioType. This did not error, but I got no results.

Code: [Select]
Public Enum TAudioAttribute
    aachannels
    aaSamplesPerSec
    aaBitsPerSample
    aaPlayTime
    aaSampleCount
    aabitrate
End Enum

Public Declare Function TagsLibrary_GetAudioAttribute Lib "TagsLib.dll" (ByVal Tags As Long, ByVal Attrib As TAudioAttribute) As Long
TagsLibrary_Load Tags, StrPtr(FileName), ttAutomatic, True
MyVar = TagsLibrary_GetAudioAttribute(Tags, aabitrate) --- MyVar=0 --- PTRtoSTR(MyVar)=0 --- Cstr(MyVar)=0

It is still a separate call to GetAudioAttribute. What I was hoping for is;

Code: [Select]
TagsLibrary_Load Tags, StrPtr(FileName), ttAutomatic, True (You would also Parse the Attributes with this call)
   
    'ATags is my own public structure. It helps a lot in replacing AudioGenie.
    With ATags
        .AUDIOAlbum = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("Album"), ttAutomatic))
        .AUDIOArtist = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("Artist"), ttAutomatic))
        .AUDIOComment = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("Comment"), ttAutomatic))
        .AUDIOGenre = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("Genre"), ttAutomatic))
        .AUDIOTitle = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("Title"), ttAutomatic))
        .AUDIOTrack = Val(PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("Track"), ttAutomatic)))
        .AUDIOYear = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("Year"), ttAutomatic))
        .AUDIOGetDuration = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("GetDuration"), ttAutomatic))
        .AUDIOGetBitrate = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("GetBitRate"), ttAutomatic)) & " Kbps"
        .AUDIOGetBitDepth = PTRtoStr(TagsLibrary_GetTag(Tags, StrPtr("GetBitDepth"), ttAutomatic))
'       ETC.........
    End With

All the best - Steve.

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #109 on: 17 Feb '15 - 23:56 »
Try this:

Code: [Select]
Public Declare Function TagsLibrary_GetAudioAttribute Lib "TagsLib.dll" (ByVal Tags As Long, ByVal Attrib As TAudioAttribute) As Double

Then something like:

Code: [Select]
Dim MyVar As Double
MyVar = TagsLibrary_GetAudioAttribute(Tags, aabitrate)

Hope it helps.

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #110 on: 18 Feb '15 - 07:41 »
Tried exactly as you suggested. No Errors. MyVar returns 0. Obviously PTRtoSTR(MyVar)="".

I know it's crazy, but I still feel the GetAttribute(s) functions are not seeing the FileName for some reason.

Many Thanks - Steve.

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #111 on: 19 Feb '15 - 20:26 »
It's really weird. :)

Internally the attributes are parsed when the TagsLibrary_Load() function is called, so if you can get the tags, the attributes (if available) are then already loaded.

The double should be converted to string with MyVar.ToString:

https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx

Additionally try CStr(MyVar).

If still not good what we could try is: make a little test app. in VB and send it to me. I can then check if the function in the .dll is called and see what happens in the call.

Guest

  • Guest
Re: NEW: Tags Library
« Reply #112 on: 19 Feb '15 - 21:48 »
?
Code: [Select]
Public Declare Function TagsLibrary_GetAudioAttribute Lib "TagsLib.dll" (ByVal Tags As Long, ByVal Attrib As TAudioAttribute) As Double
not ByRef?

Code: [Select]
Public Declare Function TagsLibrary_GetAudioAttribute Lib "TagsLib.dll" (ByVal Tags As Long, ByRef Attrib As TAudioAttribute) As Double

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #113 on: 19 Feb '15 - 23:45 »
Hi 3delite and hello guest. Guest I have tried all the things I can think of with my (it now seems limited) knowledge of VB. As the structure is an Enum it needs to be ByVal like all the other Enums that do work well.

Guest we have a situation where if I take the VB6 wrapper to 3delite's dll and put it into a new VB project and feed it a valid filename. You can get the Tags and the Attributes 100% of the time.

As soon as you put the wrapper back into my programme and feed it a valid filename, you get the Tags 100% reliably but from the Attributes you get nothing. All from the exact same wrapper!!! I had this idea that it might be because I am using some controls that are subclassed and I wondered if this could upset the dll in some way. 3delite has been amazing but he says he knows nothing of VB and I know even less about Delphi. I got a lot of help getting the wrapper translated from Bonnie West at VBforums, but I can't keep going back there for their help! Like most VB'ers I was using AudioGenie for my tagging and this is sooo much better and it works with all of the current formats.

I would be delighted if you would step in and lend a hand. To that end I am attaching the wrapper and you can get the dll from the first post. You will see where I have been messing around just now after reading your post. You will also see a UDT I've created that makes changing from AudioGenie to Tags Library really easy. You will also see that I am using Bass at the moment to get the attributes. This is fine but the bitrate is a little high as the entire file length is used to calculate, not allowing for things like cover art.

3delite. I could easily make a little project and send it to you, but we already know that it will work ok when working alone. You say that Attributes are parsed along with the Tags in the TagsLibrary_Load call. Why not present the attributes data from the GetTag call in the same way as 'Artist', 'Title' etc as we know this works so well. I suggested this a couple of posts up with an example. I am not going to give up on this as I am so impressed by it.

Best - Steve.

EWeiss

  • Posts: 355
Re: NEW: Tags Library
« Reply #114 on: 20 Feb '15 - 03:39 »
simple sample.. not finish yet

please tell me how enumerate or read the values from all tags
i think missing any...

Code: [Select]
       for i := 0 to Tags.Count - 1 do begin
            with ListView1.Items.Add do begin
                Caption := Tags.Tags[i].Name;
                Subitems.Add(Tags.Tags[i].Value);
            end;
        end;

i'm use original modules from TagsLib vers. 1.0
and add a class for VB6

greets
« Last Edit: 20 Feb '15 - 23:16 by EWeiss »

EWeiss

  • Posts: 355
Re: NEW: Tags Library
« Reply #115 on: 20 Feb '15 - 16:27 »
i'm not use your Lib only help for a working sample..
also any is wrong see PlayTime..


Code: [Select]
Public Function GetAudioAttribute(ByVal Attrib As TAudioAttribute) As String

    GetAudioAttribute = TagsLibrary_GetAudioAttribute(LngTags, Attrib)

End Function

Code: [Select]
Public Function GetTimeFormat(ByVal SongTime As Long) As String
Dim mpMin   As Long
Dim mpSec   As Long
    
    mpMin = SongTime \ 60
    mpSec = SongTime Mod 60
    
    GetTimeFormat = IIf(Trim$(mpMin) <= 9, "0" & Trim$(mpMin), Trim$(mpMin)) & ":" & _
        IIf(Trim$(mpSec) <= 9, "0" & Trim$(mpSec), Trim$(mpSec))


End Function
       

Code: [Select]
SongTime = CLng(Tags.GetAudioAttribute(aaPlayTime))
txtPlayTime.Text = Tags.GetTimeFormat(SongTime)

result of aaPlayTime is the same as LngTags
aaSamplesPerSec allways 0
aaSampleCount allways 0
aaBitRate work
aaChannels work
aaBitsPerSample work
« Last Edit: 20 Feb '15 - 17:15 by EWeiss »

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #116 on: 20 Feb '15 - 22:15 »
Those "always 0" values, do you get 0 values with the test app, too: TutorialDLLAudioAttributes.zip

@Steve Grant: if the test app. is working with a particular VB header, keep that, it's probably fine, the problem must be something else. My only idea is, please send me your app. and the steps to reproduce the problem, and I can at least see, if the function gets called.
« Last Edit: 20 Feb '15 - 22:20 by 3delite »

EWeiss

  • Posts: 355
Re: NEW: Tags Library
« Reply #117 on: 20 Feb '15 - 22:19 »
Those "always 0" values, do you get 0 values with the test app, too: TutorialDLLAudioAttributes.zip

your sample used AudioAttributes instead of AudioAttribute
what is the different from AudioAttribute and AudioAttributes
i think you can delete AudioAttribute if not work

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #118 on: 20 Feb '15 - 22:26 »
Sorry, you are right, please try this executable (uses TagsLibrary_GetAudioAttribute() 6 times): TutorialDLLAudioAttributes2.zip

It's interesting because here seems to work fine...

TagsLibrary_GetAudioAttributes() here works fine...

EWeiss

  • Posts: 355
Re: NEW: Tags Library
« Reply #119 on: 20 Feb '15 - 22:31 »
Sorry, you are right, please try this executable (uses TagsLibrary_GetAudioAttribute() 6 times): TutorialDLLAudioAttributes2.zip

It's interesting because here seems to work fine...

TagsLibrary_GetAudioAttributes() here works fine...

Code: [Select]
TagsLibrary_GetAudioAttributes() here works fine...not by me

i will test TutorialDLLAudioAttributes2
error loading tagsLib from your exe File TutorialDLLAudioAttributes2
« Last Edit: 21 Feb '15 - 16:49 by EWeiss »

3delite

  • Posts: 907
Re: NEW: Tags Library
« Reply #120 on: 20 Feb '15 - 22:52 »
Quote
error loading tagsLib from your exe File TutorialDLLAudioAttributes2

Please copy TagsLib.dll beside the .exe. :)
Note that it needs the latest version, available from the first post.

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #121 on: 20 Feb '15 - 22:56 »
@3delite @EWeiss.

I have only just discovered that the Test App (1 or 2) does not measure WavPack files. There maybe others that I have not tested. As 99% of my 38000 track library is in WavPack lossless, this may explain why I cannot get any results. Your Test Apps do measure mp3's but the data is mostly wrong. The files are not 32bit. To help you I have attached some pictures which I hope will help you. I have reduced the width of your form to reduce the size of the jpeg's.

1) The original WavPack file. Attributes by dbPA.
1a) I measured the WavPack file with both Test Apps 1 & 2 and got 0,0,0,0,0,0 in both. No picture needed.
2) After converting the WavPack file to mp3 with dbPA.
3) I measured the mp3 file with Test Apps 1 & 2. Results shown.

You can download both files for testing here: https://dl.dropboxusercontent.com/s/40kjjhav55jcyk3/Files.zip?dl=1

EWeiss

  • Posts: 355
Re: NEW: Tags Library
« Reply #122 on: 20 Feb '15 - 23:03 »
Quote
error loading tagsLib from your exe File TutorialDLLAudioAttributes2

Please copy TagsLib.dll beside the .exe. :)
Note that it needs the latest version, available from the first post.

hehehehe your mean i can not work with dependencies which used by a application?
Ok.. no Problem ;)

i have copy the DLL from first test to second test application and the second(TutorialDLLAudioAttributes2.zip) Crash

What your mean should remove this from your Library?
i think is not necessary

Code: [Select]
Public Enum TAudioAttribute
    aaChannels
    aaSamplesPerSec
    aaBitsPerSample
    aaPlayTime
    aaSampleCount
    aaBitRate
End Enum

greets

Steve Grant

  • Posts: 148
Re: NEW: Tags Library
« Reply #123 on: 20 Feb '15 - 23:06 »
Hi, the dll in the first Test App does not contain the 'Attribute' method. You must download the dll agai from the first post.

Greets - Steve.

EWeiss

  • Posts: 355
Re: NEW: Tags Library
« Reply #124 on: 20 Feb '15 - 23:10 »
Hi, the dll in the first Test App does not contain the 'Attribute' method. You must download the dll agai from the first post.

Greets - Steve.

ahh ok i will test again.
thank you

hmm work here with TutorialDLLAudioAttributes2

Channels: 2
SamplesPerSec: 44100
BitsPerSample: 32
PlayTime: 303,842475
SampleCount: 0
BitRate: 320
« Last Edit: 20 Feb '15 - 23:15 by EWeiss »