Start making it betterer
This commit is contained in:
parent
0f572a5ebe
commit
a3eefa45ed
@ -2,6 +2,11 @@
|
||||
Segaapi audio library emulator
|
||||
Parts stolen from Sega, teknogods and jayfoxrox
|
||||
Modified by doozer in 2022 to work with Outrun 2 SP under modern Linux
|
||||
|
||||
https://www.openal.org/documentation/
|
||||
https://github.com/teknogods/OpenSegaAPI/blob/master/Opensegaapi/src/opensegaapi.cpp
|
||||
https://web.archive.org/web/20070218003259/http://www.devmaster.net/articles.php?catID=6
|
||||
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -14,20 +19,14 @@
|
||||
#include <AL/alext.h>
|
||||
#include <AL/alut.h>
|
||||
|
||||
//#include "eax4.h"
|
||||
#include "segadef.h"
|
||||
#include "segaerr.h"
|
||||
#include "segaeax.h"
|
||||
|
||||
#include "segaapi.h"
|
||||
|
||||
#define TSF_IMPLEMENTATION
|
||||
#include "tsf.h"
|
||||
|
||||
// help and info
|
||||
// https://www.openal.org/documentation/
|
||||
// https://github.com/teknogods/OpenSegaAPI/blob/master/Opensegaapi/src/opensegaapi.cpp
|
||||
// https://web.archive.org/web/20070218003259/http://www.devmaster.net/articles.php?catID=6
|
||||
|
||||
//#define DEBUG_SAMPLE
|
||||
#define DEBUG_OUTPUT
|
||||
@ -216,36 +215,64 @@ static void dumpWaveBuffer(const char *path, unsigned int channels, unsigned int
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type)
|
||||
{
|
||||
switch(channels)
|
||||
{
|
||||
case AL_MONO_SOFT: size *= 1; break;
|
||||
case AL_STEREO_SOFT: size *= 2; break;
|
||||
case AL_REAR_SOFT: size *= 2; break;
|
||||
case AL_QUAD_SOFT: size *= 4; break;
|
||||
case AL_5POINT1_SOFT: size *= 6; break;
|
||||
case AL_6POINT1_SOFT: size *= 7; break;
|
||||
case AL_7POINT1_SOFT: size *= 8; break;
|
||||
}
|
||||
switch (channels)
|
||||
{
|
||||
case AL_MONO_SOFT:
|
||||
size *= 1;
|
||||
break;
|
||||
case AL_STEREO_SOFT:
|
||||
size *= 2;
|
||||
break;
|
||||
case AL_REAR_SOFT:
|
||||
size *= 2;
|
||||
break;
|
||||
case AL_QUAD_SOFT:
|
||||
size *= 4;
|
||||
break;
|
||||
case AL_5POINT1_SOFT:
|
||||
size *= 6;
|
||||
break;
|
||||
case AL_6POINT1_SOFT:
|
||||
size *= 7;
|
||||
break;
|
||||
case AL_7POINT1_SOFT:
|
||||
size *= 8;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case AL_BYTE_SOFT: size *= sizeof(ALbyte); break;
|
||||
case AL_UNSIGNED_BYTE_SOFT: size *= sizeof(ALubyte); break;
|
||||
case AL_SHORT_SOFT: size *= sizeof(ALshort); break;
|
||||
case AL_UNSIGNED_SHORT_SOFT: size *= sizeof(ALushort); break;
|
||||
case AL_INT_SOFT: size *= sizeof(ALint); break;
|
||||
case AL_UNSIGNED_INT_SOFT: size *= sizeof(ALuint); break;
|
||||
case AL_FLOAT_SOFT: size *= sizeof(ALfloat); break;
|
||||
case AL_DOUBLE_SOFT: size *= sizeof(ALdouble); break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case AL_BYTE_SOFT:
|
||||
size *= sizeof(ALbyte);
|
||||
break;
|
||||
case AL_UNSIGNED_BYTE_SOFT:
|
||||
size *= sizeof(ALubyte);
|
||||
break;
|
||||
case AL_SHORT_SOFT:
|
||||
size *= sizeof(ALshort);
|
||||
break;
|
||||
case AL_UNSIGNED_SHORT_SOFT:
|
||||
size *= sizeof(ALushort);
|
||||
break;
|
||||
case AL_INT_SOFT:
|
||||
size *= sizeof(ALint);
|
||||
break;
|
||||
case AL_UNSIGNED_INT_SOFT:
|
||||
size *= sizeof(ALuint);
|
||||
break;
|
||||
case AL_FLOAT_SOFT:
|
||||
size *= sizeof(ALfloat);
|
||||
break;
|
||||
case AL_DOUBLE_SOFT:
|
||||
size *= sizeof(ALdouble);
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int bufferSampleSize(segaapiContext_t *context)
|
||||
{ // printf("%s %d\n", __func__, __LINE__);
|
||||
return context->channels * ((context->sampleFormat == HASF_SIGNED_16PCM) ? 2 : 1);
|
||||
@ -277,7 +304,6 @@ void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate,
|
||||
samplerate);
|
||||
}
|
||||
|
||||
|
||||
static void updateBufferData(segaapiContext_t *context, unsigned int offset, size_t length)
|
||||
{
|
||||
|
||||
@ -335,18 +361,17 @@ static void updateBufferData(segaapiContext_t *context, unsigned int offset, siz
|
||||
// CHECK();
|
||||
if (offset != -1)
|
||||
{
|
||||
//printf("CANNOT DO IT\n");
|
||||
//exit(1);
|
||||
// printf("CANNOT DO IT\n");
|
||||
// exit(1);
|
||||
wrap_BufferSamples(context->alBuffer, context->sampleRate, alFormat, context->size / bufferSampleSize(context), alChannels, alType, &(context->data[offset]));
|
||||
|
||||
//alBufferSubSamplesSOFT(context->alBuffer, offset / bufferSampleSize(context), length / bufferSampleSize(context), alChannels, alType, &context->data[offset]);
|
||||
// CHECK();
|
||||
// alBufferSubSamplesSOFT(context->alBuffer, offset / bufferSampleSize(context), length / bufferSampleSize(context), alChannels, alType, &context->data[offset]);
|
||||
// CHECK();
|
||||
dbgPrint("Soft update in buffer %X at %u (%u bytes) - buffer playing at %u, unsafe region is %u to %u\n", (uintptr_t)context, offset, length, position, unsafe[0], unsafe[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
alSourcei(context->alSource, AL_BUFFER, AL_NONE);
|
||||
// CHECK();
|
||||
wrap_BufferSamples(context->alBuffer, context->sampleRate, alFormat, context->size / bufferSampleSize(context), alChannels, alType, context->data);
|
||||
@ -488,30 +513,30 @@ SEGASTATUS SEGAAPI_PlayWithSetup(CTHANDLE hHandle)
|
||||
return SEGAERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HAWOSTATUS SEGAAPI_GetPlaybackStatus(CTHANDLE hHandle)
|
||||
PlaybackStatus SEGAAPI_GetPlaybackStatus(CTHANDLE hHandle)
|
||||
{
|
||||
ALint state;
|
||||
|
||||
dbgPrint("SEGAAPI_GetPlaybackStatus() 0x%x", hHandle);
|
||||
segaapiContext_t *context = hHandle;
|
||||
if (context == NULL)
|
||||
return HAWOSTATUS_INVALID;
|
||||
return PLAYBACK_STATUS_INVALID;
|
||||
|
||||
alGetSourcei(context->alSource, AL_SOURCE_STATE, &state);
|
||||
switch (state)
|
||||
{
|
||||
case AL_PLAYING:
|
||||
return HAWOSTATUS_ACTIVE;
|
||||
return PLAYBACK_STATUS_ACTIVE;
|
||||
case AL_PAUSED:
|
||||
return HAWOSTATUS_PAUSE;
|
||||
return PLAYBACK_STATUS_PAUSE;
|
||||
case AL_INITIAL:
|
||||
case AL_STOPPED:
|
||||
return HAWOSTATUS_STOP;
|
||||
return PLAYBACK_STATUS_STOP;
|
||||
default:
|
||||
return HAWOSTATUS_INVALID;
|
||||
return PLAYBACK_STATUS_INVALID;
|
||||
}
|
||||
|
||||
return HAWOSTATUS_INVALID;
|
||||
return PLAYBACK_STATUS_INVALID;
|
||||
}
|
||||
|
||||
SEGASTATUS SEGAAPI_SetFormat(CTHANDLE hHandle, HAWOSEFORMAT *pFormat)
|
||||
@ -738,6 +763,7 @@ SEGASTATUS SEGAAPI_SetSynthParam(CTHANDLE hHandle, HASYNTHPARAMSEXT param, CTLON
|
||||
dbgPrint("SEGAAPI_SetSynthParam() 0x%x 0x%x 0x%x", hHandle, param, lPARWValue);
|
||||
|
||||
segaapiContext_t *context = hHandle;
|
||||
|
||||
if (context == NULL)
|
||||
return SEGAERR_BAD_PARAM;
|
||||
|
||||
@ -1115,21 +1141,21 @@ SEGASTATUS SEGAAPI_Init(void)
|
||||
alBufferSamplesSOFT = alGetProcAddress("alBufferSamplesSOFT");
|
||||
if (alBufferSamplesSOFT == NULL)
|
||||
{
|
||||
dbgPrint("Could not resolve AL extension!\n");
|
||||
//exit(1);
|
||||
dbgPrint("Warning: Could not resolve AL extension!\n");
|
||||
// exit(1);
|
||||
}
|
||||
|
||||
alBufferSubSamplesSOFT = alGetProcAddress("alBufferSubSamplesSOFT");
|
||||
if (alBufferSubSamplesSOFT == NULL)
|
||||
{
|
||||
dbgPrint("Could not resolve AL extension!\n");
|
||||
//exit(1);
|
||||
dbgPrint("Warning: Could not resolve AL extension!\n");
|
||||
// exit(1);
|
||||
}
|
||||
alGetBufferSamplesSOFT = alGetProcAddress("alGetBufferSamplesSOFT");
|
||||
if (alGetBufferSamplesSOFT == NULL)
|
||||
{
|
||||
dbgPrint("Could not resolve AL extension!\n");
|
||||
//exit(1);
|
||||
dbgPrint("Warning: Could not resolve AL extension!\n");
|
||||
// exit(1);
|
||||
}
|
||||
|
||||
SEGAAPI_SetGlobalEAXProperty((GUID *)&EAXPROPERTYID_EAX40_FXSlot2, 0, (void *)&EAX_NULL_GUID, 16);
|
||||
|
@ -120,11 +120,11 @@ typedef enum {
|
||||
* The Playback status.
|
||||
*/
|
||||
typedef enum {
|
||||
HAWOSTATUS_STOP, /* The voice is stopped */
|
||||
HAWOSTATUS_ACTIVE, /* The voice is playing */
|
||||
HAWOSTATUS_PAUSE, /* The voice is paused */
|
||||
HAWOSTATUS_INVALID = -1 /* Invalid state */
|
||||
} HAWOSTATUS;
|
||||
PLAYBACK_STATUS_STOP, /* The voice is stopped */
|
||||
PLAYBACK_STATUS_ACTIVE, /* The voice is playing */
|
||||
PLAYBACK_STATUS_PAUSE, /* The voice is paused */
|
||||
PLAYBACK_STATUS_INVALID = -1 /* Invalid state */
|
||||
} PlaybackStatus;
|
||||
|
||||
|
||||
/*
|
||||
@ -420,10 +420,10 @@ SEGASTATUS SEGAAPI_PlayWithSetup(CTHANDLE hHandle);
|
||||
* An opaque identifier obtained from CreateBuffer.
|
||||
*
|
||||
* @return
|
||||
* One of the playback status defined in the HAWOSTATUS enumration type.
|
||||
* If the returned status is HAWOSTATUS_INVALID, use GetLastStatus() to check the error code.
|
||||
* One of the playback status defined in the PlaybackStatus enumration type.
|
||||
* If the returned status is PLAYBACK_STATUS_INVALID, use GetLastStatus() to check the error code.
|
||||
*/
|
||||
HAWOSTATUS SEGAAPI_GetPlaybackStatus(CTHANDLE hHandle);
|
||||
PlaybackStatus SEGAAPI_GetPlaybackStatus(CTHANDLE hHandle);
|
||||
|
||||
|
||||
|
||||
@ -989,7 +989,7 @@ CTDWORD SEGAAPI_GetEndLoopOffset(CTHANDLE hHandle);
|
||||
* the buffer will halt.
|
||||
*
|
||||
* Only change the End offset position when buffer is not at
|
||||
* HAWOSTATUS_ACTIVE state. End Offset must be sample frame aligned.
|
||||
* PLAYBACK_STATUS_ACTIVE state. End Offset must be sample frame aligned.
|
||||
* For example, 16-bit 1 channel is WORD aligned, 16-bit 2 channel
|
||||
* is DWORD aligned.
|
||||
*
|
||||
|
@ -1,23 +1,8 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2004 Creative Technology Ltd. All rights reserved.
|
||||
*
|
||||
****************************************************************************
|
||||
* File: segadef.h
|
||||
*
|
||||
* This file contains the types definitions for segaapi.
|
||||
*
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __CTDEF_H
|
||||
|
||||
#ifndef __SEGAAPITYPES_H
|
||||
#define __SEGAAPITYPES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
/* 8 bit signed value */
|
||||
typedef char CTCHAR, *PCTCHAR, **PPCTCHAR;
|
||||
@ -66,11 +51,6 @@ typedef void * CTHANDLE;
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* __SEGAAPITYPES_H */
|
||||
|
||||
#endif /* __CTDEF_H */
|
||||
|
@ -1,29 +1,8 @@
|
||||
/**
|
||||
* Copyright (C) 2005 Creative Technology Ltd. All rights reserved.
|
||||
*
|
||||
****************************************************************************
|
||||
* \file segaeax.cpp
|
||||
* \brief
|
||||
* This file contains the definition of Environmental Audio Extensions version 4.0.
|
||||
* It is duplicated here for SEGAAPI_SetGlobalEAXProperty and SEGAAPI_GetGlobalEAXProperty
|
||||
* to use.
|
||||
*
|
||||
* @author CW Lim
|
||||
*
|
||||
* $Date: 2005/02/02 11:59:54 $
|
||||
*
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __SEGAEAX_H
|
||||
#define __SEGAEAX_H
|
||||
|
||||
#include "segadef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#pragma pack(push, 4)
|
||||
@ -1471,8 +1450,5 @@ typedef struct _EAXRINGMODULATORPROPERTIES
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __SEGAEAX_H
|
||||
|
Loading…
Reference in New Issue
Block a user