public WaveOverFlacStream(FlacWriter writer, int compressionLevel) { if (writer == null) { throw new ArgumentNullException("writer"); } ValidateCompressionLevel(compressionLevel); this.dataConsumer = WriteFlac(writer, compressionLevel); this.dataConsumer.MoveNext(); this.mode = WaveOverFlacStreamMode.Encode; }
public WaveOverFlacStream(FlacWriter writer) : this(writer, FlacWriter.DefaultEncodingPolicyLevel) { }
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(); } }
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 WaveOverFlacStream(FlacWriter writer, int compressionLevel) { if (writer == null) throw new ArgumentNullException("writer"); ValidateCompressionLevel(compressionLevel); this.dataConsumer = WriteFlac(writer, compressionLevel); this.dataConsumer.MoveNext(); this.mode = WaveOverFlacStreamMode.Encode; }