private PortAudioSharp.PortAudio.PaStreamCallbackResult _MyPaStreamCallback( IntPtr input, IntPtr output, uint frameCount, ref PortAudioSharp.PortAudio.PaStreamCallbackTimeInfo timeInfo, PortAudioSharp.PortAudio.PaStreamCallbackFlags statusFlags, IntPtr userData) { try { if (frameCount > 0 && input != IntPtr.Zero) { CRecordDevice dev = _Devices[userData.ToInt32()]; uint numBytes; numBytes = frameCount * (uint)dev.Channels * 2; byte[] recbuffer = new byte[numBytes]; // copy from managed to unmanaged memory Marshal.Copy(input, recbuffer, 0, (int)numBytes); _HandleData(dev, recbuffer); } } catch (Exception e) { CLog.LogError("Error on Stream Callback (rec): " + e); } return(PortAudioSharp.PortAudio.PaStreamCallbackResult.paContinue); }
PortAudio.PaStreamCallbackResult PullAudio(System.IntPtr input, System.IntPtr output, uint frameCount, ref PortAudioSharp.PortAudio.PaStreamCallbackTimeInfo timeInfo, PortAudioSharp.PortAudio.PaStreamCallbackFlags statusFlags, System.IntPtr userData) { uint length = frameCount; //System.Runtime.InteropServices.Marshal.WriteInt16 if ((!IsRunning) && (Buffers.Count < 1)) { Log(LogLevel.Debug, "Not running and no buffers left"); Player.Stop(); if (Eof) { _AudioFinished(); } return(PortAudio.PaStreamCallbackResult.paAbort); } else { int pos = 0; if (Buffers.Count < 1) { //Log(LogLevel.Warning, "Buffer underrun, {0} bytes requested",length); return(PortAudio.PaStreamCallbackResult.paContinue); } else { int copied = 0; while ((copied < length) && (Buffers.Count > 0)) { byte[] buf = Buffers.Peek(); int toCopy = (int)length - copied; int availCopy = Math.Min(buf.Length - bufPos, toCopy); System.Runtime.InteropServices.Marshal.Copy(buf, bufPos, output, availCopy); copied += availCopy; bufPos += availCopy; // pos += availCopy; output = (IntPtr)((int)output + availCopy); if (bufPos >= buf.Length) { //Log(LogLevel.Debug, "End of queued buffer ({0} bytes)", buf.Length); Buffers.Dequeue(); bufPos = 0; } } //Log(LogLevel.Debug, "Copied {0} bytes into {1} byte device buffer", copied, length); /*if ((length>copied) && (!Eof) && (IsRunning)) * Log(LogLevel.Warning, "Buffer underrun, {0} bytes short", length-copied);*/ } return(PortAudio.PaStreamCallbackResult.paContinue); } }
private PortAudioSharp.PortAudio.PaStreamCallbackResult _ProcessNewData( IntPtr input, IntPtr output, uint frameCount, ref PortAudioSharp.PortAudio.PaStreamCallbackTimeInfo timeInfo, PortAudioSharp.PortAudio.PaStreamCallbackFlags statusFlags, IntPtr userData) { var buf = new byte[frameCount * _ByteCount]; if (_Paused) { try { Marshal.Copy(buf, 0, output, buf.Length); } catch (Exception e) { Console.WriteLine(e.ToString()); } return(PortAudioSharp.PortAudio.PaStreamCallbackResult.paContinue); } lock (_LockData) { int dataLen = _Data.BytesNotRead; if ((_NoMoreData && dataLen > 0) || dataLen >= buf.Length) { dataLen = Math.Min(dataLen, buf.Length); _Data.Read(buf); //We want to scale all values. No matter how many channels we have (_ByteCount=2 or 4) we have short values //So just process 2 bytes a time float volume = Volume * VolumeMax; for (int i = 0; i < dataLen; i += 2) { byte[] b = BitConverter.GetBytes((Int16)(BitConverter.ToInt16(buf, i) * volume)); buf[i] = b[0]; buf[i + 1] = b[1]; } float latency = buf.Length / _BytesPerSecond + _Latency; float time = _TimeCode - _Data.BytesNotRead / _BytesPerSecond - latency; _SyncTimer.Update(time); } if (_Data.BytesNotRead < _BeginRefill && !_NoMoreData) { _EventDecode.Set(); } } try { Marshal.Copy(buf, 0, output, (int)frameCount * _ByteCount); } catch (Exception e) { CLog.Error("Error PortAudio.StreamCallback: " + e.Message); } return(PortAudioSharp.PortAudio.PaStreamCallbackResult.paContinue); }