Skip to content

Commit

Permalink
First Local Commit v0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
perrybutler committed Sep 10, 2013
1 parent a2788c5 commit 47bdf85
Show file tree
Hide file tree
Showing 17 changed files with 1,726 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Perry's ID3 Tag Library.sln
@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Perry's ID3 Tag Library", "Perry's ID3 Tag Library\Perry's ID3 Tag Library.vbproj", "{0AAD4FAD-D851-4A41-A299-B6728F05AA28}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0AAD4FAD-D851-4A41-A299-B6728F05AA28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AAD4FAD-D851-4A41-A299-B6728F05AA28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AAD4FAD-D851-4A41-A299-B6728F05AA28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AAD4FAD-D851-4A41-A299-B6728F05AA28}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
39 changes: 39 additions & 0 deletions Perry's ID3 Tag Library/BitManipulator.vb
@@ -0,0 +1,39 @@
Public Class BitManipulator

' The ClearBit Sub clears the 1 based, nth bit
' (MyBit) of an integer (MyByte).
Shared Sub ClearBit(ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
' Create a bitmask with the 2 to the nth power bit set:
BitMask = 2 ^ (MyBit - 1)
' Clear the nth Bit:
MyByte = MyByte And Not BitMask
End Sub

' The ExamineBit function will return True or False
' depending on the value of the 1 based, nth bit (MyBit)
' of an integer (MyByte).
Shared Function ExamineBit(ByVal MyByte, ByVal MyBit) As Boolean
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
ExamineBit = ((MyByte And BitMask) > 0)
End Function

' The SetBit Sub will set the 1 based, nth bit
' (MyBit) of an integer (MyByte).
Shared Sub SetBit(ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Or BitMask
End Sub

' The ToggleBit Sub will change the state
' of the 1 based, nth bit (MyBit)
' of an integer (MyByte).
Shared Sub ToggleBit(ByRef MyByte, ByVal MyBit)
Dim BitMask As Int16
BitMask = 2 ^ (MyBit - 1)
MyByte = MyByte Xor BitMask
End Sub

End Class
40 changes: 40 additions & 0 deletions Perry's ID3 Tag Library/ComParser.vb
@@ -0,0 +1,40 @@
<ComClass(ComParser.ClassId, ComParser.InterfaceId, ComParser.EventsId)> _
Public Class ComParser

#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "2a314524-a053-4dc4-87dc-ffe55d8efdc8"
Public Const InterfaceId As String = "70c601e7-841d-4a50-b7e7-4e69665a2783"
Public Const EventsId As String = "d969b307-6f11-47f1-97b2-9d540b069f4a"
#End Region

' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub

''' <summary>
''' Parses an MP3 file whose result is accessible through COM.
''' </summary>
''' <param name="argFilePath"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function ParseMP3(ByVal argFilePath As String) As MP3File
Return New ComMP3File(argFilePath)
End Function

Public Class ComMP3File
Inherits ID3TagLibrary.MP3File
Sub New(ByVal argFilePath As String)
MyBase.new(argFilePath)
End Sub
End Class

End Class


Binary file added Perry's ID3 Tag Library/Documentation.doc
Binary file not shown.
180 changes: 180 additions & 0 deletions Perry's ID3 Tag Library/Globals.vb
@@ -0,0 +1,180 @@
Public Module Globals

''' <summary>
''' Gets the encoded size in bytes of an ID3v2.2 tag.
''' </summary>
''' <param name="argBytes"></param>
''' <returns></returns>
''' <remarks></remarks>
Function GetID3EncodedSizeV2(ByVal argBytes() As Byte) As Integer
Dim encodedSize As Integer
'encodedSize = argBytes(0) + argBytes(1) + argBytes(2)
encodedSize = (argBytes(0) * 256 * 256) + (argBytes(1) * 256) + argBytes(2)
Return encodedSize
End Function

''' <summary>
''' Gets the encoded size in bytes of an ID3v2.3 tag.
''' </summary>
''' <param name="argBytes"></param>
''' <returns></returns>
''' <remarks></remarks>
Function GetID3EncodedSizeV3(ByVal argBytes() As Byte) As Integer
Dim encodedSize As Integer
'encodedSize = (65536 * (argBytes(0) * 256 + argBytes(1))) + (argBytes(2) * 256 + argBytes(3))
'encodedSize = (argBytes(0) * 128 * 128 * 128) + (argBytes(1) * 128 * 128) + (argBytes(2) * 128) + argBytes(3)
encodedSize = (argBytes(0) * 256 * 256 * 256) + (argBytes(1) * 256 * 256) + (argBytes(2) * 256) + argBytes(3)
Return encodedSize
End Function

''' <summary>
''' Gets the encoded size in bytes of the ID3v2.4 tag.
''' </summary>
''' <param name="argBytes"></param>
''' <returns></returns>
''' <remarks></remarks>
Function GetID3EncodedSizeV4(ByVal argBytes() As Byte) As String

' According to ID3v2 spec, the encoded size is contained by 4 bytes. Each
' byte has it's MSB set to zero. The NORMAL CHART and UNSYNCHED CHART
' show this difference.

' NORMAL CHART (last 2 bytes)
' 16 15 14 13 12 11 10 9 | 8 7 6 5 4 3 2 1
' 32768 16384 8192 4096 2048 1024 512 256 | 128 64 32 16 8 4 2 1

' UNSYNCHED CHART (last 2 bytes)
' 16 15 14 13 12 11 10 9 | 8 7 6 5 4 3 2 1
' 0 8192 4096 2048 1024 512 256 128 | 0 64 32 16 8 4 2 1

'Dim encodedSize As Integer

'' check the value of each bit in the fourth byte and increment the encoded size
'If BitManipulator.ExamineBit(argBytes(3), 1) = True Then encodedSize += 1
'If BitManipulator.ExamineBit(argBytes(3), 2) = True Then encodedSize += 2
'If BitManipulator.ExamineBit(argBytes(3), 3) = True Then encodedSize += 4
'If BitManipulator.ExamineBit(argBytes(3), 4) = True Then encodedSize += 8
'If BitManipulator.ExamineBit(argBytes(3), 5) = True Then encodedSize += 16
'If BitManipulator.ExamineBit(argBytes(3), 6) = True Then encodedSize += 32
'If BitManipulator.ExamineBit(argBytes(3), 7) = True Then encodedSize += 64

'' check the value of each bit in the third byte and increment the encoded size
'If BitManipulator.ExamineBit(argBytes(2), 1) = True Then encodedSize += 128
'If BitManipulator.ExamineBit(argBytes(2), 2) = True Then encodedSize += 256
'If BitManipulator.ExamineBit(argBytes(2), 3) = True Then encodedSize += 512
'If BitManipulator.ExamineBit(argBytes(2), 4) = True Then encodedSize += 1024
'If BitManipulator.ExamineBit(argBytes(2), 5) = True Then encodedSize += 2048
'If BitManipulator.ExamineBit(argBytes(2), 6) = True Then encodedSize += 4096
'If BitManipulator.ExamineBit(argBytes(2), 7) = True Then encodedSize += 8192

'' check the value of each bit in the second byte and increment the encoded size
'If BitManipulator.ExamineBit(argBytes(1), 1) = True Then encodedSize += 16384
'If BitManipulator.ExamineBit(argBytes(1), 2) = True Then encodedSize += 32768
'If BitManipulator.ExamineBit(argBytes(1), 3) = True Then encodedSize += 65536
'If BitManipulator.ExamineBit(argBytes(1), 4) = True Then encodedSize += 131072
'If BitManipulator.ExamineBit(argBytes(1), 5) = True Then encodedSize += 262144
'If BitManipulator.ExamineBit(argBytes(1), 6) = True Then encodedSize += 524288
'If BitManipulator.ExamineBit(argBytes(1), 7) = True Then encodedSize += 1048576

'' check the value of each bit in the first byte and increment the encoded size
'If BitManipulator.ExamineBit(argBytes(0), 1) = True Then encodedSize += 2097152
'If BitManipulator.ExamineBit(argBytes(0), 2) = True Then encodedSize += 4194304
'If BitManipulator.ExamineBit(argBytes(0), 3) = True Then encodedSize += 8388608
'If BitManipulator.ExamineBit(argBytes(0), 4) = True Then encodedSize += 16777216
'If BitManipulator.ExamineBit(argBytes(0), 5) = True Then encodedSize += 33554432
'If BitManipulator.ExamineBit(argBytes(0), 6) = True Then encodedSize += 67108864
'If BitManipulator.ExamineBit(argBytes(0), 7) = True Then encodedSize += 134217728

'' subtract the tag header size (which is always 10 bytes according to ID3v2 spec) from the encodedSize to get the final tag size in bytes
'Return encodedSize - 10 '50934

Dim encodedSize As Integer
'encodedSize = (argBytes(0) * 256 * 256 * 256) + (argBytes(1) * 256 * 256) + (argBytes(2) * 256) + argBytes(3)
encodedSize = (argBytes(0) * 128 * 128 * 128) + (argBytes(1) * 128 * 128) + (argBytes(2) * 128) + argBytes(3)
Return encodedSize

End Function

''' <summary>
''' Converts an array of Bytes to a String, optionally removing non-alphanumeric characters.
''' </summary>
''' <param name="argBytes"></param>
''' <param name="argRemoveNonAlphanumeric"></param>
''' <returns></returns>
''' <remarks></remarks>
Function BytesToText(ByVal argBytes() As Byte, ByVal argRemoveNonAlphanumeric As Boolean) As String
Dim mText As String = ""

' new method
Dim lst As New ArrayList(argBytes)
Dim x() As Byte
x = Array.FindAll(argBytes, AddressOf isAlphaNumeric)
mText = Text.Encoding.ASCII.GetString(x)

' old method
'For Each b As Byte In argBytes
' Dim mCharacter As String
' If argRemoveNonAlphanumeric = True Then
' Select Case b
' Case Is < 32
' Case Else
' mCharacter = Convert.ToChar(b)
' mText &= mCharacter
' End Select
' Else
' mCharacter = Convert.ToChar(b)
' mText &= mCharacter
' End If
'Next

Return mText
End Function

''' <summary>
''' Checks whether a byte is an alphanumeric character in the ASCII table.
''' </summary>
''' <param name="b"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function isAlphaNumeric(ByVal b As Byte) As Boolean
If b > 31 And b < 128 Then
Return True
Else
Return False
End If
End Function

''' <summary>
''' Converts a Byte array to a String of comma-delimited numeric ASCII codes.
''' </summary>
''' <param name="argBytes"></param>
''' <returns></returns>
''' <remarks></remarks>
Function BytesToAsciiCodes(ByVal argBytes() As Byte) As String
Dim mText As String = ""
For Each b As Byte In argBytes
If mText = "" Then
mText = b
Else
mText &= ", " & b
End If
Next
Return mText
End Function

''' <summary>
''' Removes one or more characters from a string.
''' </summary>
''' <param name="argString">The string that should have one or more characters removed.</param>
''' <param name="argRemove">An array of integer ASCII codes. Hint: New Integer() {1, 5, 23}</param>
''' <returns></returns>
''' <remarks></remarks>
Function RemoveChars(ByVal argString As String, ByVal argRemove() As Integer)
For i As Integer = 0 To argRemove.Length - 1
argString = argString.Replace(Chr(argRemove(i)), "")
Next
Return argString
End Function

End Module

Binary file added Perry's ID3 Tag Library/ID3LibraryKeyFile.snk
Binary file not shown.
63 changes: 63 additions & 0 deletions Perry's ID3 Tag Library/ID3v1Tag.vb
@@ -0,0 +1,63 @@
Public Class ID3v1Tag

Public FileIdentifier As String
Public Title As String
Public Artist As String
Public Album As String
Public Year As String
Public Comment As String
Public Genre As String
Public TagVersion As String

Sub New(ByVal argFileInfo As IO.FileInfo)

Dim mReader As IO.FileStream = argFileInfo.OpenRead

Dim mFileIdentifier(2) As Byte
Dim mTitle(29) As Byte
Dim mArtist(29) As Byte
Dim mAlbum(29) As Byte
Dim mYear(3) As Byte
Dim mComment(29) As Byte
Dim mGenre(0) As Byte

' start at the last 128 bytes of the file, which is where an ID3v1 tag is supposed to be
mReader.Position = mReader.Length - 128

' read the file identifier and make sure the value equals "TAG" which indicates an ID3v1 tag
mReader.Read(mFileIdentifier, 0, 3)
Me.FileIdentifier = BytesToText(mFileIdentifier, True).Trim

' read the rest of the tag if it is an ID3v1 tag
If Me.FileIdentifier = "TAG" Then

Me.TagVersion = "1.0"

mReader.Read(mTitle, 0, 30)
mReader.Read(mArtist, 0, 30)
mReader.Read(mAlbum, 0, 30)
mReader.Read(mYear, 0, 4)
mReader.Read(mComment, 0, 30)
mReader.Read(mGenre, 0, 1)

Me.Title = BytesToText(mTitle, True).Trim
Me.Artist = BytesToText(mArtist, True).Trim
Me.Album = BytesToText(mAlbum, True).Trim
Me.Year = BytesToText(mYear, True).Trim
Me.Comment = BytesToText(mComment, True).Trim
'Me.Comment = RemoveChars(Me.Comment, New Integer() {0, 1, 32})
Me.Genre = mGenre(0)

Else

'MsgBox("Could not find an ID3v1 tag!")

End If

' close the file handle (remove the lock)
mReader.Close()
mReader.Dispose()

End Sub

End Class

0 comments on commit 47bdf85

Please sign in to comment.