private void WritePCM16(float *data, int length) { if (_outputBuffer == null || _outputBuffer.Length != (length * sizeof(Int16))) { _outputBuffer = null; _outputBuffer = new byte[length * sizeof(Int16)]; } var ptr = data; for (var i = 0; i < length; i++) { var average = (Int16)(((*ptr++ + *ptr++) / 2) * 32767.0f); _outputBuffer[(i * 2)] = (byte)(average & 0x00ff); _outputBuffer[(i * 2) + 1] = (byte)(average >> 8); } int buffer_length = length * sizeof(Int16); System.Buffer.BlockCopy(_outputBuffer, 0, resampleStream.SourceBuffer, 0, buffer_length); int sourceBytesConverted = 0; var convertedBytes = resampleStream.Convert(buffer_length, out sourceBytesConverted); if (sourceBytesConverted != buffer_length) { Console.WriteLine("We didn't convert everything"); } TrxwaveFile.Write(resampleStream.DestBuffer, 0, convertedBytes); }
protected override byte[] ProcessRecordedData(byte[] recorded, int offset, int count) { lock (lockObject) { int sourceSamples = count / 4; int outSamples = sourceSamples; byte[] sourceBuffer = new byte[sourceSamples * 4]; Buffer.BlockCopy(recorded, offset, sourceBuffer, 0, sourceSamples * 4); byte[] outBuffer = new byte[outSamples * 2]; WaveBuffer sourceWaveBuffer = new WaveBuffer(sourceBuffer); WaveBuffer destWaveBuffer = new WaveBuffer(outBuffer); int destOffset = 0; for (int sample = 0; sample < sourceSamples; sample++) { #region 32 bit float to 16bit short, same channels float sample32 = sourceWaveBuffer.FloatBuffer[sample] * 1.0f; // clip if (sample32 > 1.0f) { sample32 = 1.0f; } if (sample32 < -1.0f) { sample32 = -1.0f; } destWaveBuffer.ShortBuffer[destOffset++] = (short)(sample32 * Int16.MaxValue); #endregion #region 32 bit float to 16bit short, combine left and right channels // adjust volume //float leftSample32 = sourceWaveBuffer.FloatBuffer[sample] * 1.0f; // clip //if (leftSample32 > 1.0f) // leftSample32 = 1.0f; //if (leftSample32 < -1.0f) // leftSample32 = -1.0f; //float rightSample32 = sourceWaveBuffer.FloatBuffer[sample + 1] * 1.0f; //if (rightSample32 > 1.0f) // rightSample32 = 1.0f; //if (rightSample32 < -1.0f) // rightSample32 = -1.0f; //short spl = (short)(((leftSample32 * Int16.MaxValue) + (int)(rightSample32 * Int16.MaxValue)) / 2); //destWaveBuffer.ShortBuffer[destOffset++] = spl; #endregion } Array.Copy(destWaveBuffer.ByteBuffer, convertionStream.SourceBuffer, outSamples * 2); int converted = convertionStream.Convert(outSamples * 2); converted -= converted % 4; byte[] result = new byte[converted]; Array.Copy(convertionStream.DestBuffer, result, converted); return(base.ProcessRecordedData(result, 0, converted)); } }
private static byte[] ResamplePcm(ref byte[] toResample, ref int sourceLength, WaveFormat sourceFormat, WaveFormat destPcmFormat, out int resultLength) { Debug.Assert(destPcmFormat.Encoding == WaveFormatEncoding.Pcm, "Codec format must be PCM"); if (resampleRateStream != null && (!lastResampleSourceFormat.Equals(sourceFormat) || !lastResampleDestFormat.Equals(destPcmFormat))) { resampleRateStream.Dispose(); resampleRateStream = null; } if (resampleRateStream == null) { WaveFormat sourceRateFormat = new WaveFormat(sourceFormat.SampleRate, sourceFormat.BitsPerSample, destPcmFormat.Channels); resampleRateStream = new AcmStream(sourceRateFormat, destPcmFormat); if (sourceFormat.Channels != destPcmFormat.Channels) { WaveFormat destChanFormat = new WaveFormat(sourceFormat.SampleRate, sourceFormat.BitsPerSample, destPcmFormat.Channels); if (resampleChannelStream != null) { resampleChannelStream.Dispose(); } resampleChannelStream = new AcmStream(sourceFormat, destChanFormat); } lastResampleSourceFormat = sourceFormat; lastResampleDestFormat = destPcmFormat; } int bytesConverted; if (sourceFormat.Channels != destPcmFormat.Channels) { if (destPcmFormat.Channels == 1 && sourceFormat.Channels == 2) { toResample = MixStereoToMono(toResample, sourceLength); sourceLength = toResample.Length; } else { Buffer.BlockCopy(toResample, 0, resampleChannelStream.SourceBuffer, 0, sourceLength); sourceLength = resampleChannelStream.Convert(sourceLength, out bytesConverted); if (bytesConverted >> 1 != sourceLength) { Console.WriteLine("WARNING: All input bytes were not converted."); } toResample = resampleChannelStream.DestBuffer; } } Buffer.BlockCopy(toResample, 0, resampleRateStream.SourceBuffer, 0, sourceLength); resultLength = resampleRateStream.Convert(sourceLength, out bytesConverted); if (bytesConverted != sourceLength) { Console.WriteLine("WARNING: All input bytes were not converted."); return(null); } return(resampleRateStream.DestBuffer); }
public static async Task ConvertForDiscord(byte[] audiodata, int sampleRate, int channels, VoiceTransmitSink discordTarget, ILogger logger) { var resampleStream = new AcmStream(new WaveFormat(sampleRate, 16, 1), new WaveFormat(OutSampleRate, 16, 1)); if (audiodata.Length > resampleStream.SourceBuffer.Length) { int offset = 0; logger.LogInformation("Large audio returned, the copy will need to be streamed in"); int remaining = (audiodata.Length - offset); while (remaining > 0) { Array.Clear(resampleStream.SourceBuffer, 0, resampleStream.SourceBuffer.Length); Array.Clear(resampleStream.DestBuffer, 0, resampleStream.DestBuffer.Length); int copyamount = remaining > resampleStream.SourceBuffer.Length ? resampleStream.SourceBuffer.Length : remaining; Buffer.BlockCopy(audiodata, offset, resampleStream.SourceBuffer, 0, copyamount); int sourceBytesConverted = 0; // logger.LogInformation("Resampling"); var convertedBytes = resampleStream.Convert(copyamount, out sourceBytesConverted); if (sourceBytesConverted != copyamount) { logger.LogError("Resample didn't produce correct bytestream"); break; } await discordTarget.WriteAsync(resampleStream.DestBuffer); offset += copyamount; remaining = (audiodata.Length - offset); } } else { Buffer.BlockCopy(audiodata, 0, resampleStream.SourceBuffer, 0, audiodata.Length); int sourceBytesConverted = 0; // logger.LogInformation("Resampling"); var convertedBytes = resampleStream.Convert(audiodata.Length, out sourceBytesConverted); if (sourceBytesConverted != audiodata.Length) { logger.LogError("Resample didn't produce correct bytestream"); } await discordTarget.WriteAsync(resampleStream.DestBuffer); } }
private void WritePCM16(float *data, int length) { if (_outputBuffer == null || _outputBuffer.Length != (length * sizeof(Int16))) { _outputBuffer = null; _outputBuffer = new byte[length * sizeof(Int16)]; } var ptr = data; for (var i = 0; i < length; i++) { var average = (Int16)(((*ptr++ + *ptr++) / 2) * 32767.0f); _outputBuffer[(i * 2)] = (byte)(average & 0x00ff); _outputBuffer[(i * 2) + 1] = (byte)(average >> 8); } int buffer_length = length * sizeof(Int16); System.Buffer.BlockCopy(_outputBuffer, 0, resampleStream.SourceBuffer, 0, buffer_length); int sourceBytesConverted = 0; var convertedBytes = resampleStream.Convert(buffer_length, out sourceBytesConverted); if (sourceBytesConverted != buffer_length) { Console.WriteLine("We didn't convert everything"); } var converted = new byte[convertedBytes]; System.Buffer.BlockCopy(resampleStream.DestBuffer, 0, converted, 0, convertedBytes); int counter = 0; byte[] packet = new byte[MAX_PAYLOAD]; var TxStream = new WaveFormat(48000, 16, 1); for (var i = 0; i < convertedBytes; i++) { if (counter == MAX_PAYLOAD) { _udpClient.Send(packet, counter, _udpEP); MarkAndWait(counter, TxStream.AverageBytesPerSecond); counter = 0; } packet[counter] = converted[i]; counter++; } if (counter > 0) { counter--; _udpClient.Send(packet, counter, _udpEP); MarkAndWait(counter, TxStream.AverageBytesPerSecond); } }
public int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset) { Array.Copy(frame.RawData, conversionStream.SourceBuffer, frame.FrameLength); int sourceBytesConverted = 0; int converted = conversionStream.Convert(frame.FrameLength, out sourceBytesConverted); if (sourceBytesConverted != frame.FrameLength) { throw new InvalidOperationException("Couldn't convert the whole MP3 frame"); } Array.Copy(conversionStream.DestBuffer, 0, dest, destOffset, converted); return(converted); }
private static byte[] Convert(AcmStream conversionStream, byte[] data, int offset, int length, ref int sourceBytesLeftovers) { int bytesInSourceBuffer = length + sourceBytesLeftovers; Array.Copy(data, offset, conversionStream.SourceBuffer, sourceBytesLeftovers, length); int bytesConverted = conversionStream.Convert(bytesInSourceBuffer, out var sourceBytesConverted); sourceBytesLeftovers = bytesInSourceBuffer - sourceBytesConverted; if (sourceBytesLeftovers > 0) { Array.Copy(conversionStream.SourceBuffer, sourceBytesConverted, conversionStream.SourceBuffer, 0, sourceBytesLeftovers); } byte[] encoded = new byte[bytesConverted]; Array.Copy(conversionStream.DestBuffer, 0, encoded, 0, bytesConverted); return(encoded); }
public void ProcessSamples(bool bHasAudio, byte[] samples) { if (samples == null || samples.Length <= 0) { return; } if (bHasAudio) { KickRecording(AudioKickState.Kick); } if (_recordingEnabled && _waveWriter != null) { if (_useResampler) { Buffer.BlockCopy(samples, 0, _resampleStream.SourceBuffer, 0, samples.Length); int sourceBytesConverted = 0; int convertedBytes = _resampleStream.Convert(samples.Length, out sourceBytesConverted); if (sourceBytesConverted == samples.Length) { byte[] convBytes = new byte[convertedBytes]; Buffer.BlockCopy(_resampleStream.DestBuffer, 0, convBytes, 0, convertedBytes); _waveWriter.Write(convBytes, 0, convBytes.Length); } } else { _waveWriter.Write(samples, 0, samples.Length); } } long curTicks = DateTime.Now.Ticks; if (_currentKickState == AudioKickState.On) { if (_forceOnEndTicks == 0 || _forceOnEndTicks < curTicks) { _forceOnEndTicks = 0; _endTicks = curTicks + RecordingKickTimeTicks; _currentKickState = AudioKickState.Kick; } } else if (!_recordingEnabled || (_endTicks == 0) || (_currentKickState == AudioKickState.Kick && _endTicks < DateTime.Now.Ticks)) { EndRecording(); } }
/// <summary> /// Decompresses a frame /// </summary> /// <param name="frame">The MP3 frame</param> /// <param name="dest">destination buffer</param> /// <param name="destOffset">Offset within destination buffer</param> /// <returns>Bytes written into destination buffer</returns> public int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset) { if (frame == null) { throw new ArgumentNullException("frame", "You must provide a non-null Mp3Frame to decompress"); } Array.Copy(frame.RawData, conversionStream.SourceBuffer, frame.FrameLength); int converted = conversionStream.Convert(frame.FrameLength, out int sourceBytesConverted); if (sourceBytesConverted != frame.FrameLength) { throw new InvalidOperationException(String.Format("Couldn't convert the whole MP3 frame (converted {0}/{1})", sourceBytesConverted, frame.FrameLength)); } Array.Copy(conversionStream.DestBuffer, 0, dest, destOffset, converted); return(converted); }
private async Task PlayAudioAsync(IAudioClient client) { var discord = client.CreatePCMStream(AudioApplication.Music); WasapiLoopbackCapture CaptureInstance = new WasapiLoopbackCapture(WasapiLoopbackCapture.GetDefaultLoopbackCaptureDevice()); CaptureInstance.DataAvailable += (s, a) => { //step 1 //var resampleStream = new AcmStream(WaveFormat.CreateCustomFormat(WaveFormatEncoding.IeeeFloat, 48000, 2, 384000, 8, 32), WaveFormat.CreateCustomFormat(WaveFormatEncoding.Pcm, 48000, 2, 16000, 8, 16)); var resampleStream = new AcmStream(new WaveFormat(41000, 16, 2), new WaveFormat(4800, 16, 2)); //causes demonic screeching //step 2 byte[] source = a.Buffer; Buffer.BlockCopy(source, 0, resampleStream.SourceBuffer, 0, a.BytesRecorded); //step 3 int sourceBytesConverted = 0; var convertedBytes = resampleStream.Convert(source.Length, out sourceBytesConverted); if (sourceBytesConverted != source.Length) { Console.WriteLine("We didn't convert everything {0} bytes in, {1} bytes converted"); } //step 4 var converted = new byte[convertedBytes]; Buffer.BlockCopy(resampleStream.DestBuffer, 0, converted, 0, convertedBytes); discord.Write(converted, 0, a.BytesRecorded); }; CaptureInstance.RecordingStopped += (s, a) => { Console.WriteLine("Stopped Recording!"); CaptureInstance.Dispose(); discord.Dispose(); }; CaptureInstance.StartRecording(); await Task.Delay(5000); CaptureInstance.StopRecording(); await Task.Delay(5000); }
private static byte[] Convert(AcmStream conversionStream, byte[] data, int offset, int length, ref int sourceBytesLeftovers) { int bytesInSourceBuffer = length + sourceBytesLeftovers; Array.Copy(data, offset, conversionStream.SourceBuffer, sourceBytesLeftovers, length); int bytesConverted = conversionStream.Convert(bytesInSourceBuffer, out var sourceBytesConverted); sourceBytesLeftovers = bytesInSourceBuffer - sourceBytesConverted; if (sourceBytesLeftovers > 0) { //Debug.WriteLine(String.Format("Asked for {0}, converted {1}", bytesInSourceBuffer, sourceBytesConverted)); // shift the leftovers down Array.Copy(conversionStream.SourceBuffer, sourceBytesConverted, conversionStream.SourceBuffer, 0, sourceBytesLeftovers); } byte[] encoded = new byte[bytesConverted]; Array.Copy(conversionStream.DestBuffer, 0, encoded, 0, bytesConverted); return(encoded); }
static void Main(string[] args) { var fi = new FileInfo(args[0]); var fn = fi.FullName; using (var wfr = new WaveFileReader(fn)) { var wf0 = wfr.WaveFormat; var wf1 = new WaveFormat(48000, 1); var size0 = wf0.AverageBytesPerSecond * RNNoiseCLR.FRAME_SIZE / 48000; var size1 = sizeof(short) * RNNoiseCLR.FRAME_SIZE; using (var acmr = new AcmStream(wf0, wf1)) using (var wfw = new WaveFileWriter(fn.Substring(0, fn.Length - fi.Extension.Length) + "_out" + fi.Extension, wf0)) using (var acmw = new AcmStream(wf1, wf0)) using (var rnn = new RNNoiseCLR()) { var samples = new short[RNNoiseCLR.FRAME_SIZE]; var _samples = new float[RNNoiseCLR.FRAME_SIZE]; int read; while ((read = wfr.Read(acmr.SourceBuffer, 0, size0)) > 0) { var converted = acmr.Convert(read, out _); for (var i = converted; i < size1; ++i) { acmr.DestBuffer[i] = 0; } Buffer.BlockCopy(acmr.DestBuffer, 0, samples, 0, size1); for (var i = 0; i < RNNoiseCLR.FRAME_SIZE; ++i) { _samples[i] = samples[i] * _32767; } rnn.Transform(_samples, _samples); for (var i = 0; i < RNNoiseCLR.FRAME_SIZE; ++i) { samples[i] = (short)(_samples[i] * 32767); } Buffer.BlockCopy(samples, 0, acmw.SourceBuffer, 0, converted); wfw.Write(acmw.DestBuffer, 0, acmw.Convert(converted, out _)); wfw.Flush(); } } } }
//private int leftoverSourceOffset = 0; /// <summary> /// Reads bytes from this stream /// </summary> /// <param name="buffer">Buffer to read into</param> /// <param name="offset">Offset in buffer to read into</param> /// <param name="count">Number of bytes to read</param> /// <returns>Number of bytes read</returns> public override int Read(byte[] buffer, int offset, int count) { int bytesRead = 0; if (count % BlockAlign != 0) { //throw new ArgumentException("Must read complete blocks"); count -= (count % BlockAlign); } while (bytesRead < count) { // first copy in any leftover destination bytes int readFromLeftoverDest = Math.Min(count - bytesRead, leftoverDestBytes); if (readFromLeftoverDest > 0) { Array.Copy(conversionStream.DestBuffer, leftoverDestOffset, buffer, offset + bytesRead, readFromLeftoverDest); leftoverDestOffset += readFromLeftoverDest; leftoverDestBytes -= readFromLeftoverDest; bytesRead += readFromLeftoverDest; } if (bytesRead >= count) { // we've fulfilled the request from the leftovers alone break; } // now we'll convert one full source buffer if (leftoverSourceBytes > 0) { // TODO: still to be implemented: see moving the source position back below: } // always read our preferred size, we can always keep leftovers for the next call to Read if we get // too much int sourceBytesRead = sourceStream.Read(conversionStream.SourceBuffer, 0, preferredSourceReadSize); if (sourceBytesRead == 0) { // we've reached the end of the input break; } int sourceBytesConverted; int destBytesConverted = conversionStream.Convert(sourceBytesRead, out sourceBytesConverted); if (sourceBytesConverted == 0) { Debug.WriteLine(String.Format("Warning: couldn't convert anything from {0}", sourceBytesRead)); // no point backing up in this case as we're not going to manage to finish playing this break; } else if (sourceBytesConverted < sourceBytesRead) { // cheat by backing up in the source stream (better to save the lefto sourceStream.Position -= (sourceBytesRead - sourceBytesConverted); } if (destBytesConverted > 0) { int bytesRequired = count - bytesRead; int toCopy = Math.Min(destBytesConverted, bytesRequired); // save leftovers if (toCopy < destBytesConverted) { leftoverDestBytes = destBytesConverted - toCopy; leftoverDestOffset = toCopy; } Array.Copy(conversionStream.DestBuffer, 0, buffer, bytesRead + offset, toCopy); bytesRead += toCopy; } else { // possible error here Debug.WriteLine(string.Format("sourceBytesRead: {0}, sourceBytesConverted {1}, destBytesConverted {2}", sourceBytesRead, sourceBytesConverted, destBytesConverted)); //Debug.Assert(false, "conversion stream returned nothing at all"); break; } } position += bytesRead; return(bytesRead); }
/// <summary> /// Reads bytes from this stream /// </summary> /// <param name="array">Buffer to read into</param> /// <param name="offset">Offset in array to read into</param> /// <param name="count">Number of bytes to read</param> /// <returns>Number of bytes read</returns> public override int Read(byte[] array, int offset, int count) { int bytesRead = 0; if (count % BlockAlign != 0) { //throw new ApplicationException("Must read complete blocks"); count -= (count % BlockAlign); } while (bytesRead < count) { int destBytesRequired = count - bytesRead; int sourceBytes = DestToSource(destBytesRequired); sourceBytes = Math.Min(conversionStream.SourceBuffer.Length, sourceBytes); // temporary fix for alignment problems // TODO: a better solution is to save any extra we convert for the next read /* MRH: ignore this for now - need to check ramifications * if (DestToSource(SourceToDest(sourceBytes)) != sourceBytes) * { * if (bytesRead == 0) * throw new ApplicationException("Not a one-to-one conversion"); * break; * }*/ int sourceBytesRead = sourceStream.Read(conversionStream.SourceBuffer, 0, sourceBytes); if (sourceBytesRead == 0) { break; } int silenceBytes = 0; if (sourceBytesRead % sourceStream.BlockAlign != 0) { // we have been returned something that cannot be converted - a partial // buffer. We will increase the size we supposedly read, and zero out // the end. sourceBytesRead -= (sourceBytesRead % sourceStream.BlockAlign); sourceBytesRead += sourceStream.BlockAlign; silenceBytes = SourceToDest(sourceStream.BlockAlign); } int sourceBytesConverted; int bytesConverted = conversionStream.Convert(sourceBytesRead, out sourceBytesConverted); if (sourceBytesConverted < sourceBytesRead) { // MRH: would normally throw an exception here // back up - is this the right thing to do, not sure sourceStream.Position -= (sourceBytesRead - sourceBytesConverted); } if (bytesConverted > 0) { position += bytesConverted; int availableSpace = array.Length - bytesRead - offset; int toCopy = Math.Min(bytesConverted, availableSpace); //System.Diagnostics.Debug.Assert(toCopy == bytesConverted); // TODO: save leftovers Array.Copy(conversionStream.DestBuffer, 0, array, bytesRead + offset, toCopy); bytesRead += toCopy; if (silenceBytes > 0) { // clear out the final bit Array.Clear(array, bytesRead - silenceBytes, silenceBytes); } } else { break; } } return(bytesRead); }
/// <summary> /// Reads bytes from this stream /// </summary> /// <param name="buffer">Buffer to read into</param> /// <param name="offset">Offset in buffer to read into</param> /// <param name="count">Number of bytes to read</param> /// <returns>Number of bytes read</returns> public int Read(byte[] buffer, int offset, int count) { int bytesRead = 0; if (count % WaveFormat.BlockAlign != 0) { //throw new ArgumentException("Must read complete blocks"); count -= (count % WaveFormat.BlockAlign); } while (bytesRead < count) { // first copy in any leftover destination bytes int readFromLeftoverDest = Math.Min(count - bytesRead, leftoverDestBytes); if (readFromLeftoverDest > 0) { Array.Copy(conversionStream.DestBuffer, leftoverDestOffset, buffer, offset + bytesRead, readFromLeftoverDest); leftoverDestOffset += readFromLeftoverDest; leftoverDestBytes -= readFromLeftoverDest; bytesRead += readFromLeftoverDest; } if (bytesRead >= count) { // we've fulfilled the request from the leftovers alone break; } // now we'll convert one full source buffer var sourceReadSize = Math.Min(preferredSourceReadSize, conversionStream.SourceBuffer.Length - leftoverSourceBytes); // always read our preferred size, we can always keep leftovers for the next call to Read if we get // too much int sourceBytesRead = sourceProvider.Read(conversionStream.SourceBuffer, leftoverSourceBytes, sourceReadSize); int sourceBytesAvailable = sourceBytesRead + leftoverSourceBytes; if (sourceBytesAvailable == 0) { // we've reached the end of the input break; } int sourceBytesConverted; int destBytesConverted = conversionStream.Convert(sourceBytesAvailable, out sourceBytesConverted); if (sourceBytesConverted == 0) { Debug.WriteLine(String.Format("Warning: couldn't convert anything from {0}", sourceBytesAvailable)); // no point backing up in this case as we're not going to manage to finish playing this break; } leftoverSourceBytes = sourceBytesAvailable - sourceBytesConverted; if (leftoverSourceBytes > 0) { // buffer.blockcopy is safe for overlapping copies Buffer.BlockCopy(conversionStream.SourceBuffer, sourceBytesConverted, conversionStream.SourceBuffer, 0, leftoverSourceBytes); } if (destBytesConverted > 0) { int bytesRequired = count - bytesRead; int toCopy = Math.Min(destBytesConverted, bytesRequired); // save leftovers if (toCopy < destBytesConverted) { leftoverDestBytes = destBytesConverted - toCopy; leftoverDestOffset = toCopy; } Array.Copy(conversionStream.DestBuffer, 0, buffer, bytesRead + offset, toCopy); bytesRead += toCopy; } else { // possible error here Debug.WriteLine(string.Format("sourceBytesRead: {0}, sourceBytesConverted {1}, destBytesConverted {2}", sourceBytesRead, sourceBytesConverted, destBytesConverted)); //Debug.Assert(false, "conversion stream returned nothing at all"); break; } } return(bytesRead); }
protected override void ProcessSamples(byte[] buffer, int offset, int count) { float[] samples = null; if (_silenceHelper != null) { samples = _silenceHelper.PreProcessSamplesToFloat(buffer, offset, count, _sourceFormat.BitsPerSample / 8, _sourceFormat.Encoding == WaveFormatEncoding.IeeeFloat); } base.ProcessSamples(buffer, offset, count); byte[] sampleBytes = null; if (_useResampler) { Buffer.BlockCopy(buffer, offset, _resampleStream.SourceBuffer, 0, count); int sourceBytesConverted = 0; int convertedBytes = _resampleStream.Convert(count, out sourceBytesConverted); if (sourceBytesConverted == count) { byte[] convBytes = new byte[convertedBytes]; Buffer.BlockCopy(_resampleStream.DestBuffer, 0, convBytes, 0, convertedBytes); sampleBytes = convBytes; } samples = null; } else { byte[] tmpBuffer; if (offset == 0) { tmpBuffer = buffer; } else { tmpBuffer = new byte[count]; Array.Copy(buffer, offset, tmpBuffer, 0, count); } sampleBytes = tmpBuffer; } bool bHasSound = _hasAudio; if (sampleBytes != null) { if (samples == null || samples.Length <= 0) { samples = BytesToFloatSamples(sampleBytes); } if (samples != null && samples.Length > 0) { bHasSound = _silenceHelper.HasSound; _recorder.ProcessSamples(bHasSound, sampleBytes); if (_mdc != null) { _mdc.ProcessSamples(samples, samples.Length, bHasSound); } if (_star != null) { _star.ProcessSamples(samples, samples.Length, bHasSound); } if (_rootDecoder != null) { _rootDecoder.ProcessSamples(samples, samples.Length, bHasSound); } } } if (bHasSound != _hasAudio) { _hasAudio = bHasSound; FirePropertyChanged(false); } }