SHARE
TWEET

Asignar Track Number (mp3) - MP3Info.vb

elGuille Mar 27th, 2013 230 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. '------------------------------------------------------------------------------
  2. ' MP3 Info, leer la información de ficheros MP3                     (15/Abr/06)
  3. ' Adaptado y corregido para usar Option Strict On
  4. '
  5. ' Corrijo algunas cosas para guardar bien los datos (artista, etc.) (25/Mar/13)
  6. ' sobre todo para poder asignar el Track que no siempre iba bien
  7. '
  8. ' No recuerdo de dónde bajé la clase original, (el 5 de abril de 2006 a las 06.59),
  9. ' estaba en un zip llamado: vbmp3header_src.zip y el AssemblyInfo estaba en alemán.
  10. '
  11. ' Haciendo una nueva búsqueda en la Web he encontrado el artículo del autor
  12. ' aunque no sé si me lo bajé de aquí, pero el fichero zip se llama igual y contiene
  13. ' los mismos ficheros de código y con las mismas fechas (febrero de 2005).
  14. ' Este es el enlace:
  15. ' http://www.codeproject.com/Articles/9711/Read-MP3-header-information-and-read-write-the-ID3
  16. ' y según el artículo, el autor es: Thommy Mewes y lo publicó el 1 Mar 2005
  17. '
  18. ' Por esta versión:
  19. ' ©Guillermo 'guille' Som, 2006, 2013
  20. '------------------------------------------------------------------------------
  21. Option Strict On
  22. Imports Microsoft.VisualBasic
  23. Imports System
  24. Imports System.Collections
  25. Imports System.IO
  26. Imports System.Text
  27.  
  28. Namespace elGuille.MP3
  29.  
  30.     '#If False Then
  31.  
  32.     '   ''' <summary>
  33.     '   '''     Namespace summary goes here.
  34.     '   ''' </summary>
  35.     '   ''' <remarks>
  36.     '   '''     None.
  37.     '   ''' </remarks>
  38.     '   Public Class NamespaceDoc
  39.  
  40.     '   End Class
  41.  
  42.     '#End If
  43.  
  44.     ''' <summary>
  45.     '''     MPEG Audio version ID enumeration.
  46.     ''' </summary>
  47.     ''' <remarks>
  48.     '''         See the MPEGVersion property for more information.
  49.     ''' </remarks>
  50.     Public Enum MPEGVersionEnum As Byte
  51.         ''' <summary>
  52.         '''     MPEG Version 2.5 (later extension of MPEG 2)
  53.         ''' </summary>
  54.         MPEG25 = 0
  55.         ''' <summary>
  56.         '''     Reserved
  57.         ''' </summary>
  58.         Reserved = 1
  59.         ''' <summary>
  60.         '''     MPEG Version 2 (ISO/IEC 13818-3)
  61.         ''' </summary>
  62.         MPEG2 = 2
  63.         ''' <summary>
  64.         '''     MPEG Version 1 (ISO/IEC 11172-3)
  65.         ''' </summary>
  66.         MPEG1 = 3
  67.     End Enum
  68.  
  69.     ''' <summary>
  70.     '''     Layer description enumeration.
  71.     ''' </summary>
  72.     ''' <remarks>
  73.     '''         See the Layer property for more information.
  74.     ''' </remarks>
  75.     Public Enum LayerEnum As Byte
  76.         ''' <summary>
  77.         '''     Reserved
  78.         ''' </summary>
  79.         Reserved = 0
  80.         ''' <summary>
  81.         '''     Layer III
  82.         ''' </summary>
  83.         LayerIII = 1
  84.         ''' <summary>
  85.         '''     Layer II
  86.         ''' </summary>
  87.         LayerII = 2
  88.         ''' <summary>
  89.         '''     Layer I
  90.         ''' </summary>
  91.         LayerI = 3
  92.     End Enum
  93.  
  94.     ''' <summary>
  95.     '''     Protection description enumeration.
  96.     ''' </summary>
  97.     ''' <remarks>
  98.     '''         See the Protection property for more information.
  99.     ''' </remarks>
  100.     Public Enum ProtectionEnum As Byte
  101.         ''' <summary>
  102.         '''     Protected by CRC (16bit CRC follows header)
  103.         ''' </summary>
  104.         CRC = 0
  105.         ''' <summary>
  106.         '''     Not protected
  107.         ''' </summary>
  108.         None = 1
  109.     End Enum
  110.  
  111.     ''' <summary>
  112.     '''     Channel mode enumeration.
  113.     ''' </summary>
  114.     ''' <remarks>
  115.     '''         See the ChannelMode property for more information.
  116.     ''' </remarks>
  117.     Public Enum ChannelModeEnum As Byte
  118.         ''' <summary>
  119.         '''     Stereo
  120.         ''' </summary>
  121.         Stereo = 0
  122.         ''' <summary>
  123.         '''     Joint stereo
  124.         ''' </summary>
  125.         JointStereo = 1
  126.         ''' <summary>
  127.         '''     Dualo channel (2 mono channels)
  128.         ''' </summary>
  129.         DualChannel = 2
  130.         ''' <summary>
  131.         '''     Single channel (Mono)
  132.         ''' </summary>
  133.         SingleChannel = 3
  134.     End Enum
  135.  
  136.     ''' <summary>
  137.     '''     Emphasis description enumeration.
  138.     ''' </summary>
  139.     ''' <remarks>
  140.     '''         See the Emphasis property for more information.
  141.     ''' </remarks>
  142.     Public Enum EmphasisEnum As Byte
  143.         ''' <summary>
  144.         '''     None
  145.         ''' </summary>
  146.         None = 0
  147.         ''' <summary>
  148.         '''     50/15 ms
  149.         ''' </summary>
  150.         MS5015 = 1
  151.         ''' <summary>
  152.         '''     Reserved
  153.         ''' </summary>
  154.         Reserved = 2
  155.         ''' <summary>
  156.         '''     CCIT J.17
  157.         ''' </summary>
  158.         CCIT = 3
  159.     End Enum
  160.  
  161.     ''' <summary>
  162.     '''     Encoding enumeration.
  163.     ''' </summary>
  164.     ''' <remarks>
  165.     '''         See the Encoding property for more information.
  166.     ''' </remarks>
  167.     Public Enum EncodingEnum As Byte
  168.         ''' <summary>
  169.         '''     Constant bitrate
  170.         ''' </summary>
  171.         CBR = 0
  172.         ''' <summary>
  173.         '''     Variable bitrate
  174.         ''' </summary>
  175.         VBR = 1
  176.     End Enum
  177.  
  178.     ''' <summary>
  179.     '''         ID3 v1 tag version enumeration.
  180.     ''' </summary>
  181.     ''' <remarks>
  182.     '''         See the TagVersion property for more information.
  183.     ''' </remarks>
  184.     Public Enum ID3v1TagVersionEnum As Byte
  185.         ''' <summary>
  186.         '''     Tag version 1.0
  187.         ''' </summary>
  188.         Version10 = 10
  189.         ''' <summary>
  190.         '''     Tag version 1.1
  191.         ''' </summary>
  192.         Version11 = 11
  193.     End Enum
  194.  
  195.  
  196.     ''' <summary>
  197.     '''     Provides methods to retrieve informations about MPEG files and to get and set
  198.     '''     different tag formats.
  199.     ''' </summary>
  200.     ''' <remarks>
  201.     '''     <para>Use the <b>MP3Info</b> class for typical operations on MPEG files, like reading
  202.     '''     and writing ID3 v1 and v2 tags or getting general MPEG informations.
  203.     '''     <note type="note">
  204.     '''     In members that accept a path as an input string, that path must be well-formed
  205.     '''     or an exception is raised. For example, if a path is fully qualified but begins
  206.     '''     with a space, the path is not trimmed in methods of the class. Therefore, the path
  207.     '''     is malformed and an exception is raised. Similarly, a path or a combination of
  208.     '''     paths cannot be fully qualified twice. For example, "c:\temp c:\windows" also
  209.     '''     raises an exception in most cases. Ensure that your paths are well-formed when
  210.     '''     using methods that accept a path string.
  211.     '''     </note></para>
  212.     '''     <para>This class was made by using informations from the following websites:
  213.     '''     <list type="bullet">
  214.     '''     <item><a href="http://gabriel.mp3-tech.org/mp3infotag.html">http://gabriel.mp3-tech.org/mp3infotag.html</a></item>
  215.     '''     <item><a href="http://www.multiweb.cz/twoinches/MP3inside.htm#MP3FileStructure">http://www.multiweb.cz/twoinches/MP3inside.htm#MP3FileStructure</a></item>
  216.     '''     <item><a href="http://www.codeguru.com/vb/gen/vb_multimedia/mp3s/article.php/c4267">http://www.codeguru.com/vb/gen/vb_multimedia/mp3s/article.php/c4267</a></item>
  217.     '''     <item><a href="http://www.getid3.org/">http://www.getid3.org/</a></item>
  218.     '''     <item><a href="http://www.mp3-converter.com/mp3codec/mp3_anatomy.htm">http://www.mp3-converter.com/mp3codec/mp3_anatomy.htm</a></item>
  219.     '''     <item><a href="http://www.mp3-tech.org/">http://www.mp3-tech.org/</a></item>
  220.     '''     <item><a href="http://www.codeproject.com/audio/MPEGAudioInfo.asp">http://www.codeproject.com/audio/MPEGAudioInfo.asp</a></item>
  221.     '''     </list></para>
  222.     ''' </remarks>
  223.     ''' <example>
  224.     '''         The following example demonstrates some of the main members of the
  225.     '''         <b>MP3Info</b> class.
  226.     '''         <code language="VB.NET">
  227.     '''         [Visual Basic]
  228.     '''         Dim objInfo As New MP3Info("c:\test.mp3")
  229.     '''         ...
  230.     '''         </code>
  231.     ''' </example>
  232.     Public Class MP3Info
  233.  
  234.         ''' Declarations for private variables holding the property values
  235.         Private f_strFilename As String
  236.         Private f_intHeaderPos As Long 'Integer
  237.         Private f_blnVBR As Boolean
  238.         Private f_intAudioSize As Long 'Integer
  239.         Private f_objID3v1Tag As ID3v1Tag
  240.  
  241.         ''' Declarations for internal variables
  242.         Private m_objHeaderBits As New BitArray(24)
  243.         Private m_objXingHeader As XingHeaderStructure
  244.  
  245.         '''
  246.         Private Structure XingHeaderStructure
  247.             Dim Flags As Integer
  248.             Dim FrameCount As Integer
  249.             Dim FileLenght As Integer
  250.             Dim TOC() As Integer
  251.             Dim Quality As Integer
  252.         End Structure
  253.  
  254.  
  255.         ''' <summary>
  256.         '''     Initializes a new instance of the MP3Info class.
  257.         ''' </summary>
  258.         ''' <remarks>
  259.         '''             None.
  260.         ''' </remarks>
  261.         Public Sub New()
  262.             MyBase.New()
  263.         End Sub
  264.  
  265.         ''' <summary>
  266.         '''     Initializes a new instance of the MP3Info class with the specified MP3 file.
  267.         ''' </summary>
  268.         ''' <param name="strFilename" type="String">
  269.         '''     <para>
  270.         '''         The filename of the MP3 file.
  271.         '''     </para>
  272.         ''' </param>
  273.         ''' <remarks>
  274.         '''             None.
  275.         ''' </remarks>
  276.         Public Sub New(ByVal strFilename As String)
  277.             Me.Filename = strFilename
  278.         End Sub
  279.  
  280.  
  281.  
  282.         ''' <summary>
  283.         '''     Gets or sets the filename of the MP3 file.
  284.         ''' </summary>
  285.         ''' <value>
  286.         '''     <para>
  287.         '''         The filename of the MP3 file.
  288.         '''     </para>
  289.         ''' </value>
  290.         ''' <exception cref="Exception">The specified file is not a valid MP3 file.</exception>
  291.         ''' <exception cref="IOException">The specified file doesn't exist.</exception>
  292.         ''' <remarks>
  293.         '''             None.
  294.         ''' </remarks>
  295.         Public Property Filename() As String
  296.             Get
  297.                 Return f_strFilename
  298.             End Get
  299.             Set(ByVal value As String)
  300.                 If (File.Exists(value)) Then
  301.                     f_strFilename = value
  302.                     If (Not ReadHeaders()) Then
  303.                         Throw New Exception("The specified file is not a valid MP3 file.")
  304.                     Else
  305.                         f_objID3v1Tag = GetID3v1Tag()
  306.                     End If
  307.                 Else
  308.                     Throw New IO.IOException("The specified file doesn't exist.")
  309.                 End If
  310.             End Set
  311.         End Property
  312.  
  313.         ''' <summary>
  314.         '''     Gets the total file size in size.
  315.         ''' </summary>
  316.         ''' <value>
  317.         '''     <para>
  318.         '''         File size in bytes.
  319.         '''     </para>
  320.         ''' </value>
  321.         ''' <remarks>
  322.         '''             None.
  323.         ''' </remarks>
  324.         Public ReadOnly Property Filesize() As Long 'Integer
  325.             Get
  326.                 Dim objFI As New FileInfo(f_strFilename)
  327.                 Return objFI.Length
  328.             End Get
  329.         End Property
  330.  
  331.         ''' <summary>
  332.         '''     Gets the position of the MPEG header.
  333.         ''' </summary>
  334.         ''' <value>
  335.         '''     <para>
  336.         '''         The position of the MPEG header.
  337.         '''     </para>
  338.         ''' </value>
  339.         ''' <remarks>
  340.         '''             None.
  341.         ''' </remarks>
  342.         Public ReadOnly Property HeaderPosition() As Long 'Integer
  343.             Get
  344.                 Return f_intHeaderPos
  345.             End Get
  346.         End Property
  347.  
  348.         ''' <summary>
  349.         '''     Gets or sets the ID3v1 tag.
  350.         ''' </summary>
  351.         ''' <value>
  352.         '''     <para>
  353.         '''         An ID3v1Tag object containing the ID3v1 tag.
  354.         '''     </para>
  355.         ''' </value>
  356.         ''' <remarks>
  357.         '''     None.
  358.         ''' </remarks>
  359.         Public Property ID3v1Tag() As ID3v1Tag
  360.             Get
  361.                 Return f_objID3v1Tag
  362.             End Get
  363.             Set(ByVal Value As ID3v1Tag)
  364.                 f_objID3v1Tag = Value
  365.             End Set
  366.         End Property
  367.  
  368.         ''' <summary>
  369.         '''     Gets the encoding quality for variable bitrate encoded files.
  370.         ''' </summary>
  371.         ''' <value>
  372.         '''     <para>
  373.         '''         An integer describing the quality of the encoding.
  374.         '''     </para>
  375.         ''' </value>
  376.         ''' <remarks>
  377.         '''     The range of these value starts with "0" (best) and ends with "100" (worst).
  378.         '''     The property will return "-1" if the file was encoded using a constant
  379.         '''     bitrate.
  380.         ''' </remarks>
  381.         Public ReadOnly Property VBRScale() As Integer
  382.             Get
  383.                 If (Me.Encoding = EncodingEnum.CBR) Then
  384.                     Return -1
  385.                 Else
  386.                     Return m_objXingHeader.Quality
  387.                 End If
  388.             End Get
  389.         End Property
  390.  
  391.         ''' <summary>
  392.         '''     Gets the encoding.
  393.         ''' </summary>
  394.         ''' <value>
  395.         '''     <para>
  396.         '''         An EncodingEnum value describing the encoding.
  397.         '''     </para>
  398.         ''' </value>
  399.         ''' <remarks>
  400.         '''     None.
  401.         ''' </remarks>
  402.         Public ReadOnly Property Encoding() As EncodingEnum
  403.             Get
  404.                 If f_blnVBR Then
  405.                     Return EncodingEnum.VBR
  406.                 Else
  407.                     Return EncodingEnum.CBR
  408.                 End If
  409.                 'Return IIf(f_blnVBR, EncodingEnum.VBR, EncodingEnum.CBR)
  410.             End Get
  411.         End Property
  412.  
  413.         ''' <summary>
  414.         '''     Gets the size of each frame of the audio data in bytes.
  415.         ''' </summary>
  416.         ''' <value>
  417.         '''     <para>
  418.         '''         The size of each frame of the audio data in bytes.
  419.         '''     </para>
  420.         ''' </value>
  421.         ''' <remarks>
  422.         '''             If the file is encoded with a variable bitrate, this value describes the
  423.         '''             average frame size.
  424.         ''' </remarks>
  425.         Public ReadOnly Property FrameSize() As Integer
  426.             Get
  427.                 If (Me.Encoding = EncodingEnum.CBR) Then
  428.                     Return CInt(((Me.FrameSamples / 8 * Me.Bitrate) / Me.SamplingRateFrequency) + Me.Padding)
  429.                 Else
  430.                     Return CInt(Math.Round(m_objXingHeader.FileLenght / m_objXingHeader.FrameCount, 0))
  431.                 End If
  432.             End Get
  433.         End Property
  434.  
  435.         ''' <summary>
  436.         '''     Gets the number of samples for each audio frame.
  437.         ''' </summary>
  438.         ''' <value>
  439.         '''     <para>
  440.         '''         The number of samples for each audio frame.
  441.         '''     </para>
  442.         ''' </value>
  443.         ''' <remarks>
  444.         '''             None.
  445.         ''' </remarks>
  446.         Public ReadOnly Property FrameSamples() As Integer
  447.             Get
  448.                 Select Case Me.Layer
  449.                     Case LayerEnum.LayerI
  450.                         Return 384
  451.                     Case LayerEnum.LayerII
  452.                         Return 1152
  453.                     Case LayerEnum.LayerIII
  454.                         If (Me.MPEGVersion = MPEGVersionEnum.MPEG1) Then
  455.                             Return 1152
  456.                         Else
  457.                             Return 576
  458.                         End If
  459.                 End Select
  460.             End Get
  461.         End Property
  462.  
  463.         ''' <summary>
  464.         '''     Gets the MPEG audio version.
  465.         ''' </summary>
  466.         ''' <value>
  467.         '''     <para>
  468.         '''         A MPEGTypeEnum value describing the MPEG audio type.
  469.         '''     </para>
  470.         ''' </value>
  471.         ''' <remarks>
  472.         '''     MPEG Version 2.5 was added lately to the MPEG 2 standard. It is an extension
  473.         '''     used for very low bitrate files, allowing the use of lower sampling frequencies.
  474.         '''     If your decoder does not support this extension, it is recommended for you to
  475.         '''     use 12 bits for synchronization instead of 11 bits.
  476.         ''' </remarks>
  477.         Public ReadOnly Property MPEGVersion() As MPEGVersionEnum
  478.             Get
  479.                 Select Case BitsToString(m_objHeaderBits, 3, 4)
  480.                     Case "11"
  481.                         Return MPEGVersionEnum.MPEG1
  482.                     Case "10"
  483.                         Return MPEGVersionEnum.MPEG2
  484.                     Case "00"
  485.                         Return MPEGVersionEnum.MPEG25
  486.                     Case "01"
  487.                         Return MPEGVersionEnum.Reserved
  488.                 End Select
  489.             End Get
  490.         End Property
  491.  
  492.         ''' <summary>
  493.         '''     Gets the MPEG layer.
  494.         ''' </summary>
  495.         ''' <value>
  496.         '''     <para>
  497.         '''         A LayerEnum value describing the MPEG layer.
  498.         '''     </para>
  499.         ''' </value>
  500.         ''' <remarks>
  501.         '''             None.
  502.         ''' </remarks>
  503.         Public ReadOnly Property Layer() As LayerEnum
  504.             Get
  505.                 Select Case BitsToString(m_objHeaderBits, 5, 6)
  506.                     Case "01"
  507.                         Return LayerEnum.LayerIII
  508.                     Case "10"
  509.                         Return LayerEnum.LayerII
  510.                     Case "11"
  511.                         Return LayerEnum.LayerI
  512.                     Case "00"
  513.                         Return LayerEnum.Reserved
  514.                 End Select
  515.             End Get
  516.         End Property
  517.  
  518.         ''' <summary>
  519.         '''     Gets the protection.
  520.         ''' </summary>
  521.         ''' <value>
  522.         '''     <para>
  523.         '''         A ProtectionEnum value describing the protection.
  524.         '''     </para>
  525.         ''' </value>
  526.         ''' <remarks>
  527.         '''             If this property returns CRC, the file is protected by CRC (16bit CRC follows
  528.         '''             header).
  529.         ''' </remarks>
  530.         Public ReadOnly Property Protection() As ProtectionEnum
  531.             Get
  532.                 If (Not m_objHeaderBits.Item(7)) Then
  533.                     Return ProtectionEnum.CRC
  534.                 Else
  535.                     Return ProtectionEnum.None
  536.                 End If
  537.             End Get
  538.         End Property
  539.  
  540.         ''' <summary>
  541.         '''     Gets the channel mode.
  542.         ''' </summary>
  543.         ''' <value>
  544.         '''     <para>
  545.         '''         A ChannelModeEnum value describing the channel mode.
  546.         '''     </para>
  547.         ''' </value>
  548.         ''' <remarks>
  549.         '''     Dual channel files are made of two independant mono channel. Each one uses
  550.         '''     exactly half the bitrate of the file. Most decoders output them as stereo,
  551.         '''     but it might not always be the case.
  552.         '''     <br></br>
  553.         '''     <br></br>
  554.         '''     One example of use would be some speech in two different languages carried
  555.         '''     in the same bitstream, and then an appropriate decoder would decode only
  556.         '''     the choosen language.
  557.         ''' </remarks>
  558.         Public ReadOnly Property ChannelMode() As ChannelModeEnum
  559.             Get
  560.                 Select Case BitsToString(m_objHeaderBits, 16, 17)
  561.                     Case "00"
  562.                         Return ChannelModeEnum.Stereo
  563.                     Case "01"
  564.                         Return ChannelModeEnum.JointStereo
  565.                     Case "10"
  566.                         Return ChannelModeEnum.DualChannel
  567.                     Case "11"
  568.                         Return ChannelModeEnum.SingleChannel
  569.                 End Select
  570.             End Get
  571.         End Property
  572.  
  573.         ''' <summary>
  574.         '''     Gets the sampling rate frequency in Hz.
  575.         ''' </summary>
  576.         ''' <value>
  577.         '''     <para>
  578.         '''         An integer containing the sampling rate frequency in Hz.
  579.         '''     </para>
  580.         ''' </value>
  581.         ''' <remarks>
  582.         '''             None.
  583.         ''' </remarks>
  584.         Public ReadOnly Property SamplingRateFrequency() As Integer
  585.             Get
  586.                 Select Case BitsToString(m_objHeaderBits, 12, 13)
  587.                     Case "00"
  588.                         Select Case Me.MPEGVersion
  589.                             Case MPEGVersionEnum.MPEG1
  590.                                 Return 44100
  591.                             Case MPEGVersionEnum.MPEG2
  592.                                 Return 22050
  593.                             Case MPEGVersionEnum.MPEG25
  594.                                 Return 11025
  595.                         End Select
  596.                     Case "01"
  597.                         Select Case Me.MPEGVersion
  598.                             Case MPEGVersionEnum.MPEG1
  599.                                 Return 48000
  600.                             Case MPEGVersionEnum.MPEG2
  601.                                 Return 24000
  602.                             Case MPEGVersionEnum.MPEG25
  603.                                 Return 12000
  604.                         End Select
  605.                     Case "10"
  606.                         Select Case Me.MPEGVersion
  607.                             Case MPEGVersionEnum.MPEG1
  608.                                 Return 32000
  609.                             Case MPEGVersionEnum.MPEG2
  610.                                 Return 16000
  611.                             Case MPEGVersionEnum.MPEG25
  612.                                 Return 8000
  613.                         End Select
  614.                     Case "11"
  615.                         Return -1
  616.                 End Select
  617.             End Get
  618.         End Property
  619.  
  620.         ''' <summary>
  621.         '''     Gets the copyright.
  622.         ''' </summary>
  623.         ''' <value>
  624.         '''     <para>
  625.         '''         A boolean value containing the copyright.
  626.         '''     </para>
  627.         ''' </value>
  628.         ''' <remarks>
  629.         '''             The copyright has the same meaning as the copyright bit on CDs and DAT tapes,
  630.         '''             i.e. telling that it is illegal to copy the contents if the bit is set.
  631.         ''' </remarks>
  632.         Public ReadOnly Property Copyright() As Boolean
  633.             Get
  634.                 Return m_objHeaderBits.Item(20)
  635.             End Get
  636.         End Property
  637.  
  638.         ''' <summary>
  639.         '''     Gets the bitrate in kbps.
  640.         ''' </summary>
  641.         ''' <value>
  642.         '''     <para>
  643.         '''         The bitrate in kbps.
  644.         '''     </para>
  645.         ''' </value>
  646.         ''' <remarks>
  647.         '''     The return value "0" means free format. The free bitrate must remain
  648.         '''     constant, an must be lower than the maximum allowed bitrate. Decoders are
  649.         '''     not required to support decoding of free bitrate streams.
  650.         '''     <br></br>
  651.         '''     <br></br>
  652.         '''             The return value "-1" means that the value is unallowed.
  653.         '''     <br></br>
  654.         '''     <br></br>
  655.         '''             If the file is encoded with a variable bitrate, this value describes the
  656.         '''             average bitrate.
  657.         ''' </remarks>
  658.         Public ReadOnly Property Bitrate() As Integer
  659.             Get
  660.                 If (Me.Encoding = EncodingEnum.CBR) Then
  661.  
  662.                     Dim x As Integer = (-CInt(m_objHeaderBits.Item(8))) * 8 + (-CInt(m_objHeaderBits.Item(9))) * 4 + (-CInt(m_objHeaderBits.Item(10))) * 2 + (-CInt(m_objHeaderBits.Item(11))) * 1
  663.                     If ((Me.MPEGVersion = MPEGVersionEnum.MPEG1) AndAlso (Me.Layer = LayerEnum.LayerI)) Then
  664.                         Return CInt(Choose(x + 1, 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1)) * 1000
  665.                     End If
  666.                     If ((Me.MPEGVersion = MPEGVersionEnum.MPEG1) AndAlso (Me.Layer = LayerEnum.LayerII)) Then
  667.                         Return CInt(Choose(x + 1, 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1)) * 1000
  668.                     End If
  669.                     If ((Me.MPEGVersion = MPEGVersionEnum.MPEG1) AndAlso (Me.Layer = LayerEnum.LayerIII)) Then
  670.                         Return CInt(Choose(x + 1, 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1)) * 1000
  671.                     End If
  672.                     If (((Me.MPEGVersion = MPEGVersionEnum.MPEG2) OrElse (Me.MPEGVersion = MPEGVersionEnum.MPEG25)) AndAlso (Me.Layer = LayerEnum.LayerI)) Then
  673.                         Return CInt(Choose(x + 1, 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1)) * 1000
  674.                     End If
  675.                     If (((Me.MPEGVersion = MPEGVersionEnum.MPEG2) OrElse (Me.MPEGVersion = MPEGVersionEnum.MPEG25)) AndAlso ((Me.Layer = LayerEnum.LayerII) OrElse (Me.Layer = LayerEnum.LayerIII))) Then
  676.                         Return CInt(Choose(x + 1, 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1)) * 1000
  677.                     End If
  678.  
  679.                 Else
  680.  
  681.                     Return CInt(Math.Round(((Me.FrameSize * Me.SamplingRateFrequency) / 144) / 1000, 0) * 1000)
  682.  
  683.                 End If
  684.             End Get
  685.         End Property
  686.  
  687.         ''' <summary>
  688.         '''     Gets the padding in bytes.
  689.         ''' </summary>
  690.         ''' <value>
  691.         '''     <para>
  692.         '''         The padding in bytes
  693.         '''     </para>
  694.         ''' </value>
  695.         ''' <remarks>
  696.         '''     Padding is used to exactly fit the bitrate. As an example: 128kbps 44.1kHz
  697.         '''     layer II uses a lot of 418 bytes and some of 417 bytes long frames to get
  698.         '''     the exact 128k bitrate. For Layer I slot is 32 bits long, for Layer II and
  699.         '''     Layer III slot is 8 bits long.
  700.         ''' </remarks>
  701.         Public ReadOnly Property Padding() As Integer
  702.             Get
  703.                 If (m_objHeaderBits.Item(14)) Then
  704.                     If (Me.Layer = LayerEnum.LayerI) Then
  705.                         Return 4
  706.                     Else
  707.                         Return 1
  708.                     End If
  709.                 Else
  710.                     Return 0
  711.                 End If
  712.             End Get
  713.         End Property
  714.  
  715.         ''' <summary>
  716.         '''     Gets the private bit.
  717.         ''' </summary>
  718.         ''' <value>
  719.         '''     <para>
  720.         '''         A boolean value containing the private bit.
  721.         '''     </para>
  722.         ''' </value>
  723.         ''' <remarks>
  724.         '''     This one is only informative.
  725.         ''' </remarks>
  726.         Public ReadOnly Property PrivateBit() As Boolean
  727.             Get
  728.                 Return m_objHeaderBits.Item(15)
  729.             End Get
  730.         End Property
  731.  
  732.         ''' <summary>
  733.         '''     Gets the original bit.
  734.         ''' </summary>
  735.         ''' <value>
  736.         '''     <para>
  737.         '''         A boolean value containing the original bit.
  738.         '''     </para>
  739.         ''' </value>
  740.         ''' <remarks>
  741.         '''     The original bit indicates, if it is set, that the frame is located on its
  742.         '''     original media.
  743.         ''' </remarks>
  744.         Public ReadOnly Property OriginalBit() As Boolean
  745.             Get
  746.                 Return m_objHeaderBits.Item(21)
  747.             End Get
  748.         End Property
  749.  
  750.         ''' <summary>
  751.         '''     Gets the emphasis.
  752.         ''' </summary>
  753.         ''' <value>
  754.         '''     <para>
  755.         '''         An EmphasisEnum value describing the emphasis.
  756.         '''     </para>
  757.         ''' </value>
  758.         ''' <remarks>
  759.         '''     The emphasis indication is here to tell the decoder that the file must
  760.         '''     be de-emphasized, ie the decoder must "re-equalize" the sound after a
  761.         '''     Dolby-like noise supression. It is rarely used.
  762.         ''' </remarks>
  763.         Public ReadOnly Property Emphasis() As EmphasisEnum
  764.             Get
  765.                 Select Case BitsToString(m_objHeaderBits, 22, 23)
  766.                     Case "00"
  767.                         Return EmphasisEnum.None
  768.                     Case "01"
  769.                         Return EmphasisEnum.MS5015
  770.                     Case "10"
  771.                         Return EmphasisEnum.Reserved
  772.                     Case "11"
  773.                         Return EmphasisEnum.CCIT
  774.                         '$ GUILLE (25/Mar/13)
  775.                         ' Añado la opcion predeterminada por si falla el valor
  776.                     Case Else
  777.                         Return EmphasisEnum.None
  778.                 End Select
  779.             End Get
  780.         End Property
  781.  
  782.         ''' <summary>
  783.         '''     Gets the length in seconds.
  784.         ''' </summary>
  785.         ''' <value>
  786.         '''     <para>
  787.         '''         The length in seconds.
  788.         '''     </para>
  789.         ''' </value>
  790.         ''' <remarks>
  791.         '''     None.
  792.         ''' </remarks>
  793.         Public ReadOnly Property Length() As Long
  794.             Get
  795.                 Return CLng(Math.Round(f_intAudioSize / Me.Bitrate * 8, 0))
  796.             End Get
  797.         End Property
  798.  
  799.  
  800.  
  801.         ''' <summary>
  802.         '''     Writes all changes to the file.
  803.         ''' </summary>
  804.         ''' <remarks>
  805.         '''             None.
  806.         ''' </remarks>
  807.         Public Sub Update()
  808.  
  809.             ' Write the ID3 v1 tag
  810.             SetID3v1Tag()
  811.  
  812.         End Sub
  813.  
  814.  
  815.  
  816.         ''' <summary>
  817.         '''     Retrieves the ID3v1 tag.
  818.         ''' </summary>
  819.         ''' <returns>
  820.         '''     An ID3v1Tag object containing the tag.
  821.         ''' </returns>
  822.         Private Function GetID3v1Tag() As ID3v1Tag
  823.  
  824.             '' Declarations
  825.             Dim objFS As FileStream
  826.             Dim objReader As BinaryReader
  827.             Dim bytBytes() As Byte
  828.             Dim strBytes As String
  829.             Dim objTag As ID3v1Tag
  830.  
  831.             '' Open the filestream
  832.             objFS = New FileStream(f_strFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
  833.  
  834.             '' Create the BinaryReader object to read the file
  835.             objReader = New BinaryReader(objFS)
  836.  
  837.             '' Create a new object to hold the tag content
  838.             objTag = New ID3v1Tag
  839.  
  840.             ' By default, there's no tag
  841.             objTag.TagAvailable = False
  842.  
  843.             '' The v1 tag should be found at the end of the file and has a fixed size of
  844.             '' 128 bytes, so have a look if there's one
  845.             objFS.Seek(-128, SeekOrigin.End)
  846.             strBytes = BytesToString(objReader.ReadBytes(3))
  847.             If (strBytes.ToUpper = "TAG") Then
  848.  
  849.                 ' We found a tag
  850.                 objTag.TagAvailable = True
  851.  
  852.                 With objTag
  853.  
  854.                     '' Read title, remove possible junk bytes and assign value to the property
  855.                     strBytes = BytesToString(objReader.ReadBytes(30)).Replace(Chr(0), "")
  856.                     .Title = strBytes
  857.  
  858.                     '' Read artist, remove possible junk bytes and assign value to the property
  859.                     strBytes = BytesToString(objReader.ReadBytes(30)).Replace(Chr(0), "")
  860.                     .Artist = strBytes
  861.  
  862.                     '' Read album, remove possible junk bytes and assign value to the property
  863.                     strBytes = BytesToString(objReader.ReadBytes(30)).Replace(Chr(0), "")
  864.                     .Album = strBytes
  865.  
  866.                     '' Read year
  867.                     strBytes = BytesToString(objReader.ReadBytes(4)).Replace(Chr(0), "")
  868.                     .Year = strBytes
  869.  
  870.                     '' Read 30 bytes for comment and track
  871.                     bytBytes = objReader.ReadBytes(30)
  872.  
  873.                     '' If byte 28 is zero and byte 29 non-zero, the tag has version 1.1,
  874.                     '' otherwise 1.0
  875.                     If ((bytBytes(28) = 0) AndAlso (bytBytes(29) <> 0)) Then
  876.                         .TagVersion = ID3v1TagVersionEnum.Version11
  877.                         strBytes = BytesToString(bytBytes, 0, 28).Replace(Chr(0), "")
  878.                         .Track = bytBytes(29)
  879.                     Else
  880.                         ' $ GUILLE (25/Mar/13)
  881.                         ' Guardar siempre como versión 1.1 para guardar los datos
  882.                         .TagVersion = ID3v1TagVersionEnum.Version11 ' ID3v1TagVersionEnum.Version10
  883.                         'strBytes = BytesToString(bytBytes).Replace(Chr(0), "")
  884.                         strBytes = BytesToString(bytBytes, 0, 28).Replace(Chr(0), "")
  885.                         '.Track = bytBytes(29)
  886.                         .Track = 0
  887.                     End If
  888.                     .Comment = strBytes
  889.  
  890.                     '' Read genre
  891.                     .Genre = objReader.ReadByte
  892.  
  893.                 End With
  894.  
  895.             End If
  896.  
  897.             '' Close the reader and the filestream object
  898.             objReader.Close()
  899.             objFS.Close()
  900.  
  901.             '' Return the ID3v1 tag object
  902.             Return objTag
  903.  
  904.         End Function
  905.  
  906.         ''' <summary>
  907.         '''     Writes the ID3 v1 tag.
  908.         ''' </summary>
  909.         ''' <remarks>
  910.         '''             None.
  911.         ''' </remarks>
  912.         Private Sub SetID3v1Tag()
  913.  
  914.             '' Declarations
  915.             Dim objFS As FileStream
  916.             Dim objReader As BinaryReader
  917.             Dim objWriter As BinaryWriter
  918.             Dim strBytes As String
  919.  
  920.             '' Open the filestream
  921.             objFS = New FileStream(f_strFilename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
  922.  
  923.             '' Create the BinaryReader object to read the file
  924.             objReader = New BinaryReader(objFS)
  925.  
  926.             '' The v1 tag should be found at the end of the file and has a fixed size of
  927.             '' 128 bytes, so have a look if there's one
  928.             objFS.Seek(-128, SeekOrigin.End)
  929.             strBytes = BytesToString(objReader.ReadBytes(3))
  930.             If (strBytes.ToUpper = "TAG") Then
  931.  
  932.                 '' There is an existing tag, so rewind filestream position 3 bytes
  933.                 objFS.Seek(-3, SeekOrigin.Current)
  934.  
  935.             Else
  936.  
  937.                 '' No tag found, so set filestream position to end of file
  938.                 objFS.Seek(0, SeekOrigin.End)
  939.  
  940.             End If
  941.  
  942.             '' Create the BinaryWriter object to write the tag
  943.             objWriter = New BinaryWriter(objFS)
  944.  
  945.             '' Write the tag
  946.             objWriter.Write("TAG".ToCharArray)
  947.             objWriter.Write(Me.ID3v1Tag.Title.PadRight(30, Chr(0)).ToCharArray)
  948.             objWriter.Write(Me.ID3v1Tag.Artist.PadRight(30, Chr(0)).ToCharArray)
  949.             objWriter.Write(Me.ID3v1Tag.Album.PadRight(30, Chr(0)).ToCharArray)
  950.             objWriter.Write(Me.ID3v1Tag.Year.PadRight(4, Chr(0)).ToCharArray)
  951.  
  952.             '$ GUILLE (25/Mar/13)
  953.             ' Guardarlo como ID3v1TagVersionEnum.Version11          (25/Mar/13)
  954.  
  955.             'Select Case Me.ID3v1Tag.TagVersion
  956.             '    Case ID3v1TagVersionEnum.Version10
  957.             '        objWriter.Write(Me.ID3v1Tag.Comment.PadRight(30, Chr(0)).ToCharArray)
  958.             '    Case ID3v1TagVersionEnum.Version11
  959.             '        objWriter.Write(Me.ID3v1Tag.Comment.PadRight(28, Chr(0)).ToCharArray)
  960.             '        objWriter.Write(Chr(0))
  961.             '        objWriter.Write(Me.ID3v1Tag.Track)
  962.             'End Select
  963.  
  964.             objWriter.Write(Me.ID3v1Tag.Comment.PadRight(28, Chr(0)).ToCharArray)
  965.             objWriter.Write(Chr(0))
  966.             objWriter.Write(Me.ID3v1Tag.Track)
  967.  
  968.  
  969.             objWriter.Write(Me.ID3v1Tag.Genre)
  970.             objWriter.Flush()
  971.  
  972.             '' Close the BinaryReader and BinaryWriter objects and the base stream
  973.             objWriter.Close()
  974.             objReader.Close()
  975.  
  976.         End Sub
  977.  
  978.         ''' <summary>
  979.         '''    
  980.         ''' </summary>
  981.         '''
  982.         ''' <returns>
  983.         '''    
  984.         ''' </returns>
  985.         Private Function ReadHeaders() As Boolean
  986.  
  987.             '' Declarations
  988.             Dim objFS As FileStream
  989.             Dim objBitArray As BitArray
  990.             Dim bytBytes(2) As Byte
  991.             Dim bytXingBytes(3) As Byte
  992.             Dim i, j, intIndex, intOffset As Integer ', intStart As Integer
  993.             Dim objConverter As New System.Text.UTF8Encoding
  994.             Dim blnReturn As Boolean = False
  995.             Dim intXingOffset As Integer
  996.             Dim bytFlags(3), bytFrameCount(3), bytFileLength(3), bytQuality(3) As Byte
  997.             Dim intTOC(99) As Integer
  998.             'Dim objBitConverter As BitConverter = Nothing
  999.             Dim bytXingHeader(116) As Byte
  1000.  
  1001.             '' Open the filestream
  1002.             Try
  1003.                 '
  1004.                 '--------------------------------------------------------------
  1005.                 ' Guille                                            (17/Abr/06)
  1006.                 ' No tenía el FileAccess.Read y daba error si se estaba usando
  1007.                 '--------------------------------------------------------------
  1008.                 '
  1009.                 objFS = New FileStream(f_strFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
  1010.                 If (objFS.CanRead) Then
  1011.                     objFS.Position = 0
  1012.                 Else
  1013.                     Throw New IO.IOException("Can't read file.")
  1014.                 End If
  1015.             Catch Ex As Exception
  1016.                 Throw New IO.IOException("An error occurred while trying to open the file.")
  1017.             End Try
  1018.  
  1019.             '' Read the headers
  1020.             Try
  1021.  
  1022.                 '' Read the MPEG header
  1023.                 While ((objFS.Position + 4) <= objFS.Length)
  1024.  
  1025.                     '' Read a byte from file and check if the bits are all set
  1026.                     If (objFS.ReadByte = 255) Then
  1027.  
  1028.                         '' Read the next 3 bytes (maybe the complete header)
  1029.                         objFS.Read(bytBytes, 0, 3)
  1030.                         objBitArray = New BitArray(bytBytes)
  1031.  
  1032.                         '' If bits 9 to 11 are set, we found the header
  1033.                         If (objBitArray(7)) AndAlso (objBitArray(6)) AndAlso (objBitArray(5)) Then
  1034.  
  1035.                             '' Store the header position
  1036.                             f_intHeaderPos = objFS.Position
  1037.  
  1038.                             '' Change the bit order to a more readable format
  1039.                             intIndex = 0
  1040.                             intOffset = 0
  1041.                             For j = 0 To 2
  1042.                                 For i = 7 To 0 Step -1
  1043.                                     m_objHeaderBits.Item(intIndex) = objBitArray.Item(intOffset + i)
  1044.                                     intIndex += 1
  1045.                                 Next
  1046.                                 intOffset += 8
  1047.                             Next
  1048.  
  1049.                             blnReturn = True
  1050.                             Exit While
  1051.  
  1052.                         Else
  1053.  
  1054.                             '' Rewind 3 bytes
  1055.                             objFS.Position -= 3
  1056.  
  1057.                         End If
  1058.  
  1059.                     End If
  1060.  
  1061.                 End While
  1062.  
  1063.                 '' Adjust audio size
  1064.                 f_intAudioSize = Me.Filesize - f_intHeaderPos
  1065.  
  1066.                 '' Read the extended (Xing) header
  1067.                 '' Set position of filestream (Xing header offset)
  1068.                 If (Me.MPEGVersion = MPEGVersionEnum.MPEG1) Then
  1069.                     If (Me.ChannelMode = ChannelModeEnum.SingleChannel) Then
  1070.                         intXingOffset = 17
  1071.                     Else
  1072.                         intXingOffset = 32
  1073.                     End If
  1074.                 Else
  1075.                     If (Me.ChannelMode = ChannelModeEnum.SingleChannel) Then
  1076.                         intXingOffset = 9
  1077.                     Else
  1078.                         intXingOffset = 17
  1079.                     End If
  1080.                 End If
  1081.                 objFS.Position = Me.HeaderPosition + intXingOffset
  1082.  
  1083.                 '' Read 4 bytes
  1084.                 objFS.Read(bytXingBytes, 0, 4)
  1085.  
  1086.                 '' Check for Xing header
  1087.                 If (objConverter.GetString(bytXingBytes).ToLower = "xing") Or (objConverter.GetString(bytXingBytes).ToLower = "info") Then
  1088.  
  1089.                     '' Read the extended (Xing) header
  1090.                     objFS.Read(bytXingHeader, 0, 116)
  1091.  
  1092.                     '' Check the encoding
  1093.                     If (objConverter.GetString(bytXingBytes).ToLower = "xing") Then
  1094.                         f_blnVBR = True
  1095.                     End If
  1096.  
  1097.                     '' Adjust audio size
  1098.                     f_intAudioSize -= 120
  1099.  
  1100.                     '' Populate the extended (Xing) header
  1101.                     For i = 3 To 0 Step -1
  1102.                         bytFlags(3 - i) = bytXingHeader(i)
  1103.                         bytFrameCount(3 - i) = bytXingHeader(4 + i)
  1104.                         bytFileLength(3 - i) = bytXingHeader(8 + i)
  1105.                         bytQuality(3 - i) = bytXingHeader(112 + i)
  1106.                     Next
  1107.  
  1108.                     For i = 0 To 99
  1109.                         intTOC(i) = CType(bytXingHeader(12 + i), Integer)
  1110.                     Next
  1111.  
  1112.                     With m_objXingHeader
  1113.                         .Flags = BitConverter.ToInt32(bytFlags, 0)
  1114.                         .FileLenght = BitConverter.ToInt32(bytFileLength, 0)
  1115.                         .FrameCount = BitConverter.ToInt32(bytFrameCount, 0)
  1116.                         .TOC = intTOC
  1117.                         .Quality = BitConverter.ToInt32(bytQuality, 0)
  1118.                     End With
  1119.  
  1120.                 End If
  1121.  
  1122.                 '' Read the extended (VBRI) header
  1123.                 '' Set position of filestream (VBRI header offset)
  1124.                 objFS.Position = Me.HeaderPosition + 32
  1125.  
  1126.                 '' Read 4 bytes
  1127.                 objFS.Read(bytXingBytes, 0, 4)
  1128.  
  1129.                 '' Check for Xing header
  1130.                 If (objConverter.GetString(bytXingBytes).ToLower = "vbri") Then
  1131.  
  1132.                     '' TBD
  1133.  
  1134.                 End If
  1135.  
  1136.             Catch ex As Exception
  1137.                 Throw New Exception(ex.Message)
  1138.             Finally
  1139.                 objFS.Close()
  1140.             End Try
  1141.  
  1142.             Return blnReturn
  1143.  
  1144.         End Function
  1145.  
  1146.         ''' <summary>
  1147.         '''    
  1148.         ''' </summary>
  1149.         ''' <param name="intStart" type="Int32">
  1150.         '''     <para>
  1151.         '''        
  1152.         '''     </para>
  1153.         ''' </param>
  1154.         ''' <param name="intEnd" type="Int32">
  1155.         '''     <para>
  1156.         '''        
  1157.         '''     </para>
  1158.         ''' </param>
  1159.         ''' <returns>
  1160.         '''     A System.String BitsToString  value...
  1161.         ''' </returns>
  1162.         Private Function BitsToString(ByVal objBitArray As BitArray, ByVal intStart As Integer, ByVal intEnd As Integer) As String
  1163.  
  1164.             Dim strBits As String = ""
  1165.  
  1166.             For i As Integer = intStart To intEnd
  1167.                 strBits &= CStr(IIf(objBitArray.Item(i), "1", "0"))
  1168.             Next
  1169.             Return strBits
  1170.  
  1171.         End Function
  1172.  
  1173.         ''' <summary>
  1174.         '''     Converts bytes to string.
  1175.         ''' </summary>
  1176.         ''' <param name="Bytes" type="Byte">
  1177.         '''     <para>
  1178.         '''         The byte array containing bytes to convert.
  1179.         '''     </para>
  1180.         ''' </param>
  1181.         ''' <param name="StartIndex" type="Int32">
  1182.         '''     <para>
  1183.         '''         The start index.
  1184.         '''     </para>
  1185.         ''' </param>
  1186.         ''' <param name="Length" type="Int32">
  1187.         '''     <para>
  1188.         '''         The length.
  1189.         '''     </para>
  1190.         ''' </param>
  1191.         ''' <returns>
  1192.         '''     The converted bytes as a string.
  1193.         ''' </returns>
  1194.         Private Function BytesToString(ByVal Bytes() As Byte, Optional ByVal StartIndex As Integer = 0, Optional ByVal Length As Integer = 0) As String
  1195.  
  1196.             If (Length > 0) Then
  1197.                 Return System.Text.Encoding.ASCII.GetString(Bytes, StartIndex, Length)
  1198.             Else
  1199.                 Return System.Text.Encoding.ASCII.GetString(Bytes)
  1200.             End If
  1201.  
  1202.         End Function
  1203.  
  1204.     End Class
  1205.  
  1206.     ''' <summary>
  1207.     '''    
  1208.     ''' </summary>
  1209.     ''' <remarks>
  1210.     '''     None.
  1211.     ''' </remarks>
  1212.     Public Class ID3v1Tag
  1213.  
  1214.         ''' Declarations for private variables holding the property values
  1215.         Private m_blnTagAvailable As Boolean = False
  1216.         Private m_bytTagVersion As ID3v1TagVersionEnum = ID3v1TagVersionEnum.Version10
  1217.         Private m_strArtist As String = ""
  1218.         Private m_strTitle As String = ""
  1219.         Private m_strAlbum As String = ""
  1220.         Private m_strYear As String = ""
  1221.         Private m_strComment As String = ""
  1222.         Private m_bytGenre As Byte = 0
  1223.         Private m_strGenreString As String = ""
  1224.         Private m_bytTrack As Byte = 0
  1225.  
  1226.         ''' <summary>
  1227.         '''     Gets the availability of an ID3 v1.x tag.
  1228.         ''' </summary>
  1229.         ''' <value>
  1230.         '''     <para>
  1231.         '''         A boolean value describing the availability of an ID3 v1.x tag.
  1232.         '''     </para>
  1233.         ''' </value>
  1234.         ''' <remarks>
  1235.         '''     None.
  1236.         ''' </remarks>
  1237.         Public Property TagAvailable() As Boolean
  1238.             Get
  1239.                 Return m_blnTagAvailable
  1240.             End Get
  1241.             Friend Set(ByVal value As Boolean)
  1242.                 m_blnTagAvailable = value
  1243.             End Set
  1244.         End Property
  1245.  
  1246.         ''' <summary>
  1247.         '''     Gets or sets the tag version.
  1248.         ''' </summary>
  1249.         ''' <value>
  1250.         '''     <para>
  1251.         '''         An ID3v1TagVersionEnum value describing the tag version.
  1252.         '''     </para>
  1253.         ''' </value>
  1254.         ''' <remarks>
  1255.         '''     None.
  1256.         ''' </remarks>
  1257.         Public Property TagVersion() As ID3v1TagVersionEnum
  1258.             Get
  1259.                 Return m_bytTagVersion
  1260.             End Get
  1261.             Set(ByVal Value As ID3v1TagVersionEnum)
  1262.                 m_bytTagVersion = Value
  1263.                 If (m_bytTagVersion = ID3v1TagVersionEnum.Version11 AndAlso Me.Comment.Length > 28) Then
  1264.                     Me.Comment = Me.Comment.Substring(1, 28)
  1265.                 End If
  1266.             End Set
  1267.         End Property
  1268.  
  1269.         ''' <summary>
  1270.         '''     Gets or sets the title.
  1271.         ''' </summary>
  1272.         ''' <value>
  1273.         '''     <para>
  1274.         '''         The title.
  1275.         '''     </para>
  1276.         ''' </value>
  1277.         ''' <remarks>
  1278.         '''     None.
  1279.         ''' </remarks>
  1280.         Public Property Title() As String
  1281.             Get
  1282.                 Return m_strTitle
  1283.             End Get
  1284.             Set(ByVal value As String)
  1285.                 If (String.IsNullOrWhiteSpace(value) = False AndAlso value.Length > 30) Then
  1286.                     'Throw New Exception("The length of the property 'Title' must be equal or less than 30 bytes.")
  1287.                     '$ GUILLE (25/Mar/13)
  1288.                     ' No producir error, asignar sólo los caracteres que correspondan
  1289.                     m_strTitle = value.Substring(0, 30)
  1290.                 Else
  1291.                     m_strTitle = value
  1292.                 End If
  1293.             End Set
  1294.         End Property
  1295.  
  1296.         ''' <summary>
  1297.         '''     Gets or sets the artist.
  1298.         ''' </summary>
  1299.         ''' <value>
  1300.         '''     <para>
  1301.         '''         The artist.
  1302.         '''     </para>
  1303.         ''' </value>
  1304.         ''' <remarks>
  1305.         '''     None.
  1306.         ''' </remarks>
  1307.         Public Property Artist() As String
  1308.             Get
  1309.                 Return m_strArtist
  1310.             End Get
  1311.             Set(ByVal value As String)
  1312.                 If (String.IsNullOrWhiteSpace(value) = False AndAlso value.Length > 30) Then
  1313.                     'Throw New Exception("The length of the property 'Artist' must be equal or less than 30 bytes.")
  1314.                     '$ GUILLE (25/Mar/13)
  1315.                     ' No producir error, asignar sólo los caracteres que correspondan
  1316.                     m_strArtist = value.Substring(0, 30)
  1317.                 Else
  1318.                     m_strArtist = value
  1319.                 End If
  1320.             End Set
  1321.         End Property
  1322.  
  1323.         ''' <summary>
  1324.         '''     Gets or sets the album name.
  1325.         ''' </summary>
  1326.         ''' <value>
  1327.         '''     <para>
  1328.         '''         The album name.
  1329.         '''     </para>
  1330.         ''' </value>
  1331.         ''' <remarks>
  1332.         '''     None.
  1333.         ''' </remarks>
  1334.         Public Property Album() As String
  1335.             Get
  1336.                 Return m_strAlbum
  1337.             End Get
  1338.             Set(ByVal value As String)
  1339.                 If (String.IsNullOrWhiteSpace(value) = False AndAlso value.Length > 30) Then
  1340.                     'Throw New Exception("The length of the property 'Album' must be equal or less than 30 bytes.")
  1341.                     '$ GUILLE (25/Mar/13)
  1342.                     ' No producir error, asignar sólo los caracteres que correspondan
  1343.                     m_strAlbum = value.Substring(0, 30)
  1344.                 Else
  1345.                     m_strAlbum = value
  1346.                 End If
  1347.             End Set
  1348.         End Property
  1349.  
  1350.         ''' <summary>
  1351.         '''     Gets or sets the Year.
  1352.         ''' </summary>
  1353.         ''' <value>
  1354.         '''     <para>
  1355.         '''         The year.
  1356.         '''     </para>
  1357.         ''' </value>
  1358.         ''' <remarks>
  1359.         '''     None.
  1360.         ''' </remarks>
  1361.         Public Property Year() As String
  1362.             Get
  1363.                 Return m_strYear
  1364.             End Get
  1365.             Set(ByVal value As String)
  1366.                 If (value.Length > 4) Then
  1367.                     Throw New Exception("The length of the property 'Year' must be equal or less than 4 bytes.")
  1368.                 Else
  1369.                     m_strYear = value
  1370.                 End If
  1371.             End Set
  1372.         End Property
  1373.  
  1374.         ''' <summary>
  1375.         '''     Gets or sets the track number.
  1376.         ''' </summary>
  1377.         ''' <value>
  1378.         '''     <para>
  1379.         '''         The track number.
  1380.         '''     </para>
  1381.         ''' </value>
  1382.         ''' <remarks>
  1383.         '''     None.
  1384.         ''' </remarks>
  1385.         Public Property Track() As Byte
  1386.             Get
  1387.                 Return m_bytTrack
  1388.             End Get
  1389.             Set(ByVal Value As Byte)
  1390.                 m_bytTrack = Value
  1391.             End Set
  1392.         End Property
  1393.  
  1394.         ''' <summary>
  1395.         '''     Gets or sets the comment.
  1396.         ''' </summary>
  1397.         ''' <value>
  1398.         '''     <para>
  1399.         '''         The comment.
  1400.         '''     </para>
  1401.         ''' </value>
  1402.         ''' <remarks>
  1403.         '''     None.
  1404.         ''' </remarks>
  1405.         Public Property Comment() As String
  1406.             Get
  1407.                 Return m_strComment
  1408.             End Get
  1409.             Set(ByVal value As String)
  1410.                 Select Case m_bytTagVersion
  1411.                     Case ID3v1TagVersionEnum.Version10
  1412.                         If (value.Length > 30) Then
  1413.                             Throw New Exception("The length of the property 'Comment' must be equal or less than 30 bytes for tag version 1.0.")
  1414.                         Else
  1415.                             m_strComment = value
  1416.                         End If
  1417.                     Case ID3v1TagVersionEnum.Version11
  1418.                         If (value.Length > 28) Then
  1419.                             Throw New Exception("The length of the property 'Comment' must be equal or less than 28 bytes for tag version 1.1.")
  1420.                         Else
  1421.                             m_strComment = value
  1422.                         End If
  1423.                 End Select
  1424.             End Set
  1425.         End Property
  1426.  
  1427.         ''' <summary>
  1428.         '''     Gets or sets the genre id.
  1429.         ''' </summary>
  1430.         ''' <value>
  1431.         '''     <para>
  1432.         '''         The genre id.
  1433.         '''     </para>
  1434.         ''' </value>
  1435.         ''' <remarks>
  1436.         '''     None.
  1437.         ''' </remarks>
  1438.         Public Property Genre() As Byte
  1439.             Get
  1440.                 Return m_bytGenre
  1441.             End Get
  1442.             Set(ByVal Value As Byte)
  1443.                 m_bytGenre = Value
  1444.             End Set
  1445.         End Property
  1446.  
  1447.         ''' <summary>
  1448.         '''     Gets the genre as text.
  1449.         ''' </summary>
  1450.         ''' <param name="bytGenre" type="Byte">
  1451.         '''     <para>
  1452.         '''         The genre id.
  1453.         '''     </para>
  1454.         ''' </param>
  1455.         ''' <returns>
  1456.         '''     The genre as text.
  1457.         ''' </returns>
  1458.         Public Function GetGenreString(ByVal bytGenre As Byte) As String
  1459.  
  1460.             Dim strGenres() As String = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", _
  1461.             "Hip - Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", _
  1462.             "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro -Techno", "Ambient", _
  1463.             "Trip -Hop", "Vocal", "Jazz Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", _
  1464.             "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", _
  1465.             "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno -Industrial", "Electronic", _
  1466.             "Pop -Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", _
  1467.             "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", _
  1468.             "Lo - Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", _
  1469.             "Folk", "Folk/Rock", "National Folk", "Swing", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", _
  1470.             "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", _
  1471.             "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", _
  1472.             "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", _
  1473.             "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Cappella", "Euro - House", _
  1474.              "Dance Hall", "Goa", "Drum & Bass", "Club - House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", _
  1475.             "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", _
  1476.             "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "Synthpop"}
  1477.  
  1478.             Return strGenres(bytGenre)
  1479.  
  1480.         End Function
  1481.  
  1482.     End Class
  1483.  
  1484. End Namespace
RAW Paste Data
Pastebin PRO Autumn Special!
Get 40% OFF on Pastebin PRO accounts!
Top