Hi all,
I am new to this forum So hello everyone,
I have a customer who is using dbpoweramp a lot to rip cds into there music library. He wanted me to write a program to take the data out of thw wave files he produced and update his database with the data. I initialy used a the following code to read the tags.
But I found this method very slow It took over 1 minuite to read the tags for 10 albums.
So I decided to write my own managed class to do the same thing (It only works with LIST INFO Items and ID3 Text tags IE T???) But It Is extreamly Quick. I can now read 40000 Tracks a Minute.
This also has the the advantage of not needing dbpoweramp to be installed on the client machine and also you dont need to worry about which version of dbpoweramp is loaded.
I thought It may be usefull for some of you, It dosnt write tags but I could modify it to do that if needed.
This code reads the data from my class as per the example above.
Here is the class
I am new to this forum So hello everyone,
I have a customer who is using dbpoweramp a lot to rip cds into there music library. He wanted me to write a program to take the data out of thw wave files he produced and update his database with the data. I initialy used a the following code to read the tags.
Code:
Dim db As New DMCSCRIPTINGLib.Converter For i = 0 To 1000 Dim Element As String, Value As String Element = "" Value = "" db.ReadIDTag(Filename, i, Element, Value) If Element = "" Then Exit For Results(i) = Element & "|" & Value Next
But I found this method very slow It took over 1 minuite to read the tags for 10 albums.
So I decided to write my own managed class to do the same thing (It only works with LIST INFO Items and ID3 Text tags IE T???) But It Is extreamly Quick. I can now read 40000 Tracks a Minute.
This also has the the advantage of not needing dbpoweramp to be installed on the client machine and also you dont need to worry about which version of dbpoweramp is loaded.
I thought It may be usefull for some of you, It dosnt write tags but I could modify it to do that if needed.
This code reads the data from my class as per the example above.
Code:
Dim RiffRdr As New RIFFReader(Filename) i = 0 If Not IsNothing(RiffRdr.ID3Items) Then For Each item In RiffRdr.ID3Items Results(i) = item.FriendlyName & "|" & item.Data i += 1 Next End If If Not IsNothing(RiffRdr.InfoItems) Then For Each item In RiffRdr.InfoItems Results(i) = item.FriendlyName & "|" & item.Data i += 1 Next End If RiffRdr.Dispose()
Here is the class
Code:
Public Class RIFFReader Dim RIFFfile As System.IO.FileStream Dim RIFFLength As Long Dim RIFFType As String Structure RiffFrame Dim Name As String Dim StartOfData As Long Dim Length As Long End Structure Structure InfoItem Dim TAGNAME As String Dim FriendlyName As String Dim Data As String End Structure Structure ID3Item Dim TAGNAME As String Dim FriendlyName As String Dim Data As String End Structure '4.2.1 TALB [#TALB Album/Movie/Show title] '4.2.1 TBPM [#TBPM BPM (beats per minute)] '4.2.1 TCOM [#TCOM Composer] '4.2.1 TCON [#TCON Content type] '4.2.1 TCOP [#TCOP Copyright message] '4.2.1 TDAT [#TDAT Date] '4.2.1 TDLY [#TDLY Playlist delay] '4.2.1 TENC [#TENC Encoded by] '4.2.1 TEXT [#TEXT Lyricist/Text writer] '4.2.1 TFLT [#TFLT File type] '4.2.1 TIME [#TIME Time] '4.2.1 TIT1 [#TIT1 Content group description] '4.2.1 TIT2 [#TIT2 Title/songname/content description] '4.2.1 TIT3 [#TIT3 Subtitle/Description refinement] '4.2.1 TKEY [#TKEY Initial key] '4.2.1 TLAN [#TLAN Language(s)] '4.2.1 TLEN [#TLEN Length] '4.2.1 TMED [#TMED Media type] '4.2.1 TOAL [#TOAL Original album/movie/show title] '4.2.1 TOFN [#TOFN Original filename] '4.2.1 TOLY [#TOLY Original lyricist(s)/text writer(s)] '4.2.1 TOPE [#TOPE Original artist(s)/performer(s)] '4.2.1 TORY [#TORY Original release year] '4.2.1 TOWN [#TOWN File owner/licensee] '4.2.1 TPE1 [#TPE1 Lead performer(s)/Soloist(s)] '4.2.1 TPE2 [#TPE2 Band/orchestra/accompaniment] '4.2.1 TPE3 [#TPE3 Conductor/performer refinement] '4.2.1 TPE4 [#TPE4 Interpreted, remixed, or otherwise modified by] '4.2.1 TPOS [#TPOS Part of a set] '4.2.1 TPUB [#TPUB Publisher] '4.2.1 TRCK [#TRCK Track number/Position in set] '4.2.1 TRDA [#TRDA Recording dates] '4.2.1 TRSN [#TRSN Internet radio station name] '4.2.1 TRSO [#TRSO Internet radio station owner] '4.2.1 TSIZ [#TSIZ Size] '4.2.1 TSRC [#TSRC ISRC (international standard recording code)] '4.2.1 TSSE [#TSEE Software/Hardware and settings used for encoding] '4.2.1 TYER [#TYER Year] Dim ID3TagName() As String = {"TALB", "TBPM", "TCMP", "TCOM", "TCON", "TCOP", "TDAT", "TDLY", "TENC", "TEXT", "TFLT", "TIME", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED", "TOAL", "TOFN", "TOLY", "TOPE", "TORY", "TOWN", "TPE1", "TPE2", "TPE3", "TPE4", "TPOS", "TPUB", "TRCK", "TRDA", "TRSN", "TRSO", "TSIZ", "TSRC", "TSSE", "TYER"} Dim ID3TagFriendlyName() As String = {"Album", "BPM", "Compilation", "Composer", "Genre", "Copyright message", "Date", "Playlist delay", "Encoded by", "Lyricist", "File type", "Time", "Style", "Title", "Subtitle/Description", "Initial key", "Language", "Length", "Media type", "Original album", "Original filename", "Original lyricist", "Original artist", "Original release year", "File owner/licensee", "Artist", "Album Artist", "Conductor", "Remixed", "Part of a set", "Label", "Track", "Recording dates", "Internet radio station name", "Internet radio station owner", "Size", "ISRC", "Software/Hardware and settings used for encoding", "Year"} Dim INFOTagName() As String = {"IART", "ICMT", "ICOP", "ICRD", "IGNR", "INAM", "ISRC", "IPRD", "TORG", "LOCA", "TVER", "TURL", "TLEN", "ITCH", "TRCK", "itrk", "ISRF", "ITRK"} Dim INFOTagFriendlyName() As String = {"Artist", "Comment", "Copyright", "Year", "Genre", "Title", "ISRC", "Album", "Label", "Location", "Version", "URL", "Length", "Technician", "Track", "Track", "Source", "Track"} Public RiffFrames() As RiffFrame = Nothing Public InfoItems() As InfoItem = Nothing Public ID3Items() As ID3Item = Nothing Sub New(ByVal Filename As String) If My.Computer.FileSystem.FileExists(Filename) Then RIFFfile = IO.File.Open(Filename, IO.FileMode.Open, IO.FileAccess.ReadWrite) RIFFfile.Seek(0, IO.SeekOrigin.Begin) If ReadFourCC() = "RIFF" Then 'Looks like its a riff Else Throw New Exception("Not A Riff") End If RIFFLength = RIFFfile.ReadByte() + _ RIFFfile.ReadByte() * 2 ^ 8 + _ RIFFfile.ReadByte() * 2 ^ 16 + _ RIFFfile.ReadByte() * 2 ^ 24 Else Throw New Exception("File Not Found") End If RIFFType = ReadFourCC() While RIFFfile.Position < RIFFfile.Length ' make space for the frame data If IsNothing(RiffFrames) Then ReDim RiffFrames(0) Else ReDim Preserve RiffFrames(RiffFrames.Length) End If RiffFrames(RiffFrames.Length - 1).Name = ReadFourCC() RiffFrames(RiffFrames.Length - 1).Length = ReadDWord() RiffFrames(RiffFrames.Length - 1).StartOfData = RIFFfile.Position 'seek the begining of the next frame 'MsgBox(RIFFfile.Position) RIFFfile.Seek(RiffFrames(RiffFrames.Length - 1).Length, IO.SeekOrigin.Current) 'MsgBox(RIFFfile.Position) End While For Each item In RiffFrames ' Process "LIST" Section If item.Name = "LIST" Then 'We Have A List Tag RIFFfile.Seek(item.StartOfData, IO.SeekOrigin.Begin) If ReadFourCC() = "INFO" Then 'We Have An Info Tag While RIFFfile.Position < (item.StartOfData + item.Length) ' make space for the frame data If IsNothing(InfoItems) Then ReDim InfoItems(0) Else ReDim Preserve InfoItems(InfoItems.Length) End If InfoItems(InfoItems.Length - 1).TAGNAME = ReadFourCC() InfoItems(InfoItems.Length - 1).Data = ReadString(ReadDWord) 'Set The frendly name to tag name just in case its not found InfoItems(InfoItems.Length - 1).FriendlyName = _ InfoItems(InfoItems.Length - 1).TAGNAME For i As Integer = 0 To INFOTagName.Length - 1 If INFOTagName(i) = InfoItems(InfoItems.Length - 1).TAGNAME Then InfoItems(InfoItems.Length - 1).FriendlyName = INFOTagFriendlyName(i) Exit For End If Next End While End If End If If item.Name = "id3 " Then 'We Have A List Tag RIFFfile.Seek(item.StartOfData, IO.SeekOrigin.Begin) If ReadFourCC() = "ID3" + Chr(3) Then 'We Have An ID3 Tag RIFFfile.Seek(6, IO.SeekOrigin.Current) While RIFFfile.Position < (item.StartOfData + item.Length) ' make space for the frame data Dim Tag As String = ReadFourCC() 'The Tag Dim Length As Long = ReadDWordRevProtected() 'The Length RIFFfile.ReadByte() ' Read Flags RIFFfile.ReadByte() ' Read Flags If Tag(0) = "T" Then 'Its a TextTag If IsNothing(ID3Items) Then ReDim ID3Items(0) Else ReDim Preserve ID3Items(ID3Items.Length) End If ID3Items(ID3Items.Length - 1).TAGNAME = Tag Dim InnerTag As String = ReadStringTag(Length) If Tag = "TXXX" Then ID3Items(ID3Items.Length - 1).FriendlyName = _ InnerTag.Substring(0, InnerTag.IndexOf(Chr(0))) ID3Items(ID3Items.Length - 1).Data = _ InnerTag.Substring(InnerTag.IndexOf(Chr(0)) + 1) Else ID3Items(ID3Items.Length - 1).Data = InnerTag ID3Items(ID3Items.Length - 1).FriendlyName = _ ID3Items(ID3Items.Length - 1).TAGNAME For i As Integer = 0 To ID3TagName.Length - 1 If ID3TagName(i) = ID3Items(ID3Items.Length - 1).TAGNAME Then ID3Items(ID3Items.Length - 1).FriendlyName = ID3TagFriendlyName(i) Exit For End If Next End If Else 'Its Not A Text Tag If Tag = Chr(0) + Chr(0) + Chr(0) + Chr(0) Then Exit While 'Skip The Tag RIFFfile.Seek(Length, IO.SeekOrigin.Current) End If End While End If End If Next End Sub Sub Dispose() RIFFfile.Close() RIFFfile.Dispose() ID3TagName = Nothing ID3TagFriendlyName = Nothing INFOTagName = Nothing INFOTagFriendlyName = Nothing RiffFrames = Nothing InfoItems = Nothing ID3Items = Nothing End Sub Function ReadStringTag(ByVal I As Long) As String Dim Tmp As Byte = RIFFfile.ReadByte Dim Result As String = "" Dim Unicode As Boolean Dim LowByteLast As Byte I = I - 1 If Tmp = 0 Then ' its an ordinary tag Unicode = False Else 'its a Unicode String Tmp = RIFFfile.ReadByte Tmp = RIFFfile.ReadByte Unicode = True If Tmp = 254 Then LowByteLast = True Else LowByteLast = False End If I = I - 2 End If While I > 0 Tmp = RIFFfile.ReadByte I -= 1 If Unicode Then Dim SecondByte As Byte = RIFFfile.ReadByte I -= 1 If LowByteLast Then Result += ChrW(Tmp * 256 + SecondByte) Else Result += ChrW(Tmp + SecondByte * 256) End If Else Result += Chr(Tmp) End If End While Return Result End Function Function ReadString(ByVal I As Long) As String Dim Tmp As Byte Dim Result As String = "" While I > 0 Tmp = RIFFfile.ReadByte Result += IIf(Tmp = 0, "", Chr(Tmp)) I -= 1 End While Return Result End Function Function ReadFourCC() As String 'read four bytes into a string Dim Result As String = "" Result = Chr(RIFFfile.ReadByte()) & Chr(RIFFfile.ReadByte()) & Chr(RIFFfile.ReadByte()) & Chr(RIFFfile.ReadByte()) Return Result End Function Function ReadDWord() As Long 'read four bytes into a string Return RIFFfile.ReadByte() + _ RIFFfile.ReadByte() * 2 ^ 8 + _ RIFFfile.ReadByte() * 2 ^ 16 + _ RIFFfile.ReadByte() * 2 ^ 24 End Function Function ReadDWordRevProtected() As Long 'read four bytes into a string Return RIFFfile.ReadByte() * 2 ^ 21 + _ RIFFfile.ReadByte() * 2 ^ 14 + _ RIFFfile.ReadByte() * 2 ^ 7 + _ RIFFfile.ReadByte() End Function End Class