Use a better method to time the Null and Wave Writer backends
This better compensates for precision loss when converting milliseconds to the sample rate
This commit is contained in:
parent
ee61f7a55c
commit
ae41ad5d1e
35
Alc/null.c
35
Alc/null.c
@ -30,6 +30,8 @@ typedef struct {
|
|||||||
ALvoid *buffer;
|
ALvoid *buffer;
|
||||||
ALuint size;
|
ALuint size;
|
||||||
|
|
||||||
|
ALuint startTime;
|
||||||
|
|
||||||
volatile int killNow;
|
volatile int killNow;
|
||||||
ALvoid *thread;
|
ALvoid *thread;
|
||||||
} null_data;
|
} null_data;
|
||||||
@ -41,30 +43,34 @@ static ALuint NullProc(ALvoid *ptr)
|
|||||||
{
|
{
|
||||||
ALCdevice *Device = (ALCdevice*)ptr;
|
ALCdevice *Device = (ALCdevice*)ptr;
|
||||||
null_data *data = (null_data*)Device->ExtraData;
|
null_data *data = (null_data*)Device->ExtraData;
|
||||||
ALuint frameSize;
|
ALuint now, start;
|
||||||
ALuint now, last;
|
ALuint64 avail, done;
|
||||||
ALuint avail;
|
const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 /
|
||||||
|
Device->Frequency / 2;
|
||||||
|
|
||||||
frameSize = aluFrameSizeFromFormat(Device->Format);
|
done = 0;
|
||||||
|
start = data->startTime;
|
||||||
last = timeGetTime()<<8;
|
|
||||||
while(!data->killNow && Device->Connected)
|
while(!data->killNow && Device->Connected)
|
||||||
{
|
{
|
||||||
now = timeGetTime()<<8;
|
now = timeGetTime();
|
||||||
|
|
||||||
avail = (ALuint64)(now-last) * Device->Frequency / (1000<<8);
|
avail = (ALuint64)(now-start) * Device->Frequency / 1000;
|
||||||
if(avail < Device->UpdateSize)
|
if(avail < done)
|
||||||
{
|
{
|
||||||
Sleep(1);
|
AL_PRINT("Timer wrapped\n");
|
||||||
|
aluHandleDisconnect(Device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(avail-done < Device->UpdateSize)
|
||||||
|
{
|
||||||
|
Sleep(restTime);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(avail >= Device->UpdateSize)
|
while(avail-done >= Device->UpdateSize)
|
||||||
{
|
{
|
||||||
aluMixData(Device, data->buffer, Device->UpdateSize);
|
aluMixData(Device, data->buffer, Device->UpdateSize);
|
||||||
|
done += Device->UpdateSize;
|
||||||
avail -= Device->UpdateSize;
|
|
||||||
last += (ALuint64)Device->UpdateSize * (1000<<8) / Device->Frequency;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +117,7 @@ static ALCboolean null_reset_playback(ALCdevice *device)
|
|||||||
device->TimeRes = (ALuint64)device->UpdateSize * 1000000000 /
|
device->TimeRes = (ALuint64)device->UpdateSize * 1000000000 /
|
||||||
device->Frequency;
|
device->Frequency;
|
||||||
|
|
||||||
|
data->startTime = timeGetTime();
|
||||||
data->thread = StartThread(NullProc, device);
|
data->thread = StartThread(NullProc, device);
|
||||||
if(data->thread == NULL)
|
if(data->thread == NULL)
|
||||||
{
|
{
|
||||||
|
32
Alc/wave.c
32
Alc/wave.c
@ -35,6 +35,8 @@ typedef struct {
|
|||||||
ALvoid *buffer;
|
ALvoid *buffer;
|
||||||
ALuint size;
|
ALuint size;
|
||||||
|
|
||||||
|
ALuint startTime;
|
||||||
|
|
||||||
volatile int killNow;
|
volatile int killNow;
|
||||||
ALvoid *thread;
|
ALvoid *thread;
|
||||||
} wave_data;
|
} wave_data;
|
||||||
@ -68,32 +70,42 @@ static ALuint WaveProc(ALvoid *ptr)
|
|||||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||||
wave_data *data = (wave_data*)pDevice->ExtraData;
|
wave_data *data = (wave_data*)pDevice->ExtraData;
|
||||||
ALuint frameSize;
|
ALuint frameSize;
|
||||||
ALuint now, last;
|
ALuint now, start;
|
||||||
|
ALuint64 avail, done;
|
||||||
size_t fs;
|
size_t fs;
|
||||||
ALuint avail;
|
|
||||||
union {
|
union {
|
||||||
short s;
|
short s;
|
||||||
char b[sizeof(short)];
|
char b[sizeof(short)];
|
||||||
} uSB;
|
} uSB;
|
||||||
|
const ALuint restTime = (ALuint64)pDevice->UpdateSize * 1000 /
|
||||||
|
pDevice->Frequency / 2;
|
||||||
|
|
||||||
uSB.s = 1;
|
uSB.s = 1;
|
||||||
frameSize = aluFrameSizeFromFormat(pDevice->Format);
|
frameSize = aluFrameSizeFromFormat(pDevice->Format);
|
||||||
|
|
||||||
last = timeGetTime()<<8;
|
done = 0;
|
||||||
|
start = data->startTime;
|
||||||
while(!data->killNow && pDevice->Connected)
|
while(!data->killNow && pDevice->Connected)
|
||||||
{
|
{
|
||||||
now = timeGetTime()<<8;
|
now = timeGetTime();
|
||||||
|
|
||||||
avail = (ALuint64)(now-last) * pDevice->Frequency / (1000<<8);
|
avail = (ALuint64)(now-start) * pDevice->Frequency / 1000;
|
||||||
if(avail < pDevice->UpdateSize)
|
if(avail < done)
|
||||||
{
|
{
|
||||||
Sleep(1);
|
AL_PRINT("Timer wrapped\n");
|
||||||
|
aluHandleDisconnect(pDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(avail-done < pDevice->UpdateSize)
|
||||||
|
{
|
||||||
|
Sleep(restTime);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(avail >= pDevice->UpdateSize)
|
while(avail-done >= pDevice->UpdateSize)
|
||||||
{
|
{
|
||||||
aluMixData(pDevice, data->buffer, pDevice->UpdateSize);
|
aluMixData(pDevice, data->buffer, pDevice->UpdateSize);
|
||||||
|
done += pDevice->UpdateSize;
|
||||||
|
|
||||||
if(uSB.b[0] != 1)
|
if(uSB.b[0] != 1)
|
||||||
{
|
{
|
||||||
@ -125,9 +137,6 @@ static ALuint WaveProc(ALvoid *ptr)
|
|||||||
aluHandleDisconnect(pDevice);
|
aluHandleDisconnect(pDevice);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
avail -= pDevice->UpdateSize;
|
|
||||||
last += (ALuint64)pDevice->UpdateSize * (1000<<8) / pDevice->Frequency;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +286,7 @@ static ALCboolean wave_reset_playback(ALCdevice *device)
|
|||||||
device->Frequency;
|
device->Frequency;
|
||||||
SetDefaultWFXChannelOrder(device);
|
SetDefaultWFXChannelOrder(device);
|
||||||
|
|
||||||
|
data->startTime = timeGetTime();
|
||||||
data->thread = StartThread(WaveProc, device);
|
data->thread = StartThread(WaveProc, device);
|
||||||
if(data->thread == NULL)
|
if(data->thread == NULL)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user