Implemented audio for OS/2 by using KAI

This commit is contained in:
Jochen Sch„fer 2024-05-05 09:26:18 +02:00
parent bf636a67e4
commit f41071c25b
2 changed files with 41 additions and 65 deletions

View File

@ -43,7 +43,7 @@ APP_AUTHOR := UnknownShadow200
CC := gcc CC := gcc
CFLAGS := -pipe -fno-math-errno -O3 -g -mtune=pentium4 -msse2 -march=i686 -idirafter /@unixroot/usr/include/os2tk45 -DOS2 CFLAGS := -pipe -fno-math-errno -O3 -g -mtune=pentium4 -msse2 -march=i686 -idirafter /@unixroot/usr/include/os2tk45 -DOS2
LDFLAGS := -Zhigh-mem -Zomf -Zargs-wild -Zargs-resp -Zlinker DISABLE -Zlinker 1121 LDFLAGS := -Zhigh-mem -Zomf -Zargs-wild -Zargs-resp -Zlinker DISABLE -Zlinker 1121
LIBS := -lcx -lmmpm2 -lpthread LIBS := -lcx -lmmpm2 -lpthread /@unixroot/usr/local/lib/kai.a
$(TARGET).exe: $(BUILD_DIR) $(OBJECTS) $(TARGET).exe: $(BUILD_DIR) $(OBJECTS)
$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS) $(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS)

View File

@ -1544,7 +1544,7 @@ struct AudioContext {
HKAI hkai; HKAI hkai;
void *buffers[AUDIO_MAX_BUFFERS]; void *buffers[AUDIO_MAX_BUFFERS];
cc_uint32 bufferSize[AUDIO_MAX_BUFFERS]; cc_uint32 bufferSize[AUDIO_MAX_BUFFERS];
int fillBuffer, playbackBuffer; int fillBuffer, drainBuffer;
int indexIntoBuffer; int indexIntoBuffer;
}; };
@ -1555,66 +1555,38 @@ CC_INLINE void getNextBuffer(int count, int *bufferIndex) {
ULONG APIENTRY kaiCallback(PVOID data, PVOID buffer, ULONG size) { ULONG APIENTRY kaiCallback(PVOID data, PVOID buffer, ULONG size) {
struct AudioContext *ctx = (struct AudioContext*)data; struct AudioContext *ctx = (struct AudioContext*)data;
void* dest = buffer; char* dst = buffer;
void* src = ctx->buffers[ctx->playbackBuffer]; void* src = ctx->buffers[ctx->drainBuffer];
cc_uint32 len = 0; cc_uint32 read = 0;
cc_uint32 bufferRemaining = ctx->bufferSize[ctx->playbackBuffer] - ctx->indexIntoBuffer;
if (src == NULL) {// Current buffer is empty
int inUse = 0;
Audio_Poll(ctx, &inUse);
if (inUse == 0) {
// No more buffers, we are done.
printf("Short Done\n");
return 0;
}
//Search for next buffer
for(inUse = 0; inUse < ctx->count; inUse++) {
getNextBuffer(ctx->count, &ctx->playbackBuffer);
if (ctx->buffers[ctx->playbackBuffer] != NULL) {
src = ctx->buffers[ctx->playbackBuffer];
bufferRemaining = ctx->bufferSize[ctx->playbackBuffer] - ctx->indexIntoBuffer;
break;
}
}
}
len = min(bufferRemaining, size);
Mem_Copy(dest, src, len);
// We have to fill the buffer completely, or KAI will stop playback if (!src) return 0; // Reached end of playable queue
if (len < size) {
cc_uint32 len2 = size - len; while (size) {
// Reset the current buffer cc_uint32 bufferLeft = ctx->bufferSize[ctx->drainBuffer] - ctx->indexIntoBuffer;
ctx->bufferSize[ctx->playbackBuffer] = 0; cc_uint32 len = min(bufferLeft, size);
ctx->buffers[ctx->playbackBuffer] = NULL;
// Begin at the next buffer and go to it// Goto next buffer
ctx->indexIntoBuffer = 0;
getNextBuffer(ctx->count, &ctx->playbackBuffer);
src = ctx->buffers[ctx->playbackBuffer];
// Most likely we are done
if (src == NULL) return len;
Mem_Copy(dest + len, src, len2); Mem_Copy(dst, src + ctx->indexIntoBuffer, len);
len += len2;
ctx->indexIntoBuffer += len2; dst += len;
read += len;
size -= len;
ctx->indexIntoBuffer += len;
// Finished current buffer
if (ctx->indexIntoBuffer >= ctx->bufferSize[ctx->drainBuffer]) {
// Reset the current buffer
ctx->bufferSize[ctx->drainBuffer] = 0;
ctx->buffers[ctx->drainBuffer] = NULL;
// Begin at the next buffer and go to it
ctx->drainBuffer = (ctx->drainBuffer + 1) % ctx->count;
ctx->indexIntoBuffer = 0;
src = ctx->buffers[ctx->drainBuffer];
if (!src) break; // Reached end of playable queue
}
} }
//printf("callback %d %d %d %d\n",size,ctx->count,ctx->bufferSize,len);
//printf("copied %d index %d buffer# %d\n", len, ctx->indexIntoBuffer, ctx->playbackBuffer);
ctx->indexIntoBuffer += len; return read;
if (ctx->indexIntoBuffer >= ctx->bufferSize[ctx->playbackBuffer]) { }
// Reset the current buffer
ctx->bufferSize[ctx->playbackBuffer] = 0;
ctx->buffers[ctx->playbackBuffer] = NULL;
// Begin at the next buffer and go to it
ctx->indexIntoBuffer = 0;
getNextBuffer(ctx->count, &ctx->playbackBuffer);
}
if (len < size) printf("Done\n");
return len;
}
cc_bool AudioBackend_Init(void) { cc_bool AudioBackend_Init(void) {
KAISPEC ksWanted, ksObtained; KAISPEC ksWanted, ksObtained;
@ -1641,13 +1613,14 @@ cc_result Audio_Init(struct AudioContext* ctx, int buffers) {
ctx->bufferSize[i] = 0; ctx->bufferSize[i] = 0;
} }
ctx->fillBuffer = 0; ctx->fillBuffer = 0;
ctx->playbackBuffer = 0; ctx->drainBuffer = 0;
ctx->indexIntoBuffer = 0; ctx->indexIntoBuffer = 0;
return 0; return 0;
} }
void Audio_Close(struct AudioContext* ctx) { void Audio_Close(struct AudioContext* ctx) {
printf("Audio_CLose\n"); printf("Audio_CLose\n");
ctx->count = 0;
if (ctx->hkai > 0) { if (ctx->hkai > 0) {
kaiStop(ctx->hkai); kaiStop(ctx->hkai);
kaiClose(ctx->hkai); kaiClose(ctx->hkai);
@ -1664,8 +1637,8 @@ cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate
ksWanted.ulSamplingRate = Audio_AdjustSampleRate(sampleRate, playbackRate); ksWanted.ulSamplingRate = Audio_AdjustSampleRate(sampleRate, playbackRate);
ksWanted.ulDataFormat = 0; ksWanted.ulDataFormat = 0;
ksWanted.ulChannels = channels; ksWanted.ulChannels = channels;
ksWanted.ulNumBuffers = ctx->count; ksWanted.ulNumBuffers = 0;
ksWanted.ulBufferSize = 4096*8; ksWanted.ulBufferSize = 0;
ksWanted.fShareable = TRUE; ksWanted.fShareable = TRUE;
ksWanted.pfnCallBack = kaiCallback; ksWanted.pfnCallBack = kaiCallback;
ksWanted.pCallBackData = (PVOID)ctx; ksWanted.pCallBackData = (PVOID)ctx;
@ -1676,8 +1649,8 @@ cc_result Audio_SetFormat(struct AudioContext* ctx, int channels, int sampleRate
ctx->hkai = 0; ctx->hkai = 0;
return rc; return rc;
} }
kaiSetSoundState(ctx->hkai, MCI_SET_AUDIO_ALL, true); kaiSetSoundState(ctx->hkai, MCI_SET_AUDIO_ALL, true);
return 0; return 0;
} }
@ -1687,10 +1660,13 @@ void Audio_SetVolume(struct AudioContext* ctx, int volume) {
} }
cc_result Audio_QueueChunk(struct AudioContext* ctx, void* chunk, cc_uint32 size) { cc_result Audio_QueueChunk(struct AudioContext* ctx, void* chunk, cc_uint32 size) {
if (ctx->buffers[ctx->fillBuffer])
return ERR_INVALID_ARGUMENT; // tried to queue data while either playing or queued still
//printf("-> select buffer %d\n", ctx->fillBuffer); //printf("-> select buffer %d\n", ctx->fillBuffer);
ctx->buffers[ctx->fillBuffer] = chunk; ctx->buffers[ctx->fillBuffer] = chunk;
ctx->bufferSize[ctx->fillBuffer] = size; ctx->bufferSize[ctx->fillBuffer] = size;
getNextBuffer(ctx->count, &ctx->fillBuffer); ctx->fillBuffer = (ctx->fillBuffer + 1) % ctx->count;
//printf("<- select buffer %d\n", ctx->fillBuffer); //printf("<- select buffer %d\n", ctx->fillBuffer);
return 0; return 0;
} }