unsafe void decode_metadata() { byte x; int i, id; //bool first = true; byte[] FLAC__STREAM_SYNC_STRING = new byte[] { (byte)'f', (byte)'L', (byte)'a', (byte)'C' }; byte[] ID3V2_TAG_ = new byte[] { (byte)'I', (byte)'D', (byte)'3' }; for (i = id = 0; i < 4;) { if (_IO.Read(_framesBuffer, 0, 1) == 0) { throw new Exception("FLAC stream not found"); } x = _framesBuffer[0]; if (x == FLAC__STREAM_SYNC_STRING[i]) { //first = true; i++; id = 0; continue; } if (id < 3 && x == ID3V2_TAG_[id]) { id++; i = 0; if (id == 3) { if (!skip_bytes(3)) { throw new Exception("FLAC stream not found"); } int skip = 0; for (int j = 0; j < 4; j++) { if (0 == _IO.Read(_framesBuffer, 0, 1)) { throw new Exception("FLAC stream not found"); } skip <<= 7; skip |= ((int)_framesBuffer[0] & 0x7f); } if (!skip_bytes(skip)) { throw new Exception("FLAC stream not found"); } } continue; } id = 0; if (x == 0xff) /* MAGIC NUMBER for the first 8 frame sync bits */ { do { if (_IO.Read(_framesBuffer, 0, 1) == 0) { throw new Exception("FLAC stream not found"); } x = _framesBuffer[0]; } while (x == 0xff); if (x >> 2 == 0x3e) /* MAGIC NUMBER for the last 6 sync bits */ { //_IO.Position -= 2; // state = frame throw new Exception("headerless file unsupported"); } } throw new Exception("FLAC stream not found"); } do { fill_frames_buffer(); fixed(byte *buf = _framesBuffer) { BitReader bitreader = new BitReader(buf, _framesBufferOffset, _framesBufferLength - _framesBufferOffset); bool is_last = bitreader.readbit() != 0; MetadataType type = (MetadataType)bitreader.readbits(7); int len = (int)bitreader.readbits(24); if (type == MetadataType.StreamInfo) { const int FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */ const int FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */ min_block_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN); max_block_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN); min_frame_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN); max_frame_size = bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN); int sample_rate = (int)bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN); int channels = 1 + (int)bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN); int bits_per_sample = 1 + (int)bitreader.readbits(FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN); pcm = new AudioPCMConfig(bits_per_sample, channels, sample_rate); _sampleCount = (long)bitreader.readbits64(FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN); bitreader.skipbits(FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN); } else if (type == MetadataType.Seektable) { int num_entries = len / 18; seek_table = new SeekPoint[num_entries]; for (int e = 0; e < num_entries; e++) { seek_table[e].number = bitreader.read_long(); seek_table[e].offset = bitreader.read_long(); seek_table[e].framesize = (int)bitreader.read_ushort(); } } if (_framesBufferLength < 4 + len) { _IO.Position += 4 + len - _framesBufferLength; _framesBufferLength = 0; } else { _framesBufferLength -= 4 + len; _framesBufferOffset += 4 + len; } if (is_last) { break; } } } while (true); first_frame_offset = _IO.Position - _framesBufferLength; }
private void ParseHeaders() { const long maxFileSize = 0x7FFFFFFEL; const uint fccRIFF = 0x46464952; const uint fccWAVE = 0x45564157; const uint fccFormat = 0x20746D66; const uint fccData = 0x61746164; uint lenRIFF; bool foundFormat, foundData; if (_br.ReadUInt32() != fccRIFF) { throw new Exception("Not a valid RIFF file."); } lenRIFF = _br.ReadUInt32(); if (_br.ReadUInt32() != fccWAVE) { throw new Exception("Not a valid WAVE file."); } _largeFile = false; foundFormat = false; foundData = false; long pos = 12; do { uint ckID, ckSize, ckSizePadded; long ckEnd; ckID = _br.ReadUInt32(); ckSize = _br.ReadUInt32(); ckSizePadded = (ckSize + 1U) & ~1U; pos += 8; ckEnd = pos + (long)ckSizePadded; if (ckID == fccFormat) { foundFormat = true; uint fmtTag = _br.ReadUInt16(); int _channelCount = _br.ReadInt16(); int _sampleRate = _br.ReadInt32(); _br.ReadInt32(); // bytes per second int _blockAlign = _br.ReadInt16(); int _bitsPerSample = _br.ReadInt16(); int _channelMask = 0; pos += 16; if (fmtTag == 0xFFFEU && ckSize >= 34) // WAVE_FORMAT_EXTENSIBLE { _br.ReadInt16(); // CbSize _br.ReadInt16(); // ValidBitsPerSample _channelMask = _br.ReadInt32(); fmtTag = _br.ReadUInt16(); pos += 10; } if (fmtTag != 1) // WAVE_FORMAT_PCM { throw new Exception("WAVE format tag not WAVE_FORMAT_PCM."); } pcm = new AudioPCMConfig(_bitsPerSample, _channelCount, _sampleRate, (AudioPCMConfig.SpeakerConfig)_channelMask); if (pcm.BlockAlign != _blockAlign) { throw new Exception("WAVE has strange BlockAlign"); } } else if (ckID == fccData) { foundData = true; _dataOffset = pos; if (!_IO.CanSeek || _IO.Length <= maxFileSize) { if (ckSize == 0 || ckSize >= 0x7fffffff) { _dataLen = -1; } else { _dataLen = (long)ckSize; } } else { _largeFile = true; _dataLen = _IO.Length - pos; } } if ((foundFormat & foundData) || _largeFile) { break; } if (_IO.CanSeek) { _IO.Seek(ckEnd, SeekOrigin.Begin); } else { _br.ReadBytes((int)(ckEnd - pos)); } pos = ckEnd; } while (true); if ((foundFormat & foundData) == false || pcm == null) { throw new Exception("Format or data chunk not found."); } if (pcm.ChannelCount <= 0) { throw new Exception("Channel count is invalid."); } if (pcm.SampleRate <= 0) { throw new Exception("Sample rate is invalid."); } if ((pcm.BitsPerSample <= 0) || (pcm.BitsPerSample > 32)) { throw new Exception("Bits per sample is invalid."); } if (pos != _dataOffset) { Position = 0; } }
public AudioBuffer(IAudioSource source, int _size) { pcm = source.PCM; size = _size; }
public AudioBuffer(AudioPCMConfig _pcm, byte[] _bytes, int _length) { pcm = _pcm; Prepare(_bytes, _length); }
public AudioBuffer(AudioPCMConfig _pcm, int[,] _samples, int _length) { pcm = _pcm; // assert _samples.GetLength(1) == pcm.ChannelCount Prepare(_samples, _length); }
public AudioBuffer(AudioPCMConfig _pcm, int _size) { pcm = _pcm; size = _size; length = 0; }