USB/usb-mic: Fix buffer handling

- RingBuffer would store a size of zero if you wrote the entire
   the entire buffer in one call.

 - ResetBuffers() should be called before starting the stream,
   otherwise you risk a race where the callback happens before
   the buffer is allocated.

 - Fix incorrect latency being passed into Cubeb.
This commit is contained in:
Stenzek 2023-07-07 00:49:28 +10:00 committed by Connor McLaughlin
parent 20420da326
commit b53e9856b8
3 changed files with 8 additions and 8 deletions

View File

@ -162,7 +162,7 @@ void RingBuffer::write(size_t bytes)
// push m_begin forward if m_end overlaps it
if ((m_end < m_begin && m_end + bytes > m_begin) ||
m_end + bytes > m_begin + m_capacity)
m_end + bytes >= m_begin + m_capacity)
{
m_overrun = true;
m_begin = (m_end + bytes) % m_capacity;

View File

@ -150,14 +150,13 @@ namespace usb_mic
params.prefs = CUBEB_STREAM_PREF_NONE;
// Prefer minimum latency, reduces the chance of dropped samples due to the extra buffer.
u32 streamLatency;
if (cubeb_get_min_latency(mContext, &params, &streamLatency) != CUBEB_OK)
streamLatency = mLatency;
if (cubeb_get_min_latency(mContext, &params, &mStreamLatency) != CUBEB_OK)
mStreamLatency = (mLatency * mSampleRate) / 1000u;
const bool input = (mAudioDir == AUDIODIR_SOURCE);
int res = cubeb_stream_init(mContext, &mStream, fmt::format("{}", (void*)this).c_str(),
input ? mDeviceId : nullptr, input ? &params : nullptr, input ? nullptr : mDeviceId,
input ? nullptr : &params, (streamLatency * mSampleRate) / 1000u,
input ? nullptr : &params, mStreamLatency,
&CubebAudioDevice::DataCallback, &CubebStateCallback, this);
if (res != CUBEB_OK)
{
@ -165,6 +164,8 @@ namespace usb_mic
return false;
}
ResetBuffers();
res = cubeb_stream_start(mStream);
if (res != CUBEB_OK)
{
@ -174,7 +175,6 @@ namespace usb_mic
return false;
}
ResetBuffers();
return true;
}
@ -252,9 +252,8 @@ namespace usb_mic
void CubebAudioDevice::ResetBuffers()
{
// TODO: Do we want to make the buffer size adjustable? Currently 100ms max.
std::lock_guard<std::mutex> lk(mMutex);
const u32 samples = ((mSampleRate * mChannels) * mLatency) / 1000u;
const u32 samples = std::max(((mSampleRate * mChannels) * mLatency) / 1000u, mStreamLatency * mChannels);
mBuffer.reserve(sizeof(u16) * samples);
}

View File

@ -51,6 +51,7 @@ namespace usb_mic
u32 mSampleRate = 48000;
u32 mLatency = 50;
u32 mStreamLatency = 0;
cubeb* mContext;
cubeb_stream* mStream = nullptr;
std::string mDeviceName;