public bool Read(BinaryReader source, SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams) { this.sizeInfo = sizeInfo; resetData(); source.BaseStream.Seek(sizeInfo.ID3v2Size, SeekOrigin.Begin); bool result = false; if (TTA_SIGNATURE.Equals(Utils.Latin1Encoding.GetString(source.ReadBytes(4)))) { isValid = true; audioFormat = source.ReadUInt16(); channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(source.ReadUInt16()); bitsPerSample = source.ReadUInt16(); sampleRate = source.ReadUInt32(); samplesSize = source.ReadUInt32(); cRC32 = source.ReadUInt32(); bitrate = (double)(sizeInfo.FileSize - sizeInfo.TotalTagSize) * 8.0 / ((double)samplesSize * 1000.0 / sampleRate); duration = (double)samplesSize * 1000.0 / sampleRate; result = true; } return(result); }
// Read ADIF header data private void readADIF(BinaryReader Source) { int Position; Position = (int)(sizeInfo.ID3v2Size * 8 + 32); if (0 == StreamUtils.ReadBits(Source, Position, 1)) { Position += 3; } else { Position += 75; } if (0 == StreamUtils.ReadBits(Source, Position, 1)) { bitrateTypeID = AAC_BITRATE_TYPE_CBR; } else { bitrateTypeID = AAC_BITRATE_TYPE_VBR; } Position++; bitrate = (int)StreamUtils.ReadBits(Source, Position, 23); if (AAC_BITRATE_TYPE_CBR == bitrateTypeID) { Position += 51; } else { Position += 31; } Position += 2; uint channels = 1; sampleRate = SAMPLE_RATE[StreamUtils.ReadBits(Source, Position, 4)]; Position += 4; channels += StreamUtils.ReadBits(Source, Position, 4); Position += 4; channels += StreamUtils.ReadBits(Source, Position, 4); Position += 4; channels += StreamUtils.ReadBits(Source, Position, 4); Position += 4; channels += StreamUtils.ReadBits(Source, Position, 2); channelsArrangement = ChannelsArrangements.GuessFromChannelNumber((int)channels); }
// Read ADTS header data private void readADTS(BinaryReader Source) { int frames = 0; int totalSize = 0; int position; do { frames++; position = (int)(sizeInfo.ID3v2Size + totalSize) * 8; if (StreamUtils.ReadBits(Source, position, 12) != 0xFFF) { break; } position += 18; sampleRate = SAMPLE_RATE[StreamUtils.ReadBits(Source, position, 4)]; position += 5; uint channels = StreamUtils.ReadBits(Source, position, 3); channelsArrangement = ChannelsArrangements.GuessFromChannelNumber((int)channels); position += 7; totalSize += (int)StreamUtils.ReadBits(Source, position, 13); position += 13; if (0x7FF == StreamUtils.ReadBits(Source, position, 11)) { bitrateTypeID = AAC_BITRATE_TYPE_VBR; } else { bitrateTypeID = AAC_BITRATE_TYPE_CBR; } if (AAC_BITRATE_TYPE_CBR == bitrateTypeID) { break; } }while (Source.BaseStream.Length > sizeInfo.ID3v2Size + totalSize); bitrate = (int)Math.Round(8 * totalSize / 1024.0 / frames * sampleRate); }
protected override bool read(BinaryReader source, MetaDataIO.ReadTagParams readTagParams) { fileData = new FileData(); resetData(); bool result = readData(source, readTagParams); // Process data if loaded and valid if (result && isValid(fileData)) { channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(fileData.Channels); sampleRate = fileData.SampleRate; bitrate = (sizeInfo.FileSize - sizeInfo.TotalTagSize - fileData.HeaderSize) * 8.0 / duration; isVBR = (WMA_GSM_VBR_ID == fileData.FormatTag); isLossless = (WMA_LOSSLESS_ID == fileData.FormatTag); } return(result); }
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); }
// ---------- SUPPORT METHODS private bool readWAV(Stream source, ReadTagParams readTagParams) { bool result = true; uint riffChunkSize; long riffChunkSizePos; byte[] data = new byte[4]; source.Seek(0, SeekOrigin.Begin); // Read header source.Read(data, 0, 4); string str = Utils.Latin1Encoding.GetString(data); if (str.Equals(HEADER_RIFF)) { _isLittleEndian = true; } else if (str.Equals(HEADER_RIFX)) { _isLittleEndian = false; } else { return(false); } // Force creation of FileStructureHelper with detected endianness structureHelper = new FileStructureHelper(isLittleEndian); id3v2StructureHelper = new FileStructureHelper(isLittleEndian); riffChunkSizePos = source.Position; source.Read(data, 0, 4); if (isLittleEndian) { riffChunkSize = StreamUtils.DecodeUInt32(data); } else { riffChunkSize = StreamUtils.DecodeBEUInt32(data); } // Format code source.Read(data, 0, 4); str = Utils.Latin1Encoding.GetString(data); if (!str.Equals(FORMAT_WAVE)) { return(false); } string subChunkId; uint chunkSize; long chunkDataPos; bool foundSample = false; bool foundBext = false; bool foundInfo = false; bool foundIXml = false; // Sub-chunks loop while (source.Position < riffChunkSize + 8) { // Chunk ID source.Read(data, 0, 4); if (0 == data[0]) // Sometimes data segment ends with a parasite null byte { source.Seek(-3, SeekOrigin.Current); source.Read(data, 0, 4); } subChunkId = Utils.Latin1Encoding.GetString(data); // Chunk size source.Read(data, 0, 4); if (isLittleEndian) { chunkSize = StreamUtils.DecodeUInt32(data); } else { chunkSize = StreamUtils.DecodeBEUInt32(data); } chunkDataPos = source.Position; if (subChunkId.Equals(CHUNK_FORMAT)) { source.Read(data, 0, 2); if (isLittleEndian) { formatId = StreamUtils.DecodeUInt16(data); } else { formatId = StreamUtils.DecodeBEUInt16(data); } source.Read(data, 0, 2); if (isLittleEndian) { channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(StreamUtils.DecodeUInt16(data)); } else { channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(StreamUtils.DecodeBEUInt16(data)); } source.Read(data, 0, 4); if (isLittleEndian) { sampleRate = StreamUtils.DecodeUInt32(data); } else { sampleRate = StreamUtils.DecodeBEUInt32(data); } source.Read(data, 0, 4); if (isLittleEndian) { bytesPerSecond = StreamUtils.DecodeUInt32(data); } else { bytesPerSecond = StreamUtils.DecodeBEUInt32(data); } source.Seek(2, SeekOrigin.Current); // BlockAlign source.Read(data, 0, 2); if (isLittleEndian) { bitsPerSample = StreamUtils.DecodeUInt16(data); } else { bitsPerSample = StreamUtils.DecodeBEUInt16(data); } } else if (subChunkId.Equals(CHUNK_DATA)) { headerSize = riffChunkSize - chunkSize; } else if (subChunkId.Equals(CHUNK_FACT)) { source.Read(data, 0, 4); if (isLittleEndian) { sampleNumber = StreamUtils.DecodeInt32(data); } else { sampleNumber = StreamUtils.DecodeBEInt32(data); } } else if (subChunkId.Equals(CHUNK_SAMPLE)) { structureHelper.AddZone(source.Position - 8, (int)(chunkSize + 8), subChunkId); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, subChunkId); foundSample = true; tagExists = true; SampleTag.FromStream(source, this, readTagParams); } else if (subChunkId.Equals(CHUNK_BEXT)) { structureHelper.AddZone(source.Position - 8, (int)(chunkSize + 8), subChunkId); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, subChunkId); foundBext = true; tagExists = true; BextTag.FromStream(source, this, readTagParams); } else if (subChunkId.Equals(CHUNK_INFO)) { // Purpose of the list should be INFO source.Read(data, 0, 4); string purpose = Utils.Latin1Encoding.GetString(data, 0, 4); if (purpose.Equals(InfoTag.PURPOSE_INFO)) { structureHelper.AddZone(source.Position - 12, (int)(chunkSize + 8), subChunkId); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, subChunkId); foundInfo = true; tagExists = true; InfoTag.FromStream(source, this, readTagParams, chunkSize); } } else if (subChunkId.Equals(CHUNK_IXML)) { structureHelper.AddZone(source.Position - 8, (int)(chunkSize + 8), subChunkId); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, subChunkId); foundIXml = true; tagExists = true; IXmlTag.FromStream(source, this, readTagParams, chunkSize); } else if (subChunkId.Equals(CHUNK_ID3)) { id3v2Offset = source.Position; // Zone is already added by Id3v2.Read id3v2StructureHelper.AddZone(id3v2Offset - 8, (int)(chunkSize + 8), subChunkId); id3v2StructureHelper.AddSize(riffChunkSizePos, riffChunkSize, subChunkId); } source.Seek(chunkDataPos + chunkSize, SeekOrigin.Begin); } // Add zone placeholders for future tag writing if (readTagParams.PrepareForWriting) { if (!foundSample) { structureHelper.AddZone(source.Position, 0, CHUNK_SAMPLE); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, CHUNK_SAMPLE); } if (!foundBext) { structureHelper.AddZone(source.Position, 0, CHUNK_BEXT); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, CHUNK_BEXT); } if (!foundInfo) { structureHelper.AddZone(source.Position, 0, CHUNK_INFO); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, CHUNK_INFO); } if (!foundIXml) { structureHelper.AddZone(source.Position, 0, CHUNK_IXML); structureHelper.AddSize(riffChunkSizePos, riffChunkSize, CHUNK_IXML); } } // ID3 zone should be set as the very last one for Windows to be able to read the LIST INFO zone properly if (-1 == id3v2Offset) { id3v2Offset = 0; // Switch status to "tried to read, but nothing found" if (readTagParams.PrepareForWriting) { id3v2StructureHelper.AddZone(source.Position, 0, CHUNK_ID3); id3v2StructureHelper.AddSize(riffChunkSizePos, riffChunkSize, CHUNK_ID3); } } return(result); }
public bool Read(BinaryReader source, SizeInfo sizeInfo, MetaDataIO.ReadTagParams readTagParams) { bool result = false; bool doLoop = true; long position; UInt16 readData16; UInt32 readData32; UInt32 metaType; UInt32 metaSize; long sampleCount = 0; int frameSizeType = -1; this.sizeInfo = sizeInfo; resetData(); source.BaseStream.Seek(sizeInfo.ID3v2Size, SeekOrigin.Begin); if (TAK_ID.Equals(Utils.Latin1Encoding.GetString(source.ReadBytes(4)))) { result = true; position = source.BaseStream.Position; source.BaseStream.Seek(position, SeekOrigin.Begin); do // Loop metadata { readData32 = source.ReadUInt32(); metaType = readData32 & 0x7F; metaSize = readData32 >> 8; position = source.BaseStream.Position; if (0 == metaType) { doLoop = false; // End of metadata } else if (0x01 == metaType) // Stream info { readData16 = source.ReadUInt16(); frameSizeType = readData16 & 0x003C; // bits 11 to 14 readData32 = source.ReadUInt32(); uint restOfData = source.ReadUInt32(); sampleCount = (readData16 >> 14) + (readData32 << 2) + ((restOfData & 0x00000080) << 34); sampleRate = ((restOfData >> 4) & 0x03ffff) + 6000; // bits 4 to 21 channelsArrangement = ChannelsArrangements.GuessFromChannelNumber((int)((restOfData >> 27) & 0x0F) + 1); // bits 28 to 31 if (sampleCount > 0) { duration = (double)sampleCount * 1000.0 / sampleRate; bitrate = Math.Round(((double)(sizeInfo.FileSize - source.BaseStream.Position)) * 8 / duration); //time to calculate average bitrate } } else if (0x04 == metaType) // Encoder info { readData32 = source.ReadUInt32(); formatVersion = 100 * ((readData32 & 0x00ff0000) >> 16); formatVersion += 10 * ((readData32 & 0x0000ff00) >> 8); formatVersion += (readData32 & 0x000000ff); } source.BaseStream.Seek(position + metaSize, SeekOrigin.Begin); } while (doLoop); // End of metadata loop } return(result); }
private bool _ReadV3(BinaryReader r) { RiffChunk chunk = new RiffChunk(); char[] wavchunk; FormatChunk fmt; bool hasfmt; WavpackHeader3 wvh3 = new WavpackHeader3(); bool result = false; hasfmt = false; // read and evaluate header chunk.Reset(); chunk.id = r.ReadChars(4); chunk.size = r.ReadUInt32(); wavchunk = r.ReadChars(4); if (!StreamUtils.StringEqualsArr("WAVE", wavchunk)) { return(result); } // start looking for chunks chunk.Reset(); while (r.BaseStream.Position < r.BaseStream.Length) { chunk.id = r.ReadChars(4); chunk.size = r.ReadUInt32(); if (chunk.size <= 0) { break; } if (StreamUtils.StringEqualsArr("fmt ", chunk.id)) // Format chunk found read it { if (chunk.size >= 16 /*sizeof(fmt_chunk)*/) { fmt.wformattag = r.ReadUInt16(); fmt.wchannels = r.ReadUInt16(); fmt.dwsamplespersec = r.ReadUInt32(); fmt.dwavgbytespersec = r.ReadUInt32(); fmt.wblockalign = r.ReadUInt16(); fmt.wbitspersample = r.ReadUInt16(); hasfmt = true; result = true; formatTag = fmt.wformattag; channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(fmt.wchannels); sampleRate = (int)fmt.dwsamplespersec; bits = fmt.wbitspersample; bitrate = (double)fmt.dwavgbytespersec * 8; } else { break; } } else { if ((StreamUtils.StringEqualsArr("data", chunk.id)) && hasfmt) { wvh3.Reset(); wvh3.ckID = r.ReadChars(4); wvh3.ckSize = r.ReadUInt32(); wvh3.version = r.ReadUInt16(); wvh3.bits = r.ReadUInt16(); wvh3.flags = r.ReadUInt16(); wvh3.shift = r.ReadUInt16(); wvh3.total_samples = r.ReadUInt32(); wvh3.crc = r.ReadUInt32(); wvh3.crc2 = r.ReadUInt32(); wvh3.extension = r.ReadChars(4); wvh3.extra_bc = r.ReadByte(); wvh3.extras = r.ReadChars(3); if (StreamUtils.StringEqualsArr("wvpk", wvh3.ckID)) // wavpack header found { result = true; version = wvh3.version; channelsArrangement = ChannelsArrangements.GuessFromChannelNumber(2 - (wvh3.flags & 1)); samples = wvh3.total_samples; codecFamily = AudioDataIOFactory.CF_LOSSLESS; // Encoder guess if (wvh3.bits > 0) { if ((wvh3.flags & NEW_HIGH_FLAG_v3) > 0) { encoder = "hybrid"; if ((wvh3.flags & WVC_FLAG_v3) > 0) { encoder += " lossless"; } else { encoder += " lossy"; codecFamily = AudioDataIOFactory.CF_LOSSY; } if ((wvh3.flags & EXTREME_DECORR_v3) > 0) { encoder = encoder + " (high)"; } } else { if ((wvh3.flags & (HIGH_FLAG_v3 | FAST_FLAG_v3)) == 0) { encoder = (wvh3.bits + 3).ToString() + "-bit lossy"; codecFamily = AudioDataIOFactory.CF_LOSSY; } else { encoder = (wvh3.bits + 3).ToString() + "-bit lossy"; codecFamily = AudioDataIOFactory.CF_LOSSY; if ((wvh3.flags & HIGH_FLAG_v3) > 0) { encoder += " high"; } else { encoder += " fast"; } } } } else { if ((wvh3.flags & HIGH_FLAG_v3) == 0) { encoder = "lossless (fast mode)"; } else { if ((wvh3.flags & EXTREME_DECORR_v3) > 0) { encoder = "lossless (high mode)"; } else { encoder = "lossless"; } } } if (sampleRate <= 0) { sampleRate = 44100; } duration = (double)wvh3.total_samples * 1000.0 / sampleRate; if (duration > 0) { bitrate = 8.0 * (sizeInfo.FileSize - tagSize - (double)wvh3.ckSize) / duration; } } break; } else // not a wv file { break; } } } // while return(result); }
private bool _ReadV4(BinaryReader r) { WavPackHeader4 wvh4 = new WavPackHeader4(); byte[] EncBuf = new byte[4096]; int tempo; byte encoderbyte; bool result = false; wvh4.Reset(); wvh4.ckID = r.ReadChars(4); wvh4.ckSize = r.ReadUInt32(); wvh4.version = r.ReadUInt16(); wvh4.track_no = r.ReadByte(); wvh4.index_no = r.ReadByte(); wvh4.total_samples = r.ReadUInt32(); wvh4.block_index = r.ReadUInt32(); wvh4.block_samples = r.ReadUInt32(); wvh4.flags = r.ReadUInt32(); wvh4.crc = r.ReadUInt32(); if (StreamUtils.StringEqualsArr("wvpk", wvh4.ckID)) // wavpack header found -- TODO handle exceptions better { result = true; version = (wvh4.version >> 8); channelsArrangement = ChannelsArrangements.GuessFromChannelNumber((int)(2 - (wvh4.flags & 4))); bits = (int)((wvh4.flags & 3) * 16); // bytes stored flag samples = wvh4.total_samples; bSamples = wvh4.block_samples; sampleRate = (int)((wvh4.flags & (0x1F << 23)) >> 23); if ((sampleRate > 14) || (sampleRate < 0)) { sampleRate = 44100; } else { sampleRate = sample_rates[sampleRate]; } if (8 == (wvh4.flags & 8)) // hybrid flag { encoder = "hybrid lossy"; codecFamily = AudioDataIOFactory.CF_LOSSY; } else { //if (2 == (wvh4.flags & 2) ) { // lossless flag encoder = "lossless"; codecFamily = AudioDataIOFactory.CF_LOSSLESS; } /* * if ((wvh4.flags & 0x20) > 0) // MODE_HIGH * { * FEncoder = FEncoder + " (high)"; * end * else if ((wvh4.flags & 0x40) > 0) // MODE_FAST * { * FEncoder = FEncoder + " (fast)"; * } */ duration = (double)wvh4.total_samples * 1000.0 / sampleRate; if (duration > 0) { bitrate = (sizeInfo.FileSize - tagSize) * 8 / (double)(samples * 1000.0 / (double)sampleRate); } Array.Clear(EncBuf, 0, 4096); EncBuf = r.ReadBytes(4096); for (tempo = 0; tempo < 4096; tempo++) { if (0x65 == EncBuf[tempo]) { if (0x02 == EncBuf[tempo + 1]) { encoderbyte = EncBuf[tempo + 2]; switch (encoderbyte) { case 8: encoder = encoder + " (high)"; break; case 0: encoder = encoder + " (normal)"; break; case 2: encoder = encoder + " (fast)"; break; case 6: encoder = encoder + " (very fast)"; break; } break; } } } } return(result); }