Пример #1
0
        public bool Read(BinaryReader source, AudioDataManager.SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams)
        {
            this.sizeInfo = sizeInfo;

            return(read(source, readTagParams));
        }
Пример #2
0
        public bool Read(BinaryReader source, SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams)
        {
            ApeHeaderOld  APE_OLD  = new ApeHeaderOld();  // old header   <= 3.97
            ApeHeaderNew  APE_NEW  = new ApeHeaderNew();  // new header   >= 3.98
            ApeDescriptor APE_DESC = new ApeDescriptor(); // extra header >= 3.98

            int  BlocksPerFrame;
            bool LoadSuccess;
            bool result = false;

            this.sizeInfo = sizeInfo;
            resetData();

            // reading data from file
            LoadSuccess = false;

            readCommonHeader(source);

            if (StreamUtils.StringEqualsArr("MAC ", header.cID))
            {
                isValid = true;
                version = header.nVersion;

                versionStr = ((double)version / 1000).ToString().Substring(0, 4); //Str(FVersion / 1000 : 4 : 2, FVersionStr);

                // Load New Monkey's Audio Header for version >= 3.98
                if (header.nVersion >= 3980)
                {
                    APE_DESC.padded                 = 0;
                    APE_DESC.nDescriptorBytes       = 0;
                    APE_DESC.nHeaderBytes           = 0;
                    APE_DESC.nSeekTableBytes        = 0;
                    APE_DESC.nHeaderDataBytes       = 0;
                    APE_DESC.nAPEFrameDataBytes     = 0;
                    APE_DESC.nAPEFrameDataBytesHigh = 0;
                    APE_DESC.nTerminatingDataBytes  = 0;
                    Array.Clear(APE_DESC.cFileMD5, 0, APE_DESC.cFileMD5.Length);

                    APE_DESC.padded                 = source.ReadUInt16();
                    APE_DESC.nDescriptorBytes       = source.ReadUInt32();
                    APE_DESC.nHeaderBytes           = source.ReadUInt32();
                    APE_DESC.nSeekTableBytes        = source.ReadUInt32();
                    APE_DESC.nHeaderDataBytes       = source.ReadUInt32();
                    APE_DESC.nAPEFrameDataBytes     = source.ReadUInt32();
                    APE_DESC.nAPEFrameDataBytesHigh = source.ReadUInt32();
                    APE_DESC.nTerminatingDataBytes  = source.ReadUInt32();
                    APE_DESC.cFileMD5               = source.ReadBytes(16);

                    // seek past description header
                    if (APE_DESC.nDescriptorBytes != 52)
                    {
                        source.BaseStream.Seek(APE_DESC.nDescriptorBytes - 52, SeekOrigin.Current);
                    }
                    // load new ape_header
                    if (APE_DESC.nHeaderBytes > 24 /*sizeof(APE_NEW)*/)
                    {
                        APE_DESC.nHeaderBytes = 24 /*sizeof(APE_NEW)*/;
                    }

                    APE_NEW.nCompressionLevel = 0;
                    APE_NEW.nFormatFlags      = 0;
                    APE_NEW.nBlocksPerFrame   = 0;
                    APE_NEW.nFinalFrameBlocks = 0;
                    APE_NEW.nTotalFrames      = 0;
                    APE_NEW.nBitsPerSample    = 0;
                    APE_NEW.nChannels         = 0;
                    APE_NEW.nSampleRate       = 0;

                    APE_NEW.nCompressionLevel = source.ReadUInt16();
                    APE_NEW.nFormatFlags      = source.ReadUInt16();
                    APE_NEW.nBlocksPerFrame   = source.ReadUInt32();
                    APE_NEW.nFinalFrameBlocks = source.ReadUInt32();
                    APE_NEW.nTotalFrames      = source.ReadUInt32();
                    APE_NEW.nBitsPerSample    = source.ReadUInt16();
                    APE_NEW.nChannels         = source.ReadUInt16();
                    APE_NEW.nSampleRate       = source.ReadUInt32();

                    // based on MAC SDK 3.98a1 (APEinfo.h)
                    sampleRate          = (int)APE_NEW.nSampleRate;
                    channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(APE_NEW.nChannels);
                    formatFlags         = APE_NEW.nFormatFlags;
                    bits            = APE_NEW.nBitsPerSample;
                    compressionMode = APE_NEW.nCompressionLevel;
                    // calculate total uncompressed samples
                    if (APE_NEW.nTotalFrames > 0)
                    {
                        totalSamples = (long)(APE_NEW.nBlocksPerFrame) *
                                       (long)(APE_NEW.nTotalFrames - 1) +
                                       (long)(APE_NEW.nFinalFrameBlocks);
                    }
                    LoadSuccess = true;
                }
                else
                {
                    // Old Monkey <= 3.97

                    APE_OLD.nCompressionLevel = 0;
                    APE_OLD.nFormatFlags      = 0;
                    APE_OLD.nChannels         = 0;
                    APE_OLD.nSampleRate       = 0;
                    APE_OLD.nHeaderBytes      = 0;
                    APE_OLD.nTerminatingBytes = 0;
                    APE_OLD.nTotalFrames      = 0;
                    APE_OLD.nFinalFrameBlocks = 0;
                    APE_OLD.nInt = 0;

                    APE_OLD.nCompressionLevel = source.ReadUInt16();
                    APE_OLD.nFormatFlags      = source.ReadUInt16();
                    APE_OLD.nChannels         = source.ReadUInt16();
                    APE_OLD.nSampleRate       = source.ReadUInt32();
                    APE_OLD.nHeaderBytes      = source.ReadUInt32();
                    APE_OLD.nTerminatingBytes = source.ReadUInt32();
                    APE_OLD.nTotalFrames      = source.ReadUInt32();
                    APE_OLD.nFinalFrameBlocks = source.ReadUInt32();
                    APE_OLD.nInt = source.ReadInt32();

                    compressionMode     = APE_OLD.nCompressionLevel;
                    sampleRate          = (int)APE_OLD.nSampleRate;
                    channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(APE_OLD.nChannels);
                    formatFlags         = APE_OLD.nFormatFlags;
                    bits = 16;
                    if ((APE_OLD.nFormatFlags & MONKEY_FLAG_8_BIT) != 0)
                    {
                        bits = 8;
                    }
                    if ((APE_OLD.nFormatFlags & MONKEY_FLAG_24_BIT) != 0)
                    {
                        bits = 24;
                    }

                    hasSeekElements = ((APE_OLD.nFormatFlags & MONKEY_FLAG_PEAK_LEVEL) != 0);
                    wavNotStored    = ((APE_OLD.nFormatFlags & MONKEY_FLAG_SEEK_ELEMENTS) != 0);
                    hasPeakLevel    = ((APE_OLD.nFormatFlags & MONKEY_FLAG_WAV_NOT_STORED) != 0);

                    if (hasPeakLevel)
                    {
                        peakLevel      = (uint)APE_OLD.nInt;
                        peakLevelRatio = (peakLevel / (1 << bits) / 2.0) * 100.0;
                    }

                    // based on MAC_SDK_397 (APEinfo.cpp)
                    if (version >= 3950)
                    {
                        BlocksPerFrame = 73728 * 4;
                    }
                    else if ((version >= 3900) || ((version >= 3800) && (MONKEY_COMPRESSION_EXTRA_HIGH == APE_OLD.nCompressionLevel)))
                    {
                        BlocksPerFrame = 73728;
                    }
                    else
                    {
                        BlocksPerFrame = 9216;
                    }

                    // calculate total uncompressed samples
                    if (APE_OLD.nTotalFrames > 0)
                    {
                        totalSamples = (long)(APE_OLD.nTotalFrames - 1) *
                                       (long)(BlocksPerFrame) +
                                       (long)(APE_OLD.nFinalFrameBlocks);
                    }
                    LoadSuccess = true;
                }
                if (LoadSuccess)
                {
                    // compression profile name
                    if ((0 == (compressionMode % 1000)) && (compressionMode <= 6000))
                    {
                        compressionModeStr = MONKEY_COMPRESSION[compressionMode / 1000]; // int division
                    }
                    else
                    {
                        compressionModeStr = compressionMode.ToString();
                    }
                    // length
                    if (sampleRate > 0)
                    {
                        duration = ((double)totalSamples * 1000.0 / sampleRate);
                    }
                    // average bitrate
                    if (duration > 0)
                    {
                        bitrate = 8 * (sizeInfo.FileSize - sizeInfo.TotalTagSize) / (duration);
                    }
                    // some extra sanity checks
                    isValid = ((bits > 0) && (sampleRate > 0) && (totalSamples > 0) && (channelsArrangement.NbChannels > 0));
                    result  = isValid;
                }
            }

            return(result);
        }
Пример #3
0
        public bool Read(BinaryReader source, AudioDataManager.SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams)
        {
            this.sizeInfo = sizeInfo;
            bool result = false;

            resetData();

            source.BaseStream.Seek(0, SeekOrigin.Begin);
            if (DSD_ID.Equals(Utils.Latin1Encoding.GetString(source.ReadBytes(4))))
            {
                source.BaseStream.Seek(16, SeekOrigin.Current); // Chunk size and file size
                id3v2Offset = source.ReadInt64();

                if (FMT_ID.Equals(Utils.Latin1Encoding.GetString(source.ReadBytes(4))))
                {
                    source.BaseStream.Seek(8, SeekOrigin.Current); // Chunk size

                    formatVersion = source.ReadInt32();

                    if (formatVersion > 1)
                    {
                        LogDelegator.GetLogDelegate()(Log.LV_ERROR, "DSF format version " + formatVersion + " not supported");
                        return(result);
                    }

                    isValid = true;

                    source.BaseStream.Seek(8, SeekOrigin.Current); // Format ID (4), Channel type (4)

                    uint channels = source.ReadUInt32();
                    switch (channels)
                    {
                    case 1: channelsArrangement = MONO; break;

                    case 2: channelsArrangement = STEREO; break;

                    case 3: channelsArrangement = ISO_3_0_0; break;

                    case 4: channelsArrangement = QUAD; break;

                    case 5: channelsArrangement = LRCLFE; break;

                    case 6: channelsArrangement = ISO_3_2_0; break;

                    case 7: channelsArrangement = ISO_3_2_1; break;

                    default: channelsArrangement = UNKNOWN; break;
                    }

                    sampleRate = source.ReadUInt32();
                    bits       = source.ReadUInt32();

                    ulong sampleCount = source.ReadUInt64();

                    duration = (double)sampleCount * 1000.0 / sampleRate;
                    bitrate  = Math.Round(((double)(sizeInfo.FileSize - source.BaseStream.Position)) * 8 / duration); //time to calculate average bitrate

                    result = true;
                }

                // Load tag if exists
                if (id3v2Offset > 0)
                {
                    if (readTagParams.PrepareForWriting)
                    {
                        id3v2StructureHelper.AddZone(id3v2Offset, (int)(source.BaseStream.Length - id3v2Offset));
                        id3v2StructureHelper.AddSize(12, source.BaseStream.Length);
                        id3v2StructureHelper.AddIndex(20, id3v2Offset);
                    }
                }
                else
                {
                    id3v2Offset = 0; // Switch status to "tried to read, but nothing found"

                    if (readTagParams.PrepareForWriting)
                    {
                        // Add EOF zone for future tag writing
                        id3v2StructureHelper.AddZone(source.BaseStream.Length, 0);
                        id3v2StructureHelper.AddSize(12, source.BaseStream.Length);
                        id3v2StructureHelper.AddIndex(20, source.BaseStream.Length);
                    }
                }
            }

            return(result);
        }
Пример #4
0
 public bool Read(BinaryReader source, AudioDataManager.SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams)
 {
     return(true);
 }
Пример #5
0
/* Unused for now
 *
 *              //   Get compression ratio
 *              private double getCompressionRatio()
 *              {
 *                      if (isValid())
 *                      {
 *                              return (double)sizeInfo.FileSize / (samples * channels * bitsPerSample / 8.0) * 100;
 *                      }
 *                      else
 *                      {
 *                              return 0;
 *                      }
 *              }
 *
 *              //   Get channel mode
 *              private String getChannelMode()
 *              {
 *                      String result;
 *                      if (isValid())
 *                      {
 *                              switch(channels)
 *                              {
 *                                      case 1 : result = "Mono"; break;
 *                                      case 2 : result = "Stereo"; break;
 *                                      default: result = "Multi Channel"; break;
 *                              }
 *                      }
 *                      else
 *                      {
 *                              result = "";
 *                      }
 *                      return result;
 *              }
 *
 */

        public Boolean Read(BinaryReader source, AudioDataManager.SizeInfo sizeInfo, ReadTagParams readTagParams)
        {
            this.sizeInfo = sizeInfo;

            return(Read(source, readTagParams));
        }