/// <summary> /// Setup /// </summary> private void Setup() { if (m_sampleRate < 1.0f) { return; } m_dsp = new PitchDsp(m_sampleRate, kMinFreq, kMaxFreq, m_detectLevelThreshold); m_iirFilterLoLo = new IIRFilter(); m_iirFilterLoLo.Proto = IIRFilter.ProtoType.Butterworth; m_iirFilterLoLo.Type = IIRFilter.FilterType.HP; m_iirFilterLoLo.Order = 5; m_iirFilterLoLo.FreqLow = 45.0f; m_iirFilterLoLo.SampleRate = (float)m_sampleRate; m_iirFilterLoHi = new IIRFilter(); m_iirFilterLoHi.Proto = IIRFilter.ProtoType.Butterworth; m_iirFilterLoHi.Type = IIRFilter.FilterType.LP; m_iirFilterLoHi.Order = 5; m_iirFilterLoHi.FreqHigh = 280.0f; m_iirFilterLoHi.SampleRate = (float)m_sampleRate; m_iirFilterHiLo = new IIRFilter(); m_iirFilterHiLo.Proto = IIRFilter.ProtoType.Butterworth; m_iirFilterHiLo.Type = IIRFilter.FilterType.HP; m_iirFilterHiLo.Order = 5; m_iirFilterHiLo.FreqLow = 45.0f; m_iirFilterHiLo.SampleRate = (float)m_sampleRate; m_iirFilterHiHi = new IIRFilter(); m_iirFilterHiHi.Proto = IIRFilter.ProtoType.Butterworth; m_iirFilterHiHi.Type = IIRFilter.FilterType.LP; m_iirFilterHiHi.Order = 5; m_iirFilterHiHi.FreqHigh = 1500.0f; m_iirFilterHiHi.SampleRate = (float)m_sampleRate; m_detectOverlapSamples = (int)(kDetectOverlapSec * m_sampleRate); m_maxOverlapDiff = kMaxOctaveSecRate * kDetectOverlapSec; m_pitchBufSize = (int)(((1.0f / (float)kMinFreq) * 2.0f + ((kAvgCount - 1) * kAvgOffset)) * m_sampleRate) + 16; m_pitchBufLo = new float[m_pitchBufSize + m_detectOverlapSamples]; m_pitchBufHi = new float[m_pitchBufSize + m_detectOverlapSamples]; m_samplesPerPitchBlock = (int)Math.Round(m_sampleRate / m_pitchRecordsPerSecond); m_circularBufferLo = new CircularBuffer <float>((int)(kCircularBufSaveTime * m_sampleRate + 0.5f) + 10000); m_circularBufferHi = new CircularBuffer <float>((int)(kCircularBufSaveTime * m_sampleRate + 0.5f) + 10000); }
/// <summary> /// Write data into the buffer /// </summary> /// <param name="m_pInBuffer"></param> /// <param name="count"></param> /// <returns></returns> public int WriteBuffer(T[] m_pInBuffer, int count) { count = Math.Min(count, m_bufSize); var startPos = m_availBuf != m_bufSize ? m_availBuf : m_begBufOffset; var pass1Count = Math.Min(count, m_bufSize - startPos); var pass2Count = count - pass1Count; PitchDsp.CopyBuffer(m_pInBuffer, 0, m_buffer, startPos, pass1Count); if (pass2Count > 0) { PitchDsp.CopyBuffer(m_pInBuffer, pass1Count, m_buffer, 0, pass2Count); } if (pass2Count == 0) { // did not wrap around if (m_availBuf != m_bufSize) { m_availBuf += count; // have never wrapped around } else { m_begBufOffset += count; m_startPos += count; } } else { // wrapped around if (m_availBuf != m_bufSize) { m_startPos += pass2Count; // first time wrap-around } else { m_startPos += count; } m_begBufOffset = pass2Count; m_availBuf = m_bufSize; } return(count); }
/// <summary> /// Read from the buffer /// </summary> /// <param name="outBuffer"></param> /// <param name="startRead"></param> /// <param name="readCount"></param> /// <returns></returns> public bool ReadBuffer(T[] outBuffer, long startRead, int readCount) { var endRead = (int)(startRead + readCount); var endAvail = (int)(m_startPos + m_availBuf); if (startRead < m_startPos || endRead > endAvail) { return(false); } var startReadPos = (int)(((startRead - m_startPos) + m_begBufOffset) % m_bufSize); var block1Samples = Math.Min(readCount, m_bufSize - startReadPos); var block2Samples = readCount - block1Samples; PitchDsp.CopyBuffer(m_buffer, startReadPos, outBuffer, 0, block1Samples); if (block2Samples > 0) { PitchDsp.CopyBuffer(m_buffer, 0, outBuffer, block1Samples, block2Samples); } return(true); }