mirror of
https://github.com/XProger/OpenLara.git
synced 2025-04-22 03:51:58 +02:00
play ogg from memory, #15 move sound fill to separated thread
This commit is contained in:
parent
b965ce4ef4
commit
cd2778adcf
@ -121,8 +121,7 @@ InputKey mouseToInputKey(int msg) {
|
||||
}
|
||||
|
||||
// joystick
|
||||
typedef struct _XINPUT_GAMEPAD
|
||||
{
|
||||
typedef struct _XINPUT_GAMEPAD {
|
||||
WORD wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
@ -132,14 +131,12 @@ typedef struct _XINPUT_GAMEPAD
|
||||
SHORT sThumbRY;
|
||||
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
|
||||
|
||||
typedef struct _XINPUT_STATE
|
||||
{
|
||||
typedef struct _XINPUT_STATE {
|
||||
DWORD dwPacketNumber;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
} XINPUT_STATE, *PXINPUT_STATE;
|
||||
|
||||
typedef struct _XINPUT_VIBRATION
|
||||
{
|
||||
typedef struct _XINPUT_VIBRATION {
|
||||
WORD wLeftMotorSpeed;
|
||||
WORD wRightMotorSpeed;
|
||||
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
|
||||
@ -354,10 +351,16 @@ char *sndData;
|
||||
HWAVEOUT waveOut;
|
||||
WAVEFORMATEX waveFmt = { WAVE_FORMAT_PCM, 2, 44100, 44100 * 4, 4, 16, sizeof(waveFmt) };
|
||||
WAVEHDR waveBuf[2];
|
||||
HANDLE sndThread;
|
||||
HANDLE sndSema;
|
||||
|
||||
void sndFree() {
|
||||
if (!sndReady) return;
|
||||
sndReady = false;
|
||||
ReleaseSemaphore(sndSema, 1, NULL);
|
||||
WaitForSingleObject(sndThread, INFINITE);
|
||||
CloseHandle(sndThread);
|
||||
CloseHandle(sndSema);
|
||||
waveOutUnprepareHeader(waveOut, &waveBuf[0], sizeof(WAVEHDR));
|
||||
waveOutUnprepareHeader(waveOut, &waveBuf[1], sizeof(WAVEHDR));
|
||||
waveOutReset(waveOut);
|
||||
@ -365,24 +368,43 @@ void sndFree() {
|
||||
delete[] sndData;
|
||||
}
|
||||
|
||||
void sndFill(HWAVEOUT waveOut, LPWAVEHDR waveBuf) {
|
||||
DWORD WINAPI sndPrep(void* arg) {
|
||||
int idx = 0;
|
||||
while (1) {
|
||||
WaitForSingleObject(sndSema, INFINITE);
|
||||
if (!sndReady) break;
|
||||
|
||||
WAVEHDR *hdr = waveBuf + idx;
|
||||
waveOutUnprepareHeader(waveOut, hdr, sizeof(WAVEHDR));
|
||||
Sound::fill((Sound::Frame*)hdr->lpData, SND_SIZE / 4);
|
||||
waveOutPrepareHeader(waveOut, hdr, sizeof(WAVEHDR));
|
||||
waveOutWrite(waveOut, hdr, sizeof(WAVEHDR));
|
||||
|
||||
idx ^= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sndFill(HWAVEOUT waveOut, LPWAVEHDR waveBufPrev) {
|
||||
if (!sndReady) return;
|
||||
waveOutUnprepareHeader(waveOut, waveBuf, sizeof(WAVEHDR));
|
||||
Sound::fill((Sound::Frame*)waveBuf->lpData, SND_SIZE / 4);
|
||||
waveOutPrepareHeader(waveOut, waveBuf, sizeof(WAVEHDR));
|
||||
waveOutWrite(waveOut, waveBuf, sizeof(WAVEHDR));
|
||||
ReleaseSemaphore(sndSema, 1, NULL);
|
||||
}
|
||||
|
||||
void sndInit(HWND hwnd) {
|
||||
if (waveOutOpen(&waveOut, WAVE_MAPPER, &waveFmt, (INT_PTR)hwnd, 0, CALLBACK_WINDOW) == MMSYSERR_NOERROR) {
|
||||
sndReady = true;
|
||||
sndData = new char[SND_SIZE * 2];
|
||||
memset(sndData, 0, SND_SIZE * 2);
|
||||
memset(&waveBuf, 0, sizeof(waveBuf));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
waveBuf[i].dwBufferLength = SND_SIZE;
|
||||
waveBuf[i].lpData = sndData + SND_SIZE * i;
|
||||
sndFill(waveOut, &waveBuf[i]);
|
||||
WAVEHDR *hdr = waveBuf + i;
|
||||
hdr->dwBufferLength = SND_SIZE;
|
||||
hdr->lpData = sndData + SND_SIZE * i;
|
||||
waveOutPrepareHeader(waveOut, hdr, sizeof(WAVEHDR));
|
||||
waveOutWrite(waveOut, hdr, sizeof(WAVEHDR));
|
||||
}
|
||||
sndSema = CreateSemaphore(NULL, 0, 2, NULL);
|
||||
sndThread = CreateThread(NULL, 0, sndPrep, NULL, 0, NULL);
|
||||
} else {
|
||||
sndReady = false;
|
||||
sndData = NULL;
|
||||
@ -775,7 +797,7 @@ int main(int argc, char** argv) {
|
||||
ContextSwap();
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
Sleep(20);
|
||||
Sleep(10);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
30
src/sound.h
30
src/sound.h
@ -72,7 +72,9 @@ namespace Sound {
|
||||
float out;
|
||||
|
||||
float process(float x, float gain, float damping) {
|
||||
return out = out * damping + x * gain * (1.0f - damping);
|
||||
out = out * damping + x * gain * (1.0f - damping);
|
||||
if (out < EPS) out = 0.0f;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
@ -99,6 +101,9 @@ namespace Sound {
|
||||
panCoeff[i][1] = panCoeff[i + 1][1] = k;
|
||||
}
|
||||
|
||||
memset(df, 0, sizeof(df));
|
||||
memset(af, 0, sizeof(af));
|
||||
|
||||
setRoomSize(vec3(1.0f));
|
||||
}
|
||||
|
||||
@ -120,8 +125,8 @@ namespace Sound {
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
FrameHI &frame = frames[i];
|
||||
float L = frame.L * (1.0f / 32768.0f);
|
||||
float R = frame.R * (1.0f / 32768.0f);
|
||||
float L = frame.L * (1.0f / 32767.0f);
|
||||
float R = frame.R * (1.0f / 32767.0f);
|
||||
float in = (L + R) * 0.5f;
|
||||
float out = 0.0f;
|
||||
|
||||
@ -137,14 +142,13 @@ namespace Sound {
|
||||
// apply pan
|
||||
for (int j = 0; j < MAX_FDN; j++) {
|
||||
output[j] = out - buffer[(j + MAX_FDN - 1) % MAX_FDN];
|
||||
if (output[j] < EPS)
|
||||
output[j] = 0.0f;
|
||||
if (output[j] < EPS) output[j] = 0.0f;
|
||||
L += buffer[j] * panCoeff[j][0];
|
||||
R += buffer[j] * panCoeff[j][1];
|
||||
}
|
||||
|
||||
frame.L = int(L * 32768.0f);
|
||||
frame.R = int(R * 32768.0f);
|
||||
frame.L = int(L * 32767.0f);
|
||||
frame.R = int(R * 32767.0f);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -635,14 +639,19 @@ namespace Sound {
|
||||
stb_vorbis *ogg;
|
||||
stb_vorbis_alloc alloc;
|
||||
|
||||
uint8 *data;
|
||||
|
||||
OGG(Stream *stream, int channels) : Decoder(stream, channels, 0), ogg(NULL) {
|
||||
char buf[255];
|
||||
strcpy(buf, contentDir);
|
||||
strcat(buf, stream->name);
|
||||
|
||||
data = new uint8[stream->size];
|
||||
stream->raw(data, stream->size);
|
||||
|
||||
alloc.alloc_buffer_length_in_bytes = 256 * 1024;
|
||||
alloc.alloc_buffer = new char[alloc.alloc_buffer_length_in_bytes];
|
||||
ogg = stb_vorbis_open_filename(buf, NULL, &alloc);
|
||||
ogg = stb_vorbis_open_memory(data, stream->size, NULL, &alloc);
|
||||
ASSERT(ogg);
|
||||
stb_vorbis_info info = stb_vorbis_get_info(ogg);
|
||||
this->channels = info.channels;
|
||||
@ -652,6 +661,7 @@ namespace Sound {
|
||||
virtual ~OGG() {
|
||||
stb_vorbis_close(ogg);
|
||||
delete[] alloc.alloc_buffer;
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
virtual int decode(Frame *frames, int count) {
|
||||
@ -946,8 +956,8 @@ namespace Sound {
|
||||
|
||||
void convFrames(FrameHI *from, Frame *to, int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
to[i].L = clamp(from[i].L, -32768, 32767);
|
||||
to[i].R = clamp(from[i].R, -32768, 32767);
|
||||
to[i].L = clamp(from[i].L, -32767, 32767);
|
||||
to[i].R = clamp(from[i].R, -32767, 32767);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user