DSPUtil.WaveWriter._next C# (CSharp) Method

_next() private method

private _next ( ISample sample, bool &err ) : ISample
sample ISample
err bool
return ISample
        private ISample _next(ISample sample, out bool err)
        {
            try
            {
                //            if (_gain == 0) Gain = 1;
                _sampleCount++;

                if (!_ignoreclipping && (_sampleCount % _sr == 0))
                {
                    // Every second, check for clipping and wind back the gain by 0.5dB if so
                    bool clipped = false;
                    for (int n = 0; n < _nc; n++)
                    {
                        if (_ditherProcessors[n].clipping)
                        {
                            clipped = true;
                        }
                    }
                    if (clipped)
                    {
                        // Reduce gain by 0.5dB to back off from clipping
                        Gain = _gain * 0.94406087628592338036438049660227;
                        //                            Trace.WriteLine("Gain {0} dB", MathUtil.dB(_gain));
                        for (int n = 0; n < _nc; n++)
                        {
                            _ditherProcessors[n].clipping = false;
                        }
                    }
                }

                for (int n = 0; n < _nc; n++)
                {
                    // dither processor does the float-to-PCM conversion
                    // (dither is not applied to 32-f output, only to PCM)
                    double val = sample[n];

                    if (_gain != 0 && !double.IsNaN(_gain))
                    {
                        val *= _gain;
                    }
                    if (_gains != null && !double.IsNaN(_gains[n]))
                    {
                        val *= _gains[n];
                    }

                    switch (_bitsPerSample)
                    {
                        case 8:
                            _w.Write((byte)(_ditherProcessors[n].process(val) + 127));
                            break;
                        case 16:
                            _w.Write((short)_ditherProcessors[n].process(val));
                            break;
                        case 24:
                            // Little-endian, signed 24-bit
                            int c = _ditherProcessors[n].process(val);
                            _w.Write((ushort)(c & 0xFFFF));
                            _w.Write((sbyte)(c >> 16 & 0xFF));
                            break;
                        case 32:
                            if (_audioFormat == WaveFormat.PCM || _audioFormat == WaveFormat.EXTENSIBLE)
                            {
                                _w.Write((int)_ditherProcessors[n].process(val));
                            }
                            else if (_audioFormat == WaveFormat.IEEE_FLOAT)
                            {
                                // Internals are double; just cast to float and discard any extra resolution
                                // (really we should dither here too, to approx 24 bits?)
                                _w.Write((float)val);
                            }
                            break;
                        case 64:
                            // we only do float, not PCM, 64-bits
                            _w.Write((double)val);
                            break;
                        default:
                            throw new Exception(String.Format("Bits per sample cannot be {0}", BitsPerSample));
                    }
                }

                err = false;
                if (_isConsole)
                {
                    // Check the stdout stream is still alive
                    int Err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                    if (Err != 0)
                    {
                        // Err 997: "Overlapped I/O is in progress" (don't know cause)
                        // Err 183: cannot create a file... caused in Trace
                        // Err 2:   cannot find a file... caused in Trace
                        if (Err != 997 && Err != 183 && Err != 2)
                        {
                            System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception(Err);
                            Trace.WriteLine("Write fault " + Err + ": " + e.Message);
                            err = true;// yield break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (DSPUtil.IsMono() && e.Message.Contains("Write fault on path"))
                {
                    // This is the usual end-of-stream error on Mono
                    Trace.WriteLine("Write finished; " + e.Message);
                    err = true; // yield break
                }
                else if (e.GetHashCode() == 33574638)
                {
                    // "The specified network name is no longer available", from softsqueeze
                    Trace.WriteLine("Write finished; " + e.Message);
                    err = true; // yield break
                }
                else
                {
                    // Trace.WriteLine("Interrupted: " + e.Message);
                    throw e;
                }
            }
            return sample;
        }