private IEnumerator <ArraySegment <byte> > ReadFlac(FlacReader reader) { try { while (reader.Read()) { if (reader.RecordType == FlacRecordType.MetadataBlock && reader.MetadataBlockType == FlacMetadataBlockType.Streaminfo) { streaminfo = reader.Streaminfo; ValidateBitPerSample(streaminfo.BitsPerSample); ValidateTotalSamples(streaminfo.TotalSampleCount); InitializeHelpers(reader); byte[] waveHeader = CreateWaveHeader(); yield return(new ArraySegment <byte>(waveHeader)); } else if (reader.RecordType == FlacRecordType.Frame) { yield return(ReadFrame(reader)); } } } finally { reader.Close(); } }
private IEnumerator <ArraySegment <byte> > ReadFlacSpliter(FlacStreaminfo info, Stream body) { IFlacReader reader = null; try { streaminfo = info; ValidateBitPerSample(streaminfo.BitsPerSample); ValidateTotalSamples(streaminfo.TotalSampleCount); reader = new FlacSpliteReader(streaminfo, body, true); InitializeHelpers(reader); while (reader.Read()) { if (reader.RecordType == FlacRecordType.Frame) { yield return(ReadFrame(reader)); } } } finally { if (reader != null) { reader.Close(); } } }
private void ReadStreaminfo(int metadataBlockLength) { const int Md5Length = FlacCommons.Md5Length; const int Md5Offset = FlacCommons.StreaminfoMetadataBlockLengh - Md5Length; if (metadataBlockLength < FlacCommons.StreaminfoMetadataBlockLengh) { throw new FlacException("Invalid STREAMINFO block size"); } byte[] data = ReadExactly(metadataBlockLength); FlacStreaminfo streaminfo = new FlacStreaminfo(); streaminfo.MinBlockSize = data[0] << 8 | data[1]; streaminfo.MaxBlockSize = data[2] << 8 | data[3]; streaminfo.MinFrameSize = data[4] << 16 | data[5] << 8 | data[6]; streaminfo.MaxFrameSize = data[7] << 16 | data[8] << 8 | data[9]; streaminfo.SampleRate = (data[10] << 16 | data[11] << 8 | data[12]) >> 4; streaminfo.ChannelsCount = ((data[12] >> 1) & 0x07) + 1; streaminfo.BitsPerSample = ((data[12] & 0x01) << 4 | (data[13] >> 4)) + 1; streaminfo.TotalSampleCount = ((long)(data[13] & 0x0F)) << 32 | (long)data[14] << 24 | (uint)(data[15] << 16 | data[16] << 8 | data[17]); streaminfo.MD5 = new byte[Md5Length]; Array.Copy(data, Md5Offset, streaminfo.MD5, 0, Md5Length); this.streaminfo = streaminfo; }
public void EndStream() { if (bufferSize > 0) { FlushBuffer(); } buffer = null; this.streaminfo = null; }
public WaveOverFlacStream(FlacStreaminfo info, Stream Body) { if (Body == null) { throw new ArgumentNullException("reader"); } this.dataSource = ReadFlacSpliter(info, Body); this.mode = WaveOverFlacStreamMode.Decode; }
public override void Write(byte[] buffer, int offset, int count) { int[] samples = new int[count * 8 / bitsPerSample]; if (bitsPerSample == 8) { for (int i = 0; i < count; i++) { samples[i] = buffer[offset + i]; } } else { unsafe { if (offset + count > buffer.Length) throw new IndexOutOfRangeException(); fixed(byte *rawdata = buffer) { if (bitsPerSample == 16) { short *data = (short *)(rawdata + offset); for (int i = 0; i < count / 2; i++) { samples[i] = data[i]; } } else if (bitsPerSample == 32) { int *data = (int *)(rawdata + offset); for (int i = 0; i < count / 4; i++) { samples[i] = data[i]; } } } } } var streaminfo = new FlacBox.FlacStreaminfo(); streaminfo.ChannelsCount = 1; streaminfo.SampleRate = 44100; streaminfo.BitsPerSample = 16; streaminfo.MinBlockSize = 4608; streaminfo.MaxBlockSize = 4608; writer.StartStreamNoHeader(streaminfo); writer.WriteSamples(samples); writer.EndStream(); }
public void StartStream(FlacStreaminfo streaminfo, FlacEncodingPolicy policy) { if (policy == null) { throw new ArgumentNullException("policy"); } policy.Validate(); if (streaminfo == null) { throw new ArgumentNullException("baseStream"); } this.streaminfo = streaminfo; InitializeEstimation(policy); InitializeBuffer(); WriteFlacHeader(); metaWriter = new StreaminfoWriter(streaminfo); }
public StreaminfoWriter(FlacStreaminfo streaminfo) { this.streaminfo = streaminfo; }
private IEnumerator<ArraySegment<byte>> ReadFlac(FlacReader reader) { try { while (reader.Read()) { if (reader.RecordType == FlacRecordType.MetadataBlock && reader.MetadataBlockType == FlacMetadataBlockType.Streaminfo) { streaminfo = reader.Streaminfo; ValidateBitPerSample(streaminfo.BitsPerSample); ValidateTotalSamples(streaminfo.TotalSampleCount); InitializeHelpers(reader); byte[] waveHeader = CreateWaveHeader(); yield return new ArraySegment<byte>( waveHeader ); } else if (reader.RecordType == FlacRecordType.Frame) { yield return ReadFrame(reader); } } } finally { reader.Close(); } }
public void StartStream(FlacStreaminfo streaminfo) { StartStream(streaminfo, FlacEncodingPolicy.CreateFromLevel(DefaultEncodingPolicyLevel)); }
public void StartStream(FlacStreaminfo streaminfo, int level) { StartStream(streaminfo, FlacEncodingPolicy.CreateFromLevel(level)); }
private static void EstimateMinAndMaxFrameSize(FlacStreaminfo streaminfo) { // unknown streaminfo.MinFrameSize = 0; streaminfo.MaxFrameSize = 0; }
private void ReadStreaminfo(int metadataBlockLength) { const int Md5Length = FlacCommons.Md5Length; const int Md5Offset = FlacCommons.StreaminfoMetadataBlockLengh - Md5Length; if (metadataBlockLength < FlacCommons.StreaminfoMetadataBlockLengh) throw new FlacException("Invalid STREAMINFO block size"); byte[] data = ReadExactly(metadataBlockLength); FlacStreaminfo streaminfo = new FlacStreaminfo(); streaminfo.MinBlockSize = data[0] << 8 | data[1]; streaminfo.MaxBlockSize = data[2] << 8 | data[3]; streaminfo.MinFrameSize = data[4] << 16 | data[5] << 8 | data[6]; streaminfo.MaxFrameSize = data[7] << 16 | data[8] << 8 | data[9]; streaminfo.SampleRate = (data[10] << 16 | data[11] << 8 | data[12]) >> 4; streaminfo.ChannelsCount = ((data[12] >> 1) & 0x07) + 1; streaminfo.BitsPerSample = ((data[12] & 0x01) << 4 | (data[13] >> 4)) + 1; streaminfo.TotalSampleCount = ((long)(data[13] & 0x0F)) << 32 | (long)data[14] << 24 | (uint)(data[15] << 16 | data[16] << 8 | data[17]); streaminfo.MD5 = new byte[Md5Length]; Array.Copy(data, Md5Offset, streaminfo.MD5, 0, Md5Length); this.streaminfo = streaminfo; }
private IEnumerator<WriteRequest> WriteFlac(FlacWriter writer, int compressionLevel) { try { const int RiffHeaderLength = 12; const int RiffBlockHeaderLength = 8; const int MinFormatLength = 16; const int MaxFormatLength = 128; WriteRequest request = new WriteRequest(); byte[] waveHeader = new byte[RiffHeaderLength]; ArraySegment<byte> buffer = new ArraySegment<byte>(waveHeader); do { yield return request; if (!request.IsDataPresent) throw new FlacException("RIFF header is expected"); } while (FillBuffer(ref buffer, request)); if (waveHeader[0] != 'R' || waveHeader[1] != 'I' || waveHeader[2] != 'F' || waveHeader[3] != 'F' || waveHeader[8] != 'W' || waveHeader[9] != 'A' || waveHeader[10] != 'V' || waveHeader[11] != 'E') throw new FlacException("RIFF and WAVE header are expected"); long totalStreamLength = BitConverter.ToUInt32(waveHeader, 4); do { byte[] blockHeader = new byte[RiffBlockHeaderLength]; buffer = new ArraySegment<byte>(blockHeader); while (FillBuffer(ref buffer, request)) { yield return request; if (!request.IsDataPresent) throw new FlacException("RIFF block expected"); } if (blockHeader[0] == 'f' && blockHeader[1] == 'm' && blockHeader[2] == 't' && blockHeader[3] == ' ') { int formatBlockSize = BitConverter.ToInt32(blockHeader, 4); if (formatBlockSize < MinFormatLength || formatBlockSize > MaxFormatLength) throw new FlacException("Invalid format block size"); byte[] formatBlock = new byte[formatBlockSize]; buffer = new ArraySegment<byte>(formatBlock); while (FillBuffer(ref buffer, request)) { yield return request; if (!request.IsDataPresent) throw new FlacException("format block expected"); } if(BitConverter.ToUInt16(formatBlock, 0) != 1) throw new FlacException("Unsupported alignment in WAVE"); FlacStreaminfo streaminfo = new FlacStreaminfo(); streaminfo.ChannelsCount = BitConverter.ToUInt16(formatBlock, 2); streaminfo.SampleRate = BitConverter.ToInt32(formatBlock, 4); streaminfo.BitsPerSample = BitConverter.ToUInt16(formatBlock, 14); streaminfo.MinBlockSize = FlacCommons.DefaultBlockSize; streaminfo.MaxBlockSize = FlacCommons.DefaultBlockSize; EstimateMinAndMaxFrameSize(streaminfo); this.streaminfo = streaminfo; } else if (blockHeader[0] == 'd' && blockHeader[1] == 'a' && blockHeader[2] == 't' && blockHeader[3] == 'a') { uint dataBlockSize = BitConverter.ToUInt32(blockHeader, 4); if (streaminfo == null) throw new FlacException("Format block was not found"); int bytesPerInterChannelSample = (streaminfo.ChannelsCount * streaminfo.BitsPerSample) >> 3; long totalSamples = dataBlockSize / bytesPerInterChannelSample; streaminfo.TotalSampleCount = totalSamples; sampleTransform = WaveSampleTransformerFactory.CreateWaveSampleTransformer(streaminfo.BitsPerSample); try { writer.StartStream(streaminfo); int samplesInBuffer = streaminfo.MaxBlockSize; pcmBuffer = new byte[bytesPerInterChannelSample * samplesInBuffer]; long currentSample = 0; int[] samples = new int[streaminfo.ChannelsCount * samplesInBuffer]; while (currentSample + samplesInBuffer <= totalSamples) { buffer = new ArraySegment<byte>(pcmBuffer); while (FillBuffer(ref buffer, request)) { yield return request; if (!request.IsDataPresent) throw new FlacException("data block expected"); } sampleTransform.UnpackData(pcmBuffer, samples); writer.WriteSamples(samples); currentSample += samplesInBuffer; } if (currentSample < totalSamples) { int samplesLeft = (int)(totalSamples - currentSample); buffer = new ArraySegment<byte>(pcmBuffer, 0, bytesPerInterChannelSample * samplesLeft); while (FillBuffer(ref buffer, request)) { yield return request; if (!request.IsDataPresent) throw new FlacException("data block expected"); } samples = new int[streaminfo.ChannelsCount * samplesLeft]; sampleTransform.UnpackData(pcmBuffer, samples); writer.WriteSamples(samples); } } finally { writer.EndStream(); } break; } else // otherwise skip { uint dataBlockSize = BitConverter.ToUInt32(blockHeader, 4); byte[] extraData = new byte[(int)dataBlockSize]; buffer = new ArraySegment<byte>(extraData); while (FillBuffer(ref buffer, request)) { yield return request; if (!request.IsDataPresent) throw new FlacException("extra data is expected"); } } } while (request.IsDataPresent); } finally { writer.Close(); } }
public FlacSpliteReader(FlacStreaminfo info, Stream baseStream, bool leaveOpen) { this.streaminfo = info; this.baseStream = baseStream; this.leaveOpen = leaveOpen; }
public void EndStream() { if (bufferSize > 0) FlushBuffer(); buffer = null; this.streaminfo = null; }
public void StartStream(FlacStreaminfo streaminfo, FlacEncodingPolicy policy) { if (policy == null) throw new ArgumentNullException("policy"); policy.Validate(); if (streaminfo == null) throw new ArgumentNullException("baseStream"); this.streaminfo = streaminfo; InitializeEstimation(policy); InitializeBuffer(); WriteFlacHeader(); metaWriter = new StreaminfoWriter(streaminfo); }
private IEnumerator <WriteRequest> WriteFlac(FlacWriter writer, int compressionLevel) { try { const int RiffHeaderLength = 12; const int RiffBlockHeaderLength = 8; const int MinFormatLength = 16; const int MaxFormatLength = 128; WriteRequest request = new WriteRequest(); byte[] waveHeader = new byte[RiffHeaderLength]; ArraySegment <byte> buffer = new ArraySegment <byte>(waveHeader); do { yield return(request); if (!request.IsDataPresent) { throw new FlacException("RIFF header is expected"); } } while (FillBuffer(ref buffer, request)); if (waveHeader[0] != 'R' || waveHeader[1] != 'I' || waveHeader[2] != 'F' || waveHeader[3] != 'F' || waveHeader[8] != 'W' || waveHeader[9] != 'A' || waveHeader[10] != 'V' || waveHeader[11] != 'E') { throw new FlacException("RIFF and WAVE header are expected"); } long totalStreamLength = BitConverter.ToUInt32(waveHeader, 4); do { byte[] blockHeader = new byte[RiffBlockHeaderLength]; buffer = new ArraySegment <byte>(blockHeader); while (FillBuffer(ref buffer, request)) { yield return(request); if (!request.IsDataPresent) { throw new FlacException("RIFF block expected"); } } if (blockHeader[0] == 'f' && blockHeader[1] == 'm' && blockHeader[2] == 't' && blockHeader[3] == ' ') { int formatBlockSize = BitConverter.ToInt32(blockHeader, 4); if (formatBlockSize < MinFormatLength || formatBlockSize > MaxFormatLength) { throw new FlacException("Invalid format block size"); } byte[] formatBlock = new byte[formatBlockSize]; buffer = new ArraySegment <byte>(formatBlock); while (FillBuffer(ref buffer, request)) { yield return(request); if (!request.IsDataPresent) { throw new FlacException("format block expected"); } } if (BitConverter.ToUInt16(formatBlock, 0) != 1) { throw new FlacException("Unsupported alignment in WAVE"); } FlacStreaminfo streaminfo = new FlacStreaminfo(); streaminfo.ChannelsCount = BitConverter.ToUInt16(formatBlock, 2); streaminfo.SampleRate = BitConverter.ToInt32(formatBlock, 4); streaminfo.BitsPerSample = BitConverter.ToUInt16(formatBlock, 14); streaminfo.MinBlockSize = FlacCommons.DefaultBlockSize; streaminfo.MaxBlockSize = FlacCommons.DefaultBlockSize; EstimateMinAndMaxFrameSize(streaminfo); this.streaminfo = streaminfo; } else if (blockHeader[0] == 'd' && blockHeader[1] == 'a' && blockHeader[2] == 't' && blockHeader[3] == 'a') { uint dataBlockSize = BitConverter.ToUInt32(blockHeader, 4); if (streaminfo == null) { throw new FlacException("Format block was not found"); } int bytesPerInterChannelSample = (streaminfo.ChannelsCount * streaminfo.BitsPerSample) >> 3; long totalSamples = dataBlockSize / bytesPerInterChannelSample; streaminfo.TotalSampleCount = totalSamples; sampleTransform = WaveSampleTransformerFactory.CreateWaveSampleTransformer(streaminfo.BitsPerSample); try { writer.StartStream(streaminfo); int samplesInBuffer = streaminfo.MaxBlockSize; pcmBuffer = new byte[bytesPerInterChannelSample * samplesInBuffer]; long currentSample = 0; int[] samples = new int[streaminfo.ChannelsCount * samplesInBuffer]; while (currentSample + samplesInBuffer <= totalSamples) { buffer = new ArraySegment <byte>(pcmBuffer); while (FillBuffer(ref buffer, request)) { yield return(request); if (!request.IsDataPresent) { throw new FlacException("data block expected"); } } sampleTransform.UnpackData(pcmBuffer, samples); writer.WriteSamples(samples); currentSample += samplesInBuffer; } if (currentSample < totalSamples) { int samplesLeft = (int)(totalSamples - currentSample); buffer = new ArraySegment <byte>(pcmBuffer, 0, bytesPerInterChannelSample * samplesLeft); while (FillBuffer(ref buffer, request)) { yield return(request); if (!request.IsDataPresent) { throw new FlacException("data block expected"); } } samples = new int[streaminfo.ChannelsCount * samplesLeft]; sampleTransform.UnpackData(pcmBuffer, samples); writer.WriteSamples(samples); } } finally { writer.EndStream(); } break; } else // otherwise skip { uint dataBlockSize = BitConverter.ToUInt32(blockHeader, 4); byte[] extraData = new byte[(int)dataBlockSize]; buffer = new ArraySegment <byte>(extraData); while (FillBuffer(ref buffer, request)) { yield return(request); if (!request.IsDataPresent) { throw new FlacException("extra data is expected"); } } } } while (request.IsDataPresent); } finally { writer.Close(); } }