/
FlacMetadata.cs
85 lines (70 loc) · 2.89 KB
/
FlacMetadata.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using System;
using System.Collections.Generic;
using System.IO;
namespace NAudio.Flac
{
[System.Diagnostics.DebuggerDisplay("Type:{MetaDataType} LastBlock:{IsLastMetaBlock} Length:{Length} bytes")]
public class FlacMetadata
{
public unsafe static FlacMetadata FromStream(Stream stream)
{
bool lastBlock = false;
FlacMetaDataType type = FlacMetaDataType.Undef;
int length = 0;
byte[] b = new byte[4];
if (stream.Read(b, 0, 4) <= 0)
throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata);
fixed (byte* headerBytes = b)
{
FlacBitReader bitReader = new FlacBitReader(headerBytes, 0);
lastBlock = bitReader.ReadBits(1) == 1;
type = (FlacMetaDataType)bitReader.ReadBits(7);
length = (int)bitReader.ReadBits(24);
////1000 0000
//if (((b[0] & 0x80) >> 7) == 1)
// lastBlock = true;
//type = (FlacMetaDataType)(b[0] & 0x7F);
//int length = (b[1] + (b[2] << 8) + (b[3] << 16));
}
FlacMetadata data;
long streamStartPosition = stream.Position;
if ((int)type < 0 || (int)type > 6)
return null;
switch (type)
{
case FlacMetaDataType.StreamInfo:
data = new FlacMetadataStreamInfo(stream, length, lastBlock);
break;
case FlacMetaDataType.Seektable:
data = new FlacMetadataSeekTable(stream, length, lastBlock);
break;
default:
data = new FlacMetadata(type, lastBlock, length);
break;
}
stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current);
return data;
}
public static List<FlacMetadata> ReadAllMetadataFromStream(Stream stream)
{
List<FlacMetadata> metaDataCollection = new List<FlacMetadata>();
while (true)
{
FlacMetadata data = FromStream(stream);
if (data != null)
metaDataCollection.Add(data);
if (data == null || data.IsLastMetaBlock)
return metaDataCollection;
}
}
protected FlacMetadata(FlacMetaDataType type, bool lastBlock, Int32 length)
{
MetaDataType = type;
IsLastMetaBlock = lastBlock;
Length = length;
}
public FlacMetaDataType MetaDataType { get; private set; }
public Boolean IsLastMetaBlock { get; private set; }
public Int32 Length { get; private set; }
}
}