int CaptureStreamT::Read(unsigned char* Buffer, unsigned int Size) { const unsigned int MAX_WRITE_SAMPLES=Size/BytesPerSample(m_FORMAT); // If this is the first read after initialization or a rewind, start capturing now. // When capturing has been stopped before and is restarted here, GetNumCaptureSamples() should return 0, // just as if it had been started for the first time. See Rewind() for more information. if (!m_IsCapturing) { alcCaptureStart(m_CaptureDevice); m_IsCapturing=true; } // std::cout << "\n" << __FUNCTION__ << "():\n" << " "; PrintDebug(); // If there are not enough "live" capture samples available, fill-in zeros until // the buffer is half full. This gives the device the chance to capture more data. if (GetNumCaptureSamples() < m_MAX_CAPTURE_BUFFER_SAMPLES/8) { m_ZeroSamples=m_MAX_CAPTURE_BUFFER_SAMPLES/2-GetNumCaptureSamples(); // std::cout << " + ... "; PrintDebug(); } // If the capture buffer is too full, we have probably lost data already. // In order to prevent this from happening over and over again, reduce it to half its size. if (m_ZeroSamples+GetNumCaptureSamples() >= m_MAX_CAPTURE_BUFFER_SAMPLES) { m_ZeroSamples=0; ReduceSamplesTo(m_MAX_CAPTURE_BUFFER_SAMPLES/2 + MAX_WRITE_SAMPLES); // std::cout << " - ... "; PrintDebug(); } // Write the leading zero samples. unsigned int SamplesWritten=std::min(m_ZeroSamples, MAX_WRITE_SAMPLES); memset(Buffer, 0, SamplesWritten*BytesPerSample(m_FORMAT)); m_ZeroSamples-=SamplesWritten; // Write the samples with real, live, captured data. if (GetNumCaptureSamples()>0 && SamplesWritten<MAX_WRITE_SAMPLES) { const unsigned int NumLive=std::min(GetNumCaptureSamples(), MAX_WRITE_SAMPLES-SamplesWritten); alcCaptureSamples(m_CaptureDevice, &Buffer[SamplesWritten*BytesPerSample(m_FORMAT)], NumLive); SamplesWritten+=NumLive; } // std::cout << " " << SamplesWritten << " samples written,\n" << " = "; PrintDebug(); return SamplesWritten*BytesPerSample(m_FORMAT); }
void Resize(int channels, int bits) { m_bits = bits; m_channels = channels; m_sizeMax = ((m_sample_rate * kBufferMilliSecs) / 1000) * BytesPerSample(); resize(0); }
void CaptureStreamT::ReduceSamplesTo(unsigned int NumLeft) { const unsigned int NumNow=GetNumCaptureSamples(); if (NumNow>NumLeft) { ArrayT<unsigned char> Discard; Discard.PushBackEmpty((NumNow-NumLeft)*BytesPerSample(m_FORMAT)); alcCaptureSamples(m_CaptureDevice, &Discard[0], NumNow-NumLeft); } }
inline unsigned Bytes2Samples(unsigned bytes) const { return (m_channels && m_bits) ? bytes / BytesPerSample() : 0; }
const int16_t* Data16(const range_t &avail) const { unsigned start = MS2Samples(avail.first - m_tcFirst); return reinterpret_cast< const int16_t* >(constData() + start * BytesPerSample()); }