public IEnumerable<AudioChunk> StreamData( Stream source ) { infoBuffer.Length = 0; info = new AudioChunk(); PrimitiveReader reader = new PrimitiveReader( source ); string signature = reader.ReadASCIIString( 4 ); if( signature != "FORM" ) throw new InvalidDataException( "Invalid initial signature." ); reader.BigEndian = true; int formChunkSize = reader.ReadInt32(); AppendInfoLine( 0, "-- Begin info --" ); AppendInfoLine( 0, "{0} (Chunk size: {1} bytes, {2} KB, {3} MB)", signature, formChunkSize, formChunkSize / 1024, formChunkSize / 1024 / 1024 ); string format = reader.ReadASCIIString( 4 ); switch( format ) { case "AIFF": break; //http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/Docs/AIFF-C.9.26.91.pdf case "AIFC": aifcFormat = true; break; default: throw new InvalidDataException( "Invalid initial signature." ); } AiffChunkHeader chunk; while( true ) { chunk = ReadChunkHeader( reader ); AppendInfoLine( 1, "{0} (Chunk size: {1})", chunk.Signature, chunk.DataSize ); if( chunk.Signature == "COMM" ) { ProcessCommonChunk( chunk, reader ); } else if( chunk.Signature == "SSND" ) { break; } else { SkipChunkData( reader, chunk.DataSize ); } } AppendInfoLine( 0, "-- End info --" ); fileinfo = infoBuffer.ToString(); return StreamDataCore( chunk, reader ); }
public override void ReadMetadata() { reader = new PrimitiveReader( stream ); string signature = reader.ReadASCIIString( 4 ); bool bigendian = false, reverseHeaders = false; if( signature == "RIFF" ) { } else if( signature == "RIFX" ) { bigendian = true; } else if( signature == "FFIR" ) { bigendian = true; reverseHeaders = true; } else { throw new InvalidDataException( "Invalid initial signature" ); } reader.BigEndian = bigendian; int riffChunkSize = reader.ReadInt32(); string format = reader.ReadASCIIString( 4 ); if( !( format == "WAVE" || format == "EVAW" ) ) throw new InvalidDataException( "Invalid format." ); // Although technically a wave chunk is supposed to consist of // a 'fmt ' chunk followed by a 'data' chunk, this is not always the case. RiffChunkHeader chunk; while( true ) { chunk = ReadChunkHeader( reader, reverseHeaders ); if( chunk.Signature == "fmt " ) { ProcessFormatChunk( chunk, reader ); foundAudioInfo = true; } else if( chunk.Signature == "data" ) { if( !foundAudioInfo ) { Logger.Log( LoggingType.CodecError, "Data chunk found before format chunk.", "This usually indicates an improper encoder or a corrupted file." ); throw new InvalidOperationException( "Stream must be seekable when the data chunk is before the format chunk." ); } break; } else { reader.SkipData( chunk.DataSize ); } } chunkDataSize = chunk.DataSize; }
public override void ReadMetadata() { PrimitiveReader reader = new PrimitiveReader( this ); string signature = reader.ReadASCIIString( 4 ); if( signature != "fLaC" ) { throw new InvalidDataException( "Invalid signature." ); } reader.BigEndian = true; while( !ReadMetadataBlock( reader ) ); }
bool ReadV2Frame( PrimitiveReader reader, ref int len ) { string frameId = reader.ReadASCIIString( 4 ); len -= 4; if( frameId == "\0\0\0\0" ) return true; int frameDataSize = reader.ReadUInt24(); len -= ( frameDataSize + 3 ); Console.WriteLine( "reading frame: " + frameId ); Console.WriteLine( " skipping frame." ); reader.SkipData( frameDataSize ); return false; }
public override void ReadMetadata() { PrimitiveReader reader = new PrimitiveReader( this ); while( true ) { string header = reader.ReadASCIIString( 4 ); if( header == "TAG+" ) { // ID3 1.1 Extended tag ReadID31Extended( reader ); } else if( header.StartsWith( "TAG" ) ) { // ID3 1 reader.Seek( -1, SeekOrigin.Current ); ReadID31( reader ); } else if( header.StartsWith( "ID3" ) ) { // ID3 2 ID3v2Frame tag = new ID3v2Frame( this, reader, (byte)header[3] ); } else { // Unrecognised header, it's probably the start of the actual MPEG audio stream. reader.Seek( -4, SeekOrigin.Current ); break; } } }
public IEnumerable<AudioChunk> StreamData( Stream source ) { infoBuffer.Length = 0; chunk = new AudioChunk(); PrimitiveReader reader = new PrimitiveReader( source ); string signature = reader.ReadASCIIString( 4 ); if( signature != ".snd" ) { throw new InvalidDataException( "Invalid initial signature." ); } AppendInfoLine( 0, "-- Begin info --" ); reader.BigEndian = true; uint dataOffset = reader.ReadUInt32(); AppendInfoLine( 0, "Data offset: {0}", dataOffset ); uint dataSize = reader.ReadUInt32(); if( dataSize == 0xFFFFFFFF ) { dataLength = source.Length - dataOffset; } else { dataLength = dataSize; } AppendInfoLine( 0, "Data length: {0}", dataLength ); AuEncoding encoding = (AuEncoding)reader.ReadUInt32(); AppendInfoLine( 0, "Encoding: {0}", encoding ); uint sampleRate = reader.ReadUInt32(); AppendInfoLine( 0, "Sample rate: {0}", sampleRate ); uint channels = reader.ReadUInt32(); AppendInfoLine( 0, "Channels: {0}", channels ); if( dataOffset > 24 ) { int infoLength = (int)( dataOffset - 24 ); string info = reader.ReadASCIIString( infoLength ); AppendInfoLine( 0, "Info: {0}", info ); } int bitsPerSample = bitsPerSampleEncoding[(int)encoding]; int adjustedBitsPerSample = paddedBitsPerSampleEncoding[(int)encoding]; bufferSize = (int)( sampleRate * channels * adjustedBitsPerSample / 8 ); AppendInfoLine( 0, "-- End info --" ); fileinfo = infoBuffer.ToString(); return StreamDataCore( reader ); }
public override void ReadMetadata() { reader = new PrimitiveReader( stream ); string signature = reader.ReadASCIIString( 4 ); if( signature != ".snd" ) { throw new InvalidDataException( "Invalid initial signature." ); } reader.BigEndian = true; uint dataOffset = reader.ReadUInt32(); dataLength = reader.ReadUInt32(); if( dataLength == 0xFFFFFFFF ) { dataLength = (uint)( reader.Length - dataOffset ); } AuEncoding encoding = (AuEncoding)reader.ReadUInt32(); Metadata["AU encoding"] = encoding.ToString(); freq = reader.ReadInt32(); Metadata[MetadataKeys.SampleRate] = freq.ToString(); channels = reader.ReadInt32(); Metadata[MetadataKeys.Channels] = channels.ToString(); if( dataOffset > 24 ) { int infoLength = (int)( dataOffset - 24 ); string info = reader.ReadASCIIString( infoLength ); Metadata["File comment"] = info; } transformer = EmptyTransformer.Instance; switch( encoding ) { case AuEncoding.Int8G711uLaw: transformer = MuLawTransformer.Instance; bitsPerSample = 16; codecBitsPerSample = 8; break; case AuEncoding.Int8LinearPcm: bitsPerSample = codecBitsPerSample = 8; break; case AuEncoding.Int16LinearPcm: bitsPerSample = codecBitsPerSample = 16; transformer = BigEndian16BitTo16BitTransformer.Instance; break; case AuEncoding.Int24LinearPcm: bitsPerSample = 16; codecBitsPerSample = 24; transformer = BigEndian24BitTo16BitTransformer.Instance; break; case AuEncoding.Int32LinearPcm: bitsPerSample = 16; codecBitsPerSample = 32; transformer = BigEndian32BitTo16BitTransformer.Instance; break; case AuEncoding.Float32LinearPcm: bitsPerSample = 16; codecBitsPerSample = 32; transformer = BigEndianFloat32To16BitTransformer.Instance; break; case AuEncoding.Float64LinearPcm: bitsPerSample = 16; codecBitsPerSample = 64; transformer = BigEndianFloat64To16BitTransformer.Instance; break; case AuEncoding.Int8G711ALaw: transformer = ALawTransformer.Instance; bitsPerSample = 16; codecBitsPerSample = 8; break; default: throw new NotSupportedException( "Unsupported audio format: " + encoding ); } Metadata[MetadataKeys.BitsPerSample] = bitsPerSample.ToString(); }
void ProcessCommonChunk( AiffChunkHeader chunk, PrimitiveReader reader ) { byte[] chunkData = reader.ReadBytes( chunk.DataSize ); Stream source = reader.stream; reader.stream = new MemoryStream( chunkData ); int channelsCount = reader.ReadInt16(); uint frameCount = reader.ReadUInt32(); int bitsPerSample = reader.ReadInt16(); byte[] sampleRateBytes = reader.ReadBytes( 10 ); double sampleRate = ConvertFromIeeeExtended( sampleRateBytes ); Console.WriteLine( sampleRate ); AppendInfoLine( 2, "Channels Count: {0}", channelsCount ); AppendInfoLine( 2, "Sample rate (frames/sec): {0}", sampleRate ); AppendInfoLine( 2, "Bits per sample: {0}", bitsPerSample ); AppendInfoLine( 2, "Frame count: {0}", frameCount ); int byteRate = (int)Math.Ceiling( sampleRate ) * channelsCount * bitsPerSample / 8; info.Frequency = (int)sampleRate; Console.WriteLine( "BPS:" + bitsPerSample + ", SR:" + info.Frequency ); transformer = EmptyTransformer.Instance; if( bitsPerSample > 8 && bitsPerSample <= 16 ) { transformer = BigEndian16BitTo16BitTransformer.Instance; } if( bitsPerSample > 16 && bitsPerSample <= 24 ) { transformer = BigEndian24BitTo16BitTransformer.Instance; } // Number of bytes that make up a second's worth of audio data. bufferSize = byteRate; info.Channels = channelsCount; actualBitsPerSample = bitsPerSample; // TODO: Remove this hackery. if( bitsPerSample > 16 ) bitsPerSample = 16; info.BitsPerSample = bitsPerSample; if( aifcFormat ) { string compressionType = reader.ReadASCIIString( 4 ); string compressionName = reader.ReadASCIIString( reader.ReadByte() ); AppendInfoLine( 2, "Compression type: {0}", compressionType ); AppendInfoLine( 2, "Compression name: {0}", compressionName ); switch( compressionType ) { case "NONE": case "sowt": break; case "alaw": case "ALAW": info.BitsPerSample = 16; transformer = ALawTransformer.Instance; break; case "ulaw": case "ULAW": info.BitsPerSample = 16; transformer = MuLawTransformer.Instance; break; } } reader.stream = source; }
static AiffChunkHeader ReadChunkHeader( PrimitiveReader reader ) { AiffChunkHeader chunk = new AiffChunkHeader(); chunk.Signature = reader.ReadASCIIString( 4 ); chunk.DataSize = reader.ReadInt32(); return chunk; }
void ProcessMetadataCuesheet( int len, PrimitiveReader reader ) { string catalogueNumber = reader.ReadASCIIString( 128 ); ulong leadInSamplesCount = reader.ReadUInt64(); byte format = reader.ReadByte(); // All bits other than 1 are reserved. bool compactDisc = ( format & 0x01 ) != 0; byte[] reserved = reader.ReadBytes( 258 ); byte trackCount = reader.ReadByte(); bool cdda = leadInSamplesCount != 0; for( int i = 0; i < trackCount; i++ ) { ulong trackOffset = reader.ReadUInt64(); byte trackNumber = reader.ReadByte(); bool leadOut = cdda ? trackNumber == 170 : trackNumber == 255; string isrc = reader.ReadASCIIString( 12 ); byte trackFlags = reader.ReadByte(); // All bits other than 1 and 2 are reserved. bool audio = ( trackFlags & 0x01 ) == 0; bool preEmphasis = ( trackFlags & 0x02 ) != 0; byte[] trackReserved = reader.ReadBytes( 13 ); byte indexCount = reader.ReadByte(); for( int j = 0; j < indexCount; j++ ) { ulong indexOffset = reader.ReadUInt64(); byte indexPointNumber = reader.ReadByte(); byte[] indexReserved = reader.ReadBytes( 3 ); } } }
void ProcessMetadataApplication( int len, PrimitiveReader reader ) { string appID = reader.ReadASCIIString( 4 ); int dataSize = len - 4; }
void ProcessMetadataPicture( int len, PrimitiveReader reader ) { uint type = reader.ReadUInt32(); PictureType pictureType = (PictureType)type; int mimeTypeLength = reader.ReadInt32(); string mimeType = reader.ReadASCIIString( mimeTypeLength ); int descriptionLength = reader.ReadInt32(); string description = reader.ReadUTF8String( descriptionLength ); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int colourDepth = reader.ReadInt32(); // Bits per pixel. int indexedColoursUsed = reader.ReadInt32(); int picturelength = reader.ReadInt32(); byte[] data = reader.ReadBytes( picturelength ); }
bool ReadV3Frame( PrimitiveReader reader, ref int len ) { string frameId = reader.ReadASCIIString( 4 ); len -= 4; if( frameId == "\0\0\0\0" ) return true; int frameDataSize = reader.ReadInt32(); ushort frameFlags = reader.ReadUInt16(); len -= ( frameDataSize + 4 + 2 ); bool encryption = ( frameFlags & 0x80 ) != 0; bool compression = ( frameFlags & 0x40 ) != 0; bool groupingInfo = ( frameFlags & 0x20 ) != 0; if( groupingInfo ) { byte groupIdentifier = reader.ReadByte(); } if( encryption || compression ) throw new NotImplementedException( "encryption and/or compression support is not yet implemented." ); Console.WriteLine( "reading frame: " + frameId ); if( v3TagConstructors == null ) { v3TagConstructors = ID3v2Tag.Makev3TagConstructors(); } Func<ID3v2Tag> constructor; if( v3TagConstructors.TryGetValue( frameId, out constructor ) ) { ID3v2Tag tag = constructor(); tag.Identifier = frameId; tag.DataSize = frameDataSize; tag.Read( container, reader ); } else { Console.WriteLine( " skipping frame." ); reader.SkipData( frameDataSize ); } return false; }
public void ReadData(string path) { PrimitiveReader reader = new PrimitiveReader(path); SaveGameFile file = new SaveGameFile(); file.Version = reader.ReadASCIIString(8); file.Unknown1 = reader.ReadFloat32(); bool aiDataIncluded = reader.ReadUInt32() != 0; if (aiDataIncluded) { file.AiInfo2 = AiInfo.ReadFrom(reader); } file.Unknown2 = reader.ReadUInt32(); file.GameSpeed1 = reader.ReadUInt32(); file.Unknown3 = reader.ReadUInt32(); file.GameSpeed2 = reader.ReadUInt32(); file.Unknown4 = reader.ReadFloat32(); file.Unknown5 = reader.ReadUInt32(); file.Unknown6 = reader.ReadBytes(17); file.RecordedGamePlayerNumber = reader.ReadUInt16(); //System.Diagnostics.Debugger.Break(); file.PlayersCount = reader.ReadUInt8(); file.Unknown7 = reader.ReadUInt32(); file.Unknown8 = reader.ReadBytes(12); file.Unknown9 = reader.ReadBytes(14); file.Unknown10 = reader.ReadUInt32Array(8); //System.Diagnostics.Debugger.Break(); reader.SeekAbsolute(126); int mapWidth = reader.ReadInt32(); int mapLength = reader.ReadInt32(); uint unknownDataCount = reader.ReadUInt32(); ushort unknown2 = reader.ReadUInt16(); SaveGameMap map = SaveGameMap.ReadFrom(reader, mapWidth, mapLength); /*int unknownIntsArrayCount = reader.ReadInt32(); * uint[][] unknowns = new uint[unknownIntsArrayCount][]; * for( int i = 0; i < unknowns.Length; i++ ) { * int intsCount = reader.ReadInt32() - 1; * if( intsCount < 0 ) throw new Exception(); * unknowns[i] = reader.ReadUInt32Array( intsCount ); * }*/ reader.SeekAbsolute(29132); int mapWidth2 = reader.ReadInt32(); int mapLength2 = reader.ReadInt32(); uint[] unknownMap2 = reader.ReadUInt32Array(mapWidth2 * mapLength2); //byte unknownIntsCount1 = reader.ReadUInt8(); //uint[] unknownInts = reader.ReadUInt32Array( unknownIntsCount1 ); reader.SeekAbsolute(88779); SavePlayerInfo f = SavePlayerInfo.ReadFrom(reader, 2); System.Diagnostics.Debugger.Break(); }