I have a sample code in C# which compiles fine without any errors.
It compiles and produces a ReadMP3.dll file in the debug folder of the obj and bin folders. What command prompts should I use to select and read an MP3 file?
Printable View
I have a sample code in C# which compiles fine without any errors.
It compiles and produces a ReadMP3.dll file in the debug folder of the obj and bin folders. What command prompts should I use to select and read an MP3 file?
Not sure what you mean by "What command prompts I should use".
Are you wondering how to utilize the DLL it created for you?
Not being familiar with ReadMP3.dll myself, I can only guess that it contains some sort of class that you can create and use its functions.
Sorry, I should have phrased that better. Yes how do I utilize the dll file given?
The name of the project is 'ReadMP3', so it produces a ReadMP3.dll file.
the only way i know how to run a method from a dll in command line is to do call the rundll32.exe with proper parameters
This particular project doesn't produce an .exe file.
BitReader.cs
Code:using System;
namespace ReadMP3
{
/// <summary>
/// Summary description for BitReader.
/// </summary>
public class BitReader
{
public static bool GetBitAtPosition (byte b, int position)
{
bool[] bitArray = ToBitBool(b);
return bitArray[position];
}
public static bool[] ToBitBool( byte newByte )
{
// get the value of hte byte
int myNum = System.Convert.ToInt32(newByte);
// make a bool array for the bits.
// 0 == falseu
// 1 == true; duh
bool[] myByte = new bool[8];
for (int i = 0; i < 8; i++)
{
// ANDing against each bit to set the bool value
if ((myNum & (1 << (7 - i))) != 0)
{
myByte[i] = true;
}
}
return myByte;
}
public static char[] To*****ar( byte newByte )
{
char[] myChar = new char[8];
bool[] myBool = ToBitBool(newByte);
for (int i = 0; i < 8; i++)
{
if (myBool[i])
{
myChar[i] = System.Convert.ToChar("1");
}
else
{
myChar[i] = System.Convert.ToChar("0");
}
}
return myChar;
}
public static char[] To*****ars( byte[] myBytes )
{
char[] myChars = new char[myBytes.Length * 8];
int i = 0;
foreach (byte b in myBytes)
{
bool[] bit = ToBitBool( b );
for (int j = 0; j < 8; j++)
{
if (bit[j])
{
myChars[i++] = System.Convert.ToChar("1");
}
else
{
myChars[i++] = System.Convert.ToChar("0");
}
}
}
return myChars;
}
public static bool[] ToBitBools( byte[] myBytes )
{
bool[] myBools = new bool[myBytes.Length * 8 ];
int i = 0;
foreach (byte b in myBytes)
{
bool[] bit = ToBitBool( b );
for (int j = 0; j < 8; j++)
{
if (bit[j])
{
myBools[i++] = true;
}
else
{
myBools[i++] = false;
}
}
}
return myBools;
}
public static byte ToByteChar( char[] myChar )
{
int myInt = 0;
for (int i = 0; i < 8 ; i++ )
{
if ( myChar[i].Equals("1"))
myInt += (int)Math.Pow(2, 7 - i);
}
return System.Convert.ToByte(myInt);
}
public static byte ToByteBool( bool[] myBool )
{
int myInt = 0;
for (int i = 0; i < 8 ; i++ )
{
if ( myBool[i])
myInt += (int)Math.Pow(2, 7 - i);
}
return System.Convert.ToByte(myInt);
}
public BitReader()
{
//
// TODO: Add constructor logic here
//
}
}
}
ID3v1.cs
Code:using System;
using System.IO;
using System.Text;
namespace ReadMP3
{
/// <summary>
/// Reads/writes Id3v1 tags. lots of help from Paul Lockwood's code
/// http://www.csharphelp.com/archives/archive226.html
/// </summary>
public class ID3v1
{
public string filename;
public string Title;
public string Artist;
public string Album;
public string Year;
public string Comment;
public int GenreID;
public int Track;
public bool hasTag;
private void Initialize_Components()
{
hasTag = false;
filename = "";
Title = "";
Artist = "";
Album = "";
Year = "";
Comment = "";
GenreID = 0;
Track = 0;
}
public ID3v1()
{
Initialize_Components();
}
public ID3v1( string filename )
{
Initialize_Components();
this.filename = filename;
}
public void Read ()
{
// Read the 128 byte ID3 tag into a byte array
FileStream oFileStream;
oFileStream = new FileStream( this.filename, FileMode.Open);
byte[] bBuffer = new byte[128];
oFileStream.Seek(-128, SeekOrigin.End);
oFileStream.Read(bBuffer,0, 128);
oFileStream.Close();
// Convert the Byte Array to a String
Encoding instEncoding = new ASCIIEncoding(); // NB: Encoding is an Abstract class
string id3Tag = instEncoding.GetString(bBuffer);
// If there is an attched ID3 v1.x TAG then read it
if (id3Tag .Substring(0,3) == "TAG")
{
this.Title = id3Tag.Substring( 3, 30).Trim();
this.Artist = id3Tag.Substring( 33, 30).Trim();
this.Album = id3Tag.Substring( 63, 30).Trim();
this.Year = id3Tag.Substring( 93, 4).Trim();
this.Comment = id3Tag.Substring( 97,28).Trim();
// Get the track number if TAG conforms to ID3 v1.1
if (id3Tag[125]==0)
this.Track = bBuffer[126];
else
this.Track = 0;
this.GenreID = bBuffer[127];
this.hasTag = true;
// ********* IF USED IN ANGER: ENSURE to test for non-numeric year
}
else
{
this.hasTag = false;
}
}
public void updateMP3Tag ()
{
// Trim any whitespace
this.Title = this.Title.Trim();
this.Artist = this.Artist.Trim();
this.Album = this.Album.Trim();
this.Year = this.Year.Trim();
this.Comment = this.Comment.Trim();
// Ensure all properties are correct size
if (this.Title.Length > 30) this.Title = this.Title.Substring(0,30);
if (this.Artist.Length > 30) this.Artist = this.Artist.Substring(0,30);
if (this.Album.Length > 30) this.Album = this.Album.Substring(0,30);
if (this.Year.Length > 4) this.Year = this.Year.Substring(0,4);
if (this.Comment.Length > 28) this.Comment = this.Comment.Substring(0,28);
// Build a new ID3 Tag (128 Bytes)
byte[] tagByteArray = new byte[128];
for ( int i = 0; i < tagByteArray.Length; i++ ) tagByteArray[i] = 0; // Initialise array to nulls
// Convert the Byte Array to a String
Encoding instEncoding = new ASCIIEncoding(); // NB: Encoding is an Abstract class // ************ To DO: Make a shared instance of ASCIIEncoding so we don't keep creating/destroying it
// Copy "TAG" to Array
byte[] workingByteArray = instEncoding.GetBytes("TAG");
Array.Copy(workingByteArray, 0, tagByteArray, 0, workingByteArray.Length);
// Copy Title to Array
workingByteArray = instEncoding.GetBytes(this.Title);
Array.Copy(workingByteArray, 0, tagByteArray, 3, workingByteArray.Length);
// Copy Artist to Array
workingByteArray = instEncoding.GetBytes(this.Artist);
Array.Copy(workingByteArray, 0, tagByteArray, 33, workingByteArray.Length);
// Copy Album to Array
workingByteArray = instEncoding.GetBytes(this.Album);
Array.Copy(workingByteArray, 0, tagByteArray, 63, workingByteArray.Length);
// Copy Year to Array
workingByteArray = instEncoding.GetBytes(this.Year);
Array.Copy(workingByteArray, 0, tagByteArray, 93, workingByteArray.Length);
// Copy Comment to Array
workingByteArray = instEncoding.GetBytes(this.Comment);
Array.Copy(workingByteArray, 0, tagByteArray, 97, workingByteArray.Length);
// Copy Track and Genre to Array
tagByteArray[126] = System.Convert.ToByte(this.Track);
tagByteArray[127] = System.Convert.ToByte(this.GenreID);
// SAVE TO DISK: Replace the final 128 Bytes with our new ID3 tag
FileStream oFileStream = new FileStream(this.filename , FileMode.Open);
if (this.hasTag)
oFileStream.Seek(-128, SeekOrigin.End);
else
oFileStream.Seek(0, SeekOrigin.End);
oFileStream.Write(tagByteArray,0, 128);
oFileStream.Close();
this.hasTag = true;
}
}
}
ID3v2.cs
Code:using System;
using System.IO;
using System.Text;
namespace ReadMP3
{
/// <summary>
/// Reads/writes Id3v1 tags. lots of help from Paul Lockwood's code
/// http://www.csharphelp.com/archives/archive226.html
/// </summary>
public class ID3v1
{
public string filename;
public string Title;
public string Artist;
public string Album;
public string Year;
public string Comment;
public int GenreID;
public int Track;
public bool hasTag;
private void Initialize_Components()
{
hasTag = false;
filename = "";
Title = "";
Artist = "";
Album = "";
Year = "";
Comment = "";
GenreID = 0;
Track = 0;
}
public ID3v1()
{
Initialize_Components();
}
public ID3v1( string filename )
{
Initialize_Components();
this.filename = filename;
}
public void Read ()
{
// Read the 128 byte ID3 tag into a byte array
FileStream oFileStream;
oFileStream = new FileStream( this.filename, FileMode.Open);
byte[] bBuffer = new byte[128];
oFileStream.Seek(-128, SeekOrigin.End);
oFileStream.Read(bBuffer,0, 128);
oFileStream.Close();
// Convert the Byte Array to a String
Encoding instEncoding = new ASCIIEncoding(); // NB: Encoding is an Abstract class
string id3Tag = instEncoding.GetString(bBuffer);
// If there is an attched ID3 v1.x TAG then read it
if (id3Tag .Substring(0,3) == "TAG")
{
this.Title = id3Tag.Substring( 3, 30).Trim();
this.Artist = id3Tag.Substring( 33, 30).Trim();
this.Album = id3Tag.Substring( 63, 30).Trim();
this.Year = id3Tag.Substring( 93, 4).Trim();
this.Comment = id3Tag.Substring( 97,28).Trim();
// Get the track number if TAG conforms to ID3 v1.1
if (id3Tag[125]==0)
this.Track = bBuffer[126];
else
this.Track = 0;
this.GenreID = bBuffer[127];
this.hasTag = true;
// ********* IF USED IN ANGER: ENSURE to test for non-numeric year
}
else
{
this.hasTag = false;
}
}
public void updateMP3Tag ()
{
// Trim any whitespace
this.Title = this.Title.Trim();
this.Artist = this.Artist.Trim();
this.Album = this.Album.Trim();
this.Year = this.Year.Trim();
this.Comment = this.Comment.Trim();
// Ensure all properties are correct size
if (this.Title.Length > 30) this.Title = this.Title.Substring(0,30);
if (this.Artist.Length > 30) this.Artist = this.Artist.Substring(0,30);
if (this.Album.Length > 30) this.Album = this.Album.Substring(0,30);
if (this.Year.Length > 4) this.Year = this.Year.Substring(0,4);
if (this.Comment.Length > 28) this.Comment = this.Comment.Substring(0,28);
// Build a new ID3 Tag (128 Bytes)
byte[] tagByteArray = new byte[128];
for ( int i = 0; i < tagByteArray.Length; i++ ) tagByteArray[i] = 0; // Initialise array to nulls
// Convert the Byte Array to a String
Encoding instEncoding = new ASCIIEncoding(); // NB: Encoding is an Abstract class // ************ To DO: Make a shared instance of ASCIIEncoding so we don't keep creating/destroying it
// Copy "TAG" to Array
byte[] workingByteArray = instEncoding.GetBytes("TAG");
Array.Copy(workingByteArray, 0, tagByteArray, 0, workingByteArray.Length);
// Copy Title to Array
workingByteArray = instEncoding.GetBytes(this.Title);
Array.Copy(workingByteArray, 0, tagByteArray, 3, workingByteArray.Length);
// Copy Artist to Array
workingByteArray = instEncoding.GetBytes(this.Artist);
Array.Copy(workingByteArray, 0, tagByteArray, 33, workingByteArray.Length);
// Copy Album to Array
workingByteArray = instEncoding.GetBytes(this.Album);
Array.Copy(workingByteArray, 0, tagByteArray, 63, workingByteArray.Length);
// Copy Year to Array
workingByteArray = instEncoding.GetBytes(this.Year);
Array.Copy(workingByteArray, 0, tagByteArray, 93, workingByteArray.Length);
// Copy Comment to Array
workingByteArray = instEncoding.GetBytes(this.Comment);
Array.Copy(workingByteArray, 0, tagByteArray, 97, workingByteArray.Length);
// Copy Track and Genre to Array
tagByteArray[126] = System.Convert.ToByte(this.Track);
tagByteArray[127] = System.Convert.ToByte(this.GenreID);
// SAVE TO DISK: Replace the final 128 Bytes with our new ID3 tag
FileStream oFileStream = new FileStream(this.filename , FileMode.Open);
if (this.hasTag)
oFileStream.Seek(-128, SeekOrigin.End);
else
oFileStream.Seek(0, SeekOrigin.End);
oFileStream.Write(tagByteArray,0, 128);
oFileStream.Close();
this.hasTag = true;
}
}
}
idv3frame.cs
Code:using System;
using System.IO;
using System.Text;
namespace ReadMP3
{
/// <summary>
/// Piece of ID3v2 reader. reads frmes one at a time given the proper position in a binary stream
/// </summary>
public class id3v2Frame
{
public string frameName;
public byte[] frameContents;
public ulong frameSize;
public int MajorVersion;
public bool F_TagAlterPreservation;
public bool F_FileAlterPreservation;
public bool F_ReadOnly;
public bool F_Compression;
public bool F_Encryption;
public bool F_GroupingIdentity;
public bool F_Unsynchronisation;
public bool F_DataLengthIndicator;
public bool padding;
public id3v2Frame()
{
this.padding = false;
this.frameName ="";
this.frameSize = 0;
this.MajorVersion = 0;
this.F_TagAlterPreservation = false;
this.F_FileAlterPreservation = false;
this.F_ReadOnly = false;
this.F_Compression= false;
this.F_Encryption = false;
this.F_GroupingIdentity = false;
this.F_Unsynchronisation = false;
this.F_DataLengthIndicator = false;
}
public id3v2Frame ReadFrame (BinaryReader br, int version)
{
char[] tagSize; // I use this to read the bytes in from the file
int[] bytes; // for bit shifting
ulong newSize = 0; // for the final number
int nameSize = 4;
if (version == 2)
{
nameSize = 3;
}
else if ((version == 3) || (version == 4))
{
nameSize = 4;
}
id3v2Frame f1 = new id3v2Frame();
f1.frameName = new string (br.ReadChars(nameSize));
f1.MajorVersion = version;
// in order to check for padding I have to build a string of 4 (or 3 if v2.2) null bytes
// there must be a better way to do this
char nullChar = System.Convert.ToChar(0);
StringBuilder sb = new StringBuilder(0,nameSize);
sb.Append(nullChar);
sb.Append(nullChar);
sb.Append(nullChar);
if (nameSize == 4)
{
sb.Append(nullChar);
}
if (f1.frameName == sb.ToString())
{
f1.padding = true;
return f1;
}
if (version == 2)
{
// only have 3 bytes for size ;
tagSize = br.ReadChars(3); // I use this to read the bytes in from the file
bytes = new int[3]; // for bit shifting
newSize = 0; // for the final number
// The ID3v2 tag size is encoded with four bytes
// where the most significant bit (bit 7)
// is set to zero in every byte,
// making a total of 28 bits.
// The zeroed bits are ignored
//
// Some bit grinding is necessary. Hang on.
bytes[3] = tagSize[2] | ((tagSize[1] & 1) << 7) ;
bytes[2] = ((tagSize[1] >> 1) & 63) | ((tagSize[0] & 3) << 6) ;
bytes[1] = ((tagSize[0] >> 2) & 31) ;
newSize = ((UInt64)bytes[3] |
((UInt64)bytes[2] << 8) |
((UInt64)bytes[1] << 16));
//End Dan Code
}
else if (version == 3 || version == 4)
{
// version 2.4
tagSize = br.ReadChars(4); // I use this to read the bytes in from the file
bytes = new int[4]; // for bit shifting
newSize = 0; // for the final number
// The ID3v2 tag size is encoded with four bytes
// where the most significant bit (bit 7)
// is set to zero in every byte,
// making a total of 28 bits.
// The zeroed bits are ignored
//
// Some bit grinding is necessary. Hang on.
bytes[3] = tagSize[3] | ((tagSize[2] & 1) << 7) ;
bytes[2] = ((tagSize[2] >> 1) & 63) | ((tagSize[1] & 3) << 6) ;
bytes[1] = ((tagSize[1] >> 2) & 31) | ((tagSize[0] & 7) << 5) ;
bytes[0] = ((tagSize[0] >> 3) & 15) ;
newSize = ((UInt64)bytes[3] |
((UInt64)bytes[2] << 8) |
((UInt64)bytes[1] << 16) |
((UInt64)bytes[0] << 24)) ;
//End Dan Code
}
f1.frameSize = newSize;
if (version > 2)
{
// versions 3+ have frame tags.
if (version == 3)
{
bool [] c;
// read teh tags
c = BitReader.ToBitBool(br.ReadByte());
f1.F_TagAlterPreservation = c[0];
f1.F_FileAlterPreservation= c[1];
f1.F_ReadOnly= c[2];
c = BitReader.ToBitBool(br.ReadByte());
f1.F_Compression= c[0];
f1.F_Encryption= c[1];
f1.F_GroupingIdentity= c[2];
}
else if (version == 4)
{
//%0abc0000 %0h00kmnp
//a - Tag alter preservation
// 0 Frame should be preserved.
// 1 Frame should be discarded.
// b - File alter preservation
// 0 Frame should be preserved.
//1 Frame should be discarded.
// c - Read only
// h - Grouping identity
// 0 Frame does not contain group information
// 1 Frame contains group information
// k - Compression
// 0 Frame is not compressed.
// 1 Frame is compressed using zlib [zlib] deflate method.
// If set, this requires the 'Data Length Indicator' bit
// to be set as well.
// m - Encryption
// 0 Frame is not encrypted.
// 1 Frame is encrypted.
// n - Unsynchronisation
// 0 Frame has not been unsynchronised.
// 1 Frame has been unsyrchronised.
// p - Data length indicator
// 0 There is no Data Length Indicator.
// 1 A data length Indicator has been added to the frame.
bool [] c;
// read teh tags
c = BitReader.ToBitBool(br.ReadByte());
f1.F_TagAlterPreservation = c[1];
f1.F_FileAlterPreservation= c[2];
f1.F_ReadOnly= c[3];
c = BitReader.ToBitBool(br.ReadByte());
f1.F_GroupingIdentity= c[1];
f1.F_Compression= c[4];
f1.F_Encryption= c[5];
f1.F_Unsynchronisation = c[6];
f1.F_DataLengthIndicator = c[7];
}
if (f1.frameSize > 0)
{
f1.frameContents = br.ReadBytes((int)f1.frameSize);
}
}
return f1;
}
}
}
MPEG.cs
Code:using System;
using System.IO;
namespace ReadMP3
{
/// <summary>
/// Summary description for MPEG.
/// </summary>
public class MPEG
{
public long length; // in seconds
public long audioBytes;
public long fileSize;
public string filename;
public string Version;
public string Layer;
public bool Protection;
public string Bitrate;
public string Frequency;
public bool Padding;
public bool Private;
public string ChannelMode;
public string ModeExtension;
public bool CopyRight;
public bool Original;
public string Emphasis;
public long headerPosition;
private BinaryReader br;
public MPEG()
{
Initialize_Components();
}
public MPEG( string fileName)
{
Initialize_Components();
this.filename = fileName;
}
public void Read (string fileName)
{
this.filename = fileName;
Read();
}
private void Initialize_Components()
{
this.audioBytes = 0;
this.filename = "";
this.Version = "";
this.Layer = "";
this.Protection = false;
this.Bitrate = "";
this.Frequency = "";
this.Padding = false;
this.Private = false;
this.ChannelMode = "";
this.ModeExtension = "";
this.CopyRight = false;
this.Original = false;
this.Emphasis = "";
this.headerPosition = 0;
}
public void Read()
{
FileStream fs = new FileStream(this.filename, FileMode.Open, FileAccess.Read);
br = new BinaryReader (fs);
byte[] headerBytes = FindHeader();
ParseHeader(headerBytes);
br.Close();
fs.Close();
}
private void CalculateLength()
{
FileInfo fi = new FileInfo(this.filename);
this.fileSize = fi.Length;
this.audioBytes = this.fileSize - this.headerPosition;
int bitrate = System.Convert.ToInt32(this.Bitrate);
if (bitrate > 0)
{
this.length = (this.audioBytes * 8) / (1000 * bitrate);
}
}
public void ParseHeader (byte[] headerBytes)
{
bool [] boolHeader = BitReader.ToBitBools(headerBytes);
ParseVersion(boolHeader[11], boolHeader[12]);
ParseLayer(boolHeader[13], boolHeader[14]);
this.Protection = boolHeader[15];
ParseBitRate(boolHeader[16], boolHeader[17], boolHeader[18], boolHeader[19]);
ParseFrequency(boolHeader[20], boolHeader[21]);
this.Padding = boolHeader[22];
this.Private = boolHeader[23];
ParseChannelMode(boolHeader[24], boolHeader[25]);
ParseModeExtension(boolHeader[26], boolHeader[27]);
this.CopyRight = boolHeader[28];
this.Original = boolHeader[29];
ParseEmphasis(boolHeader[30], boolHeader[31]);
}
private void ParseFrequency ( bool b1, bool b2)
{
if (b1)
{
if(b2)
{
//"11"
this.Frequency = "reserved";
}
else
{
// "01"
switch (this.Version)
{
case "MPEG Version 1":
this.Frequency = "32000";
break;
case "MPEG Version 2":
this.Frequency = "16000";
break;
case "MPEG Version 2.5":
this.Frequency = "8000";
break;
}
}
}
else
{
if (b2)
{
//"01"
switch (this.Version)
{
case "MPEG Version 1":
this.Frequency = "32000";
break;
case "MPEG Version 2":
this.Frequency = "16000";
break;
case "MPEG Version 2.5":
this.Frequency = "8000";
break;
}
}
else
{
// "00"
switch (this.Version)
{
case "MPEG Version 1":
this.Frequency = "44100";
break;
case "MPEG Version 2":
this.Frequency = "22050";
break;
case "MPEG Version 2.5":
this.Frequency = "11025";
break;
}
}
}
}
private void ParseModeExtension (bool b1, bool b2)
{
if (b1)
{
if (b2)
{
if (this.Layer.Equals("Layer III"))
{
// "11", L3
this.ModeExtension = "IS+MS";
}
else
{
// "11", L1 or L2
this.ModeExtension = "16-31";
}
}
else
{
if (this.Layer.Equals("Layer III"))
{
// "10", L3
this.ModeExtension = "MS";
}
else
{
// "10", L1 or L2
this.ModeExtension = "12-31";
}
}
}
else
{
if (b2)
{
if (this.Layer.Equals("Layer III"))
{
// "01", L3
this.ModeExtension = "IS";
}
else
{
// "01", L1 or L2
this.ModeExtension = "8-31";
}
}
else
{
if (this.Layer.Equals("Layer III"))
{
// "00", L3
this.ModeExtension = "";
}
else
{
// "00", L1 or L2
this.ModeExtension = "4-31";
}
}
}
}
private void ParseEmphasis (bool b1, bool b2)
{
//00 - none
//01 - 50/15 ms
//10 - reserved
//11 - CCIT J.17
if (b1)
{
if(b2)
{
//"11"
this.Emphasis = "CCIT J.17";
}
else
{
//"10"
this.Emphasis = "reserved";
}
}
else
{
if (b2)
{
//"01"
this.Emphasis = "50/15 ms";
}
else
{
//"00"
this.Emphasis = "none";
}
}
}
private void ParseChannelMode (bool b1, bool b2)
{
//00 - Stereo
//01 - Joint stereo (Stereo)
//10 - Dual channel (Stereo)
//11 - Single channel (Mono)
if (b1)
{
if(b2)
{
//"11"
this.ChannelMode = "Single Channel";
}
else
{
//"10"
this.ChannelMode = "Dual Channel";
}
}
else
{
if (b2)
{
//"01"
this.ChannelMode = "Joint Stereo";
}
else
{
//"00"
this.ChannelMode = "Stereo";
}
}
}
private void ParseVersion (bool b1, bool b2)
{
// get the MPEG Audio Version ID
//MPEG Audio version ID
//00 - MPEG Version 2.5
//01 - reserved
//10 - MPEG Version 2 (ISO/IEC 13818-3)
//11 - MPEG Version 1 (ISO/IEC 11172-3)
if (b1)
{
if(b2)
{
this.Version = "MPEG Version 1";
}
else
{
this.Version = "MPEG Version 2";
}
}
else
{
if (b2)
{
this.Version = "reserved";
}
else
{
this.Version = "MPEG Version 2.5";
}
}
}
private void ParseLayer (bool b1, bool b2)
{
if (b1)
{
if(b2)
{
// if "11"
this.Layer = "Layer I";
}
else
{
// "10"
this.Layer = "Layer II";
}
}
else
{
if (b2)
{
// "01"
this.Layer = "Layer III";
}
else
{
// "00"
this.Layer = "reserved";
}
}
}
private void ParseBitRate (bool b1, bool b2, bool b3, bool b4)
{
// I know there is a more elegant way than this.
if (b1)
{
if (b2)
{
if (b3)
{
if (b4)
{
#region "1111"
this.Bitrate = "bad";
#endregion
}
else
{
#region "1110"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "448";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "384";
}
else
{
// V1, L3
this.Bitrate = "320";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "256";
}
else
{
// V2, L2 & L3
this.Bitrate = "160";
}
}
#endregion
}
}
else
{
if (b4)
{
#region "1101"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "416";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "320";
}
else
{
// V1, L3
this.Bitrate = "256";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "224";
}
else
{
// V2, L2 & L3
this.Bitrate = "144";
}
}
#endregion
}
else
{
#region "1100"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "384";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "256";
}
else
{
// V1, L3
this.Bitrate = "224";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "192";
}
else
{
// V2, L2 & L3
this.Bitrate = "128";
}
}
#endregion
}
}
}
else //b2 not set
{
if (b3)
{
if (b4)
{
#region "1011"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "352";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "224";
}
else
{
// V1, L3
this.Bitrate = "192";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "176";
}
else
{
// V2, L2 & L3
this.Bitrate = "112";
}
}
#endregion
}
else
{
#region "1010"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "320";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "192";
}
else
{
// V1, L3
this.Bitrate = "160";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "160";
}
else
{
// V2, L2 & L3
this.Bitrate = "96";
}
}
#endregion
}
}
else
{
if (b4)
{
#region "1001"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "288";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "160";
}
else
{
// V1, L3
this.Bitrate = "128";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "144";
}
else
{
// V2, L2 & L3
this.Bitrate = "80";
}
}
#endregion
}
else
{
#region "1000"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "256";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "128";
}
else
{
// V1, L3
this.Bitrate = "112";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "128";
}
else
{
// V2, L2 & L3
this.Bitrate = "64";
}
}
#endregion
}
}
}
}
else
{
if (b2)
{
if (b3)
{
if (b4)
{
#region "0111"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "224";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "112";
}
else
{
// V1, L3
this.Bitrate = "96";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "112";
}
else
{
// V2, L2 & L3
this.Bitrate = "56";
}
}
#endregion
}
else
{
#region "0110"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "192";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "96";
}
else
{
// V1, L3
this.Bitrate = "80";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "96";
}
else
{
// V2, L2 & L3
this.Bitrate = "48";
}
}
#endregion
}
}
else
{
if (b4)
{
#region "0101"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "160";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "80";
}
else
{
// V1, L3
this.Bitrate = "64";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "80";
}
else
{
// V2, L2 & L3
this.Bitrate = "40";
}
}
#endregion
}
else
{
#region "0100"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "128";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "64";
}
else
{
// V1, L3
this.Bitrate = "56";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "64";
}
else
{
// V2, L2 & L3
this.Bitrate = "32";
}
}
#endregion
}
}
}
else //b2 not set
{
if (b3)
{
if (b4)
{
#region "0011"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "96";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "56";
}
else
{
// V1, L3
this.Bitrate = "48";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "56";
}
else
{
// V2, L2 & L3
this.Bitrate = "24";
}
}
#endregion
}
else
{
#region "0010"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "64";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "48";
}
else
{
// V1, L3
this.Bitrate = "40";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "48";
}
else
{
// V2, L2 & L3
this.Bitrate = "16";
}
}
#endregion
}
}
else
{
if (b4)
{
#region "0001"
if (this.Version.EndsWith("1"))
{
if (this.Layer.EndsWith(" I"))
{
// V1, L1
this.Bitrate = "32";
}
else if (this.Layer.EndsWith(" II"))
{
// v1, L2
this.Bitrate = "32";
}
else
{
// V1, L3
this.Bitrate = "32";
}
}
else
{
if (this.Layer.EndsWith(" I"))
{
// V2, L1
this.Bitrate = "32";
}
else
{
// V2, L2 & L3
this.Bitrate = "8";
}
}
#endregion
}
else
{
#region "1000"
this.Bitrate = "free";
#endregion
}
}
}
}
}
private byte[] FindHeader ()
{
byte thisByte = br.ReadByte();
while ( br.BaseStream.Position < br.BaseStream.Length )
{
if (System.Convert.ToInt32(thisByte) == 255)
{
bool[] thatByte = BitReader.ToBitBool(br.ReadByte());
br.BaseStream.Position --;
if ( thatByte[0] && thatByte[1] && thatByte[2])
{
// we found the sync.
this.headerPosition = br.BaseStream.Position - 1;
byte [] retByte = new byte [4];
retByte[0] = thisByte;
retByte[1] = br.ReadByte();
retByte[2] = br.ReadByte();
retByte[3] = br.ReadByte();
return retByte;
}
else
{
thisByte = br.ReadByte();
}
}
else
{
thisByte = br.ReadByte();
}
}
return null;
}
}
}
mp3info.cs
Code:using System;
using System.IO;
namespace ReadMP3
{
/// <summary>
/// Summary description for mp3info.
/// </summary>
public class mp3info
{
public string filename;
public long fileSize;
public long length; // in seconds
public ID3v1 id3v1;
public ID3v2 id3v2;
public MPEG mpeg;
public bool hasID3v1;
public bool hasID3v2;
private void Initialize_Components()
{
filename = "";
}
public mp3info()
{
Initialize_Components();
}
public mp3info(string fileName)
{
Initialize_Components();
this.filename = fileName;
}
public void ReadAll()
{
if (this.filename.Equals(""))
{
// we are ****ed we need a filename
}
else
{
ReadAll (this.filename);
}
}
private void CalculateLength()
{
FileInfo fi = new FileInfo(this.filename);
this.fileSize = fi.Length;
this.mpeg.audioBytes = this.fileSize - this.mpeg.headerPosition;
try
{
int bitrate = System.Convert.ToInt32(this.mpeg.Bitrate);
if (bitrate > 0)
{
if (this.id3v1.hasTag)
{
this.length = ((this.mpeg.audioBytes - 128 )* 8) / (1000 * bitrate);
}
else
{
this.length = (this.mpeg.audioBytes * 8) / (1000 * bitrate);
}
}
}
catch (Exception e)
{
this.length = 0;
}
}
public void ReadAll(string file)
{
if (this.filename.Equals(""))
{
// we are ****ed, we need a filename
return;
}
else
{
ReadID3v1(this.filename);
ReadID3v2(this.filename);
ReadMPEG(this.filename);
CalculateLength();
}
}
public void ReadID3v1()
{
if (this.filename.Equals(""))
{
// we are ****ed we need a filename
}
else
{
ReadID3v1 (this.filename);
}
}
public void ReadID3v1(string file)
{
// read id3 stuff
id3v1 = new ID3v1(file);
id3v1.Read();
this.hasID3v1 = id3v1.hasTag;;
}
public void ReadID3v2()
{
if (this.filename.Equals(""))
{
// we are ****ed we need a filename
}
else
{
ReadID3v2 (this.filename);
}
}
public void ReadID3v2(string file)
{
// read id3 stuff
id3v2 = new ID3v2(file);
id3v2.Read();
this.hasID3v2 = id3v2.hasTag;
}
public void ReadMPEG()
{
if (this.filename.Equals(""))
{
// we are ****ed we need a filename
}
else
{
ReadMPEG (this.filename);
}
}
public void ReadMPEG(string file)
{
// read id3 stuff
mpeg = new MPEG(file);
mpeg.Read();
}
}
}
i know, that's way i suggested you to call you're dll's methods with rundll32.exe. however i don't know if this will work for your dll, i mean if the classes or methods does not need any special attributes.
Looking quickly at the files you pasted it seems to me that the DLL file it creates doesn't actually expose any kind of outputting functions.
OTOH, it does give you a few classes you can utilize, mp3info being the most interesting.
What you have to do is to create another project Console or Win Forms that utilizes the DLL to gather the mp3 information.
In Visual Studio a Solution can contain multiple Projects, so I'd go and right click the ReadMP3 sollution in the Sollution Explorer and add a new project to it.
Once you have a new project in the same solution, you need to add a reference to the ReadMP3 project, in your newly created project. Hope this makes sense ;)
If you gotten everything to work alright, executing your program should give you a Window (or a console depending on what you chose).
Now, to you use the ReadMP3 you would do something like this:
Code:public void ShowMeMP3Info(string fileName)
{
mp3info info = new mp3info(fileName);
info.ReadAll();
// Your info class should now contain all the information about the mp3 file, like so
Console.WriteLine("Title: " + info.id3v2.Title + " Artist: " + info.id3v2.Artist);
}
OK I've added a console application project with reference to the last project.
It's now creating the error ('mp3info' is a 'namespace' but is being used like a 'type').Code:using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
}
public void ShowMeMP3Info(string fileName)
{
mp3info info = new mp3info(fileName);
info.ReadAll();
// Your info class should now contain all the information about the mp3 file, like so
Console.WriteLine("Title: " + info.id3v2.Title + " Artist: " + info.id3v2.Artist);
}
}
}
To use .net assembly (.dll) you have to reference it from the project where you want to use it (or you can do some sophisticated tricks with Assembly.Load() method and reflection). To add reference in VS, select "Add Reference..." from context menu of "References" folder in Solution Explorer.
Seems a bit strange as I see no namespace called mp3info in the files you pasted.Quote:
It's now creating the error ('mp3info' is a 'namespace' but is being used like a 'type')
However, I see in your console application that you never told it to use the ReadMP3 namespace.
Does adding that namespace make any difference?
Like so:
Code:using System.Text;
using ReadMP3; // <--------------- add this
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ShowMeMP3Info(@"c:\somemusic.mp3"); // call the function with a file that DOES exist ;)
}
public void ShowMeMP3Info(string fileName)
{
mp3info info = new mp3info(fileName);
info.ReadAll();
// Your info class should now contain all the information about the mp3 file, like so
Console.WriteLine("Title: " + info.id3v2.Title + " Artist: " + info.id3v2.Artist);
}
}
}
It's creating an error with the 'ShowMeMP3Info()' method.
Error: An object reference is required for the non-static field, method, or property 'ConsoleApplication1.Program.ShowMeMP3Info(string)'.Code:using System.Text;
using ReadMP3;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ShowMeMP3Info(@"c:\somemusic.mp3"); -----error here.
}
public void ShowMeMP3Info(string fileName)
{
mp3info info = new mp3info(fileName);
info.ReadAll();
Console.WriteLine("Title: " + info.id3v2.Title + " Artist: " + info.id3v2.Artist);
}
}
}
Should it not just be public 'mp3info()' instead of showMeMP3Info(), as a call from this method in files mp3info.cs?
Or am I reading that wrong?
the "Main" method is static and "ShowMeMP3Info" is not. you cannot call an instance method from a static one. try to make ShowMeMP3Info static too.
Okay, I changed the ShowMeMP3Info method to static .
Now when it compiles, it just comes up completely blank with no information on whether it complied successfully or not. Forgive me if I did that wrong.Code:public static void ShowMeMP3Info(string fileName)
{
make the output window visible, then you can see the result of the build: View > Output
Could you repost the idv2.cs class code. It looks like you pasted the code from id3v1.cs into it. I would like to try and build a project to get this to work.
Alright cool, it's produced a ConsoleApplication1.exe file in the Debug folder.
I tried writhing in a location for an MP3 file and then called the exe with the command prompt, but it just return:
'Title: Artist:'
Do the MP3 files need to be in the same folder as the exe file?
Sure. But the is actually too long for the post, so I'll do half and half.
ID3V.cs
Code:
using System;
using System.Collections;
using System.Text;
using System.IO;
namespace ReadMP3
{
/// <summary>
/// Summary description for ID3v2.
/// </summary>
public class ID3v2
{
public string filename;
// id3v2 header
public int MajorVersion;
public int MinorVersion;
public bool FA_Unsynchronisation;
public bool FB_ExtendedHeader;
public bool FC_ExperimentalIndicator;
public bool FD_Footer;
// ext header
public ulong extHeaderSize;
public int extNumFlagBytes;
public bool EB_Update;
public bool EC_CRC;
public bool ED_Restrictions;
public ulong extC_CRC;
public byte extD_Restrictions;
private BinaryReader br;
private byte[] ba;
public bool hasTag;
public ulong headerSize;
public Hashtable framesHash;
public ArrayList frames;
private bool fileOpen;
//public bool header;
// song info
public string Title;
public string Artist;
public string Album;
public string Year;
public string Comment;
public string Genre;
public string Track;
public string totalTracks;
private void Initialize_Components()
{
this.filename = "";
this.MajorVersion = 0;
this.MinorVersion = 0;
this.FA_Unsynchronisation = false;
this.FB_ExtendedHeader = false;
this.FC_ExperimentalIndicator = false;
this.fileOpen = false;
this.frames = new ArrayList();
this.framesHash = new Hashtable();
this.Album = "";
this.Artist = "";
this.Comment = "";
this.extC_CRC = 0;
this.EB_Update = false;
this.EC_CRC = false;
this.ED_Restrictions = false;
this.extD_Restrictions = 0;
this.extHeaderSize = 0;
this.extNumFlagBytes = 0;
this.fileOpen = false;
this.hasTag = false;
this.headerSize = 0;
this.Title = "";
this.totalTracks = "";
this.Track = "";
this.Year = "";
}
public ID3v2()
{
Initialize_Components();
}
public ID3v2( string fileName)
{
Initialize_Components();
this.filename = fileName;
}
private void CloseFile()
{
br.Close();
}
private void ReadHeader ( )
{
// bring in the first three bytes. it must be ID3 or we have no tag
// TODO add logic to check the end of the file for "3D1" and other
// possible starting spots
string id3start = new string (br.ReadChars(3));
// check for a tag
if (!id3start.Equals("ID3"))
{
// TODO we are ****ed.
//throw id3v2ReaderException;
this.hasTag = false;
return;
}
else
{
this.hasTag = true;
// read id3 version. 2 bytes:
// The first byte of ID3v2 version is it's major version,
// while the second byte is its revision number
this.MajorVersion = System.Convert.ToInt32(br.ReadByte());
this.MinorVersion = System.Convert.ToInt32(br.ReadByte());
//read next byte for flags
bool [] boolar = BitReader.ToBitBool(br.ReadByte());
// set the flags
this.FA_Unsynchronisation= boolar[0];
this.FB_ExtendedHeader = boolar[1];
this.FC_ExperimentalIndicator = boolar[2];
// read teh size
// this code is courtesy of Daniel E. White w/ minor modifications by me Thanx Dan
//Dan Code
char[] tagSize = br.ReadChars(4); // I use this to read the bytes in from the file
int[] bytes = new int[4]; // for bit shifting
ulong newSize = 0; // for the final number
// The ID3v2 tag size is encoded with four bytes
// where the most significant bit (bit 7)
// is set to zero in every byte,
// making a total of 28 bits.
// The zeroed bits are ignored
//
// Some bit grinding is necessary. Hang on.
bytes[3] = tagSize[3] | ((tagSize[2] & 1) << 7) ;
bytes[2] = ((tagSize[2] >> 1) & 63) | ((tagSize[1] & 3) << 6) ;
bytes[1] = ((tagSize[1] >> 2) & 31) | ((tagSize[0] & 7) << 5) ;
bytes[0] = ((tagSize[0] >> 3) & 15) ;
newSize = ((UInt64)10 + (UInt64)bytes[3] |
((UInt64)bytes[2] << 8) |
((UInt64)bytes[1] << 16) |
((UInt64)bytes[0] << 24)) ;
//End Dan Code
this.headerSize = newSize;
}
}
private void ReadFrames ()
{
id3v2Frame f = new id3v2Frame();
do
{
f = f.ReadFrame(br, this.MajorVersion);
// check if we have hit the padding.
if (f.padding == true)
{
//we hit padding. lets advance to end and stop reading.
br.BaseStream.Position = System.Convert.ToInt64(headerSize);
break;
}
this.frames.Add(f);
this.framesHash.Add(f.frameName, f);
#region frameprocessing
/*
else
{
// figure out which type it is
if (f.frameName.StartsWith("T"))
{
if (f.frameName.Equals("TXXX"))
{
ProcessTXXX(f);
}
else
{
ProcessTTYPE(f);
}
}
else
{
if (f.frameName.StartsWith("W"))
{
if (f.frameName.Equals("WXXX"))
{
ProcessWXXX(f);
}
else
{
ProcessWTYPE(f);
}
}
else
{
// if it isn't a muliple reader case (above) then throw it into the switch to process
switch (f.frameName)
{
case "IPLS":
ProcessIPLS(f);
break;
case "MCDI":
ProcessMCDI(f);
break;
case "UFID":
ProcessUFID(f);
break;
case "COMM":
ProcessCOMM(f);
break;
default:
frames.Add(f.frameName, f.frameContents);
AddItemToList(f.frameName, "non text");
break;
}
}
}
}*/
#endregion
} while (br.BaseStream.Position <= System.Convert.ToInt64(this.headerSize));
}
public void Read()
{
FileStream fs = new FileStream(this.filename, FileMode.Open, FileAccess.Read);
br = new BinaryReader (fs);
ReadHeader();
if (this.hasTag)
{
if (this.FB_ExtendedHeader)
{
ReadExtendedHeader();
}
ReadFrames();
if (this.FD_Footer)
{
ReadFooter();
}
ParseCommonHeaders();
}
fs.Close();
br.Close();
#region tag reader
/*if (!fileOpen)
{
if (!this.filename == "")
{
OpenFile();
}
else
{
// we are ****ed. throw an exception or something
}
}
// bring in the first three bytes. it must be ID3 or we have no tag
// TODO add logic to check the end of the file for "3D1" and other
// possible starting spots
string id3start = new string (br.ReadChars(3));
// check for a tag
if (!id3start.Equals("ID3"))
{
// TODO we are ****ed. not really we just don't ahve a tag
// and we need to bail out gracefully.
throw id3v23ReaderException;
}
else
{
// we have a tag
this.header = true;
}
// read id3 version. 2 bytes:
// The first byte of ID3v2 version is it's major version,
// while the second byte is its revision number
this.MajorVersion = System.Convert.ToInt32(br.ReadByte());
this.MinorVersion = System.Convert.ToInt32(br.ReadByte());
// here is where we get fancy. I am useing silisoft's php code as
// a reference here. we are going to try and parse for 2.2, 2.3 and 2.4
// in one pass. hold on!!
if ((this.header) && (this.MajorVersion <= 4)) // probably won't work on higher versions
{
// (%ab000000 in v2.2, %abc00000 in v2.3, %abcd0000 in v2.4.x)
//read next byte for flags
bool [] boolar = BitReader.ToBitBool(br.ReadByte());
// set the flags
if (this.MajorVersion == 2)
{
this.FA_Unsyncronisation = boolar[0];
this.FB_ExtendedHeader = boolar[1];
}
else if ( this.MajorVersion == 3 )
{
// set the flags
this.FA_Unsyncronisation = boolar[0];
this.FB_ExtendedHeader = boolar[1];
this.FC_ExperimentalIndicator = boolar[2];
}
else if (this.MajorVersion == 4)
{
// set the flags
this.FA_Unsyncronisation = boolar[0];
this.FB_ExtendedHeader = boolar[1];
this.FC_ExperimentalIndicator = boolar[2];
this.FD_Footer = boolar[3];
}
// read teh size
// this code is courtesy of Daniel E. White w/ minor modifications by me Thanx Dan
//Dan Code
char[] tagSize = br.ReadChars(4); // I use this to read the bytes in from the file
int[] bytes = new int[4]; // for bit shifting
ulong newSize = 0; // for the final number
// The ID3v2 tag size is encoded with four bytes
// where the most significant bit (bit 7)
// is set to zero in every byte,
// making a total of 28 bits.
// The zeroed bits are ignored
//
// Some bit grinding is necessary. Hang on.
bytes[3] = tagSize[3] | ((tagSize[2] & 1) << 7) ;
bytes[2] = ((tagSize[2] >> 1) & 63) | ((tagSize[1] & 3) << 6) ;
bytes[1] = ((tagSize[1] >> 2) & 31) | ((tagSize[0] & 7) << 5) ;
bytes[0] = ((tagSize[0] >> 3) & 15) ;
newSize = ((UInt64)10 + (UInt64)bytes[3] |
((UInt64)bytes[2] << 8) |
((UInt64)bytes[1] << 16) |
((UInt64)bytes[0] << 24)) ;
//End Dan Code
this.id3v2HeaderSize = newSize;
}
*/
#endregion
}
private void ParseCommonHeaders()
{
if (this.MajorVersion == 2)
{
if(this.framesHash.Contains("TT2"))
{
byte [] bytes = ((id3v2Frame)this.framesHash["TT2"]).frameContents;
StringBuilder sb = new StringBuilder();
byte textEncoding;
for (int i = 1; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
//this.Title = myString.Substring(1);
this.Title = sb.ToString();
}
}
if(this.framesHash.Contains("TP1"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TP1"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Artist = sb.ToString();
}
}
if(this.framesHash.Contains("TAL"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TAL"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Album = sb.ToString();
}
}
if(this.framesHash.Contains("TYE"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TYE"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Year = sb.ToString();
}
}
if(this.framesHash.Contains("TRK"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TRK"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Track = sb.ToString();
}
}
if(this.framesHash.Contains("TCO"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TCO"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Genre = sb.ToString();
}
}
if(this.framesHash.Contains("COM"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["COM"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Comment = sb.ToString();
}
}
}
else
{ // $id3info["majorversion"] > 2
if(this.framesHash.Contains("TIT2"))
{
byte [] bytes = ((id3v2Frame)this.framesHash["TIT2"]).frameContents;
StringBuilder sb = new StringBuilder();
byte textEncoding;
for (int i = 1; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
//this.Title = myString.Substring(1);
this.Title = sb.ToString();
}
}
if(this.framesHash.Contains("TPE1"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TPE1"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Artist = sb.ToString();
}
}
Code:else
{ // $id3info["majorversion"] > 2
if(this.framesHash.Contains("TIT2"))
{
byte [] bytes = ((id3v2Frame)this.framesHash["TIT2"]).frameContents;
StringBuilder sb = new StringBuilder();
byte textEncoding;
for (int i = 1; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
//this.Title = myString.Substring(1);
this.Title = sb.ToString();
}
}
if(this.framesHash.Contains("TPE1"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TPE1"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Artist = sb.ToString();
}
}
if(this.framesHash.Contains("TALB"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TALB"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Album = sb.ToString();
}
}
if(this.framesHash.Contains("TYER"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TYER"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Year = sb.ToString();
}
}
if(this.framesHash.Contains("TRCK"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TRCK"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Track = sb.ToString();
}
}
if(this.framesHash.Contains("TCON"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["TCON"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Genre = sb.ToString();
}
}
if(this.framesHash.Contains("COMM"))
{
StringBuilder sb = new StringBuilder();
byte [] bytes = ((id3v2Frame)this.framesHash["COMM"]).frameContents;
byte textEncoding;
for (int i = 0; i < bytes.Length; i++)
{
if (i == 0)
{
//read the text encoding.
textEncoding = bytes[i];
}
else
{
sb.Append(System.Convert.ToChar(bytes[i]));
}
this.Comment = sb.ToString();
}
}
}
string [] trackHolder = this.Track.Split('/');
this.Track = trackHolder[0];
if (trackHolder.Length > 1)
this.totalTracks = trackHolder[1];
}
private void ReadFooter()
{
// bring in the first three bytes. it must be ID3 or we have no tag
// TODO add logic to check the end of the file for "3D1" and other
// possible starting spots
string id3start = new string (br.ReadChars(3));
// check for a tag
if (!id3start.Equals("3DI"))
{
// TODO we are ****ed. not really we just don't ahve a tag
// and we need to bail out gracefully.
//throw id3v23ReaderException;
}
else
{
// we have a tag
this.hasTag = true;
}
// read id3 version. 2 bytes:
// The first byte of ID3v2 version is it's major version,
// while the second byte is its revision number
this.MajorVersion = System.Convert.ToInt32(br.ReadByte());
this.MinorVersion = System.Convert.ToInt32(br.ReadByte());
// here is where we get fancy. I am useing silisoft's php code as
// a reference here. we are going to try and parse for 2.2, 2.3 and 2.4
// in one pass. hold on!!
if ((this.hasTag) && (this.MajorVersion <= 4)) // probably won't work on higher versions
{
// (%ab000000 in v2.2, %abc00000 in v2.3, %abcd0000 in v2.4.x)
//read next byte for flags
bool [] boolar = BitReader.ToBitBool(br.ReadByte());
// set the flags
if (this.MajorVersion == 2)
{
this.FA_Unsynchronisation = boolar[0];
this.FB_ExtendedHeader = boolar[1];
}
else if ( this.MajorVersion == 3 )
{
// set the flags
this.FA_Unsynchronisation = boolar[0];
this.FB_ExtendedHeader = boolar[1];
this.FC_ExperimentalIndicator = boolar[2];
}
else if (this.MajorVersion == 4)
{
// set the flags
this.FA_Unsynchronisation = boolar[0];
this.FB_ExtendedHeader = boolar[1];
this.FC_ExperimentalIndicator = boolar[2];
this.FD_Footer = boolar[3];
}
// read teh size
// this code is courtesy of Daniel E. White w/ minor modifications by me Thanx Dan
//Dan Code
char[] tagSize = br.ReadChars(4); // I use this to read the bytes in from the file
int[] bytes = new int[4]; // for bit shifting
ulong newSize = 0; // for the final number
// The ID3v2 tag size is encoded with four bytes
// where the most significant bit (bit 7)
// is set to zero in every byte,
// making a total of 28 bits.
// The zeroed bits are ignored
//
// Some bit grinding is necessary. Hang on.
bytes[3] = tagSize[3] | ((tagSize[2] & 1) << 7) ;
bytes[2] = ((tagSize[2] >> 1) & 63) | ((tagSize[1] & 3) << 6) ;
bytes[1] = ((tagSize[1] >> 2) & 31) | ((tagSize[0] & 7) << 5) ;
bytes[0] = ((tagSize[0] >> 3) & 15) ;
newSize = ((UInt64)10 + (UInt64)bytes[3] |
((UInt64)bytes[2] << 8) |
((UInt64)bytes[1] << 16) |
((UInt64)bytes[0] << 24)) ;
//End Dan Code
this.headerSize = newSize;
}
}
private void ReadExtendedHeader()
{
// Extended header size 4 * %0xxxxxxx
// Number of flag bytes $01
// Extended Flags $xx
// Where the 'Extended header size' is the size of the whole extended header, stored as a 32 bit synchsafe integer.
// read teh size
// this code is courtesy of Daniel E. White w/ minor modifications by me Thanx Dan
//Dan Code
char[] extHeaderSize = br.ReadChars(4); // I use this to read the bytes in from the file
int[] bytes = new int[4]; // for bit shifting
ulong newSize = 0; // for the final number
// The ID3v2 tag size is encoded with four bytes
// where the most significant bit (bit 7)
// is set to zero in every byte,
// making a total of 28 bits.
// The zeroed bits are ignored
//
// Some bit grinding is necessary. Hang on.
bytes[3] = extHeaderSize[3] | ((extHeaderSize[2] & 1) << 7) ;
bytes[2] = ((extHeaderSize[2] >> 1) & 63) | ((extHeaderSize[1] & 3) << 6) ;
bytes[1] = ((extHeaderSize[1] >> 2) & 31) | ((extHeaderSize[0] & 7) << 5) ;
bytes[0] = ((extHeaderSize[0] >> 3) & 15) ;
newSize = ((UInt64)10 + (UInt64)bytes[3] |
((UInt64)bytes[2] << 8) |
((UInt64)bytes[1] << 16) |
((UInt64)bytes[0] << 24)) ;
//End Dan Code
this.extHeaderSize = newSize;
// next we read the number of flag bytes
this.extNumFlagBytes = System.Convert.ToInt32(br.ReadByte());
// read the flag byte(s) and set the flags
bool[] extFlags = BitReader.ToBitBools(br.ReadBytes(this.extNumFlagBytes));
this.EB_Update = extFlags[1];
this.EC_CRC = extFlags[2];
this.ED_Restrictions = extFlags[3];
// check for flags
if (this.EB_Update)
{
// this tag has no data but will have a null byte so we need to read it in
//Flag data length $00
br.ReadByte();
}
if (this.EC_CRC)
{
// Flag data length $05
// Total frame CRC 5 * %0xxxxxxx
// read the first byte and check to make sure it is 5. if not the header is corrupt
// we will still try to process but we may be funked.
int extC_FlagDataLength = System.Convert.ToInt32(br.ReadByte());
if (extC_FlagDataLength == 5)
{
extHeaderSize = br.ReadChars(5); // I use this to read the bytes in from the file
bytes = new int[4]; // for bit shifting
newSize = 0; // for the final number
// The ID3v2 tag size is encoded with four bytes
// where the most significant bit (bit 7)
// is set to zero in every byte,
// making a total of 28 bits.
// The zeroed bits are ignored
//
// Some bit grinding is necessary. Hang on.
bytes[4] = extHeaderSize[4] | ((extHeaderSize[3] & 1) << 7 ) ;
bytes[3] = ((extHeaderSize[3] >> 1) & 63) | ((extHeaderSize[2] & 3) << 6) ;
bytes[2] = ((extHeaderSize[2] >> 2) & 31) | ((extHeaderSize[1] & 7) << 5) ;
bytes[1] = ((extHeaderSize[1] >> 3) & 15) | ((extHeaderSize[0] & 15) << 4) ;
bytes[0] = ((extHeaderSize[0] >> 4) & 7);
newSize = ((UInt64)10 + (UInt64)bytes[4] |
((UInt64)bytes[3] << 8) |
((UInt64)bytes[2] << 16) |
((UInt64)bytes[1] << 24) |
((UInt64)bytes[0] << 32)) ;
this.extHeaderSize = newSize;
}
else
{
// we are ****ed. do something
}
}
if (this.ED_Restrictions)
{
// Flag data length $01
//Restrictions %ppqrrstt
// advance past flag data lenght byte
br.ReadByte();
this.extD_Restrictions = br.ReadByte();
}
}
}
}
Okay, so I have the location of the music files and the name of the song in the code.
Then in command prompt I type 'ConsoleApplication1.exe' and it just returns
Title: Artist:
I create a project out of it. Passed in one of my MP3's and was getting an error on the Read Frames one ID3v2 class. Is it possible you are not processing an MP3 that have v2 tags. When running it, I do get the info from v1.
OK, A different MP3 I passed in worked, it read both tags.
A link for the source code is here.
http://www.developerfusion.com/code/...3v1-and-id3v2/
i don't know the specification of the mp3 file but it seems that there is something wrong with this bytes or there is some other encoding there
because the output string is rubbishCode:if (this.framesHash.Contains("TPE1"))
{
byte[] bytes = ((id3v2Frame)this.framesHash["TPE1"]).frameContents;
string str = System.Text.UTF8Encoding.UTF8.GetString(bytes);
this.Artist = str
}
Is there anyway of rewriting it, or should the whole thing be scraped?
the code processing frames is commented out, this could be the cause
id3v2.cs > method: private void ReadFrames ()
this code is so ugly :sick::eek: public fields etc. :D
It does appear that there might be an issue with the code processing the v2 tags. On several of my MP3's it will not show anyinfo on the v2 tags. even though it sets the hasid3v2 property to true. On some of my MP3's it does come back with the correct information though. I would suggest you download a MP3 editor and set the tag. I used audacity on one of the MP3s that originally did not show a v2 tag, edited the tag, re-exported the mp3 and now it shows the v2 tag.
I used audacity to edit the v2 tags on one of the mp3s that were not showing anything. I saved a new v2 tag to the mp3, and now it does show the information.
Attached is my project. You can either use the console app or the Windows app.
ETA: I agree with meneloo, there is definatly something wrong with the v2 processing.
every char in the tags seems to be followed by a \0, mhmm ... i give up, i had to know the specification of mp3 tags
there has to be somewhere some info how the text is stored... but i don't know where.
A good place to start.
http://www.id3.org/
ETA: Probably a better place to look..
http://www.idsharp.com/
i even found the original page of this files presented here
http://www.developerfusion.com/code/...3v1-and-id3v2/
If you are really looking at editing/reading the ID tags, you should look at the idsharp link above.
i think i'll try to implement it or at least parts of it. i could be a good training to use some pointers, unsafe code etc.
edit: cool one can learn a lot from implementhig mp3 tags. i've just found that this text is utf16 and the first bytes describe how it's stored ;]