#include-once #include #include #include Dim $ID3Filenames = "",$AlbumArtFilename = "" Dim $ID3BufferArray[1] = [0];use to buffer ID3 Data ;=============================================================================== ; Function Name: _ID3ReadTag($Filename, $iVersion = 0, $sFilter = -1, $iReturnArray = 0) ; Description: Reads ID3 Tag data from mp3 file and stores tag data in an array ; Reads ID3v1.0, ID3v1.1, ID3v2.3, ID3v2.2($sFilter will not work for ID3v2.2) ; Author(s): None listed, but believed to originally be joeyb1275 etc at the AutoIt Forum ; ( http://www.autoitscript.com/forum/index.php?showtopic=43950&st=0 ) ; TheSaint (for several additional modifications/changes listed throughout) ; Parameter(s): $Filename - Filename of mp3 file include full path ; $iVersion - ID3 Version to read (Default: 0 => ID3v1 & ID3v2) ; 0 => Read ID3v1 & ID3v2 ; 1 => Read ID3v1 ; 2 => Read ID3v2 ; $sFilter - ID3v2 Frame Filter (Default: -1 => all frames) ; If used format should be a pipe delimted string ; of the Frame IDs (ie. "TIT2|TALB|TPE1|TYER|APIC") ; $iReturnArray - Return Array of Field Data (Default: 0 => array not returned) ; 0 => Do not return Array ; 1 => Return Array ; 2 => Testing I presume (this comment by TheSaint) ; Requirement(s): None ; Return Value(s): On Success - Returns the Array of tag fields and data or 1 depends on $iReturnArray. ; On Failure - 0 and Sets @error = -1 for end-of-file, @error = 1 for other errors ;Notes: (Frame ID Definitions - not all may work) ;~ AENC Audio encryption ;~ APIC Attached picture ;~ COMM Comments ;~ COMR Commercial frame ;~ ENCR Encryption method registration ;~ EQUA Equalization ;~ ETCO Event timing codes ;~ GEOB General encapsulated object ;~ GRID Group identification registration ;~ IPLS Involved people list ;~ LINK Linked information ;~ MCDI Music CD identifier ;~ MLLT MPEG location lookup table ;~ OWNE Ownership frame ;~ PRIV Private frame ;~ PCNT Play counter ;~ POPM Popularimeter ;~ POSS Position synchronisation frame ;~ RBUF Recommended buffer size ;~ RVAD Relative volume adjustment ;~ RVRB Reverb ;~ SYLT Synchronized lyric/text ;~ SYTC Synchronized tempo codes ;~ TALB Album/Movie/Show title ;~ TBPM BPM (beats per minute) ;~ TCOM Composer ;~ TCON Content type ;~ TCOP Copyright message ;~ TDAT Date ;~ TDLY Playlist delay ;~ TENC Encoded by ;~ TEXT Lyricist/Text writer ;~ TFLT File type ;~ TIME Time ;~ TIT1 Content group description ;~ TIT2 Title/songname/content description ;~ TIT3 Subtitle/Description refinement ;~ TKEY Initial key ;~ TLAN Language(s) ;~ TLEN Length ;~ TMED Media type ;~ TOAL Original album/movie/show title ;~ TOFN Original filename ;~ TOLY Original lyricist(s)/text writer(s) ;~ TOPE Original artist(s)/performer(s) ;~ TORY Original release year ;~ TOWN File owner/licensee ;~ TPE1 Lead performer(s)/Soloist(s) ;~ TPE2 Band/orchestra/accompaniment ;~ TPE3 Conductor/performer refinement ;~ TPE4 Interpreted, remixed, or otherwise modified by ;~ TPOS Part of a set ;~ TPUB Publisher ;~ TRCK Track number/Position in set ;~ TRDA Recording dates ;~ TRSN Internet radio station name ;~ TRSO Internet radio station owner ;~ TSIZ Size ;~ TSRC ISRC (international standard recording code) ;~ TSSE Software/Hardware and settings used for encoding ;~ TYER Year ;~ TXXX User defined text information frame ;~ UFID Unique file identifier ;~ USER Terms of use ;~ USLT Unsychronized lyric/text transcription ;~ WCOM Commercial information ;~ WCOP Copyright/Legal information ;~ WOAF Official audio file webpage ;~ WOAR Official artist/performer webpage ;~ WOAS Official audio source webpage ;~ WORS Official internet radio station homepage ;~ WPAY Payment ;~ WPUB Publishers official webpage ;~ WXXX User defined URL link frame ;=============================================================================== Func _ID3ReadTag($Filename, $iVersion = 0, $sFilter = -1, $iReturnArray = 0) If Not(FileExists($Filename)) Then Return 0 Dim $ID3BufferArray[1] = [0] ;clear Buffer Switch $iVersion Case 0 _ReadID3v2($Filename,$ID3BufferArray,$sFilter) _ReadID3v1($Filename,$ID3BufferArray) Case 1 _ReadID3v1($Filename,$ID3BufferArray) Case 2 _ReadID3v2($Filename,$ID3BufferArray,$sFilter) EndSwitch ;Add Filename to buffer ;**************************************************************************************** _ArrayAdd($ID3BufferArray,$Filename) $ID3BufferArray[0] += 1 SetError(0) ;**************************************************************************************** ;Setup simple array to return (IF $iReturnArray = 1) ;**************************************************************************************** Local $ID3Array[1] = [0] If $iReturnArray = 1 Or $iReturnArray = 3 Then ; The following was added by TheSaint, as Artist & Title were not being returned in the ; final array Dim $f If $iVersion = 1 Then $f = 1 Else $f = 3 EndIf ; For $i = $f To $ID3BufferArray[0] $ID3FrameArray = StringSplit($ID3BufferArray[$i], "|") _ArrayAdd($ID3Array,$ID3FrameArray[1] & "|" & _ID3GetTagField($ID3FrameArray[1])) $ID3Array[0] += 1 Next Return $ID3Array Elseif $iReturnArray = 2 Then Return $ID3BufferArray Else Return 1 EndIf ;**************************************************************************************** EndFunc ;=============================================================================== ; Function Name: _ID3GetTagField() ; Description: Reads the ID3 Tag Data from an mp3 file and stores it in a Buffer and returns the Field Requested ; Parameter(s): $Filename - Filename of mp3 file include full path ; $sFieldIDRequest - ID3 Field ID String of the Field to return (ie. "TIT2" for ID3v2 Title or "Title" for ID3v1 Title) ; $undef - Value determines what's displayed etc (Added by TheSaint) ; 0 => Do not display 'Undefined' msg dialog ; 1 => Display 'Undefined' msg dialog & return 'Undefined' ; 2 => Don't display 'Undefined' msg dialog but return 'Undefined' ; Requirement(s): None ; Return Value(s): On Success - Returns Field String. If multiple fields found string is delimited with @CRLF. ; @error = 0; @extended = number of fields found (ID3v2 can have multiple COMM Fields) ; On Failure - Returns Empty String meaning $sFieldIDRequest did not match any IDs in the mp3 File ; @error = 1; @extended = 0 ; This has now been somewhat modified by TheSaint, as enduser (not programmer) ; does not need to see these errors in most circumstances. ; Notes: $undef parameter is passed to _GetID3FrameString function (when requested) ;=============================================================================== Func _ID3GetTagField($sFieldIDRequest, $undef = 0) ;add support for ID3v2.2 ; $undef - Added by TheSaint ;Check Buffer; If buffer is empty then set error and return If $ID3BufferArray[0] == 0 Then SetError(1) Return "" EndIf Local $sFieldID, $sFieldString = "", $TagFound = False, $NumFound = 0 ;get specified field from buffer For $i = 1 To $ID3BufferArray[0] $aBufferFrameString = StringSplit($ID3BufferArray[$i],"|") If $aBufferFrameString[0] > 1 Then $sFieldID = $aBufferFrameString[1] If $sFieldID == $sFieldIDRequest Then $TagFound = True $sFieldString = _GetID3FrameString($ID3BufferArray[$i], $undef) ;~ If $TagFound Then ;~ $sFieldString = $sFieldString & @CRLF & $aBufferFrameString[2] ;~ Else ;~ $sFieldString = $aBufferFrameString[2] ;~ EndIf ;$NumFound += 1 ;$TagFound = True EndIf EndIf Next ;Set Error and Extended Macros SetError(Not($TagFound),$NumFound) Return $sFieldString EndFunc ;updates the field in the buffer and updates the Frame Size in buffer Func _ID3SetTagField($sFieldIDRequest, $sFieldValue) Local $FrameID = "" Local $FrameIDFound = False, $TagSize = 0 Local $ArrayIndex = 0, $TagSizeIndex = 0 ;Get specified field from buffer ;**************************************************************************************** For $i = 1 To $ID3BufferArray[0] $aBufferFrameString = StringSplit($ID3BufferArray[$i],"|") If $aBufferFrameString[0] > 1 Then $FrameID = $aBufferFrameString[1] If $FrameID == "TagSize" Then $TagSize = Number($aBufferFrameString[2]) $TagSizeIndex = $i EndIf If $FrameID == $sFieldIDRequest Then $FrameIDFound = True $ArrayIndex = $i ExitLoop EndIf EndIf Next ;**************************************************************************************** ;Change Frame Data and Size (Need to add all Frame Types) ;**************************************************************************************** If Not $FrameIDFound Then _ArrayAdd($ID3BufferArray,"") $ID3BufferArray[0] += 1 $ArrayIndex = $ID3BufferArray[0] $FrameID = $sFieldIDRequest EndIf If (StringMid($FrameID,1,1) == "T") and (StringLen($FrameID) == 4) and ($FrameID <> "TXXX") Then ;~
;~ Text encoding $xx ;~ Information $bFrameData = Binary("0x00") ;Text Encoding $bFrameData &= StringToBinary($sFieldValue) ;~ If $FrameID = "TPE1" Then MsgBox(262144, "$sFieldValue", $sFieldValue) $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $bFrameData & "|" & BinaryLen($bFrameData) Elseif $FrameID == "Title" Or $FrameID == "Artist" Or $FrameID == "Album" _ Or $FrameID == "Year" Or $FrameID == "Comment" Or $FrameID == "Track" _ Or $FrameID == "Genre" Then ; This whole 'ElseIf' code was added by TheSaint, because ID3v1 tags were not being ; written in any way that he could detect - it all seemed incomplete $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $sFieldValue Elseif $FrameID == "TXXX" Then ;~
;~ Text encoding $xx ;~ Description $00 (00) ;~ Value $bFrameData = Binary("0x00") ;Text Encoding $bFrameData = Binary("0x00") ;Description $bFrameData &= StringToBinary($sFieldValue) $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $bFrameData & "|" & BinaryLen($bFrameData) ElseIf (StringMid($FrameID,1,1) == "W") and (StringLen($FrameID) == 4) and ($FrameID <> "WXXX") Then ;~
;~ URL $bFrameData = StringToBinary($sFieldValue) $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $bFrameData & "|" & BinaryLen($bFrameData) ElseIf $FrameID == "WXXX" Then ;~
;~ Text encoding $xx ;~ Description $00 (00) ;~ URL $bFrameData = Binary("0x00") ;Text Encoding $bFrameData = Binary("0x00") ;Description $bFrameData &= StringToBinary($sFieldValue) $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $bFrameData & "|" & BinaryLen($bFrameData) Else Switch $FrameID Case "COMM" ;~
;~ Text encoding $xx ;~ Language $xx xx xx ;~ Short content descrip. $00 (00) ;~ The actual text $bFrameData = Binary("0x00") ;Text Encoding $bFrameData &= StringToBinary("eng") ;Language (eng ONLY) $bFrameData &= Binary("0x00") ;Short content descrip. (NONE) $bFrameData &= StringToBinary($sFieldValue) $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $bFrameData & "|" & BinaryLen($bFrameData) Case "APIC" ;~
;~ Text encoding $xx ;~ MIME type $00 ;~ Picture type $xx ;~ Description $00 (00) ;~ Picture data $bFrameData = Binary("0x00") ;Text Encoding $bFrameData &= StringToBinary("image/jpg") & Binary("0x00") ;MIME type (JPEG ONLY) $bFrameData &= Binary("0x03") ;Picture type ($03 Cover (front) ONLY) $bFrameData &= StringToBinary("Cover Image") & Binary("0x00") ;Description $FrameSize = FileGetSize($sFieldValue) + BinaryLen($bFrameData) $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $bFrameData & "|" & $sFieldValue & "|" & $FrameSize Case "USLT" ;~
;~ Text encoding $xx ;~ Language $xx xx xx ;~ Content descriptor $00 (00) ;~ Lyrics/text $bFrameData = Binary("0x00") ;Text Encoding $bFrameData &= StringToBinary("eng") ;Language (eng ONLY) $bFrameData &= Binary("0x00") ;Content descriptor (NONE) $FrameSize = FileGetSize($sFieldValue) + BinaryLen($bFrameData) $ID3BufferArray[$ArrayIndex] = $FrameID & "|" & $bFrameData & "|" & $sFieldValue & "|" & $FrameSize Case "UFID" ;Not Implimented Yet ;~
;~ Owner identifier $00 ;~ Identifier EndSwitch EndIf ;**************************************************************************************** EndFunc Func _ID3RemoveField($sFieldIDRequest) Local $FrameID = "" Local $FrameIDFound = False, $TagSize = 0 Local $ArrayIndex = 0, $TagSizeIndex = 0 ;Get specified field from buffer ;**************************************************************************************** For $i = 1 To $ID3BufferArray[0] $aBufferFrameString = StringSplit($ID3BufferArray[$i],"|") If $aBufferFrameString[0] > 1 Then $FrameID = $aBufferFrameString[1] If $FrameID == "TagSize" Then $TagSize = Number($aBufferFrameString[2]) $TagSizeIndex = $i EndIf If $FrameID == $sFieldIDRequest Then $FrameIDFound = True $ArrayIndex = $i ExitLoop EndIf EndIf Next ;**************************************************************************************** If $FrameIDFound Then _ArrayDelete($ID3BufferArray,$ArrayIndex) $ID3BufferArray[0] -= 1 EndIf EndFunc ;actually writes the tag Func _ID3WriteTag($Filename,$iFlag = 0) Switch $iFlag Case 0 ;Wite both ID3v1 and ID3v2 Tags $TagFile = StringTrimRight($Filename,4) & "_ID3TAG.mp3" _FileCreate($TagFile) Local $OldTagSize = 0, $ID3v1Tag = StringToBinary("TAG"), $ID3v1_Artist = "" Local $ID3v1_Title = "", $ID3v1_Album = "", $ID3v1_Year = "", $ID3v1_Comment = "" Local $ID3v1_Genre = "", $ID3v1_Track = "" $hTagFile = Fileopen($TagFile,1) ;append ;Write ID3 FileWrite($TagFile,StringToBinary("ID3")) ;Write Version (Assume ID3v2.3) ;**************************************************************************************** FileWrite($TagFile,Binary("0x" & Hex(Number(3),2))) FileWrite($TagFile,Binary("0x" & Hex(Number(0),2))) ;**************************************************************************************** ;Write Flags (Assume all zero) ;**************************************************************************************** FileWrite($TagFile,Binary("0x00")) ;**************************************************************************************** ;Calculate new TagSize ;**************************************************************************************** Dim $NewTagSize = 0 For $i = 1 To $ID3BufferArray[0] $aBufferFrameString = StringSplit($ID3BufferArray[$i],"|") If $aBufferFrameString[0] > 2 Then $NewTagSize += Number($aBufferFrameString[$aBufferFrameString[0]]) + 10 EndIf If $aBufferFrameString[1] == "ZPAD" Then $NewTagSize += Number($aBufferFrameString[$aBufferFrameString[0]]) EndIf Next ;~ MsgBox(262144,"$NewTagSize",$NewTagSize) ;**************************************************************************************** ;Write TagSize (4 byte number) ;**************************************************************************************** $sTagSize = $NewTagSize $iTagSize = Hex($NewTagSize) $bTagSize = _HexToBin_ID3($iTagSize) $bTagSize = _StringReverse($bTagSize) $bTagSize = StringLeft($bTagSize,28) $TagHeaderBin = StringMid($bTagSize,1,7) & "0" & StringMid($bTagSize,8,7) & "0" & _ StringMid($bTagSize,15,7) & "0" & StringMid($bTagSize,22,7) & "0" $TagHeaderBin = _StringReverse($TagHeaderBin) $TagHeader = _BinToHex_ID3($TagHeaderBin) FileWrite($TagFile,Binary("0x" & $TagHeader)) ;**************************************************************************************** ;Write Frames to File ;**************************************************************************************** For $i = 1 To $ID3BufferArray[0] ; The line below relocated here by TheSaint, because of $ZPAD not assigned error Dim $ZPAD = Binary("0x00") $aBufferFrameString = StringSplit($ID3BufferArray[$i],"|") ;~ If $aBufferFrameString[0] = 1 Then ;~ MsgBox(262144, $i, $aBufferFrameString[1]) ;~ ElseIf $aBufferFrameString[0] = 2 Then ;~ MsgBox(262144, $i, $aBufferFrameString[1] & " | " & $aBufferFrameString[2]) ;~ ElseIf $aBufferFrameString[0] = 3 Then ;~ MsgBox(262144, $i, $aBufferFrameString[1] & " | " & $aBufferFrameString[2] & " | " & $aBufferFrameString[3]) ;~ EndIf If $aBufferFrameString[1] == "ZPAD" Then ;Dim $ZPAD = Binary("0x00") For $iZPAD = 2 to Number($aBufferFrameString[$aBufferFrameString[0]]) $ZPAD &= Binary("0x00") Next $NewTagSize += Number($aBufferFrameString[$aBufferFrameString[0]]) ElseIf $aBufferFrameString[1] == "TagSize" Then $OldTagSize = Number($aBufferFrameString[2]) ;MsgBox(262144,"$OldTagSize",$OldTagSize) ElseIf $aBufferFrameString[1] == "Title" Then $ID3v1_Title = StringToBinary(StringLeft($aBufferFrameString[2],30)) for $iPAD = 1 to (30 - BinaryLen($ID3v1_Title)) $ID3v1_Title &= Binary("0x00") Next ElseIf $aBufferFrameString[1] == "Artist" Then ;MsgBox(262144, "$aBufferFrameString[2]", $aBufferFrameString[2]) $ID3v1_Artist = StringToBinary(StringLeft($aBufferFrameString[2],30)) for $iPAD = 1 to (30 - BinaryLen($ID3v1_Artist)) $ID3v1_Artist &= Binary("0x00") Next ElseIf $aBufferFrameString[1] == "Album" Then $ID3v1_Album = StringToBinary(StringLeft($aBufferFrameString[2],30)) for $iPAD = 1 to (30 - BinaryLen($ID3v1_Album)) $ID3v1_Album &= Binary("0x00") Next ElseIf $aBufferFrameString[1] == "Year" Then $ID3v1_Year = StringToBinary(StringLeft($aBufferFrameString[2],4)) ElseIf $aBufferFrameString[1] == "Comment" Then $ID3v1_Comment = StringToBinary(StringLeft($aBufferFrameString[2],28)) ;28 bytes for ID3v1.1 for $iPAD = 1 to (28 - BinaryLen($ID3v1_Comment)) $ID3v1_Comment &= Binary("0x00") Next ElseIf $aBufferFrameString[1] == "Track" Then $ID3v1_Track = StringLeft($aBufferFrameString[2],3) ElseIf $aBufferFrameString[1] == "Genre" Then $ID3v1_Genre = $aBufferFrameString[2] EndIf If $aBufferFrameString[0] > 2 Then If $aBufferFrameString[1] == "APIC" Then FileWrite($TagFile,StringToBinary($aBufferFrameString[1])) FileWrite($TagFile,Binary("0x" & Hex($aBufferFrameString[$aBufferFrameString[0]],8))) ;FrameSize FileWrite($TagFile,Binary("0x" & Hex(0,2))) ;FrameFlag1 FileWrite($TagFile,Binary("0x" & Hex(0,2))) ;FrameFlag2 FileWrite($TagFile,Binary($aBufferFrameString[2])) $PicFile_h = FileOpen($aBufferFrameString[3], 16) ;force binary $WriteError = FileWrite($TagFile,FileRead($PicFile_h)) FileClose($PicFile_h) ElseIf $aBufferFrameString[1] == "USLT" Then FileWrite($TagFile,StringToBinary($aBufferFrameString[1])) FileWrite($TagFile,Binary("0x" & Hex($aBufferFrameString[$aBufferFrameString[0]],8))) ;FrameSize FileWrite($TagFile,Binary("0x" & Hex(0,2))) ;FrameFlag1 FileWrite($TagFile,Binary("0x" & Hex(0,2))) ;FrameFlag2 FileWrite($TagFile,Binary($aBufferFrameString[2])) $LyricsFile_h = FileOpen($aBufferFrameString[3], 16) ;force binary $LyricData = FileRead($LyricsFile_h) $WriteError = FileWrite($TagFile,$LyricData) FileClose($LyricsFile_h) Else FileWrite($TagFile,StringToBinary($aBufferFrameString[1])) FileWrite($TagFile,Binary("0x" & Hex($aBufferFrameString[$aBufferFrameString[0]],8))) ;FrameSize FileWrite($TagFile,Binary("0x" & Hex(0,2))) ;FrameFlag1 FileWrite($TagFile,Binary("0x" & Hex(0,2))) ;FrameFlag2 FileWrite($TagFile,Binary($aBufferFrameString[2])) ;Frame Data EndIf $NewTagSize += Number($aBufferFrameString[$aBufferFrameString[0]]) + 10 EndIf Next ;**************************************************************************************** ;Write Tag Padding ;**************************************************************************************** FileWrite($TagFile,$ZPAD) ;**************************************************************************************** ;Write MP3 Data ;**************************************************************************************** $hFile = FileOpen($Filename,16) ;read force binary FileRead($hFile,$OldTagSize) ;read past Old Tag FileWrite($hTagFile,FileRead($hFile,FileGetSize($Filename) - 128 - $OldTagSize)) ;Write the mp3 data ;**************************************************************************************** ;Write ID3v1.1 Tag ;**************************************************************************************** $ID3v1Tag &= $ID3v1_Title $ID3v1Tag &= $ID3v1_Artist $ID3v1Tag &= $ID3v1_Album $ID3v1Tag &= $ID3v1_Year $ID3v1Tag &= $ID3v1_Comment $ID3v1Tag &= Binary("0x00") $ID3v1Tag &= Binary("0x" & Hex(Number($ID3v1_Track),2)) $ID3v1Tag &= Binary("0x" & Hex(_GetGenreID($ID3v1_Genre),2)) FileWrite($hTagFile,$ID3v1Tag) ;**************************************************************************************** ;~ MsgBox(262144, "$ID3v1_Artist", BinaryToString($ID3v1_Artist)) FileClose($hFile) FileClose($hTagFile) FileCopy($TagFile,$Filename,1) FileDelete($TagFile) EndSwitch EndFunc ;=============================================================================== ; Function Name: _ID3DeleteFiles() ; Description: Deletes any files created by ID3.au3 (ie. AlbumArt.jpeg and SongLyrics.txt) ; Parameter(s): None ; Requirement(s): None ; Return Value(s): On Success - Returns 1. ; On Failure - Returns 0 ;=============================================================================== Func _ID3DeleteFiles() If $ID3Filenames == "" Then Return 1 $aID3File = StringSplit($ID3Filenames,"|") For $i = 1 To $aID3File[0] If FileExists($aID3File[$i]) Then $ret = FileDelete($aID3File[$i]) If $ret == 0 Then Return 0 EndIf Next $ID3Filenames = "" Return 1 EndFunc ; ----------------------------------------------------------------------------- ;------------------- Main File Reading Functions ----------------------------- Func _ReadID3v2($Filename, ByRef $aID3V2Tag, $sFilter = -1) Local $ZPAD = 0, $BytesRead = 0 Local $hFile = FileOpen($Filename,16) ;mode = Force binary Local $iFilterNum If $sFilter <> -1 Then $aFilter = StringSplit($sFilter,"|") $iFilterNum = $aFilter[0] EndIf ;Read Header Bytes (First 10 Bytes of File) ;**************************************************************************************** Local $ID3v2Header = FileRead($hFile, 10) _ArrayAdd($aID3V2Tag,"Header" & "|" & $ID3v2Header) $aID3V2Tag[0] += 1 $BytesRead = 10 ;ID3 Header has been read (Header Size = 10 Bytes) ;~ MsgBox(262144,"$ID3v2Header",$ID3v2Header) ;**************************************************************************************** ;Read "ID3" string ;**************************************************************************************** If Not(BinaryToString(BinaryMid($ID3v2Header,1,3)) == "ID3") Then FileClose($hFile) SetError(1) Return 0 EndIf ;**************************************************************************************** ;GetTagVer ;**************************************************************************************** Local $FrameIDLen ;equals 3 or 4 depending on ID3v2.2 or ID3v2.3+ Local $ID3v2Version = String(Number(BinaryMid($ID3v2Header,4,1))) & "." & String(Number(BinaryMid($ID3v2Header,5,1))) ;~ If $sFilter == -1 Then ;~ ;_ArrayAdd($aID3V2Tag,"Version" & "|" & "ID3v2." & $ID3v2Version) ;~ ;$aID3V2Tag[0] += 1 ;~ EndIf ;~ MsgBox(262144,"$ID3v2Version",$ID3v2Version) If StringInStr($ID3v2Version,"2.") Then $FrameIDLen = 3 If $sFilter <> -1 Then _ConvertFilterToID3v2_2($sFilter) EndIf Else $FrameIDLen = 4 EndIf ;**************************************************************************************** ;GetTagFlags ;**************************************************************************************** Local $TagFlagsBin = BinaryMid($ID3v2Header,6,1) Local $TagFlags = _HexToBin_ID3(StringTrimLeft($TagFlagsBin,2)) Local $Unsynchronisation = StringMid($TagFlags,1,1) Local $ExtendedHeader = StringMid($TagFlags,2,1) Local $ExperimentalIndicator = StringMid($TagFlags,3,1) Local $Footer = StringMid($TagFlags,4,1) If Not $TagFlags == "00000000" Then MsgBox(262144,"$ID3TagFlags", $TagFlags) EndIf ;~ If $sFilter == -1 Then ;~ _ArrayAdd($aID3V2Tag,"Unsynchronisation" & "|" & $Unsynchronisation) ;~ _ArrayAdd($aID3V2Tag,"ExtendedHeader" & "|" & $ExtendedHeader) ;~ _ArrayAdd($aID3V2Tag,"ExperimentalIndicator" & "|" & $ExperimentalIndicator) ;~ _ArrayAdd($aID3V2Tag,"Footer" & "|" & $Footer) ;~ $aID3V2Tag[0] += 4 ;~ EndIf ;**************************************************************************************** ;GetTagSize ;**************************************************************************************** Local $TagSizeBin = "" $TagHeaderBin = _HexToBin_ID3(StringTrimLeft(BinaryMid($ID3v2Header,7,4),2)) ;Removes 0x For $i = 1 To 33 Step 8 $TagSizeBin &= StringMid($TagHeaderBin,$i + 1,7) ;Skip most significant bit in every byte Next Local $TagSize = Dec(_BinToHex_ID3($TagSizeBin)) + 10 ;add 10 to include header If ($sFilter == -1) or StringInStr($sFilter,"TagSize") Then _ArrayAdd($aID3V2Tag,"TagSize" & "|" & $TagSize) $aID3V2Tag[0] += 1 If $aID3V2Tag[0] == ($iFilterNum + 1) Then ;Plus one needed to account for Header FileClose($hFile) Return 1 EndIf EndIf ;~ MsgBox(262144,"$TagSize",$TagSize) ;**************************************************************************************** ;Read in all of the tag and close the file might be faster Local $ZPadding, $FrameIDFristHex, $FrameID, $FrameSizeHex, $FrameSize, $FrameFlag1, $FrameFlag2, $FoundTag, $index Local $FrameHeader ;Get Rest Of Tag While $BytesRead < $TagSize ;Initialize ZPAD & Read first Hex value to test for new Frame or NULL Bytes ;**************************************************************************************** $ZPadding = 0 $FrameIDFristHex = StringTrimLeft(FileRead($hFile,1),2) $BytesRead += 1 ;~ MsgBox(262144,"Chr(Dec($FrameIDFristHex))",Chr(Dec($FrameIDFristHex))) ;**************************************************************************************** ;check for NULL If $FrameIDFristHex == "00" Then ;Count how many NULL Bytes at the end of the Tag then Exit Loop ;**************************************************************************************** $ZPadding += 1 While $FrameIDFristHex == "00" $FrameIDFristHex = StringTrimLeft(FileRead($hFile,1),2) $BytesRead += 1 $ZPadding += 1 If $BytesRead >= $TagSize Then ExitLoop EndIf WEnd $ZPAD = $ZPadding ExitLoop ;**************************************************************************************** Else ;Read Frame ID String ;**************************************************************************************** $FrameID = Chr(Dec($FrameIDFristHex)) & BinaryToString(FileRead($hFile,$FrameIDLen-1)) $BytesRead += $FrameIDLen-1 ;**************************************************************************************** ;Check for a valid frameID string If StringIsAlNum($FrameID) Then ;Read Frame Header & Size (Differant for 2.2 and 2.3+) ;**************************************************************************************** If $FrameIDLen == 4 Then $bFrameHeader = FileRead($hFile,6) $BytesRead += 6 $FrameSizeHex = StringTrimLeft(BinaryMid($bFrameHeader,1,4),2) $FrameSize = _HexToUint32_ID3($FrameSizeHex) $FrameFlag1 = _HexToBin_ID3(StringTrimLeft(BinaryMid($bFrameHeader,5,1),2)) $FrameFlag2 = _HexToBin_ID3(StringTrimLeft(BinaryMid($bFrameHeader,6,1),2)) ElseIf $FrameIDLen == 3 Then $bFrameHeader = FileRead($hFile,3) ;only frame size $BytesRead += 3 $FrameSizeHex = StringTrimLeft(BinaryMid($bFrameHeader,1,3),2) $FrameSize = Dec($FrameSizeHex) EndIf ;~ MsgBox(262144,$FrameID,$FrameID) ;**************************************************************************************** ;Add FrameID and Frame Data to array ;**************************************************************************************** Dim $FrameData If $sFilter == -1 Then ;MsgBox(262192, "Got Here", 1) Switch $FrameID Case "APIC" ;Picture (Write to File) $FrameData = _GetAlbumArt($hFile,$FrameSize) Case "USLT" ;Lyrics (Write to File) $FrameData = _GetSongLyrics($hFile,$FrameSize) Case Else ;If $BytesRead > 427 Then MsgBox(262192, "$FrameSize", $FrameSize) ; Memory fix by TheSaint (just to avoid crashing)(not a true fix) If $FrameSize > 100000 Then $FrameSize = 100000 $bad = 1 ;MsgBox(262192, "$FrameSize", $FrameSize) EndIf $FrameData = FileRead($hFile,$FrameSize) EndSwitch _ArrayAdd($aID3V2Tag,$FrameID & "|" & $FrameData & "|" & $FrameSize) $aID3V2Tag[0] += 1 $BytesRead += $FrameSize Else If $aID3V2Tag[0] == ($iFilterNum + 1) Then ;Plus one needed to account for Header ExitLoop EndIf If StringInStr($sFilter,$FrameID) Then Switch $FrameID Case "APIC" ;Picture (Write to File) $FrameData = _GetAlbumArt($hFile,$FrameSize) Case "USLT" ;Lyrics (Write to File) $FrameData = _GetSongLyrics($hFile,$FrameSize) Case Else $FrameData = FileRead($hFile,$FrameSize) EndSwitch _ArrayAdd($aID3V2Tag,$FrameID & "|" & $FrameData & "|" & $FrameSize) $aID3V2Tag[0] += 1 Else FileRead($hFile,$FrameSize) EndIf $BytesRead += $FrameSize EndIf ;**************************************************************************************** EndIf EndIf WEnd ;Read MPEG Header & Write to Array MPEG & ZPAD ;**************************************************************************************** If ($sFilter == -1) or StringInStr($sFilter,"MPEG") or StringInStr($sFilter,"ZPAD") Then Local $MPEGHeaderCheck = $FrameIDFristHex & StringTrimLeft(FileRead($hFile,50),2) Local $index = StringInStr($MPEGHeaderCheck,"FF") Local $MPEGHeaderHex = StringMid($MPEGHeaderCheck,$index,8) ;check MPEG Header If _CheckMPEGHeader($MPEGHeaderHex) and (StringInStr($sFilter,"MPEG") or ($sFilter == -1)) Then _ArrayAdd($aID3V2Tag,"MPEG" & "|" & $MPEGHeaderHex) $aID3V2Tag[0] += 1 EndIf If StringInStr($sFilter,"ZPAD") or ($sFilter == -1) Then _ArrayAdd($aID3V2Tag,"ZPAD" & "|" & $ZPAD) $aID3V2Tag[0] += 1 EndIf EndIf ;**************************************************************************************** FileClose($hFile) Return 1 EndFunc Func _ReadID3v1($Filename, ByRef $aID3V1Tag) Local $hfile = FileOpen($Filename,16) ;open in binary mode FileRead($hfile,FileGetSize($Filename)-128) Local $ID3v1Tag = FileRead($hfile) FileClose($hfile) Local $ID3v1ID = BinaryToString(BinaryMid($ID3v1Tag,1,3)) If Not($ID3v1ID == "TAG") Then FileClose($hfile) SetError(-1) Return 0 EndIf Local $Title, $Artist, $Album, $Year, $Comment, $Track, $GenreID, $Genre $Title = BinaryToString(BinaryMid($ID3v1Tag,4,30)) _ArrayAdd($aID3V1Tag,"Title" & "|" & $Title) $aID3V1Tag[0] += 1 $Artist = BinaryToString(BinaryMid($ID3v1Tag,34,30)) _ArrayAdd($aID3V1Tag,"Artist" & "|" & $Artist) $aID3V1Tag[0] += 1 $Album = BinaryToString(BinaryMid($ID3v1Tag,64,30)) _ArrayAdd($aID3V1Tag,"Album" & "|" & $Album) $aID3V1Tag[0] += 1 $Year = BinaryToString(BinaryMid($ID3v1Tag,94,4)) _ArrayAdd($aID3V1Tag,"Year" & "|" & $Year) $aID3V1Tag[0] += 1 $Comment = BinaryToString(BinaryMid($ID3v1Tag,98,28)) _ArrayAdd($aID3V1Tag,"Comment" & "|" & $Comment) $aID3V1Tag[0] += 1 $Track = Dec(StringTrimLeft(BinaryMid($ID3v1Tag,126,2),2)) If $Track < 1000 And $Track > 0 Then _ArrayAdd($aID3V1Tag,"Track" & "|" & $Track) $aID3V1Tag[0] += 1 Else _ArrayAdd($aID3V1Tag,"Track" & "|" & "") $aID3V1Tag[0] += 1 EndIf $GenreID = Dec(StringTrimLeft(BinaryMid($ID3v1Tag,128,1),2)) $Genre = _GetGenreByID($GenreID) _ArrayAdd($aID3V1Tag,"Genre" & "|" & $Genre) $aID3V1Tag[0] += 1 If $Track == 0 Then _ArrayAdd($aID3V1Tag,"Version" & "|" & "ID3v1.0") $aID3V1Tag[0] += 1 Else _ArrayAdd($aID3V1Tag,"Version" & "|" & "ID3v1.1") $aID3V1Tag[0] += 1 EndIf FileClose($hfile) Return 1 EndFunc Func _GetID3FrameString($sFrameData, $undef = 0) ; $undef - Added by TheSaint Local $bTagFieldFound = False, $sFrameString = "" Local $bText_Encoding $aFrameData = StringSplit($sFrameData,"|") $FrameID = $aFrameData[1] If (StringMid($FrameID,1,1) == "T") and (StringLen($FrameID) == 4) and ($FrameID <> "TXXX") and ($FrameID <> "TCON") Then $bTagFieldFound = True $bFrameData = Binary($aFrameData[2]) $sFrameString = BinaryToString(BinaryMid($bFrameData,2)) Elseif $FrameID == "TXXX" Then $bTagFieldFound = True $bFrameData = Binary($aFrameData[2]) $bText_Encoding = BinaryMid($bFrameData,1,1) $ByteIndex = 2 $Description = "" $Byte = BinaryMid($bFrameData,$ByteIndex,1) $ByteIndex += 1 While $Byte <> "0x00" $Description &= BinaryToString($Byte) $Byte = BinaryMid($bFrameData,$ByteIndex,1) $ByteIndex += 1 WEnd $sFrameString = BinaryToString(BinaryMid($bFrameData,$ByteIndex)) Elseif $FrameID == "TCON" Then;Content Type/Genre $bTagFieldFound = True $bFrameData = Binary($aFrameData[2]) ; TheSaint added the following line which appeared to be missing, and because he ; was not ever getting the ID3 tag genre value being returned. He gleaned this ; from comparisons & testing, etc. This allowed a non genre number ID (i.e. text) ; to be returned. In any case, without that addition, the number ID wouldn't have ; been returning either. $bFrameData = BinaryMid($bFrameData,2) ; $Genre = BinaryToString($bFrameData) If StringMid($Genre,1,1) == "(" Then ;check if first char is "(" $closeparindex = StringInStr($Genre,")") $GenreID = StringMid($Genre,2,$closeparindex-1) $Genre = _GetGenreByID($GenreID) EndIf ;If no "(" then return the whole field as is $sFrameString = $Genre ElseIf (StringMid($FrameID,1,1) == "W") and (StringLen($FrameID) == 4) and ($FrameID <> "WXXX") Then $bTagFieldFound = True $bFrameData = Binary($aFrameData[2]) $sFrameString = BinaryToString($bFrameData) ElseIf $FrameID == "WXXX" Then $bTagFieldFound = True $bFrameData = Binary($aFrameData[2]) $bText_Encoding = BinaryMid($bFrameData,1,1) $ByteIndex = 2 $Description = "" $Byte = BinaryMid($bFrameData,$ByteIndex,1) $ByteIndex += 1 While $Byte <> "0x00" $Description &= BinaryToString($Byte) $Byte = BinaryMid($bFrameData,$ByteIndex,1) $ByteIndex += 1 WEnd $sFrameString = BinaryToString(BinaryMid($bFrameData,$ByteIndex)) Else Switch $FrameID Case "COMM", "COM" ;Comment $bTagFieldFound = True $bFrameData = Binary($aFrameData[2]) $bText_Encoding = BinaryMid($bFrameData,1,1) $Language = BinaryToString(BinaryMid($bFrameData,2,3)) $ByteIndex = 5 $Short_Content_Descrip = "" $Byte = BinaryMid($bFrameData,$ByteIndex,1) $ByteIndex += 1 While $Byte <> "0x00" $Short_Content_Descrip &= BinaryToString($Byte) $Byte = BinaryMid($bFrameData,$ByteIndex,1) $ByteIndex += 1 WEnd $sFrameString = BinaryToString(BinaryMid($bFrameData,$ByteIndex)) Case "APIC" $bTagFieldFound = True $sFrameString = $aFrameData[3] Case "USLT" $bTagFieldFound = True $sFrameString = $aFrameData[3] Case "UFID" $bTagFieldFound = True $bFrameData = Binary($aFrameData[2]) $sFrameString = BinaryToString(BinaryMid($bFrameData,2)) Case "Artist" ;ID3v1 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "Title" ;ID3v1 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "Album" ;ID3v1 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "Track" ;ID3v1 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "Year" ;ID3v1 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "Genre" ;ID3v1 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "Comment" ;ID3v1 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "Version" ;ID3v1 ; Case for Version was missing, so added by TheSaint $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "ZPAD" ;ID3v2 $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "MPEG" ;MPEG $bTagFieldFound = True $sFrameString = $aFrameData[2] Case "NCON" ;??http://www.id3.org/Compliance_Issues --- non-standard NCON frame in tag $bTagFieldFound = True $sFrameString &= "Non-Standard NCON Frame" Case "PRIV" ;Private frame $bTagFieldFound = True ;~ $Owner_Identifier = FileRead($hFile,1) ;~ $LengthToRead -= 1 ;~ $FrameString &= FileRead($hFile,$LengthToRead) ;~ Case "PCNT", "CNT" ;Play counter ;~ $bTagFieldFound = True ;~ $FrameString &= _HexToUint32_ID3(StringTrimLeft($aFrameData[2],2)) ;Not Tested ;~ Case "RVA" ;Relative volume adjustment ID3v2.2 only ;~ $bTagFieldFound = True ;~ $FrameString &= "TBP - Relative Volume Adjustment" ;Not Tested ;~ FileRead($hFile,$LengthToRead) Case Else ;MsgBox(262144,"$undef", $undef) If $undef = 1 Then MsgBox(262144,"$FrameID Unknown",$FrameID) $sFrameString &= "Undefined FrameID" ElseIf $undef = 2 Then $sFrameString &= "Undefined FrameID" Else ;$bTagFieldFound = True $sFrameString = $aFrameData[2] EndIf EndSwitch EndIf If $bTagFieldFound == False Then SetError(1) EndIf Return $sFrameString EndFunc ;-------------------------- Support Functions -------------------------------- Func _CheckMPEGHeader($MPEGFrameSyncHex) $MPEGFrameSyncUint32 = _HexToUint32_ID3($MPEGFrameSyncHex) If $MPEGFrameSyncUint32 > _HexToUint32_ID3("FFE00000") Then If $MPEGFrameSyncUint32 < _HexToUint32_ID3("FFFFEC00") Then If Not(StringMid($MPEGFrameSyncHex,4,1) == "0") Then If Not(StringMid($MPEGFrameSyncHex,4,1) == "1") Then If Not(StringMid($MPEGFrameSyncHex,4,1) == "9") Then ;valid MPEG Header Found Return 1 EndIf EndIf EndIf EndIf EndIf Return 0 EndFunc Func _GetAlbumArt($hFile,$FrameLen) Local $LengthToRead = $FrameLen, $AlbumArtFilename = @ScriptDir & "\" & "AlbumArt", $bReturn $bText_Encoding = FileRead($hFile,1) $LengthToRead -= 1 $MIME_Type = "" $Byte = FileRead($hFile,1) $bMIME_Type = $Byte $LengthToRead -= 1 While $Byte <> "0x00" $MIME_Type &= BinaryToString($Byte) $Byte = FileRead($hFile,1) $bMIME_Type &= $Byte $LengthToRead -= 1 WEnd ;~ MsgBox(262144,"$bMIME_Type",$bMIME_Type) $bPicture_Type = FileRead($hFile,1) $LengthToRead -= 1 $Description = "" $Byte = FileRead($hFile,1) $bDescription = $Byte $LengthToRead -= 1 While $Byte <> "0x00" $Description &= BinaryToString($Byte) $Byte = FileRead($hFile,1) $bDescription &= $Byte $LengthToRead -= 1 WEnd ;~ MsgBox(262144,"$Description",$Description) If StringInStr($MIME_Type,"jpg") Or StringInStr($MIME_Type,"jpeg") Then $AlbumArtFilename &= ".jpg" $ID3Filenames &= $AlbumArtFilename & "|" ElseIf StringInStr($MIME_Type,"png") Then $AlbumArtFilename &= ".png" $ID3Filenames &= $AlbumArtFilename & "|" Else $AlbumArtFilename = "File Type Unknown" EndIf ;Read Picture data to file ;**************************************************************************************** $PicFile_h = FileOpen($AlbumArtFilename, 2) ;Open for write and erase existing $WriteError = FileWrite($PicFile_h,FileRead($hFile, $LengthToRead)) FileClose($PicFile_h) ;**************************************************************************************** $bReturn = $bText_Encoding & $bMIME_Type $bReturn &= $bPicture_Type & $bDescription $bReturn &= "|" & $AlbumArtFilename Return $bReturn EndFunc Func _GetSongLyrics($hFile,$FrameLen) Local $LengthToRead = $FrameLen, $LyricsFilename = @ScriptDir & "\" & "SongLyrics.txt", $bReturn $ID3Filenames &= $LyricsFilename & "|" $bText_Encoding = FileRead($hFile,1) $LengthToRead -= 1 $bLanguage = FileRead($hFile,3) $LengthToRead -= 3 $Content_Descriptor = "" $Byte = FileRead($hFile,1) $bContent_Descriptor = $Byte $LengthToRead -= 1 While $Byte <> "0x00" $Content_Descriptor &= BinaryToString($Byte) $Byte = FileRead($hFile,1) $bContent_Descriptor &= $Byte $LengthToRead -= 1 WEnd $bLyrics_Text = FileRead($hFile,$LengthToRead) $Lyrics_Text = BinaryToString($bLyrics_Text) $hLyricFile = FileOpen($LyricsFilename, 2) ;Open for write and erase existing FileWrite($hLyricFile,$Lyrics_Text) FileClose($hLyricFile) $bReturn = $bText_Encoding & $bLanguage & $bContent_Descriptor $bReturn &= "|" & $LyricsFilename Return $bReturn EndFunc Func _ConvertFilterToID3v2_2(ByRef $sFilter) $sFilter = StringReplace($sFilter,"TIT1", "TT1") $sFilter = StringReplace($sFilter,"TIT2", "TT2") $sFilter = StringReplace($sFilter,"TIT3", "TT3") $sFilter = StringReplace($sFilter,"TEXT", "TXT") $sFilter = StringReplace($sFilter,"TLAN", "TLA") $sFilter = StringReplace($sFilter,"TKEY", "TKE") $sFilter = StringReplace($sFilter,"TMED", "TMT") $sFilter = StringReplace($sFilter,"TOAL", "TOT") $sFilter = StringReplace($sFilter,"TOFN", "TOF") $sFilter = StringReplace($sFilter,"TOLY", "TOL") $sFilter = StringReplace($sFilter,"TOPE", "TOA") $sFilter = StringReplace($sFilter,"TORY", "TOR") $sFilter = StringReplace($sFilter,"TPE1", "TP1") $sFilter = StringReplace($sFilter,"TPE2", "TP2") $sFilter = StringReplace($sFilter,"TPE3", "TP3") $sFilter = StringReplace($sFilter,"TPE4", "TP4") $sFilter = StringReplace($sFilter,"TPOS", "TPA") $sFilter = StringReplace($sFilter,"TALB", "TRK") $sFilter = StringReplace($sFilter,"TRCK", "TP2") $sFilter = StringReplace($sFilter,"TYER", "TYE") $sFilter = StringReplace($sFilter,"COMM", "COM") $sFilter = StringReplace($sFilter,"APIC", "PIC") $sFilter = StringReplace($sFilter,"USLT", "ULT") $sFilter = StringReplace($sFilter,"TSSE", "TSS") $sFilter = StringReplace($sFilter,"TENC", "TEN") $sFilter = StringReplace($sFilter,"TCOP", "TCR") $sFilter = StringReplace($sFilter,"TBPM", "TBP") $sFilter = StringReplace($sFilter,"TRDA", "TRD") $sFilter = StringReplace($sFilter,"TSIZ", "TSI") $sFilter = StringReplace($sFilter,"TSRC", "TRC") $sFilter = StringReplace($sFilter,"TCON", "TCO") $sFilter = StringReplace($sFilter,"TLEN", "TLE") $sFilter = StringReplace($sFilter,"TPUB", "TPB") $sFilter = StringReplace($sFilter,"TFLT", "TFT") $sFilter = StringReplace($sFilter,"UFID", "UFI") $sFilter = StringReplace($sFilter,"TCOM", "TCM") $sFilter = StringReplace($sFilter,"WCOM", "WCM") $sFilter = StringReplace($sFilter,"WCOP", "WCP") $sFilter = StringReplace($sFilter,"WXXX", "WXX") $sFilter = StringReplace($sFilter,"WOAR", "WAR") $sFilter = StringReplace($sFilter,"WOAS", "WAS") $sFilter = StringReplace($sFilter,"WOAF", "WAF") $sFilter = StringReplace($sFilter,"WPUB", "WPB") $sFilter = StringReplace($sFilter,"PCNT", "CNT") EndFunc ;Author: YDY (Lazycat) Thank you for writing all this out Func _GetGenreByID($iID) Local $asGenre = StringSplit("Blues,Classic Rock,Country,Dance,Disco,Funk,Grunge,Hip-Hop," & _ "Jazz,Metal,New Age, Oldies,Other,Pop,R&B,Rap,Reggae,Rock,Techno,Industrial,Alternative," & _ "Ska,Death Metal,Pranks,Soundtrack,Euro-Techno,Ambient,Trip-Hop,Vocal,Jazz+Funk,Fusion," & _ "Trance,Classical,Instrumental,Acid,House,Game,Sound Clip,Gospel,Noise,Alternative Rock," & _ "Bass,Soul,Punk,Space,Meditative,Instrumental Pop,Instrumental Rock,Ethnic,Gothic,Darkwave," & _ "Techno-Industrial,Electronic,Pop-Folk,Eurodance,Dream,Southern Rock,Comedy,Cult,Gangsta," & _ "Top 40,Christian Rap,Pop/Funk,Jungle,Native US,Cabaret,New Wave,Psychadelic,Rave,Showtunes," & _ "Trailer,Lo-Fi,Tribal,Acid Punk,Acid Jazz,Polka,Retro,Musical,Rock & Roll,Hard Rock,Folk," & _ "Folk-Rock,National Folk,Swing,Fast Fusion,Bebob,Latin,Revival,Celtic,Bluegrass,Avantgarde," & _ "Gothic Rock,Progressive Rock,Psychedelic Rock,Symphonic Rock,Slow Rock,Big Band,Chorus," & _ "Easy Listening,Acoustic,Humour,Speech,Chanson,Opera,Chamber Music,Sonata,Symphony,Booty Bass," & _ "Primus,Porn Groove,Satire,Slow Jam,Club,Tango,Samba,Folklore,Ballad,Power Ballad,Rhytmic Soul," & _ "Freestyle,Duet,Punk Rock,Drum Solo,Acapella,Euro-House,Dance Hall,Goa,Drum & Bass,Club-House," & _ "Hardcore,Terror,Indie,BritPop,Negerpunk,Polsk Punk,Beat,Christian Gangsta,Heavy Metal,Black Metal," & _ "Crossover,Contemporary C,Christian Rock,Merengue,Salsa,Thrash Metal,Anime,JPop,SynthPop", ",") If ($iID >= 0) and ($iID < 148) Then Return $asGenre[$iID + 1] Return("") EndFunc Func _GetGenreID($sGrenre) Local $asGenre = StringSplit("Blues,Classic Rock,Country,Dance,Disco,Funk,Grunge,Hip-Hop," & _ "Jazz,Metal,New Age, Oldies,Other,Pop,R&B,Rap,Reggae,Rock,Techno,Industrial,Alternative," & _ "Ska,Death Metal,Pranks,Soundtrack,Euro-Techno,Ambient,Trip-Hop,Vocal,Jazz+Funk,Fusion," & _ "Trance,Classical,Instrumental,Acid,House,Game,Sound Clip,Gospel,Noise,Alternative Rock," & _ "Bass,Soul,Punk,Space,Meditative,Instrumental Pop,Instrumental Rock,Ethnic,Gothic,Darkwave," & _ "Techno-Industrial,Electronic,Pop-Folk,Eurodance,Dream,Southern Rock,Comedy,Cult,Gangsta," & _ "Top 40,Christian Rap,Pop/Funk,Jungle,Native US,Cabaret,New Wave,Psychadelic,Rave,Showtunes," & _ "Trailer,Lo-Fi,Tribal,Acid Punk,Acid Jazz,Polka,Retro,Musical,Rock & Roll,Hard Rock,Folk," & _ "Folk-Rock,National Folk,Swing,Fast Fusion,Bebob,Latin,Revival,Celtic,Bluegrass,Avantgarde," & _ "Gothic Rock,Progressive Rock,Psychedelic Rock,Symphonic Rock,Slow Rock,Big Band,Chorus," & _ "Easy Listening,Acoustic,Humour,Speech,Chanson,Opera,Chamber Music,Sonata,Symphony,Booty Bass," & _ "Primus,Porn Groove,Satire,Slow Jam,Club,Tango,Samba,Folklore,Ballad,Power Ballad,Rhytmic Soul," & _ "Freestyle,Duet,Punk Rock,Drum Solo,Acapella,Euro-House,Dance Hall,Goa,Drum & Bass,Club-House," & _ "Hardcore,Terror,Indie,BritPop,Negerpunk,Polsk Punk,Beat,Christian Gangsta,Heavy Metal,Black Metal," & _ "Crossover,Contemporary C,Christian Rock,Merengue,Salsa,Thrash Metal,Anime,JPop,SynthPop", ",") For $i = 1 to $asGenre[0] If $sGrenre == $asGenre[$i] Then Return $i - 1 EndIf Next Return 12 ;Other EndFunc Func _HexToUint32_ID3($HexString4Byte) Return Dec(StringLeft($HexString4Byte,2)) * Dec("FFFFFF") + Dec(StringTrimLeft($HexString4Byte,2));need this because function Dec is signed EndFunc Func _HexToBin_ID3($HexString) Local $Bin = "" For $i = 1 To StringLen($HexString) Step 1 $Hex = StringRight(StringLeft($HexString, $i), 1) Select Case $Hex = "0" $Bin = $Bin & "0000" Case $Hex = "1" $Bin = $Bin & "0001" Case $Hex = "2" $Bin = $Bin & "0010" Case $Hex = "3" $Bin = $Bin & "0011" Case $Hex = "4" $Bin = $Bin & "0100" Case $Hex = "5" $Bin = $Bin & "0101" Case $Hex = "6" $Bin = $Bin & "0110" Case $Hex = "7" $Bin = $Bin & "0111" Case $Hex = "8" $Bin = $Bin & "1000" Case $Hex = "9" $Bin = $Bin & "1001" Case $Hex = "A" $Bin = $Bin & "1010" Case $Hex = "B" $Bin = $Bin & "1011" Case $Hex = "C" $Bin = $Bin & "1100" Case $Hex = "D" $Bin = $Bin & "1101" Case $Hex = "E" $Bin = $Bin & "1110" Case $Hex = "F" $Bin = $Bin & "1111" Case Else SetError(-1) EndSelect Next If @error Then Return "ERROR" Else Return $Bin EndIf EndFunc Func _BinToHex_ID3($BinString) Local $Hex = "" If Not IsInt(StringLen($BinString) / 4) Then $Num = ((StringLen($BinString) / 4) - Int(StringLen($BinString) / 4)) * 4 ;~ MsgBox(262144, "", $Num) For $i = 1 To 4 - $Num Step 1 $BinString = "0" & $BinString Next EndIf For $i = 4 To StringLen($BinString) Step 4 $Bin = StringLeft(StringRight($BinString, $i), 4) Select Case $Bin = "0000" $Hex = $Hex & "0" Case $Bin = "0001" $Hex = $Hex & "1" Case $Bin = "0010" $Hex = $Hex & "2" Case $Bin = "0011" $Hex = $Hex & "3" Case $Bin = "0100" $Hex = $Hex & "4" Case $Bin = "0101" $Hex = $Hex & "5" Case $Bin = "0110" $Hex = $Hex & "6" Case $Bin = "0111" $Hex = $Hex & "7" Case $Bin = "1000" $Hex = $Hex & "8" Case $Bin = "1001" $Hex = $Hex & "9" Case $Bin = "1010" $Hex = $Hex & "A" Case $Bin = "1011" $Hex = $Hex & "B" Case $Bin = "1100" $Hex = $Hex & "C" Case $Bin = "1101" $Hex = $Hex & "D" Case $Bin = "1110" $Hex = $Hex & "E" Case $Bin = "1111" $Hex = $Hex & "F" Case Else SetError(-1) EndSelect Next If @error Then Return "ERROR" Else Return _StringReverse($Hex) EndIf EndFunc ; -----------------------------------------------------------------------------