Specify the buffer size as itself instead of the period count
Certain backends don't need a buffer size to be a strict multiple of the period count, which allows a little more flexibility. The period/update size simply acts as the minimum request, which helps control CPU load by determining how often parameter and other pre-mixing updates are processed.
This commit is contained in:
parent
348e01dc4b
commit
f23ff0394d
47
Alc/alc.cpp
47
Alc/alc.cpp
@ -1743,7 +1743,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
|
||||
if(!loopback)
|
||||
{
|
||||
device->NumUpdates = DEFAULT_NUM_UPDATES;
|
||||
device->BufferSize = DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES;
|
||||
device->UpdateSize = DEFAULT_UPDATE_SIZE;
|
||||
device->Frequency = DEFAULT_OUTPUT_RATE;
|
||||
|
||||
@ -1754,21 +1754,24 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
{
|
||||
freq = maxi(freq, MIN_OUTPUT_RATE);
|
||||
|
||||
device->NumUpdates = (device->NumUpdates*freq + device->NumUpdates/2) /
|
||||
device->Frequency;
|
||||
device->BufferSize = (device->BufferSize*freq + device->Frequency/2) /
|
||||
device->Frequency;
|
||||
|
||||
device->Frequency = freq;
|
||||
device->Flags |= DEVICE_FREQUENCY_REQUEST;
|
||||
}
|
||||
|
||||
ConfigValueUInt(devname, nullptr, "periods", &device->NumUpdates);
|
||||
device->NumUpdates = clampu(device->NumUpdates, 2, 16);
|
||||
|
||||
ConfigValueUInt(devname, nullptr, "period_size", &device->UpdateSize);
|
||||
device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
|
||||
/* SSE and Neon do best with the update size being a multiple of 4. */
|
||||
if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
|
||||
device->UpdateSize = (device->UpdateSize+3u)&~3u;
|
||||
|
||||
ALuint periods{};
|
||||
if(ConfigValueUInt(devname, nullptr, "periods", &periods))
|
||||
device->BufferSize = device->UpdateSize * clampu(periods, 2, 16);
|
||||
else
|
||||
device->BufferSize = maxu(device->BufferSize, device->UpdateSize*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1880,12 +1883,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
oldChans = device->FmtChans;
|
||||
oldType = device->FmtType;
|
||||
|
||||
TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
|
||||
TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u / %u buffer\n",
|
||||
(device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans),
|
||||
(device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", DevFmtTypeString(device->FmtType),
|
||||
(device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", device->Frequency,
|
||||
device->UpdateSize, device->NumUpdates
|
||||
);
|
||||
device->UpdateSize, device->BufferSize);
|
||||
|
||||
if(device->Backend->reset() == ALC_FALSE)
|
||||
return ALC_INVALID_DEVICE;
|
||||
@ -1916,10 +1918,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
|
||||
WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
|
||||
}
|
||||
|
||||
TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
|
||||
TRACE("Post-reset: %s, %s, %uhz, %u / %u buffer\n",
|
||||
DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
|
||||
device->Frequency, device->UpdateSize, device->NumUpdates
|
||||
);
|
||||
device->Frequency, device->UpdateSize, device->BufferSize);
|
||||
|
||||
aluInitRenderer(device, hrtf_id, hrtf_appreq, hrtf_userreq);
|
||||
TRACE("Channel config, Main: %d, Real: %d\n", device->Dry.NumChannels,
|
||||
@ -3670,7 +3671,7 @@ START_API_FUNC
|
||||
device->FmtType = DevFmtTypeDefault;
|
||||
device->Frequency = DEFAULT_OUTPUT_RATE;
|
||||
device->UpdateSize = DEFAULT_UPDATE_SIZE;
|
||||
device->NumUpdates = DEFAULT_NUM_UPDATES;
|
||||
device->BufferSize = DEFAULT_UPDATE_SIZE * DEFAULT_NUM_UPDATES;
|
||||
device->LimiterState = ALC_TRUE;
|
||||
|
||||
device->SourcesMax = 256;
|
||||
@ -3764,19 +3765,22 @@ START_API_FUNC
|
||||
ERR("%uhz request clamped to %uhz minimum\n", freq, MIN_OUTPUT_RATE);
|
||||
freq = MIN_OUTPUT_RATE;
|
||||
}
|
||||
device->NumUpdates = (device->NumUpdates*freq + device->Frequency/2) / device->Frequency;
|
||||
device->BufferSize = (device->BufferSize*freq + device->Frequency/2) / device->Frequency;
|
||||
device->Frequency = freq;
|
||||
device->Flags |= DEVICE_FREQUENCY_REQUEST;
|
||||
}
|
||||
|
||||
ConfigValueUInt(deviceName, nullptr, "periods", &device->NumUpdates);
|
||||
device->NumUpdates = clampu(device->NumUpdates, 2, 16);
|
||||
|
||||
ConfigValueUInt(deviceName, nullptr, "period_size", &device->UpdateSize);
|
||||
device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
|
||||
if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
|
||||
device->UpdateSize = (device->UpdateSize+3u)&~3u;
|
||||
|
||||
ALuint periods{};
|
||||
if(ConfigValueUInt(deviceName, nullptr, "periods", &periods))
|
||||
device->BufferSize = device->UpdateSize * clampu(periods, 2, 16);
|
||||
else
|
||||
device->BufferSize = maxu(device->BufferSize, device->UpdateSize*2);
|
||||
|
||||
ConfigValueUInt(deviceName, nullptr, "sources", &device->SourcesMax);
|
||||
if(device->SourcesMax == 0) device->SourcesMax = 256;
|
||||
|
||||
@ -3927,7 +3931,7 @@ START_API_FUNC
|
||||
device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
|
||||
|
||||
device->UpdateSize = samples;
|
||||
device->NumUpdates = 1;
|
||||
device->BufferSize = samples;
|
||||
|
||||
device->Backend = CaptureBackend.getFactory().createBackend(device.get(),
|
||||
BackendType::Capture);
|
||||
@ -3937,10 +3941,9 @@ START_API_FUNC
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TRACE("Capture format: %s, %s, %uhz, %u update size x%d\n",
|
||||
TRACE("Capture format: %s, %s, %uhz, %u / %u buffer\n",
|
||||
DevFmtChannelsString(device->FmtChans), DevFmtTypeString(device->FmtType),
|
||||
device->Frequency, device->UpdateSize, device->NumUpdates
|
||||
);
|
||||
device->Frequency, device->UpdateSize, device->BufferSize);
|
||||
ALCenum err{device->Backend->open(deviceName)};
|
||||
if(err != ALC_NO_ERROR)
|
||||
{
|
||||
@ -4082,7 +4085,7 @@ START_API_FUNC
|
||||
device->NumAuxSends = DEFAULT_SENDS;
|
||||
|
||||
//Set output format
|
||||
device->NumUpdates = 0;
|
||||
device->BufferSize = 0;
|
||||
device->UpdateSize = 0;
|
||||
|
||||
device->Frequency = DEFAULT_OUTPUT_RATE;
|
||||
|
@ -421,8 +421,8 @@ int AlsaPlayback::mixerProc()
|
||||
SetRTPriority();
|
||||
althrd_setname(MIXER_THREAD_NAME);
|
||||
|
||||
snd_pcm_uframes_t update_size{mDevice->UpdateSize};
|
||||
snd_pcm_uframes_t num_updates{mDevice->NumUpdates};
|
||||
const snd_pcm_uframes_t update_size{mDevice->UpdateSize};
|
||||
const snd_pcm_uframes_t num_updates{mDevice->BufferSize / update_size};
|
||||
while(!mKillNow.load(std::memory_order_acquire))
|
||||
{
|
||||
int state{verify_state(mPcmHandle)};
|
||||
@ -504,8 +504,8 @@ int AlsaPlayback::mixerNoMMapProc()
|
||||
SetRTPriority();
|
||||
althrd_setname(MIXER_THREAD_NAME);
|
||||
|
||||
snd_pcm_uframes_t update_size{mDevice->UpdateSize};
|
||||
snd_pcm_uframes_t num_updates{mDevice->NumUpdates};
|
||||
const snd_pcm_uframes_t update_size{mDevice->UpdateSize};
|
||||
const snd_pcm_uframes_t buffer_size{mDevice->BufferSize};
|
||||
while(!mKillNow.load(std::memory_order_acquire))
|
||||
{
|
||||
int state{verify_state(mPcmHandle)};
|
||||
@ -523,7 +523,7 @@ int AlsaPlayback::mixerNoMMapProc()
|
||||
continue;
|
||||
}
|
||||
|
||||
if(static_cast<snd_pcm_uframes_t>(avail) > update_size*num_updates)
|
||||
if(static_cast<snd_pcm_uframes_t>(avail) > buffer_size)
|
||||
{
|
||||
WARN("available samples exceeds the buffer size\n");
|
||||
snd_pcm_reset(mPcmHandle);
|
||||
@ -654,17 +654,18 @@ ALCboolean AlsaPlayback::reset()
|
||||
}
|
||||
|
||||
bool allowmmap{!!GetConfigValueBool(mDevice->DeviceName.c_str(), "alsa", "mmap", 1)};
|
||||
ALuint periods{mDevice->NumUpdates};
|
||||
ALuint periodLen{static_cast<ALuint>(mDevice->UpdateSize * 1000000_u64 / mDevice->Frequency)};
|
||||
ALuint bufferLen{periodLen * periods};
|
||||
ALuint bufferLen{static_cast<ALuint>(mDevice->BufferSize * 1000000_u64 / mDevice->Frequency)};
|
||||
ALuint rate{mDevice->Frequency};
|
||||
|
||||
snd_pcm_uframes_t periodSizeInFrames;
|
||||
snd_pcm_uframes_t periodSizeInFrames{};
|
||||
snd_pcm_uframes_t bufferSizeInFrames{};
|
||||
snd_pcm_sw_params_t *sp{};
|
||||
snd_pcm_hw_params_t *hp{};
|
||||
snd_pcm_access_t access;
|
||||
const char *funcerr;
|
||||
int dir, err;
|
||||
snd_pcm_access_t access{};
|
||||
const char *funcerr{};
|
||||
int err{};
|
||||
|
||||
snd_pcm_hw_params_malloc(&hp);
|
||||
#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
|
||||
CHECK(snd_pcm_hw_params_any(mPcmHandle, hp));
|
||||
@ -745,22 +746,20 @@ ALCboolean AlsaPlayback::reset()
|
||||
/* retrieve configuration info */
|
||||
CHECK(snd_pcm_hw_params_get_access(hp, &access));
|
||||
CHECK(snd_pcm_hw_params_get_period_size(hp, &periodSizeInFrames, nullptr));
|
||||
CHECK(snd_pcm_hw_params_get_periods(hp, &periods, &dir));
|
||||
if(dir != 0)
|
||||
WARN("Inexact period count: %u (%d)\n", periods, dir);
|
||||
CHECK(snd_pcm_hw_params_get_buffer_size(hp, &bufferSizeInFrames));
|
||||
snd_pcm_hw_params_free(hp);
|
||||
hp = nullptr;
|
||||
|
||||
snd_pcm_sw_params_malloc(&sp);
|
||||
CHECK(snd_pcm_sw_params_current(mPcmHandle, sp));
|
||||
CHECK(snd_pcm_sw_params_set_avail_min(mPcmHandle, sp, periodSizeInFrames));
|
||||
CHECK(snd_pcm_sw_params_set_stop_threshold(mPcmHandle, sp, periodSizeInFrames*periods));
|
||||
CHECK(snd_pcm_sw_params_set_stop_threshold(mPcmHandle, sp, bufferSizeInFrames));
|
||||
CHECK(snd_pcm_sw_params(mPcmHandle, sp));
|
||||
#undef CHECK
|
||||
snd_pcm_sw_params_free(sp);
|
||||
sp = nullptr;
|
||||
|
||||
mDevice->NumUpdates = periods;
|
||||
mDevice->BufferSize = bufferSizeInFrames;
|
||||
mDevice->UpdateSize = periodSizeInFrames;
|
||||
mDevice->Frequency = rate;
|
||||
|
||||
@ -950,8 +949,7 @@ ALCenum AlsaCapture::open(const ALCchar *name)
|
||||
break;
|
||||
}
|
||||
|
||||
snd_pcm_uframes_t bufferSizeInFrames{maxu(mDevice->UpdateSize*mDevice->NumUpdates,
|
||||
100*mDevice->Frequency/1000)};
|
||||
snd_pcm_uframes_t bufferSizeInFrames{maxu(mDevice->BufferSize, 100*mDevice->Frequency/1000)};
|
||||
snd_pcm_uframes_t periodSizeInFrames{minu(bufferSizeInFrames, 25*mDevice->Frequency/1000)};
|
||||
|
||||
bool needring{false};
|
||||
@ -987,8 +985,7 @@ ALCenum AlsaCapture::open(const ALCchar *name)
|
||||
|
||||
if(needring)
|
||||
{
|
||||
mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates,
|
||||
mDevice->frameSizeFromFmt(), false);
|
||||
mRing = CreateRingBuffer(mDevice->BufferSize, mDevice->frameSizeFromFmt(), false);
|
||||
if(!mRing)
|
||||
{
|
||||
ERR("ring buffer create failed\n");
|
||||
|
@ -51,7 +51,7 @@ ClockLatency BackendBase::getClockLatency()
|
||||
* any given time during playback. Without a more accurate measurement from
|
||||
* the output, this is an okay approximation.
|
||||
*/
|
||||
ret.Latency = std::chrono::seconds{mDevice->UpdateSize*maxi(mDevice->NumUpdates-1, 0)};
|
||||
ret.Latency = std::chrono::seconds{maxi(mDevice->BufferSize-mDevice->UpdateSize, 0)};
|
||||
ret.Latency /= mDevice->Frequency;
|
||||
|
||||
return ret;
|
||||
|
@ -177,7 +177,7 @@ ALCboolean CoreAudioPlayback::reset()
|
||||
|
||||
if(mDevice->Frequency != streamFormat.mSampleRate)
|
||||
{
|
||||
mDevice->NumUpdates = static_cast<ALuint>(uint64_t{mDevice->NumUpdates} *
|
||||
mDevice->BufferSize = static_cast<ALuint>(uint64_t{mDevice->BufferSize} *
|
||||
streamFormat.mSampleRate / mDevice->Frequency);
|
||||
mDevice->Frequency = streamFormat.mSampleRate;
|
||||
}
|
||||
|
@ -496,19 +496,16 @@ retry_open:
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
if(mDevice->NumUpdates > MAX_UPDATES)
|
||||
{
|
||||
mDevice->UpdateSize = (mDevice->UpdateSize*mDevice->NumUpdates + MAX_UPDATES-1) /
|
||||
MAX_UPDATES;
|
||||
mDevice->NumUpdates = MAX_UPDATES;
|
||||
}
|
||||
ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
||||
if(num_updates > MAX_UPDATES)
|
||||
num_updates = MAX_UPDATES;
|
||||
mDevice->BufferSize = mDevice->UpdateSize * num_updates;
|
||||
|
||||
DSBUFFERDESC DSBDescription{};
|
||||
DSBDescription.dwSize = sizeof(DSBDescription);
|
||||
DSBDescription.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 |
|
||||
DSBCAPS_GLOBALFOCUS;
|
||||
DSBDescription.dwBufferBytes = mDevice->UpdateSize * mDevice->NumUpdates *
|
||||
OutputType.Format.nBlockAlign;
|
||||
DSBDescription.dwBufferBytes = mDevice->BufferSize * OutputType.Format.nBlockAlign;
|
||||
DSBDescription.lpwfxFormat = &OutputType.Format;
|
||||
|
||||
hr = mDS->CreateSoundBuffer(&DSBDescription, &mBuffer, nullptr);
|
||||
@ -528,15 +525,16 @@ retry_open:
|
||||
auto Notifies = static_cast<IDirectSoundNotify*>(ptr);
|
||||
mNotifies = Notifies;
|
||||
|
||||
mDevice->NumUpdates = minu(mDevice->NumUpdates, MAX_UPDATES);
|
||||
ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
||||
assert(num_updates <= MAX_UPDATES);
|
||||
|
||||
std::array<DSBPOSITIONNOTIFY,MAX_UPDATES> nots;
|
||||
for(ALuint i{0};i < mDevice->NumUpdates;++i)
|
||||
for(ALuint i{0};i < num_updates;++i)
|
||||
{
|
||||
nots[i].dwOffset = i * mDevice->UpdateSize * OutputType.Format.nBlockAlign;
|
||||
nots[i].hEventNotify = mNotifyEvent;
|
||||
}
|
||||
if(Notifies->SetNotificationPositions(mDevice->NumUpdates, nots.data()) != DS_OK)
|
||||
if(Notifies->SetNotificationPositions(num_updates, nots.data()) != DS_OK)
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
@ -743,7 +741,7 @@ ALCenum DSoundCapture::open(const ALCchar *name)
|
||||
InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
|
||||
}
|
||||
|
||||
ALuint samples{mDevice->UpdateSize * mDevice->NumUpdates};
|
||||
ALuint samples{mDevice->BufferSize};
|
||||
samples = maxu(samples, 100 * mDevice->Frequency / 1000);
|
||||
|
||||
DSCBUFFERDESC DSCBDescription{};
|
||||
@ -758,8 +756,7 @@ ALCenum DSoundCapture::open(const ALCchar *name)
|
||||
mDSC->CreateCaptureBuffer(&DSCBDescription, &mDSCbuffer, nullptr);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates,
|
||||
InputType.Format.nBlockAlign, false);
|
||||
mRing = CreateRingBuffer(mDevice->BufferSize, InputType.Format.nBlockAlign, false);
|
||||
if(!mRing) hr = DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
|
@ -202,14 +202,14 @@ int JackPlayback::bufferSizeNotify(jack_nframes_t numframes)
|
||||
{
|
||||
std::lock_guard<std::mutex> _{mDevice->StateLock};
|
||||
mDevice->UpdateSize = numframes;
|
||||
mDevice->NumUpdates = 2;
|
||||
mDevice->BufferSize = numframes*2;
|
||||
|
||||
ALuint bufsize{mDevice->UpdateSize};
|
||||
if(ConfigValueUInt(mDevice->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
|
||||
bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
|
||||
mDevice->NumUpdates = (bufsize+mDevice->UpdateSize) / mDevice->UpdateSize;
|
||||
mDevice->BufferSize = bufsize + mDevice->UpdateSize;
|
||||
|
||||
TRACE("%u update size x%u\n", mDevice->UpdateSize, mDevice->NumUpdates);
|
||||
TRACE("%u / %u buffer\n", mDevice->UpdateSize, mDevice->BufferSize);
|
||||
|
||||
mRing = nullptr;
|
||||
mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true);
|
||||
@ -373,12 +373,12 @@ ALCboolean JackPlayback::reset()
|
||||
*/
|
||||
mDevice->Frequency = jack_get_sample_rate(mClient);
|
||||
mDevice->UpdateSize = jack_get_buffer_size(mClient);
|
||||
mDevice->NumUpdates = 2;
|
||||
mDevice->BufferSize = mDevice->UpdateSize * 2;
|
||||
|
||||
ALuint bufsize{mDevice->UpdateSize};
|
||||
if(ConfigValueUInt(mDevice->DeviceName.c_str(), "jack", "buffer-size", &bufsize))
|
||||
bufsize = maxu(NextPowerOf2(bufsize), mDevice->UpdateSize);
|
||||
mDevice->NumUpdates = (bufsize+mDevice->UpdateSize) / mDevice->UpdateSize;
|
||||
mDevice->BufferSize = bufsize + mDevice->UpdateSize;
|
||||
|
||||
/* Force 32-bit float output. */
|
||||
mDevice->FmtType = DevFmtFloat;
|
||||
|
@ -352,7 +352,6 @@ ALCboolean OpenSLPlayback::reset()
|
||||
SLDataLocator_OutputMix loc_outmix;
|
||||
SLDataSource audioSrc;
|
||||
SLDataSink audioSnk;
|
||||
ALuint sampleRate;
|
||||
SLInterfaceID ids[2];
|
||||
SLboolean reqs[2];
|
||||
SLresult result;
|
||||
@ -363,7 +362,6 @@ ALCboolean OpenSLPlayback::reset()
|
||||
|
||||
mRing = nullptr;
|
||||
|
||||
sampleRate = mDevice->Frequency;
|
||||
#if 0
|
||||
if(!(mDevice->Flags&DEVICE_FREQUENCY_REQUEST))
|
||||
{
|
||||
@ -432,14 +430,6 @@ ALCboolean OpenSLPlayback::reset()
|
||||
}
|
||||
#endif
|
||||
|
||||
if(sampleRate != mDevice->Frequency)
|
||||
{
|
||||
mDevice->NumUpdates = (mDevice->NumUpdates*sampleRate + (mDevice->Frequency>>1)) /
|
||||
mDevice->Frequency;
|
||||
mDevice->NumUpdates = maxu(mDevice->NumUpdates, 2);
|
||||
mDevice->Frequency = sampleRate;
|
||||
}
|
||||
|
||||
mDevice->FmtChans = DevFmtStereo;
|
||||
mDevice->FmtType = DevFmtShort;
|
||||
|
||||
@ -448,7 +438,7 @@ ALCboolean OpenSLPlayback::reset()
|
||||
|
||||
|
||||
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
loc_bufq.numBuffers = mDevice->NumUpdates;
|
||||
loc_bufq.numBuffers = mDevice->BufferSize / mDevice->UpdateSize;
|
||||
|
||||
#ifdef SL_DATAFORMAT_PCM_EX
|
||||
SLDataFormat_PCM_EX format_pcm;
|
||||
@ -514,12 +504,13 @@ ALCboolean OpenSLPlayback::reset()
|
||||
}
|
||||
if(SL_RESULT_SUCCESS == result)
|
||||
{
|
||||
const ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
|
||||
try {
|
||||
mRing = CreateRingBuffer(mDevice->NumUpdates, mFrameSize*mDevice->UpdateSize, true);
|
||||
mRing = CreateRingBuffer(num_updates, mFrameSize*mDevice->UpdateSize, true);
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
ERR("Failed allocating ring buffer %ux%ux%u: %s\n", mDevice->UpdateSize,
|
||||
mDevice->NumUpdates, mFrameSize, e.what());
|
||||
num_updates, mFrameSize, e.what());
|
||||
result = SL_RESULT_MEMORY_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -694,17 +685,17 @@ ALCenum OpenSLCapture::open(const ALCchar* name)
|
||||
{
|
||||
mFrameSize = mDevice->frameSizeFromFmt();
|
||||
/* Ensure the total length is at least 100ms */
|
||||
ALsizei length{maxi(mDevice->NumUpdates*mDevice->UpdateSize, mDevice->Frequency/10)};
|
||||
ALsizei length{maxi(mDevice->BufferSize, mDevice->Frequency/10)};
|
||||
/* Ensure the per-chunk length is at least 10ms, and no more than 50ms. */
|
||||
ALsizei update_len{clampi(mDevice->NumUpdates*mDevice->UpdateSize / 3,
|
||||
mDevice->Frequency/100, mDevice->Frequency/100*5)};
|
||||
ALsizei update_len{clampi(mDevice->BufferSize/3, mDevice->Frequency/100,
|
||||
mDevice->Frequency/100*5)};
|
||||
ALsizei num_updates{(length+update_len-1) / update_len};
|
||||
|
||||
try {
|
||||
mRing = CreateRingBuffer(num_updates, update_len*mFrameSize, false);
|
||||
|
||||
mDevice->UpdateSize = update_len;
|
||||
mDevice->NumUpdates = mRing->writeSpace();
|
||||
mDevice->BufferSize = mRing->writeSpace() * update_len;
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
ERR("Failed to allocate ring buffer: %s\n", e.what());
|
||||
@ -728,7 +719,7 @@ ALCenum OpenSLCapture::open(const ALCchar* name)
|
||||
|
||||
SLDataLocator_AndroidSimpleBufferQueue loc_bq{};
|
||||
loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
|
||||
loc_bq.numBuffers = mDevice->NumUpdates;
|
||||
loc_bq.numBuffers = mDevice->BufferSize / mDevice->UpdateSize;
|
||||
|
||||
#ifdef SL_DATAFORMAT_PCM_EX
|
||||
SLDataFormat_PCM_EX format_pcm{};
|
||||
|
@ -391,7 +391,7 @@ ALCboolean OSSPlayback::reset()
|
||||
break;
|
||||
}
|
||||
|
||||
periods = mDevice->NumUpdates;
|
||||
periods = mDevice->BufferSize / mDevice->UpdateSize;
|
||||
numChannels = mDevice->channelsFromFmt();
|
||||
ossSpeed = mDevice->Frequency;
|
||||
frameSize = numChannels * mDevice->bytesFromFmt();
|
||||
@ -436,7 +436,7 @@ ALCboolean OSSPlayback::reset()
|
||||
|
||||
mDevice->Frequency = ossSpeed;
|
||||
mDevice->UpdateSize = info.fragsize / frameSize;
|
||||
mDevice->NumUpdates = info.fragments;
|
||||
mDevice->BufferSize = info.fragments * mDevice->UpdateSize;
|
||||
|
||||
SetDefaultChannelOrder(mDevice);
|
||||
|
||||
@ -598,8 +598,7 @@ ALCenum OSScapture::open(const ALCchar *name)
|
||||
int numChannels{mDevice->channelsFromFmt()};
|
||||
int frameSize{numChannels * mDevice->bytesFromFmt()};
|
||||
int ossSpeed{static_cast<int>(mDevice->Frequency)};
|
||||
int log2FragmentSize{log2i(mDevice->UpdateSize * mDevice->NumUpdates *
|
||||
frameSize / periods)};
|
||||
int log2FragmentSize{log2i(mDevice->BufferSize * frameSize / periods)};
|
||||
|
||||
/* according to the OSS spec, 16 bytes are the minimum */
|
||||
log2FragmentSize = std::max(log2FragmentSize, 4);
|
||||
@ -645,7 +644,7 @@ ALCenum OSScapture::open(const ALCchar *name)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates, frameSize, false);
|
||||
mRing = CreateRingBuffer(mDevice->BufferSize, frameSize, false);
|
||||
if(!mRing)
|
||||
{
|
||||
ERR("Ring buffer create failed\n");
|
||||
|
@ -133,8 +133,7 @@ ALCenum PortPlayback::open(const ALCchar *name)
|
||||
mParams.device = -1;
|
||||
if(!ConfigValueInt(nullptr, "port", "device", &mParams.device) || mParams.device < 0)
|
||||
mParams.device = Pa_GetDefaultOutputDevice();
|
||||
mParams.suggestedLatency = (mDevice->UpdateSize*mDevice->NumUpdates) /
|
||||
static_cast<float>(mDevice->Frequency);
|
||||
mParams.suggestedLatency = mDevice->BufferSize / static_cast<double>(mDevice->Frequency);
|
||||
mParams.hostApiSpecificStreamInfo = nullptr;
|
||||
|
||||
mParams.channelCount = ((mDevice->FmtChans == DevFmtMono) ? 1 : 2);
|
||||
@ -294,7 +293,7 @@ ALCenum PortCapture::open(const ALCchar *name)
|
||||
else if(strcmp(name, pa_device) != 0)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
ALuint samples{mDevice->UpdateSize * mDevice->NumUpdates};
|
||||
ALuint samples{mDevice->BufferSize};
|
||||
samples = maxu(samples, 100 * mDevice->Frequency / 1000);
|
||||
ALsizei frame_size{mDevice->frameSizeFromFmt()};
|
||||
|
||||
|
@ -691,7 +691,7 @@ void PulsePlayback::bufferAttrCallbackC(pa_stream *stream, void *pdata)
|
||||
|
||||
void PulsePlayback::bufferAttrCallback(pa_stream *stream)
|
||||
{
|
||||
/* FIXME: Update the device's UpdateSize (and/or NumUpdates) using the new
|
||||
/* FIXME: Update the device's UpdateSize (and/or BufferSize) using the new
|
||||
* buffer attributes? Changing UpdateSize will change the ALC_REFRESH
|
||||
* property, which probably shouldn't change between device resets. But
|
||||
* leaving it alone means ALC_REFRESH will be off.
|
||||
@ -1007,11 +1007,10 @@ ALCboolean PulsePlayback::reset()
|
||||
}
|
||||
SetDefaultWFXChannelOrder(mDevice);
|
||||
|
||||
size_t period_size{mDevice->UpdateSize * pa_frame_size(&mSpec)};
|
||||
mAttr.maxlength = -1;
|
||||
mAttr.tlength = period_size * maxu(mDevice->NumUpdates, 2);
|
||||
mAttr.tlength = mDevice->BufferSize * pa_frame_size(&mSpec);
|
||||
mAttr.prebuf = 0;
|
||||
mAttr.minreq = period_size;
|
||||
mAttr.minreq = mDevice->UpdateSize * pa_frame_size(&mSpec);
|
||||
mAttr.fragsize = -1;
|
||||
|
||||
mStream = pulse_connect_stream(mDeviceName.c_str(), mLoop, mContext, flags, &mAttr, &mSpec,
|
||||
@ -1028,14 +1027,14 @@ ALCboolean PulsePlayback::reset()
|
||||
{
|
||||
/* Server updated our playback rate, so modify the buffer attribs
|
||||
* accordingly. */
|
||||
mDevice->NumUpdates = static_cast<ALuint>(clampd(
|
||||
static_cast<ALdouble>(mSpec.rate)/mDevice->Frequency*mDevice->NumUpdates + 0.5, 2.0, 16.0));
|
||||
double newlen{clampd(
|
||||
static_cast<double>(mSpec.rate)/mDevice->Frequency*mDevice->BufferSize + 0.5,
|
||||
mDevice->UpdateSize*2, std::numeric_limits<int>::max()/mFrameSize)};
|
||||
|
||||
period_size = mDevice->UpdateSize * mFrameSize;
|
||||
mAttr.maxlength = -1;
|
||||
mAttr.tlength = period_size * maxu(mDevice->NumUpdates, 2);
|
||||
mAttr.tlength = static_cast<ALuint>(newlen) * mFrameSize;
|
||||
mAttr.prebuf = 0;
|
||||
mAttr.minreq = period_size;
|
||||
mAttr.minreq = mDevice->UpdateSize * mFrameSize;
|
||||
|
||||
op = pa_stream_set_buffer_attr(mStream, &mAttr, stream_success_callback, mLoop);
|
||||
wait_for_operation(op, mLoop);
|
||||
@ -1046,7 +1045,7 @@ ALCboolean PulsePlayback::reset()
|
||||
pa_stream_set_buffer_attr_callback(mStream, &PulsePlayback::bufferAttrCallbackC, this);
|
||||
bufferAttrCallback(mStream);
|
||||
|
||||
mDevice->NumUpdates = clampu((mAttr.tlength + mAttr.minreq/2u) / mAttr.minreq, 2u, 16u);
|
||||
mDevice->BufferSize = mAttr.tlength / mFrameSize;
|
||||
mDevice->UpdateSize = mAttr.minreq / mFrameSize;
|
||||
|
||||
/* HACK: prebuf should be 0 as that's what we set it to. However on some
|
||||
@ -1058,15 +1057,9 @@ ALCboolean PulsePlayback::reset()
|
||||
if(mAttr.prebuf != 0)
|
||||
{
|
||||
ALuint len{mAttr.prebuf / mFrameSize};
|
||||
if(len <= mDevice->UpdateSize*mDevice->NumUpdates)
|
||||
if(len <= mDevice->BufferSize)
|
||||
ERR("Non-0 prebuf, %u samples (%u bytes), device has %u samples\n",
|
||||
len, mAttr.prebuf, mDevice->UpdateSize*mDevice->NumUpdates);
|
||||
else
|
||||
{
|
||||
ERR("Large prebuf, %u samples (%u bytes), increasing device from %u samples",
|
||||
len, mAttr.prebuf, mDevice->UpdateSize*mDevice->NumUpdates);
|
||||
mDevice->NumUpdates = (len+mDevice->UpdateSize-1) / mDevice->UpdateSize;
|
||||
}
|
||||
len, mAttr.prebuf, mDevice->BufferSize);
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
@ -1328,7 +1321,7 @@ ALCenum PulseCapture::open(const ALCchar *name)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
ALuint samples{mDevice->UpdateSize * mDevice->NumUpdates};
|
||||
ALuint samples{mDevice->BufferSize};
|
||||
samples = maxu(samples, 100 * mDevice->Frequency / 1000);
|
||||
|
||||
mAttr.minreq = -1;
|
||||
@ -1337,7 +1330,7 @@ ALCenum PulseCapture::open(const ALCchar *name)
|
||||
mAttr.tlength = -1;
|
||||
mAttr.fragsize = minu(samples, 50*mDevice->Frequency/1000) * pa_frame_size(&mSpec);
|
||||
|
||||
pa_stream_flags_t flags{PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY};
|
||||
pa_stream_flags_t flags{PA_STREAM_START_CORKED | PA_STREAM_ADJUST_LATENCY};
|
||||
if(!GetConfigValueBool(nullptr, "pulse", "allow-moves", 0))
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
|
||||
|
@ -380,8 +380,8 @@ static ALCboolean qsa_reset_playback(PlaybackWrapper *self)
|
||||
data->cparams.stop_mode=SND_PCM_STOP_STOP;
|
||||
|
||||
data->cparams.buf.block.frag_size=device->UpdateSize * device->frameSizeFromFmt();
|
||||
data->cparams.buf.block.frags_max=device->NumUpdates;
|
||||
data->cparams.buf.block.frags_min=device->NumUpdates;
|
||||
data->cparams.buf.block.frags_max=device->BufferSize / device->UpdateSize;
|
||||
data->cparams.buf.block.frags_min=data->cparams.buf.block.frags_max;
|
||||
|
||||
data->cparams.format.interleave=1;
|
||||
data->cparams.format.rate=device->Frequency;
|
||||
|
@ -146,7 +146,7 @@ ALCenum Sdl2Backend::open(const ALCchar *name)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
mDevice->UpdateSize = have.samples;
|
||||
mDevice->NumUpdates = 2; /* SDL always (tries to) use two periods. */
|
||||
mDevice->BufferSize = have.samples * 2; /* SDL always (tries to) use two periods. */
|
||||
|
||||
mFrameSize = mDevice->frameSizeFromFmt();
|
||||
mFrequency = mDevice->Frequency;
|
||||
@ -164,7 +164,7 @@ ALCboolean Sdl2Backend::reset()
|
||||
mDevice->FmtChans = mFmtChans;
|
||||
mDevice->FmtType = mFmtType;
|
||||
mDevice->UpdateSize = mUpdateSize;
|
||||
mDevice->NumUpdates = 2;
|
||||
mDevice->BufferSize = mUpdateSize * 2;
|
||||
SetDefaultWFXChannelOrder(mDevice);
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ ALCboolean SndioPlayback::reset()
|
||||
par.le = SIO_LE_NATIVE;
|
||||
|
||||
par.round = mDevice->UpdateSize;
|
||||
par.appbufsz = mDevice->UpdateSize * (mDevice->NumUpdates-1);
|
||||
par.appbufsz = mDevice->BufferSize - mDevice->UpdateSize;
|
||||
if(!par.appbufsz) par.appbufsz = mDevice->UpdateSize;
|
||||
|
||||
if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
|
||||
@ -203,7 +203,7 @@ ALCboolean SndioPlayback::reset()
|
||||
SetDefaultChannelOrder(mDevice);
|
||||
|
||||
mDevice->UpdateSize = par.round;
|
||||
mDevice->NumUpdates = (par.bufsz/par.round) + 1;
|
||||
mDevice->BufferSize = par.bufsz + par.round;
|
||||
|
||||
mBuffer.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
|
||||
std::fill(mBuffer.begin(), mBuffer.end(), 0);
|
||||
@ -374,12 +374,11 @@ ALCenum SndioCapture::open(const ALCchar *name)
|
||||
par.rchan = mDevice->channelsFromFmt();
|
||||
par.rate = mDevice->Frequency;
|
||||
|
||||
par.appbufsz = maxu(mDevice->UpdateSize*mDevice->NumUpdates, (mDevice->Frequency+9)/10);
|
||||
par.round = clampu(par.appbufsz/mDevice->NumUpdates, (mDevice->Frequency+99)/100,
|
||||
(mDevice->Frequency+19)/20);
|
||||
par.appbufsz = maxu(mDevice->BufferSize, mDevice->Frequency/10);
|
||||
par.round = minu(par.appbufsz, mDevice->Frequency/40);
|
||||
|
||||
mDevice->UpdateSize = par.round;
|
||||
mDevice->NumUpdates = maxu(par.appbufsz/par.round, 1);
|
||||
mDevice->BufferSize = par.appbufsz;
|
||||
|
||||
if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
|
||||
{
|
||||
@ -408,11 +407,10 @@ ALCenum SndioCapture::open(const ALCchar *name)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
mRing = CreateRingBuffer(mDevice->UpdateSize*mDevice->NumUpdates, par.bps*par.rchan, false);
|
||||
mRing = CreateRingBuffer(mDevice->BufferSize, par.bps*par.rchan, false);
|
||||
if(!mRing)
|
||||
{
|
||||
ERR("Failed to allocate %u-byte ringbuffer\n",
|
||||
mDevice->UpdateSize*mDevice->NumUpdates*par.bps*par.rchan);
|
||||
ERR("Failed to allocate %u-byte ringbuffer\n", mDevice->BufferSize*par.bps*par.rchan);
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ ALCboolean SolarisBackend::reset()
|
||||
}
|
||||
|
||||
ALsizei frameSize{numChannels * mDevice->bytesFromFmt()};
|
||||
info.play.buffer_size = mDevice->UpdateSize*mDevice->NumUpdates * frameSize;
|
||||
info.play.buffer_size = mDevice->BufferSize * frameSize;
|
||||
|
||||
if(ioctl(mFd, AUDIO_SETINFO, &info) < 0)
|
||||
{
|
||||
@ -222,7 +222,8 @@ ALCboolean SolarisBackend::reset()
|
||||
}
|
||||
|
||||
mDevice->Frequency = info.play.sample_rate;
|
||||
mDevice->UpdateSize = (info.play.buffer_size/mDevice->NumUpdates) + 1;
|
||||
mDevice->BufferSize = info.play.buffer_size / frameSize;
|
||||
mDevice->UpdateSize = mDevice->BufferSize / 2;
|
||||
|
||||
SetDefaultChannelOrder(mDevice);
|
||||
|
||||
|
@ -561,7 +561,7 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
|
||||
althrd_setname(MIXER_THREAD_NAME);
|
||||
|
||||
const ALuint update_size{mDevice->UpdateSize};
|
||||
const UINT32 buffer_len{update_size * mDevice->NumUpdates};
|
||||
const UINT32 buffer_len{mDevice->BufferSize};
|
||||
while(!mKillNow.load(std::memory_order_relaxed))
|
||||
{
|
||||
UINT32 written;
|
||||
@ -789,8 +789,7 @@ HRESULT WasapiPlayback::resetProxy()
|
||||
CoTaskMemFree(wfx);
|
||||
wfx = nullptr;
|
||||
|
||||
REFERENCE_TIME buf_time{ScaleCeil(mDevice->UpdateSize*mDevice->NumUpdates, REFTIME_PER_SEC,
|
||||
mDevice->Frequency)};
|
||||
REFERENCE_TIME buf_time{mDevice->BufferSize * REFTIME_PER_SEC / mDevice->Frequency};
|
||||
|
||||
if(!(mDevice->Flags&DEVICE_FREQUENCY_REQUEST))
|
||||
mDevice->Frequency = OutputType.Format.nSamplesPerSec;
|
||||
@ -968,8 +967,8 @@ HRESULT WasapiPlayback::resetProxy()
|
||||
|
||||
SetDefaultWFXChannelOrder(mDevice);
|
||||
|
||||
hr = mClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||
buf_time, 0, &OutputType.Format, nullptr);
|
||||
hr = mClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, buf_time,
|
||||
0, &OutputType.Format, nullptr);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to initialize audio client: 0x%08lx\n", hr);
|
||||
@ -980,26 +979,24 @@ HRESULT WasapiPlayback::resetProxy()
|
||||
REFERENCE_TIME min_per;
|
||||
hr = mClient->GetDevicePeriod(&min_per, nullptr);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
min_len = (UINT32)ScaleCeil(min_per, mDevice->Frequency, REFTIME_PER_SEC);
|
||||
/* Find the nearest multiple of the period size to the update size */
|
||||
if(min_len < mDevice->UpdateSize)
|
||||
min_len *= maxu((mDevice->UpdateSize + min_len/2) / min_len, 1u);
|
||||
hr = mClient->GetBufferSize(&buffer_len);
|
||||
}
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to get audio buffer info: 0x%08lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
min_len = (UINT32)ScaleCeil(min_per, mDevice->Frequency, REFTIME_PER_SEC);
|
||||
/* Find the nearest multiple of the period size to the update size */
|
||||
if(min_len < mDevice->UpdateSize)
|
||||
min_len *= maxu((mDevice->UpdateSize + min_len/2) / min_len, 1u);
|
||||
|
||||
mDevice->UpdateSize = min_len;
|
||||
mDevice->NumUpdates = buffer_len / mDevice->UpdateSize;
|
||||
if(mDevice->NumUpdates <= 1)
|
||||
mDevice->BufferSize = buffer_len;
|
||||
if(mDevice->BufferSize <= mDevice->UpdateSize)
|
||||
{
|
||||
ERR("Audio client returned buffer_len < period*2; expect break up\n");
|
||||
mDevice->NumUpdates = 2;
|
||||
mDevice->UpdateSize = buffer_len / mDevice->NumUpdates;
|
||||
mDevice->UpdateSize = buffer_len / 2;
|
||||
}
|
||||
|
||||
hr = mClient->SetEventHandle(mNotifyEvent);
|
||||
@ -1351,12 +1348,9 @@ HRESULT WasapiCapture::resetProxy()
|
||||
}
|
||||
mClient = static_cast<IAudioClient*>(ptr);
|
||||
|
||||
REFERENCE_TIME buf_time{ScaleCeil(mDevice->UpdateSize*mDevice->NumUpdates, REFTIME_PER_SEC,
|
||||
mDevice->Frequency)};
|
||||
// Make sure buffer is at least 100ms in size
|
||||
REFERENCE_TIME buf_time{mDevice->BufferSize * REFTIME_PER_SEC / mDevice->Frequency};
|
||||
buf_time = maxu64(buf_time, REFTIME_PER_SEC/10);
|
||||
mDevice->UpdateSize = (ALuint)ScaleCeil(buf_time, mDevice->Frequency, REFTIME_PER_SEC) /
|
||||
mDevice->NumUpdates;
|
||||
|
||||
WAVEFORMATEXTENSIBLE OutputType;
|
||||
OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
@ -1533,8 +1527,8 @@ HRESULT WasapiCapture::resetProxy()
|
||||
mDevice->Frequency, DevFmtTypeString(srcType), OutputType.Format.nSamplesPerSec);
|
||||
}
|
||||
|
||||
hr = mClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||
buf_time, 0, &OutputType.Format, nullptr);
|
||||
hr = mClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, buf_time,
|
||||
0, &OutputType.Format, nullptr);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to initialize audio client: 0x%08lx\n", hr);
|
||||
@ -1542,14 +1536,20 @@ HRESULT WasapiCapture::resetProxy()
|
||||
}
|
||||
|
||||
UINT32 buffer_len;
|
||||
hr = mClient->GetBufferSize(&buffer_len);
|
||||
REFERENCE_TIME min_per;
|
||||
hr = mClient->GetDevicePeriod(&min_per, nullptr);
|
||||
if(SUCCEEDED(hr))
|
||||
hr = mClient->GetBufferSize(&buffer_len);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to get buffer size: 0x%08lx\n", hr);
|
||||
return hr;
|
||||
}
|
||||
mDevice->UpdateSize = static_cast<ALuint>(ScaleCeil(min_per, mDevice->Frequency,
|
||||
REFTIME_PER_SEC));
|
||||
mDevice->BufferSize = buffer_len;
|
||||
|
||||
buffer_len = maxu(mDevice->UpdateSize*mDevice->NumUpdates, buffer_len);
|
||||
buffer_len = maxu(mDevice->BufferSize, buffer_len);
|
||||
mRing = CreateRingBuffer(buffer_len, mDevice->frameSizeFromFmt(), false);
|
||||
if(!mRing)
|
||||
{
|
||||
|
@ -265,10 +265,10 @@ retry_open:
|
||||
|
||||
ALCboolean WinMMPlayback::reset()
|
||||
{
|
||||
mDevice->UpdateSize = static_cast<ALuint>(uint64_t{mDevice->UpdateSize} *
|
||||
mDevice->BufferSize = static_cast<ALuint>(uint64_t{mDevice->BufferSize} *
|
||||
mFormat.nSamplesPerSec / mDevice->Frequency);
|
||||
mDevice->UpdateSize = (mDevice->UpdateSize*mDevice->NumUpdates + 3) / 4;
|
||||
mDevice->NumUpdates = 4;
|
||||
mDevice->BufferSize = (mDevice->BufferSize+3) & ~0x3;
|
||||
mDevice->UpdateSize = mDevice->BufferSize / 4;
|
||||
mDevice->Frequency = mFormat.nSamplesPerSec;
|
||||
|
||||
if(mFormat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
|
||||
@ -523,9 +523,8 @@ ALCenum WinMMCapture::open(const ALCchar *name)
|
||||
|
||||
// Allocate circular memory buffer for the captured audio
|
||||
// Make sure circular buffer is at least 100ms in size
|
||||
ALuint CapturedDataSize{mDevice->UpdateSize*mDevice->NumUpdates};
|
||||
CapturedDataSize = static_cast<ALuint>(
|
||||
std::max<size_t>(CapturedDataSize, BufferSize*mWaveBuffer.size()));
|
||||
ALuint CapturedDataSize{mDevice->BufferSize};
|
||||
CapturedDataSize = static_cast<ALuint>(maxz(CapturedDataSize, BufferSize*mWaveBuffer.size()));
|
||||
|
||||
mRing = CreateRingBuffer(CapturedDataSize, mFormat.nBlockAlign, false);
|
||||
if(!mRing) return ALC_INVALID_VALUE;
|
||||
|
@ -342,7 +342,8 @@ struct ALCdevice {
|
||||
|
||||
ALuint Frequency{};
|
||||
ALuint UpdateSize{};
|
||||
ALuint NumUpdates{};
|
||||
ALuint BufferSize{};
|
||||
|
||||
DevFmtChannels FmtChans{};
|
||||
DevFmtType FmtType{};
|
||||
ALboolean IsHeadphones{AL_FALSE};
|
||||
|
Loading…
x
Reference in New Issue
Block a user