Exemplo n.º 1
0
		/// <summary>
		/// Refreshes the metadata of the audio file.
		/// </summary>
		public void RefreshMetadata()
		{
            // Get file size
            #if WINDOWSSTORE
		    fileSize = 0;
            #else
            var fileInfo = new FileInfo(filePath);
            fileSize = fileInfo.Length;
            #endif

            // Check what is the type of the audio file
            if (fileType == AudioFileFormat.MP3)
			{
                // Declare variables
                TagLib.Mpeg.AudioFile file = null;

                try
                {
                    // Create a more specific type of class for MP3 files
                    file = new TagLib.Mpeg.AudioFile(filePath);                    

                    // Get the position of the first and last block
                    firstBlockPosition = file.InvariantStartPosition;
                    lastBlockPosition = file.InvariantEndPosition;

                    // Copy tags
                    FillProperties(file.Tag);

                    // Loop through codecs (usually just one)
                    foreach (TagLib.ICodec codec in file.Properties.Codecs)
                    {
                        // Convert codec into a header 
                        TagLib.Mpeg.AudioHeader header = (TagLib.Mpeg.AudioHeader)codec;

                        // Copy properties						
                        audioChannels = header.AudioChannels;
                        frameLength = header.AudioFrameLength;
                        audioLayer = header.AudioLayer;
                        sampleRate = header.AudioSampleRate;
                        bitsPerSample = 16; // always 16-bit
                        channelMode = header.ChannelMode;
                        bitrate = header.AudioBitrate;
                        length = Conversion.TimeSpanToTimeString(header.Duration);
                    }
                }
                catch (Exception ex)
                {
                    // Throw exception TODO: Check if file exists when catching the exception (to make a better error description)
                    throw new Exception("An error occured while reading the tags and properties of the file (" + filePath + ").", ex);
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }

                try
                {
//                    // Check if there's a Xing header
//                    XingInfoHeaderData xingHeader = XingInfoHeaderReader.ReadXingInfoHeader(filePath, firstBlockPosition);
//
//                    // Check if the read was successful
//                    if (xingHeader.Status == XingInfoHeaderStatus.Successful)
//                    {
//                        // Set property value
//                        //m_xingInfoHeader = xingHeader;
//                        mp3EncoderDelay = xingHeader.EncoderDelay;
//                        mp3EncoderPadding = xingHeader.EncoderPadding;
//                        mp3EncoderVersion = xingHeader.EncoderVersion;
//                        mp3HeaderType = xingHeader.HeaderType;
//                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
			}
            else if (fileType == AudioFileFormat.FLAC)
			{
                // Declare variables 
                TagLib.Flac.File file = null;

                try
                {
                    // Read VorbisComment in FLAC file
                    file = new TagLib.Flac.File(filePath);

                    // Get the position of the first and last block
                    firstBlockPosition = file.InvariantStartPosition;
                    lastBlockPosition = file.InvariantEndPosition;

                    // Copy tags
                    FillProperties(file.Tag);

                    // Loop through codecs (usually just one)
                    foreach (TagLib.ICodec codec in file.Properties.Codecs)
                    {
                        // Convert codec into a header 
                        TagLib.Flac.StreamHeader header = (TagLib.Flac.StreamHeader)codec;

                        // Copy properties
                        bitrate = header.AudioBitrate;
                        audioChannels = header.AudioChannels;
                        sampleRate = header.AudioSampleRate;
                        bitsPerSample = header.BitsPerSample;
                        length = Conversion.TimeSpanToTimeString(header.Duration);
                    }
                }
                catch (Exception ex)
                {
                    // Throw exception
                    throw new Exception("An error occured while reading the tags and properties of the file (" + filePath + ").", ex);
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }
			}
            else if (fileType == AudioFileFormat.OGG)
			{
                // Declare variables 
                TagLib.Ogg.File file = null;

                try
                {
                    // Read VorbisComment in OGG file
                    file = new TagLib.Ogg.File(filePath);

                    // Get the position of the first and last block
                    firstBlockPosition = file.InvariantStartPosition;
                    lastBlockPosition = file.InvariantEndPosition;

                    // Copy tags
                    FillProperties(file.Tag);

                    // Loop through codecs (usually just one)
                    foreach (TagLib.ICodec codec in file.Properties.Codecs)
                    {
                        // Check what kind of codec is used 
                        if (codec is TagLib.Ogg.Codecs.Theora)
                        {
                            // Do nothing, this is useless for audio.
                        }
                        else if (codec is TagLib.Ogg.Codecs.Vorbis)
                        {
                            // Convert codec into a header 
                            TagLib.Ogg.Codecs.Vorbis header = (TagLib.Ogg.Codecs.Vorbis)codec;

                            // Copy properties
                            bitrate = header.AudioBitrate;
                            audioChannels = header.AudioChannels;
                            sampleRate = header.AudioSampleRate;
                            bitsPerSample = 16;
                            length = Conversion.TimeSpanToTimeString(header.Duration);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Throw exception
                    throw new Exception("An error occured while reading the tags and properties of the file (" + filePath + ").", ex);
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }
			}
            else if (fileType == AudioFileFormat.APE)
            {
                // Monkey's Audio (APE) supports APEv2 tags.
                // http://en.wikipedia.org/wiki/Monkey's_Audio

                // Declare variables
                TagLib.Ape.File file = null;

                try
                {
                    // Read APE metadata
                    apeTag = APEMetadata.Read(filePath);

                    // Get APEv1/v2 tags from APE file
                    file = new TagLib.Ape.File(filePath);

                    // Get the position of the first and last block
                    firstBlockPosition = file.InvariantStartPosition;
                    lastBlockPosition = file.InvariantEndPosition;

                    // Copy tags
                    FillProperties(file.Tag);

                    // Loop through codecs (usually just one)
                    foreach (TagLib.ICodec codec in file.Properties.Codecs)
                    {
                        // Check what kind of codec is used 
                        if (codec is TagLib.Ape.StreamHeader)
                        {
                            // Convert codec into a header 
                            TagLib.Ape.StreamHeader header = (TagLib.Ape.StreamHeader)codec;

                            // Copy properties
                            bitrate = header.AudioBitrate;
                            audioChannels = header.AudioChannels;
                            sampleRate = header.AudioSampleRate;
                            bitsPerSample = 16;
                            length = Conversion.TimeSpanToTimeString(header.Duration);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Throw exception
                    throw new Exception("An error occured while reading the tags and properties of the file (" + filePath + ").", ex);
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }
            }
            else if (fileType == AudioFileFormat.MPC)
            {                
                // MusePack (MPC) supports APEv2 tags.
                // http://en.wikipedia.org/wiki/Musepack
                try
                {
                    // Try to read SV8 header
                    sv8Tag = SV8Metadata.Read(filePath);

                    // Set audio properties
                    audioChannels = sv8Tag.AudioChannels;
                    sampleRate = sv8Tag.SampleRate;
                    bitsPerSample = 16;
                    length = sv8Tag.Length;
                    bitrate = sv8Tag.Bitrate;
                }
                catch (SV8TagNotFoundException exSV8)
                {
                    try
                    {
                        // Try to read the SV7 header
                        sv7Tag = SV7Metadata.Read(filePath);

                        // Set audio properties
                        audioChannels = sv7Tag.AudioChannels;
                        sampleRate = sv7Tag.SampleRate;
                        bitsPerSample = 16;
                        length = sv7Tag.Length;
                        bitrate = sv7Tag.Bitrate;
                    }
                    catch (SV7TagNotFoundException exSV7)
                    {
                        // No headers have been found!
                        SV8TagNotFoundException finalEx = new SV8TagNotFoundException(exSV8.Message, exSV7);
                        throw new Exception("Error: The file is not in SV7/MPC or SV8/MPC format!",  finalEx);
                    }
                }

                try
                {
                    // Read APE tag
                    apeTag = APEMetadata.Read(filePath);

                    // Copy tags
                    FillProperties(apeTag);
                }
                catch (Exception ex)
                {
                    // Check exception
                    if (ex is APETagNotFoundException)
                    {
                        // Skip file
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            else if (fileType == AudioFileFormat.OFR)
            {
                // TagLib does not support OFR files...
                // OptimFROG (OFR) supports APEv2 tags.
                // http://en.wikipedia.org/wiki/OptimFROG                
            }
            else if (fileType == AudioFileFormat.WV)
            {
                // WavPack supports APEv2 and ID3v1 tags.
                // http://www.wavpack.com/wavpack_doc.html

                // Declare variables
                TagLib.WavPack.File file = null;

                try
                {
                    // Read WavPack tags
                    file = new TagLib.WavPack.File(filePath);

                    // Get the position of the first and last block
                    firstBlockPosition = file.InvariantStartPosition;
                    lastBlockPosition = file.InvariantEndPosition;

                    // Copy tags
                    FillProperties(file.Tag);

                    // Loop through codecs (usually just one)
                    foreach (TagLib.ICodec codec in file.Properties.Codecs)
                    {
                        // Check what kind of codec is used 
                        if (codec is TagLib.WavPack.StreamHeader)
                        {
                            // Convert codec into a header 
                            TagLib.WavPack.StreamHeader header = (TagLib.WavPack.StreamHeader)codec;

                            // Copy properties
                            bitrate = header.AudioBitrate;
                            audioChannels = header.AudioChannels;
                            sampleRate = header.AudioSampleRate;
                            bitsPerSample = 16;
                            length = Conversion.TimeSpanToTimeString(header.Duration);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Throw exception
                    throw new Exception("An error occured while reading the tags and properties of the file (" + filePath + ").", ex);
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }
            }
            else if (fileType == AudioFileFormat.TTA)
            {
                // The True Audio (TTA) format supports ID3v1, ID3v2 and APEv2 tags.
                // http://en.wikipedia.org/wiki/TTA_(codec)

                audioChannels = 2;
                sampleRate = 44100;
                bitsPerSample = 16;

                // TagLib doesn't work.
            }
            else if (fileType == AudioFileFormat.WAV)
            {
                // Declare variables
                TagLib.Riff.File file = null;

                try
                {
                    // Get WAV file
                    file = new TagLib.Riff.File(filePath);                    

                    // Get the position of the first and last block
                    firstBlockPosition = file.InvariantStartPosition;
                    lastBlockPosition = file.InvariantEndPosition;

                    // Copy tags
                    FillProperties(file.Tag);

                    // Loop through codecs (usually just one)
                    foreach (TagLib.ICodec codec in file.Properties.Codecs)
                    {
                        // Check what kind of codec is used 
                        if (codec is TagLib.Riff.WaveFormatEx)
                        {
                            // Convert codec into a header 
                            TagLib.Riff.WaveFormatEx header = (TagLib.Riff.WaveFormatEx)codec;

                            // Copy properties
                            bitrate = header.AudioBitrate;
                            audioChannels = header.AudioChannels;
                            sampleRate = header.AudioSampleRate;
                            bitsPerSample = 16;
                            length = Conversion.TimeSpanToTimeString(header.Duration);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Throw exception
                    throw new Exception("An error occured while reading the tags and properties of the file (" + filePath + ").", ex);
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }
            }
            else if (fileType == AudioFileFormat.WMA)
            {
                // Declare variables
                TagLib.Asf.File file = null;

                try
                {
                    // Read ASF/WMA tags
                    file = new TagLib.Asf.File(filePath);

                    // Get the position of the first and last block
                    firstBlockPosition = file.InvariantStartPosition;
                    lastBlockPosition = file.InvariantEndPosition;

                    // Copy tags
                    FillProperties(file.Tag);

                    // The right length is here, not in the codec data structure
                    length = Conversion.TimeSpanToTimeString(file.Properties.Duration);

                    // Loop through codecs (usually just one)
                    foreach (TagLib.ICodec codec in file.Properties.Codecs)
                    {
                        // Check what kind of codec is used 
                        if (codec is TagLib.Riff.WaveFormatEx)
                        {
                            // Convert codec into a header 
                            TagLib.Riff.WaveFormatEx header = (TagLib.Riff.WaveFormatEx)codec;

                            // Copy properties
                            bitrate = header.AudioBitrate;
                            audioChannels = header.AudioChannels;
                            sampleRate = header.AudioSampleRate;
                            bitsPerSample = 16;                            
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }
            }
            else if (fileType == AudioFileFormat.AAC)
            {
                // Declare variables
                TagLib.Aac.File file = null;

                try
                {
                    // Read AAC tags
                    file = new TagLib.Aac.File(filePath);

                    // Doesn't seem to work very well...
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    // Dispose file (if needed)
                    if (file != null)
                        file.Dispose();
                }
            }              
            
			// If the song has no name, give filename as the name                
			if (String.IsNullOrEmpty(Title))
			{
				Title = Path.GetFileNameWithoutExtension(filePath);
			}

			// If the artist has no name, give it "Unknown Artist"
			if (String.IsNullOrEmpty(ArtistName))
			{
				ArtistName = "Unknown Artist";
			}

			// If the song has no album title, give it "Unknown Album"
			if (String.IsNullOrEmpty(AlbumTitle))
			{
				AlbumTitle = "Unknown Album";
			}
		}
Exemplo n.º 2
0
        /// <summary>
        /// Reads the SV7 metadata from a MPC (MusePack) audio file.        
        /// </summary>
        /// <param name="filePath">Audio file path</param>        
        /// <returns>SV7 data structure</returns>
        public static SV7Tag Read(string filePath)
        {
            if (String.IsNullOrEmpty(filePath))
                throw new Exception("The file path cannot be null or empty!");

            SV7Tag data = new SV7Tag();

            #if WINDOWSSTORE
            #else            
            BinaryReader reader = null;
            FileStream stream = null;

            try
            {
                // Open binary reader                        
                stream = File.OpenRead(filePath);
                reader = new BinaryReader(stream);

                // Get file length
                long fileLength = reader.BaseStream.Length;

                // Read signature
                byte[] bytesSigntaure = reader.ReadBytes(3);
                string signature = Encoding.UTF8.GetString(bytesSigntaure, 0, bytesSigntaure.Length);

                // Validate signature
                if (signature.ToUpper() != "MP+")
                {
                    throw new SV7TagNotFoundException("The file is not in MPC/SV7 format!", null);
                }

                // Read stream major/minor version
                byte byteStreamMajorMinorVersion = reader.ReadByte();
                int streamVersionMinor = ((int)byteStreamMajorMinorVersion >> 4) & 0x0F;
                int streamVersionMajor = ((int)byteStreamMajorMinorVersion & 0x0F);

                // Validate version
                if (streamVersionMajor != 7)
                {
                    throw new SV7TagNotFoundException("This file header version is not SV7!", null);
                }

                // Read frame count (32-bits)
                byte[] bytesFrameCount = reader.ReadBytes(4);
                data.FrameCount = BitConverter.ToInt32(bytesFrameCount, 0);

                // Read Max level
                byte[] bytesMaxLevel = reader.ReadBytes(2);
                data.MaxLevel = BitConverter.ToInt16(bytesMaxLevel, 0);

                // Read Profile / Link / SampleFreq
                byte byteProfile_Link_SampleFreq = reader.ReadByte();
                data.EncoderProfile = ((int)byteProfile_Link_SampleFreq & 0xF0) >> 4;
                int link = ((int)byteProfile_Link_SampleFreq & 0x0C) >> 2;
                int sampleFrequency = ((int)byteProfile_Link_SampleFreq & 0x03) >> 0;

                // Read Intensity stereo / Mid side stereo / Max band
                byte byteIntensityStereo_MidSideStereo_MaxBand = reader.ReadByte();
                int intensityStereo = ((int)byteIntensityStereo_MidSideStereo_MaxBand & 0x80) >> 7;
                int midSideStereo = ((int)byteIntensityStereo_MidSideStereo_MaxBand & 0x40) >> 6;
                data.MaxBand = ((int)byteIntensityStereo_MidSideStereo_MaxBand & 0x3F) >> 2;

                // Read title peak
                byte[] bytesTitlePeak = reader.ReadBytes(2);
                data.TitlePeak = BitConverter.ToInt16(bytesTitlePeak, 0);

                // Read title gain
                byte[] bytesTitleGain = reader.ReadBytes(2);
                data.TitleGain = BitConverter.ToInt16(bytesTitleGain, 0);

                // Read album peak
                byte[] bytesAlbumPeak = reader.ReadBytes(2);
                data.AlbumPeak = BitConverter.ToInt16(bytesAlbumPeak, 0);

                // Read album gain
                byte[] bytesAlbumGain = reader.ReadBytes(2);
                data.AlbumGain = BitConverter.ToInt16(bytesAlbumGain, 0);

                // Read unused bytes
                reader.ReadBytes(2);

                // Read true gapless / last frame length / fast seeking
                byte[] bytesTrueGapless_LastFrameLength_FastSeeking = reader.ReadBytes(2);
                int trueGapless = ((int)bytesTrueGapless_LastFrameLength_FastSeeking[0] & 0x80) >> 7;
                data.LastFrameLength = ((int)bytesTrueGapless_LastFrameLength_FastSeeking[0] & 0x80) >> 7;

                // Get last frame length
                int lastFrameLength = BitConverter.ToInt16(bytesTrueGapless_LastFrameLength_FastSeeking, 0);
                data.LastFrameLength = (lastFrameLength & 0x7FF0) >> 4;

                // Read unused bytes
                reader.ReadBytes(3);

                // Read encoder version
                byte byteEncoderVersion = reader.ReadByte();
                string encoderVersion = "mppenc ";

                // Check for beta
                if (byteEncoderVersion % 2 == 0)
                {
                    encoderVersion += "Beta ";
                }
                // Check for alpha
                else if (byteEncoderVersion % 2 == 1)
                {
                    encoderVersion += "Alpha ";
                }

                // Complete string with version
                encoderVersion += ((double)byteEncoderVersion / 100).ToString("0.00");

                // Set metadata
                data.EncoderVersion = encoderVersion;
                data.IntensityStereo = (intensityStereo == 1) ? true : false;
                data.MidSideStereoEnabled = (midSideStereo == 1) ? true : false;
                data.TrueGapless = (trueGapless == 1) ? true : false;

                // Sample rate
                if (sampleFrequency == 0)
                {
                    data.SampleRate = 44100;
                }
                else if (sampleFrequency == 1)
                {
                    data.SampleRate = 48000;
                }
                else if (sampleFrequency == 2)
                {
                    data.SampleRate = 37800;
                }
                else if (sampleFrequency == 3)
                {
                    data.SampleRate = 32000;
                }

                // Calculate length
                data.LengthSamples = ((((data.FrameCount - 1) * 1152) + data.LastFrameLength) * data.AudioChannels) / 2; // floating point
                data.LengthMS = ConvertAudio.ToMS(data.LengthSamples, (uint)data.SampleRate);
                data.Length = Conversion.MillisecondsToTimeString((ulong)data.LengthMS);
                long audioLengthBytes = fileLength - 28; // SV7 header is always 28 bytes
                data.Bitrate = (int)(audioLengthBytes / data.LengthMS) * 8;
            }
            catch
            {
                throw;
            }
            finally
            {
                // Dispose stream (reader will be automatically disposed too)                
                stream.Close();                
            }

            #endif

            return data;
        }