mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-26 03:30:46 +00:00
Misc audiolib cleanups
git-svn-id: https://svn.eduke32.com/eduke32@8213 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/audiolib/src/fx_man.cpp # source/audiolib/src/multivoc.cpp # Conflicts: # source/audiolib/include/multivoc.h # source/audiolib/src/multivoc.cpp # source/audiolib/src/vorbis.cpp
This commit is contained in:
parent
89cd122d14
commit
c0b7745013
11 changed files with 203 additions and 276 deletions
|
@ -34,7 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "drivers.h"
|
#include "drivers.h"
|
||||||
|
|
||||||
typedef enum
|
typedef enum : char
|
||||||
{
|
{
|
||||||
FMT_UNKNOWN,
|
FMT_UNKNOWN,
|
||||||
FMT_RAW,
|
FMT_RAW,
|
||||||
|
@ -83,9 +83,7 @@ void MV_SetReverb(int32_t reverb);
|
||||||
int32_t MV_GetMaxReverbDelay(void);
|
int32_t MV_GetMaxReverbDelay(void);
|
||||||
int32_t MV_GetReverbDelay(void);
|
int32_t MV_GetReverbDelay(void);
|
||||||
void MV_SetReverbDelay(int32_t delay);
|
void MV_SetReverbDelay(int32_t delay);
|
||||||
// int32_t MV_SetMixMode( int32_t numchannels, int32_t samplebits );
|
|
||||||
// int32_t MV_StartPlayback( void );
|
|
||||||
// void MV_StopPlayback( void );
|
|
||||||
int32_t MV_PlayWAV3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchoffset, int32_t angle, int32_t distance, int32_t priority,
|
int32_t MV_PlayWAV3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchoffset, int32_t angle, int32_t distance, int32_t priority,
|
||||||
float volume, intptr_t callbackval);
|
float volume, intptr_t callbackval);
|
||||||
int32_t MV_PlayWAV(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
|
int32_t MV_PlayWAV(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
|
||||||
|
@ -118,7 +116,6 @@ int MV_IdentifyXMP(char const *ptr, uint32_t length);
|
||||||
int32_t MV_GetPosition(int32_t handle, int32_t *position);
|
int32_t MV_GetPosition(int32_t handle, int32_t *position);
|
||||||
int32_t MV_SetPosition(int32_t handle, int32_t position);
|
int32_t MV_SetPosition(int32_t handle, int32_t position);
|
||||||
|
|
||||||
// void MV_CreateVolumeTable( int32_t index, int32_t volume, int32_t MaxVolume );
|
|
||||||
void MV_SetVolume(int32_t volume);
|
void MV_SetVolume(int32_t volume);
|
||||||
int32_t MV_GetVolume(void);
|
int32_t MV_GetVolume(void);
|
||||||
void MV_SetCallBack(void (*function)(intptr_t));
|
void MV_SetCallBack(void (*function)(intptr_t));
|
||||||
|
@ -127,6 +124,6 @@ int32_t MV_GetReverseStereo(void);
|
||||||
int32_t MV_Init(int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numchannels,
|
int32_t MV_Init(int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numchannels,
|
||||||
void *initdata);
|
void *initdata);
|
||||||
int32_t MV_Shutdown(void);
|
int32_t MV_Shutdown(void);
|
||||||
void MV_SetPrintf(void (*function)(const char *fmt, ...));
|
static inline void MV_SetPrintf(void (*function)(const char *, ...)) { if (function) MV_Printf = function; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -232,7 +232,11 @@ extern int32_t MV_ErrorCode;
|
||||||
extern int32_t MV_Installed;
|
extern int32_t MV_Installed;
|
||||||
extern int32_t MV_MixRate;
|
extern int32_t MV_MixRate;
|
||||||
|
|
||||||
#define MV_SetErrorCode(status) MV_ErrorCode = (status);
|
static FORCE_INLINE int MV_SetErrorCode(int status)
|
||||||
|
{
|
||||||
|
MV_ErrorCode = status;
|
||||||
|
return MV_Error;
|
||||||
|
}
|
||||||
|
|
||||||
void MV_PlayVoice(VoiceNode *voice);
|
void MV_PlayVoice(VoiceNode *voice);
|
||||||
|
|
||||||
|
|
|
@ -112,8 +112,7 @@ static void FillBuffer(int32_t bufnum)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fail:
|
fail:
|
||||||
if (MV_Printf)
|
MV_Printf("DirectSound FillBuffer: err %x\n", (uint32_t)err);
|
||||||
MV_Printf("DirectSound FillBuffer: err %x\n", (uint32_t)err);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -158,8 +157,7 @@ static DWORD WINAPI fillDataThread(LPVOID lpParameter)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (MV_Printf)
|
MV_Printf("DirectSound fillDataThread: wfmo err %d\n", (int32_t)waitret);
|
||||||
MV_Printf("DirectSound fillDataThread: wfmo err %d\n", (int32_t)waitret);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,13 +170,10 @@ static DWORD WINAPI fillDataThread(LPVOID lpParameter)
|
||||||
static void TeardownDSound(HRESULT err)
|
static void TeardownDSound(HRESULT err)
|
||||||
{
|
{
|
||||||
if (FAILED(err))
|
if (FAILED(err))
|
||||||
{
|
MV_Printf("Dying error: %x\n", (uint32_t)err);
|
||||||
if (MV_Printf)
|
|
||||||
MV_Printf("Dying error: %x\n", (uint32_t)err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpdsnotify)
|
if (lpdsnotify)
|
||||||
IDirectSoundNotify_Release(lpdsnotify), lpdsnotify = NULL;
|
IDirectSoundNotify_Release(lpdsnotify), lpdsnotify = nullptr;
|
||||||
|
|
||||||
for (int i = 0; i < MIXBUFFERPOSITIONS + 1; i++)
|
for (int i = 0; i < MIXBUFFERPOSITIONS + 1; i++)
|
||||||
{
|
{
|
||||||
|
@ -189,17 +184,17 @@ static void TeardownDSound(HRESULT err)
|
||||||
|
|
||||||
#ifdef RENDERTYPEWIN
|
#ifdef RENDERTYPEWIN
|
||||||
if (mutex)
|
if (mutex)
|
||||||
CloseHandle(mutex), mutex = NULL;
|
CloseHandle(mutex), mutex = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (lpdsbsec)
|
if (lpdsbsec)
|
||||||
IDirectSoundBuffer_Release(lpdsbsec), lpdsbsec = NULL;
|
IDirectSoundBuffer_Release(lpdsbsec), lpdsbsec = nullptr;
|
||||||
|
|
||||||
if (lpdsbprimary)
|
if (lpdsbprimary)
|
||||||
IDirectSoundBuffer_Release(lpdsbprimary), lpdsbprimary = NULL;
|
IDirectSoundBuffer_Release(lpdsbprimary), lpdsbprimary = nullptr;
|
||||||
|
|
||||||
if (lpds)
|
if (lpds)
|
||||||
IDirectSound_Release(lpds), lpds = NULL;
|
IDirectSound_Release(lpds), lpds = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DirectSound_Error(HRESULT err, int code)
|
static int DirectSound_Error(HRESULT err, int code)
|
||||||
|
@ -254,13 +249,13 @@ int32_t DirectSoundDrv_PCM_Init(int32_t *mixrate, int32_t *numchannels, void * i
|
||||||
for (int i = 0; i < MIXBUFFERPOSITIONS; i++)
|
for (int i = 0; i < MIXBUFFERPOSITIONS; i++)
|
||||||
{
|
{
|
||||||
notifyPositions[i].dwOffset = (bufdesc.dwBufferBytes/MIXBUFFERPOSITIONS)*i;
|
notifyPositions[i].dwOffset = (bufdesc.dwBufferBytes/MIXBUFFERPOSITIONS)*i;
|
||||||
notifyPositions[i].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
|
notifyPositions[i].hEventNotify = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
if (!notifyPositions[i].hEventNotify)
|
if (!notifyPositions[i].hEventNotify)
|
||||||
return DirectSound_Error(DS_OK, DSErr_NotifyEvents);
|
return DirectSound_Error(DS_OK, DSErr_NotifyEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyPositions[MIXBUFFERPOSITIONS].dwOffset = DSBPN_OFFSETSTOP;
|
notifyPositions[MIXBUFFERPOSITIONS].dwOffset = DSBPN_OFFSETSTOP;
|
||||||
notifyPositions[MIXBUFFERPOSITIONS].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
|
notifyPositions[MIXBUFFERPOSITIONS].hEventNotify = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
|
|
||||||
if (FAILED(err = IDirectSoundNotify_SetNotificationPositions(lpdsnotify, MIXBUFFERPOSITIONS+1, notifyPositions)))
|
if (FAILED(err = IDirectSoundNotify_SetNotificationPositions(lpdsnotify, MIXBUFFERPOSITIONS+1, notifyPositions)))
|
||||||
return DirectSound_Error(err, DSErr_SetNotificationPositions);
|
return DirectSound_Error(err, DSErr_SetNotificationPositions);
|
||||||
|
@ -306,7 +301,7 @@ int32_t DirectSoundDrv_PCM_BeginPlayback(char *BufferStart, int32_t BufferSize,
|
||||||
// prime the buffer
|
// prime the buffer
|
||||||
FillBuffer(0);
|
FillBuffer(0);
|
||||||
|
|
||||||
if ((mixThread = CreateThread(NULL, 0, fillDataThread, 0, 0, 0)) == NULL)
|
if ((mixThread = CreateThread(nullptr, 0, fillDataThread, 0, 0, 0)) == nullptr)
|
||||||
{
|
{
|
||||||
ErrorCode = DSErr_CreateThread;
|
ErrorCode = DSErr_CreateThread;
|
||||||
return DSErr_Error;
|
return DSErr_Error;
|
||||||
|
|
|
@ -40,20 +40,20 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int32_t ErrorCode = SDLErr_Ok;
|
static int32_t ErrorCode = SDLErr_Ok;
|
||||||
static int32_t Initialised = 0;
|
static int32_t Initialised;
|
||||||
static int32_t Playing = 0;
|
static int32_t Playing;
|
||||||
static int32_t StartedSDL = -1;
|
static int32_t StartedSDL = -1;
|
||||||
|
|
||||||
static char *MixBuffer = 0;
|
static char *MixBuffer;
|
||||||
static int32_t MixBufferSize = 0;
|
static int32_t MixBufferSize;
|
||||||
static int32_t MixBufferCount = 0;
|
static int32_t MixBufferCount;
|
||||||
static int32_t MixBufferCurrent = 0;
|
static int32_t MixBufferCurrent;
|
||||||
static int32_t MixBufferUsed = 0;
|
static int32_t MixBufferUsed;
|
||||||
static void ( *MixCallBack )( void ) = 0;
|
static void ( *MixCallBack )( void );
|
||||||
|
|
||||||
static Mix_Chunk *DummyChunk = NULL;
|
static Mix_Chunk *DummyChunk;
|
||||||
static uint8_t *DummyBuffer = NULL;
|
static uint8_t *DummyBuffer;
|
||||||
static int32_t InterruptsDisabled = 0;
|
static int32_t InterruptsDisabled;
|
||||||
static mutex_t EffectFence;
|
static mutex_t EffectFence;
|
||||||
|
|
||||||
static void fillData(int chan, void *ptr, int remaining, void *udata)
|
static void fillData(int chan, void *ptr, int remaining, void *udata)
|
||||||
|
@ -198,13 +198,13 @@ int32_t SDLDrv_PCM_Init(int32_t *mixrate, int32_t *numchannels, void * initdata)
|
||||||
*mixrate = intmixrate;
|
*mixrate = intmixrate;
|
||||||
*numchannels = intnumchannels;
|
*numchannels = intnumchannels;
|
||||||
|
|
||||||
//Mix_SetPostMix(fillData, NULL);
|
//Mix_SetPostMix(fillData, nullptr);
|
||||||
|
|
||||||
mutex_init(&EffectFence);
|
mutex_init(&EffectFence);
|
||||||
|
|
||||||
// channel 0 and 1 are actual sounds
|
// channel 0 and 1 are actual sounds
|
||||||
// dummy channel 2 runs our fillData() callback as an effect
|
// dummy channel 2 runs our fillData() callback as an effect
|
||||||
Mix_RegisterEffect(2, fillData, NULL, NULL);
|
Mix_RegisterEffect(2, fillData, nullptr, nullptr);
|
||||||
|
|
||||||
DummyBuffer = (uint8_t *) calloc(1, chunksize);
|
DummyBuffer = (uint8_t *) calloc(1, chunksize);
|
||||||
|
|
||||||
|
@ -223,10 +223,10 @@ void SDLDrv_PCM_Shutdown(void)
|
||||||
return;
|
return;
|
||||||
else Mix_HaltChannel(-1);
|
else Mix_HaltChannel(-1);
|
||||||
|
|
||||||
if (DummyChunk != NULL)
|
if (DummyChunk != nullptr)
|
||||||
{
|
{
|
||||||
Mix_FreeChunk(DummyChunk);
|
Mix_FreeChunk(DummyChunk);
|
||||||
DummyChunk = NULL;
|
DummyChunk = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DO_FREE_AND_NULL(DummyBuffer);
|
DO_FREE_AND_NULL(DummyBuffer);
|
||||||
|
|
|
@ -34,10 +34,10 @@
|
||||||
#include "FLAC/all.h"
|
#include "FLAC/all.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "pitch.h"
|
|
||||||
#include "multivoc.h"
|
|
||||||
#include "_multivc.h"
|
#include "_multivc.h"
|
||||||
|
#include "multivoc.h"
|
||||||
|
#include "pitch.h"
|
||||||
|
#include "pragmas.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -233,12 +233,12 @@ FLAC__StreamDecoderWriteStatus write_flac_stream(const FLAC__StreamDecoder *deco
|
||||||
(FLAC__uint64)(uintptr_t)voice->LoopStart, (FLAC__uint64)(uintptr_t)voice->LoopEnd);
|
(FLAC__uint64)(uintptr_t)voice->LoopStart, (FLAC__uint64)(uintptr_t)voice->LoopEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t const size = samples * voice->channels * (voice->bits / 8);
|
size_t const size = samples * voice->channels * (voice->bits >> 3);
|
||||||
|
|
||||||
voice->position = 0;
|
voice->position = 0;
|
||||||
voice->BlockLength = 0;
|
voice->BlockLength = 0;
|
||||||
// CODEDUP multivoc.c MV_SetVoicePitch
|
// CODEDUP multivoc.c MV_SetVoicePitch
|
||||||
voice->RateScale = (voice->SamplingRate * voice->PitchScale) / MV_MixRate;
|
voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate);
|
||||||
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
||||||
MV_SetVoiceMixMode(voice);
|
MV_SetVoiceMixMode(voice);
|
||||||
|
|
||||||
|
@ -389,10 +389,7 @@ int32_t MV_PlayFLAC3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitch
|
||||||
int32_t status;
|
int32_t status;
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance < 0)
|
if (distance < 0)
|
||||||
{
|
{
|
||||||
|
@ -431,24 +428,18 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
UNREFERENCED_PARAMETER(loopend);
|
UNREFERENCED_PARAMETER(loopend);
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = (flac_data *)Xcalloc(1, sizeof(flac_data));
|
fd = (flac_data *)Xcalloc(1, sizeof(flac_data));
|
||||||
if (!fd)
|
if (!fd)
|
||||||
{
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd->ptr = ptr;
|
fd->ptr = ptr;
|
||||||
fd->pos = 0;
|
fd->pos = 0;
|
||||||
fd->blocksize = 0;
|
fd->blocksize = 0;
|
||||||
fd->length = length;
|
fd->length = length;
|
||||||
|
|
||||||
fd->block = NULL;
|
fd->block = nullptr;
|
||||||
|
|
||||||
fd->stream = FLAC__stream_decoder_new();
|
fd->stream = FLAC__stream_decoder_new();
|
||||||
fd->sample_pos = 0;
|
fd->sample_pos = 0;
|
||||||
|
@ -457,24 +448,22 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
|
|
||||||
if (FLAC__stream_decoder_init_stream(fd->stream, read_flac_stream, seek_flac_stream, tell_flac_stream,
|
if (FLAC__stream_decoder_init_stream(fd->stream, read_flac_stream, seek_flac_stream, tell_flac_stream,
|
||||||
length_flac_stream, eof_flac_stream, write_flac_stream,
|
length_flac_stream, eof_flac_stream, write_flac_stream,
|
||||||
/*metadata_flac_stream*/ NULL, error_flac_stream,
|
/*metadata_flac_stream*/ nullptr, error_flac_stream,
|
||||||
(void *)fd) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
(void *)fd) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
||||||
{
|
{
|
||||||
Xfree(fd);
|
Xfree(fd);
|
||||||
MV_Printf("MV_PlayFLAC: %s\n", FLAC__stream_decoder_get_resolved_state_string(fd->stream));
|
MV_Printf("MV_PlayFLAC: %s\n", FLAC__stream_decoder_get_resolved_state_string(fd->stream));
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request a voice from the voice pool
|
// Request a voice from the voice pool
|
||||||
voice = MV_AllocVoice(priority);
|
voice = MV_AllocVoice(priority);
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
{
|
{
|
||||||
FLAC__stream_decoder_finish(fd->stream);
|
FLAC__stream_decoder_finish(fd->stream);
|
||||||
FLAC__stream_decoder_delete(fd->stream);
|
FLAC__stream_decoder_delete(fd->stream);
|
||||||
Xfree(fd);
|
Xfree(fd);
|
||||||
MV_SetErrorCode(MV_NoVoices);
|
return MV_SetErrorCode(MV_NoVoices);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fd->owner = voice;
|
fd->owner = voice;
|
||||||
|
@ -486,8 +475,8 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
voice->LoopCount = 0;
|
voice->LoopCount = 0;
|
||||||
voice->BlockLength = 0;
|
voice->BlockLength = 0;
|
||||||
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
||||||
voice->next = NULL;
|
voice->next = nullptr;
|
||||||
voice->prev = NULL;
|
voice->prev = nullptr;
|
||||||
voice->priority = priority;
|
voice->priority = priority;
|
||||||
voice->callbackval = callbackval;
|
voice->callbackval = callbackval;
|
||||||
|
|
||||||
|
@ -504,16 +493,16 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
// but libvorbisfile may be confused by the signedness of char* vs FLAC__byte* and this code does not depend on
|
// but libvorbisfile may be confused by the signedness of char* vs FLAC__byte* and this code does not depend on
|
||||||
// HAVE_VORBIS.
|
// HAVE_VORBIS.
|
||||||
metadata_chain = FLAC__metadata_chain_new();
|
metadata_chain = FLAC__metadata_chain_new();
|
||||||
if (metadata_chain != NULL)
|
if (metadata_chain != nullptr)
|
||||||
{
|
{
|
||||||
if (FLAC__metadata_chain_read_with_callbacks(metadata_chain, fd, flac_callbacks))
|
if (FLAC__metadata_chain_read_with_callbacks(metadata_chain, fd, flac_callbacks))
|
||||||
{
|
{
|
||||||
FLAC__Metadata_Iterator *metadata_iterator = FLAC__metadata_iterator_new();
|
FLAC__Metadata_Iterator *metadata_iterator = FLAC__metadata_iterator_new();
|
||||||
if (metadata_iterator != NULL)
|
if (metadata_iterator != nullptr)
|
||||||
{
|
{
|
||||||
char *vc_loopstart = NULL;
|
char *vc_loopstart = nullptr;
|
||||||
char *vc_loopend = NULL;
|
char *vc_loopend = nullptr;
|
||||||
char *vc_looplength = NULL;
|
char *vc_looplength = nullptr;
|
||||||
|
|
||||||
FLAC__metadata_iterator_init(metadata_iterator, metadata_chain);
|
FLAC__metadata_iterator_init(metadata_iterator, metadata_chain);
|
||||||
|
|
||||||
|
@ -533,8 +522,7 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
FLAC__stream_decoder_finish(fd->stream);
|
FLAC__stream_decoder_finish(fd->stream);
|
||||||
FLAC__stream_decoder_delete(fd->stream);
|
FLAC__stream_decoder_delete(fd->stream);
|
||||||
Xfree(fd);
|
Xfree(fd);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
voice->channels = info->channels;
|
voice->channels = info->channels;
|
||||||
|
@ -549,27 +537,27 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
for (comment = 0; comment < tags->data.vorbis_comment.num_comments; ++comment)
|
for (comment = 0; comment < tags->data.vorbis_comment.num_comments; ++comment)
|
||||||
{
|
{
|
||||||
const char *entry = (const char *)tags->data.vorbis_comment.comments[comment].entry;
|
const char *entry = (const char *)tags->data.vorbis_comment.comments[comment].entry;
|
||||||
if (entry != NULL && entry[0] != '\0')
|
if (entry != nullptr && entry[0] != '\0')
|
||||||
{
|
{
|
||||||
const char *value = strchr(entry, '=');
|
const char *value = strchr(entry, '=');
|
||||||
const size_t field = value - entry;
|
const size_t field = value - entry;
|
||||||
value += 1;
|
value += 1;
|
||||||
|
|
||||||
for (int t = 0; t < loopStartTagCount && vc_loopstart == NULL; ++t)
|
for (int t = 0; t < loopStartTagCount && vc_loopstart == nullptr; ++t)
|
||||||
{
|
{
|
||||||
char const * const tag = loopStartTags[t];
|
char const * const tag = loopStartTags[t];
|
||||||
if (field == strlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
if (field == strlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
||||||
vc_loopstart = Xstrdup(value);
|
vc_loopstart = Xstrdup(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int t = 0; t < loopEndTagCount && vc_loopend == NULL; ++t)
|
for (int t = 0; t < loopEndTagCount && vc_loopend == nullptr; ++t)
|
||||||
{
|
{
|
||||||
char const * const tag = loopEndTags[t];
|
char const * const tag = loopEndTags[t];
|
||||||
if (field == strlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
if (field == strlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
||||||
vc_loopend = Xstrdup(value);
|
vc_loopend = Xstrdup(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int t = 0; t < loopLengthTagCount && vc_looplength == NULL; ++t)
|
for (int t = 0; t < loopLengthTagCount && vc_looplength == nullptr; ++t)
|
||||||
{
|
{
|
||||||
char const * const tag = loopLengthTags[t];
|
char const * const tag = loopLengthTags[t];
|
||||||
if (field == strlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
if (field == strlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
||||||
|
@ -583,7 +571,7 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
tags); // If it were not for this, I would assign pointers instead of strdup().
|
tags); // If it were not for this, I would assign pointers instead of strdup().
|
||||||
} while (FLAC__metadata_iterator_next(metadata_iterator));
|
} while (FLAC__metadata_iterator_next(metadata_iterator));
|
||||||
|
|
||||||
if (vc_loopstart != NULL)
|
if (vc_loopstart != nullptr)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
const FLAC__int64 flac_loopstart = atol(vc_loopstart);
|
const FLAC__int64 flac_loopstart = atol(vc_loopstart);
|
||||||
|
@ -595,7 +583,7 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
}
|
}
|
||||||
free(vc_loopstart);
|
free(vc_loopstart);
|
||||||
}
|
}
|
||||||
if (vc_loopend != NULL)
|
if (vc_loopend != nullptr)
|
||||||
{
|
{
|
||||||
if (voice->LoopSize > 0)
|
if (voice->LoopSize > 0)
|
||||||
{
|
{
|
||||||
|
@ -605,7 +593,7 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
}
|
}
|
||||||
free(vc_loopend);
|
free(vc_loopend);
|
||||||
}
|
}
|
||||||
if (vc_looplength != NULL)
|
if (vc_looplength != nullptr)
|
||||||
{
|
{
|
||||||
if (voice->LoopSize > 0 && voice->LoopEnd == 0)
|
if (voice->LoopSize > 0 && voice->LoopEnd == 0)
|
||||||
{
|
{
|
||||||
|
@ -631,7 +619,7 @@ int32_t MV_PlayFLAC(char *ptr, uint32_t length, int32_t loopstart, int32_t loope
|
||||||
MV_Printf("Error allocating FLAC__Metadata_Chain!\n");
|
MV_Printf("Error allocating FLAC__Metadata_Chain!\n");
|
||||||
|
|
||||||
// CODEDUP multivoc.c MV_SetVoicePitch
|
// CODEDUP multivoc.c MV_SetVoicePitch
|
||||||
voice->RateScale = (voice->SamplingRate * voice->PitchScale) / MV_MixRate;
|
voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate);
|
||||||
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
||||||
MV_SetVoiceMixMode(voice);
|
MV_SetVoiceMixMode(voice);
|
||||||
|
|
||||||
|
@ -652,7 +640,7 @@ void MV_ReleaseFLACVoice(VoiceNode *voice)
|
||||||
}
|
}
|
||||||
|
|
||||||
voice->rawdataptr = 0;
|
voice->rawdataptr = 0;
|
||||||
if (fd->stream != NULL)
|
if (fd->stream != nullptr)
|
||||||
{
|
{
|
||||||
auto stream = fd->stream;
|
auto stream = fd->stream;
|
||||||
fd->stream = nullptr;
|
fd->stream = nullptr;
|
||||||
|
|
|
@ -24,16 +24,17 @@
|
||||||
* Raw, WAV, and VOC source support for MultiVoc
|
* Raw, WAV, and VOC source support for MultiVoc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "compat.h"
|
|
||||||
#include "pitch.h"
|
|
||||||
#include "multivoc.h"
|
|
||||||
#include "_multivc.h"
|
#include "_multivc.h"
|
||||||
|
#include "compat.h"
|
||||||
|
#include "multivoc.h"
|
||||||
|
#include "pitch.h"
|
||||||
|
#include "pragmas.h"
|
||||||
|
|
||||||
static playbackstatus MV_GetNextWAVBlock(VoiceNode *voice)
|
static playbackstatus MV_GetNextWAVBlock(VoiceNode *voice)
|
||||||
{
|
{
|
||||||
if (voice->BlockLength == 0)
|
if (voice->BlockLength == 0)
|
||||||
{
|
{
|
||||||
if (voice->LoopStart == NULL)
|
if (voice->LoopStart == nullptr)
|
||||||
return NoMoreData;
|
return NoMoreData;
|
||||||
|
|
||||||
voice->BlockLength = voice->LoopSize;
|
voice->BlockLength = voice->LoopSize;
|
||||||
|
@ -45,7 +46,7 @@ static playbackstatus MV_GetNextWAVBlock(VoiceNode *voice)
|
||||||
voice->sound = voice->NextBlock;
|
voice->sound = voice->NextBlock;
|
||||||
voice->position -= voice->length;
|
voice->position -= voice->length;
|
||||||
voice->length = min(voice->BlockLength, 0x8000u);
|
voice->length = min(voice->BlockLength, 0x8000u);
|
||||||
voice->NextBlock += voice->length * (voice->channels * voice->bits / 8);
|
voice->NextBlock += voice->length * ((voice->channels * voice->bits) >> 3);
|
||||||
voice->BlockLength -= voice->length;
|
voice->BlockLength -= voice->length;
|
||||||
voice->length <<= 16;
|
voice->length <<= 16;
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||||
if (voice->BlockLength > 0)
|
if (voice->BlockLength > 0)
|
||||||
{
|
{
|
||||||
voice->position -= voice->length;
|
voice->position -= voice->length;
|
||||||
voice->sound += (voice->length >> 16) * (voice->channels * voice->bits / 8);
|
voice->sound += (voice->length >> 16) * ((voice->channels * voice->bits) >> 3);
|
||||||
voice->length = min(voice->BlockLength, 0x8000u);
|
voice->length = min(voice->BlockLength, 0x8000u);
|
||||||
voice->BlockLength -= voice->length;
|
voice->BlockLength -= voice->length;
|
||||||
voice->length <<= 16;
|
voice->length <<= 16;
|
||||||
|
@ -84,8 +85,8 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Stop playing if we get a NULL pointer
|
// Stop playing if we get a null pointer
|
||||||
if (ptr == NULL)
|
if (ptr == nullptr)
|
||||||
{
|
{
|
||||||
done = 2;
|
done = 2;
|
||||||
break;
|
break;
|
||||||
|
@ -113,7 +114,7 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||||
case 0 :
|
case 0 :
|
||||||
end_of_data:
|
end_of_data:
|
||||||
// End of data
|
// End of data
|
||||||
if ((voice->LoopStart == NULL) ||
|
if ((voice->LoopStart == nullptr) ||
|
||||||
((intptr_t) voice->LoopStart >= ((intptr_t) ptr - 4)))
|
((intptr_t) voice->LoopStart >= ((intptr_t) ptr - 4)))
|
||||||
{
|
{
|
||||||
done = 2;
|
done = 2;
|
||||||
|
@ -172,7 +173,7 @@ end_of_data:
|
||||||
|
|
||||||
case 6 :
|
case 6 :
|
||||||
// Repeat begin
|
// Repeat begin
|
||||||
if (voice->LoopEnd == NULL)
|
if (voice->LoopEnd == nullptr)
|
||||||
{
|
{
|
||||||
voice->LoopCount = B_LITTLE16(*(uint16_t const *)ptr);
|
voice->LoopCount = B_LITTLE16(*(uint16_t const *)ptr);
|
||||||
voice->LoopStart = (char *)((intptr_t) ptr + blocklength);
|
voice->LoopStart = (char *)((intptr_t) ptr + blocklength);
|
||||||
|
@ -187,14 +188,14 @@ end_of_data:
|
||||||
voice->LoopCount = 0;
|
voice->LoopCount = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((voice->LoopCount > 0) && (voice->LoopStart != NULL))
|
if ((voice->LoopCount > 0) && (voice->LoopStart != nullptr))
|
||||||
{
|
{
|
||||||
ptr = (uint8_t const *) voice->LoopStart;
|
ptr = (uint8_t const *) voice->LoopStart;
|
||||||
|
|
||||||
if (voice->LoopCount < 0xffff)
|
if (voice->LoopCount < 0xffff)
|
||||||
{
|
{
|
||||||
if (--voice->LoopCount == 0)
|
if (--voice->LoopCount == 0)
|
||||||
voice->LoopStart = NULL;
|
voice->LoopStart = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,13 +264,13 @@ end_of_data:
|
||||||
|
|
||||||
// CODEDUP multivoc.c MV_SetVoicePitch
|
// CODEDUP multivoc.c MV_SetVoicePitch
|
||||||
voice->SamplingRate = samplespeed;
|
voice->SamplingRate = samplespeed;
|
||||||
voice->RateScale = (voice->SamplingRate * voice->PitchScale) / MV_MixRate;
|
voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate);
|
||||||
|
|
||||||
// Multiply by MV_MIXBUFFERSIZE - 1
|
// Multiply by MV_MIXBUFFERSIZE - 1
|
||||||
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) -
|
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) -
|
||||||
voice->RateScale;
|
voice->RateScale;
|
||||||
|
|
||||||
if (voice->LoopEnd != NULL)
|
if (voice->LoopEnd != nullptr)
|
||||||
{
|
{
|
||||||
if (blocklength > (uintptr_t)voice->LoopEnd)
|
if (blocklength > (uintptr_t)voice->LoopEnd)
|
||||||
blocklength = (uintptr_t)voice->LoopEnd;
|
blocklength = (uintptr_t)voice->LoopEnd;
|
||||||
|
@ -356,10 +357,7 @@ int32_t MV_PlayWAV(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
riff.format_size = B_LITTLE32(riff.format_size);
|
riff.format_size = B_LITTLE32(riff.format_size);
|
||||||
|
|
||||||
if ((memcmp(riff.RIFF, "RIFF", 4) != 0) || (memcmp(riff.WAVE, "WAVE", 4) != 0) || (memcmp(riff.fmt, "fmt ", 4) != 0))
|
if ((memcmp(riff.RIFF, "RIFF", 4) != 0) || (memcmp(riff.WAVE, "WAVE", 4) != 0) || (memcmp(riff.fmt, "fmt ", 4) != 0))
|
||||||
{
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
format_header format;
|
format_header format;
|
||||||
memcpy(&format, ptr + sizeof(riff_header), sizeof(format_header));
|
memcpy(&format, ptr + sizeof(riff_header), sizeof(format_header));
|
||||||
|
@ -377,20 +375,14 @@ int32_t MV_PlayWAV(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
// Check if it's PCM data.
|
// Check if it's PCM data.
|
||||||
if (format.wFormatTag != 1 || (format.nChannels != 1 && format.nChannels != 2) ||
|
if (format.wFormatTag != 1 || (format.nChannels != 1 && format.nChannels != 2) ||
|
||||||
((format.nBitsPerSample != 8) && (format.nBitsPerSample != 16)) || memcmp(data.DATA, "data", 4) != 0)
|
((format.nBitsPerSample != 8) && (format.nBitsPerSample != 16)) || memcmp(data.DATA, "data", 4) != 0)
|
||||||
{
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request a voice from the voice pool
|
// Request a voice from the voice pool
|
||||||
|
|
||||||
VoiceNode *voice = MV_AllocVoice(priority);
|
VoiceNode *voice = MV_AllocVoice(priority);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
{
|
return MV_SetErrorCode(MV_NoVoices);
|
||||||
MV_SetErrorCode(MV_NoVoices);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
voice->wavetype = FMT_WAV;
|
voice->wavetype = FMT_WAV;
|
||||||
voice->bits = format.nBitsPerSample;
|
voice->bits = format.nBitsPerSample;
|
||||||
|
@ -419,12 +411,12 @@ int32_t MV_PlayWAV(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
voice->length = 0;
|
voice->length = 0;
|
||||||
voice->BlockLength = blocklen;
|
voice->BlockLength = blocklen;
|
||||||
voice->NextBlock = (char *)((intptr_t) ptr + sizeof(riff_header) + riff.format_size + sizeof(data_header));
|
voice->NextBlock = (char *)((intptr_t) ptr + sizeof(riff_header) + riff.format_size + sizeof(data_header));
|
||||||
voice->next = NULL;
|
voice->next = nullptr;
|
||||||
voice->prev = NULL;
|
voice->prev = nullptr;
|
||||||
voice->priority = priority;
|
voice->priority = priority;
|
||||||
voice->callbackval = callbackval;
|
voice->callbackval = callbackval;
|
||||||
voice->LoopStart = loopstart >= 0 ? voice->NextBlock : NULL;
|
voice->LoopStart = loopstart >= 0 ? voice->NextBlock : nullptr;
|
||||||
voice->LoopEnd = NULL;
|
voice->LoopEnd = nullptr;
|
||||||
voice->LoopSize = loopend > 0 ? loopend - loopstart + 1 : blocklen;
|
voice->LoopSize = loopend > 0 ? loopend - loopstart + 1 : blocklen;
|
||||||
|
|
||||||
MV_SetVoicePitch(voice, format.nSamplesPerSec, pitchoffset);
|
MV_SetVoicePitch(voice, format.nSamplesPerSec, pitchoffset);
|
||||||
|
@ -463,19 +455,13 @@ int32_t MV_PlayVOC(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
|
|
||||||
// Make sure it looks like a valid VOC file.
|
// Make sure it looks like a valid VOC file.
|
||||||
if (memcmp(ptr, "Creative Voice File", 19) != 0)
|
if (memcmp(ptr, "Creative Voice File", 19) != 0)
|
||||||
{
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request a voice from the voice pool
|
// Request a voice from the voice pool
|
||||||
VoiceNode *voice = MV_AllocVoice(priority);
|
VoiceNode *voice = MV_AllocVoice(priority);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
{
|
return MV_SetErrorCode(MV_NoVoices);
|
||||||
MV_SetErrorCode(MV_NoVoices);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
voice->rawdataptr = (uint8_t *)ptr;
|
voice->rawdataptr = (uint8_t *)ptr;
|
||||||
voice->ptrlength = length;
|
voice->ptrlength = length;
|
||||||
|
@ -489,12 +475,12 @@ int32_t MV_PlayVOC(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
voice->BlockLength = 0;
|
voice->BlockLength = 0;
|
||||||
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
||||||
voice->length = 0;
|
voice->length = 0;
|
||||||
voice->next = NULL;
|
voice->next = nullptr;
|
||||||
voice->prev = NULL;
|
voice->prev = nullptr;
|
||||||
voice->priority = priority;
|
voice->priority = priority;
|
||||||
voice->callbackval = callbackval;
|
voice->callbackval = callbackval;
|
||||||
voice->LoopStart = loopstart >= 0 ? voice->NextBlock : NULL;
|
voice->LoopStart = loopstart >= 0 ? voice->NextBlock : nullptr;
|
||||||
voice->LoopEnd = NULL;
|
voice->LoopEnd = nullptr;
|
||||||
voice->LoopSize = loopend - loopstart + 1;
|
voice->LoopSize = loopend - loopstart + 1;
|
||||||
|
|
||||||
voice->volume = volume;
|
voice->volume = volume;
|
||||||
|
|
|
@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "fx_man.h"
|
#include "fx_man.h"
|
||||||
|
|
||||||
int32_t FX_ErrorCode = FX_Ok;
|
int32_t FX_ErrorCode = FX_Ok;
|
||||||
int32_t FX_Installed = FALSE;
|
int32_t FX_Installed;
|
||||||
|
|
||||||
const char *FX_ErrorString(int32_t ErrorNumber)
|
const char *FX_ErrorString(int32_t ErrorNumber)
|
||||||
{
|
{
|
||||||
|
@ -138,7 +138,7 @@ int32_t FX_Play(char *ptr, uint32_t ptrlength, int32_t loopstart, int32_t loopen
|
||||||
int32_t vol, int32_t left, int32_t right, int32_t priority, float volume, intptr_t callbackval)
|
int32_t vol, int32_t left, int32_t right, int32_t priority, float volume, intptr_t callbackval)
|
||||||
{
|
{
|
||||||
static int32_t(*const func[])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, float, intptr_t) =
|
static int32_t(*const func[])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, float, intptr_t) =
|
||||||
{ NULL, NULL, MV_PlayVOC, MV_PlayWAV, MV_PlayVorbis, MV_PlayFLAC, MV_PlayXA, MV_PlayXMP };
|
{ nullptr, nullptr, MV_PlayVOC, MV_PlayWAV, MV_PlayVorbis, MV_PlayFLAC, MV_PlayXA, MV_PlayXMP };
|
||||||
|
|
||||||
EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func));
|
EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func));
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ int32_t FX_Play3D(char *ptr, uint32_t ptrlength, int32_t loophow, int32_t pitcho
|
||||||
int32_t priority, float volume, intptr_t callbackval)
|
int32_t priority, float volume, intptr_t callbackval)
|
||||||
{
|
{
|
||||||
static int32_t (*const func[])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, float, intptr_t) =
|
static int32_t (*const func[])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, float, intptr_t) =
|
||||||
{ NULL, NULL, MV_PlayVOC3D, MV_PlayWAV3D, MV_PlayVorbis3D, MV_PlayFLAC3D, MV_PlayXA3D, MV_PlayXMP3D };
|
{ nullptr, nullptr, MV_PlayVOC3D, MV_PlayWAV3D, MV_PlayVorbis3D, MV_PlayFLAC3D, MV_PlayXA3D, MV_PlayXMP3D };
|
||||||
|
|
||||||
EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func));
|
EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func));
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
(c) Copyright 1993 James R. Dose. All Rights Reserved.
|
(c) Copyright 1993 James R. Dose. All Rights Reserved.
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "compat.h"
|
|
||||||
#include "pragmas.h"
|
|
||||||
#include "linklist.h"
|
|
||||||
#include "drivers.h"
|
|
||||||
#include "pitch.h"
|
|
||||||
#include "multivoc.h"
|
#include "multivoc.h"
|
||||||
|
|
||||||
#include "_multivc.h"
|
#include "_multivc.h"
|
||||||
|
#include "baselayer.h"
|
||||||
|
#include "compat.h"
|
||||||
|
#include "drivers.h"
|
||||||
#include "fx_man.h"
|
#include "fx_man.h"
|
||||||
|
#include "linklist.h"
|
||||||
|
#include "osd.h"
|
||||||
|
#include "pitch.h"
|
||||||
|
#include "pragmas.h"
|
||||||
|
|
||||||
static void MV_StopVoice(VoiceNode *voice);
|
static void MV_StopVoice(VoiceNode *voice);
|
||||||
static void MV_ServiceVoc(void);
|
static void MV_ServiceVoc(void);
|
||||||
|
@ -51,7 +54,7 @@ static float MV_ReverbVolume;
|
||||||
|
|
||||||
Pan MV_PanTable[MV_NUMPANPOSITIONS][MV_MAXVOLUME + 1];
|
Pan MV_PanTable[MV_NUMPANPOSITIONS][MV_MAXVOLUME + 1];
|
||||||
|
|
||||||
int32_t MV_Installed = FALSE;
|
int32_t MV_Installed;
|
||||||
static int32_t MV_TotalVolume = MV_MAXTOTALVOLUME;
|
static int32_t MV_TotalVolume = MV_MAXTOTALVOLUME;
|
||||||
static int32_t MV_MaxVoices = 1;
|
static int32_t MV_MaxVoices = 1;
|
||||||
|
|
||||||
|
@ -62,22 +65,22 @@ static int32_t MV_NumberOfBuffers = MV_NUMBEROFBUFFERS;
|
||||||
|
|
||||||
static int32_t MV_Channels = 1;
|
static int32_t MV_Channels = 1;
|
||||||
|
|
||||||
static int32_t MV_ReverseStereo = FALSE;
|
static int32_t MV_ReverseStereo;
|
||||||
|
|
||||||
int32_t MV_MixRate;
|
int32_t MV_MixRate;
|
||||||
|
|
||||||
static int32_t MV_BufferEmpty[MV_NUMBEROFBUFFERS];
|
static int32_t MV_BufferEmpty[MV_NUMBEROFBUFFERS];
|
||||||
char *MV_MixBuffer[MV_NUMBEROFBUFFERS + 1];
|
char *MV_MixBuffer[MV_NUMBEROFBUFFERS + 1];
|
||||||
|
|
||||||
static VoiceNode *MV_Voices = NULL;
|
static VoiceNode *MV_Voices;
|
||||||
|
|
||||||
static VoiceNode VoiceList;
|
static VoiceNode VoiceList;
|
||||||
static VoiceNode VoicePool;
|
static VoiceNode VoicePool;
|
||||||
|
|
||||||
static int32_t MV_MixPage = 0;
|
static int32_t MV_MixPage;
|
||||||
|
|
||||||
void (*MV_Printf)(const char *fmt, ...) = NULL;
|
void (*MV_Printf)(const char *fmt, ...) = initprintf;
|
||||||
static void (*MV_CallBackFunc)(intptr_t) = NULL;
|
static void (*MV_CallBackFunc)(uint32_t);
|
||||||
|
|
||||||
char *MV_MixDestination;
|
char *MV_MixDestination;
|
||||||
int32_t MV_SampleSize = 1;
|
int32_t MV_SampleSize = 1;
|
||||||
|
@ -88,19 +91,19 @@ int32_t MV_ErrorCode = MV_NotInstalled;
|
||||||
float MV_GlobalVolume = 1.f;
|
float MV_GlobalVolume = 1.f;
|
||||||
float MV_VolumeSmooth = 1.f;
|
float MV_VolumeSmooth = 1.f;
|
||||||
|
|
||||||
static int lockdepth = 0;
|
static int lockdepth;
|
||||||
|
|
||||||
void MV_Lock(void)
|
static inline void MV_Lock(void)
|
||||||
{
|
{
|
||||||
if (!lockdepth++)
|
if (!lockdepth++)
|
||||||
SoundDriver_Lock();
|
SoundDriver_Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MV_Unlock(void)
|
static inline void MV_Unlock(void)
|
||||||
{
|
{
|
||||||
if (!--lockdepth)
|
if (!--lockdepth)
|
||||||
SoundDriver_Unlock();
|
SoundDriver_Unlock();
|
||||||
else if (lockdepth < 0 && MV_Printf)
|
else if (lockdepth < 0)
|
||||||
MV_Printf("MV_Unlock(): lockdepth < 0!\n");
|
MV_Printf("MV_Unlock(): lockdepth < 0!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,9 +281,8 @@ static VoiceNode *MV_GetVoice(int32_t handle)
|
||||||
{
|
{
|
||||||
if (handle < MV_MINVOICEHANDLE || handle > MV_MaxVoices)
|
if (handle < MV_MINVOICEHANDLE || handle > MV_MaxVoices)
|
||||||
{
|
{
|
||||||
if (MV_Printf)
|
|
||||||
MV_Printf("MV_GetVoice(): bad handle (%d)!\n", handle);
|
MV_Printf("MV_GetVoice(): bad handle (%d)!\n", handle);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MV_Lock();
|
MV_Lock();
|
||||||
|
@ -296,20 +298,20 @@ static VoiceNode *MV_GetVoice(int32_t handle)
|
||||||
|
|
||||||
MV_Unlock();
|
MV_Unlock();
|
||||||
MV_SetErrorCode(MV_VoiceNotFound);
|
MV_SetErrorCode(MV_VoiceNotFound);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoiceNode *MV_BeginService(int32_t handle)
|
VoiceNode *MV_BeginService(int32_t handle)
|
||||||
{
|
{
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
return NULL;
|
return nullptr;
|
||||||
|
|
||||||
VoiceNode *voice = MV_GetVoice(handle);
|
VoiceNode *voice = MV_GetVoice(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
{
|
{
|
||||||
MV_SetErrorCode(MV_VoiceNotFound);
|
MV_SetErrorCode(MV_VoiceNotFound);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MV_Lock();
|
MV_Lock();
|
||||||
|
@ -361,7 +363,7 @@ int32_t MV_Kill(int32_t handle)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
MV_StopVoice(voice);
|
MV_StopVoice(voice);
|
||||||
|
@ -389,7 +391,7 @@ int32_t MV_VoicesPlaying(void)
|
||||||
|
|
||||||
VoiceNode *MV_AllocVoice(int32_t priority)
|
VoiceNode *MV_AllocVoice(int32_t priority)
|
||||||
{
|
{
|
||||||
VoiceNode *voice, *node;
|
VoiceNode *voice;
|
||||||
|
|
||||||
MV_Lock();
|
MV_Lock();
|
||||||
|
|
||||||
|
@ -397,7 +399,7 @@ VoiceNode *MV_AllocVoice(int32_t priority)
|
||||||
if (LL::Empty(&VoicePool))
|
if (LL::Empty(&VoicePool))
|
||||||
{
|
{
|
||||||
// check if we have a higher priority than a voice that is playing.
|
// check if we have a higher priority than a voice that is playing.
|
||||||
for (voice = node = VoiceList.next; node != &VoiceList; node = node->next)
|
for (auto node = voice = VoiceList.next; node != &VoiceList; node = node->next)
|
||||||
{
|
{
|
||||||
if (node->priority < voice->priority)
|
if (node->priority < voice->priority)
|
||||||
voice = node;
|
voice = node;
|
||||||
|
@ -410,7 +412,7 @@ VoiceNode *MV_AllocVoice(int32_t priority)
|
||||||
{
|
{
|
||||||
// No free voices
|
// No free voices
|
||||||
MV_Unlock();
|
MV_Unlock();
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,10 +442,10 @@ int32_t MV_VoiceAvailable(int32_t priority)
|
||||||
|
|
||||||
MV_Lock();
|
MV_Lock();
|
||||||
|
|
||||||
VoiceNode *voice, *node;
|
VoiceNode *voice;
|
||||||
|
|
||||||
// check if we have a higher priority than a voice that is playing.
|
// check if we have a higher priority than a voice that is playing.
|
||||||
for (voice = node = VoiceList.next; node != &VoiceList; node = node->next)
|
for (auto node = voice = VoiceList.next; node != &VoiceList; node = node->next)
|
||||||
{
|
{
|
||||||
if (node->priority < voice->priority)
|
if (node->priority < voice->priority)
|
||||||
voice = node;
|
voice = node;
|
||||||
|
@ -463,7 +465,7 @@ void MV_SetVoicePitch(VoiceNode *voice, uint32_t rate, int32_t pitchoffset)
|
||||||
{
|
{
|
||||||
voice->SamplingRate = rate;
|
voice->SamplingRate = rate;
|
||||||
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
||||||
voice->RateScale = (rate * voice->PitchScale) / MV_MixRate;
|
voice->RateScale = divideu32(rate * voice->PitchScale, MV_MixRate);
|
||||||
|
|
||||||
// Multiply by MV_MIXBUFFERSIZE - 1
|
// Multiply by MV_MIXBUFFERSIZE - 1
|
||||||
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) -
|
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) -
|
||||||
|
@ -474,7 +476,7 @@ int32_t MV_SetPitch(int32_t handle, int32_t pitchoffset)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
MV_SetVoicePitch(voice, voice->SamplingRate, pitchoffset);
|
MV_SetVoicePitch(voice, voice->SamplingRate, pitchoffset);
|
||||||
|
@ -487,7 +489,7 @@ int32_t MV_SetFrequency(int32_t handle, int32_t frequency)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
MV_SetVoicePitch(voice, frequency, 0);
|
MV_SetVoicePitch(voice, frequency, 0);
|
||||||
|
@ -541,13 +543,11 @@ void MV_SetVoiceVolume(VoiceNode *voice, int32_t vol, int32_t left, int32_t righ
|
||||||
{
|
{
|
||||||
if (MV_Channels == 1)
|
if (MV_Channels == 1)
|
||||||
left = right = vol;
|
left = right = vol;
|
||||||
|
else if (MV_ReverseStereo)
|
||||||
|
swap(&left, &right);
|
||||||
|
|
||||||
voice->LeftVolumeDest = float(left)*(1.f/MV_MAXTOTALVOLUME);
|
voice->LeftVolumeDest = float(left)*(1.f/MV_MAXTOTALVOLUME);
|
||||||
voice->RightVolumeDest = float(right)*(1.f/MV_MAXTOTALVOLUME);
|
voice->RightVolumeDest = float(right)*(1.f/MV_MAXTOTALVOLUME);
|
||||||
|
|
||||||
if (MV_ReverseStereo)
|
|
||||||
swapfloat(&voice->LeftVolumeDest, &voice->RightVolumeDest);
|
|
||||||
|
|
||||||
voice->volume = volume;
|
voice->volume = volume;
|
||||||
|
|
||||||
MV_SetVoiceMixMode(voice);
|
MV_SetVoiceMixMode(voice);
|
||||||
|
@ -557,7 +557,7 @@ int32_t MV_PauseVoice(int32_t handle, int32_t pause)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
voice->Paused = pause;
|
voice->Paused = pause;
|
||||||
|
@ -570,7 +570,7 @@ int32_t MV_GetPosition(int32_t handle, int32_t *position)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
switch (voice->wavetype)
|
switch (voice->wavetype)
|
||||||
|
@ -585,7 +585,6 @@ int32_t MV_GetPosition(int32_t handle, int32_t *position)
|
||||||
#ifdef HAVE_XMP
|
#ifdef HAVE_XMP
|
||||||
case FMT_XMP: *position = MV_GetXMPPosition(voice); break;
|
case FMT_XMP: *position = MV_GetXMPPosition(voice); break;
|
||||||
#endif
|
#endif
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MV_EndService();
|
MV_EndService();
|
||||||
|
@ -597,7 +596,7 @@ int32_t MV_SetPosition(int32_t handle, int32_t position)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
switch (voice->wavetype)
|
switch (voice->wavetype)
|
||||||
|
@ -612,7 +611,6 @@ int32_t MV_SetPosition(int32_t handle, int32_t position)
|
||||||
#ifdef HAVE_XMP
|
#ifdef HAVE_XMP
|
||||||
case FMT_XMP: MV_SetXMPPosition(voice, position); break;
|
case FMT_XMP: MV_SetXMPPosition(voice, position); break;
|
||||||
#endif
|
#endif
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MV_EndService();
|
MV_EndService();
|
||||||
|
@ -624,12 +622,12 @@ int32_t MV_EndLooping(int32_t handle)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
voice->LoopCount = 0;
|
voice->LoopCount = 0;
|
||||||
voice->LoopStart = NULL;
|
voice->LoopStart = nullptr;
|
||||||
voice->LoopEnd = NULL;
|
voice->LoopEnd = nullptr;
|
||||||
|
|
||||||
MV_EndService();
|
MV_EndService();
|
||||||
|
|
||||||
|
@ -640,7 +638,7 @@ int32_t MV_SetPan(int32_t handle, int32_t vol, int32_t left, int32_t right)
|
||||||
{
|
{
|
||||||
VoiceNode *voice = MV_BeginService(handle);
|
VoiceNode *voice = MV_BeginService(handle);
|
||||||
|
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
return MV_Error;
|
return MV_Error;
|
||||||
|
|
||||||
MV_SetVoiceVolume(voice, vol, left, right, voice->volume);
|
MV_SetVoiceVolume(voice, vol, left, right, voice->volume);
|
||||||
|
@ -672,7 +670,7 @@ void MV_SetReverb(int32_t reverb)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t MV_GetMaxReverbDelay(void) { return MV_MIXBUFFERSIZE * MV_NumberOfBuffers; }
|
int32_t MV_GetMaxReverbDelay(void) { return MV_MIXBUFFERSIZE * MV_NumberOfBuffers; }
|
||||||
int32_t MV_GetReverbDelay(void) { return MV_ReverbDelay / MV_SampleSize; }
|
int32_t MV_GetReverbDelay(void) { return tabledivide32(MV_ReverbDelay, MV_SampleSize); }
|
||||||
|
|
||||||
void MV_SetReverbDelay(int32_t delay)
|
void MV_SetReverbDelay(int32_t delay)
|
||||||
{
|
{
|
||||||
|
@ -688,7 +686,7 @@ static int32_t MV_SetMixMode(int32_t numchannels)
|
||||||
MV_SampleSize = sizeof(int8_t) * MV_Channels * 2;
|
MV_SampleSize = sizeof(int8_t) * MV_Channels * 2;
|
||||||
|
|
||||||
MV_BufferSize = MV_MIXBUFFERSIZE * MV_SampleSize;
|
MV_BufferSize = MV_MIXBUFFERSIZE * MV_SampleSize;
|
||||||
MV_NumberOfBuffers = MV_TOTALBUFFERSIZE / MV_BufferSize;
|
MV_NumberOfBuffers = tabledivide32(MV_TOTALBUFFERSIZE, MV_BufferSize);
|
||||||
Bassert(isPow2(MV_NumberOfBuffers));
|
Bassert(isPow2(MV_NumberOfBuffers));
|
||||||
MV_BufferLength = MV_TOTALBUFFERSIZE;
|
MV_BufferLength = MV_TOTALBUFFERSIZE;
|
||||||
|
|
||||||
|
@ -708,10 +706,7 @@ static int32_t MV_StartPlayback(void)
|
||||||
MV_MixPage = 1;
|
MV_MixPage = 1;
|
||||||
|
|
||||||
if (SoundDriver_BeginPlayback(MV_MixBuffer[0], MV_BufferSize, MV_NumberOfBuffers, MV_ServiceVoc) != MV_Ok)
|
if (SoundDriver_BeginPlayback(MV_MixBuffer[0], MV_BufferSize, MV_NumberOfBuffers, MV_ServiceVoc) != MV_Ok)
|
||||||
{
|
return MV_SetErrorCode(MV_DriverError);
|
||||||
MV_SetErrorCode(MV_DriverError);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MV_Ok;
|
return MV_Ok;
|
||||||
}
|
}
|
||||||
|
@ -769,7 +764,7 @@ void MV_SetVolume(int32_t volume)
|
||||||
|
|
||||||
int32_t MV_GetVolume(void) { return MV_TotalVolume; }
|
int32_t MV_GetVolume(void) { return MV_TotalVolume; }
|
||||||
|
|
||||||
void MV_SetCallBack(void (*function)(intptr_t)) { MV_CallBackFunc = function; }
|
void MV_SetCallBack(void (*function)(uint32_t)) { MV_CallBackFunc = function; }
|
||||||
|
|
||||||
void MV_SetReverseStereo(int32_t setting) { MV_ReverseStereo = setting; }
|
void MV_SetReverseStereo(int32_t setting) { MV_ReverseStereo = setting; }
|
||||||
|
|
||||||
|
@ -788,10 +783,7 @@ int32_t MV_Init(int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numc
|
||||||
char *ptr = (char *) Xaligned_alloc(16, totalmem);
|
char *ptr = (char *) Xaligned_alloc(16, totalmem);
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
{
|
return MV_SetErrorCode(MV_NoMem);
|
||||||
MV_SetErrorCode(MV_NoMem);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bmemset(ptr, 0, totalmem);
|
Bmemset(ptr, 0, totalmem);
|
||||||
|
|
||||||
|
@ -823,7 +815,7 @@ int32_t MV_Init(int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numc
|
||||||
}
|
}
|
||||||
|
|
||||||
MV_Installed = TRUE;
|
MV_Installed = TRUE;
|
||||||
MV_CallBackFunc = NULL;
|
MV_CallBackFunc = nullptr;
|
||||||
MV_ReverbLevel = 0;
|
MV_ReverbLevel = 0;
|
||||||
MV_ReverbVolume = 0.f;
|
MV_ReverbVolume = 0.f;
|
||||||
|
|
||||||
|
@ -853,8 +845,7 @@ int32_t MV_Init(int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numc
|
||||||
// Preserve error code while we shutdown.
|
// Preserve error code while we shutdown.
|
||||||
int status = MV_ErrorCode;
|
int status = MV_ErrorCode;
|
||||||
MV_Shutdown();
|
MV_Shutdown();
|
||||||
MV_SetErrorCode(status);
|
return MV_SetErrorCode(status);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MV_Ok;
|
return MV_Ok;
|
||||||
|
@ -885,15 +876,13 @@ int32_t MV_Shutdown(void)
|
||||||
|
|
||||||
// Release the descriptor from our mix buffer
|
// Release the descriptor from our mix buffer
|
||||||
for (int buffer = 0; buffer < MV_NUMBEROFBUFFERS; buffer++)
|
for (int buffer = 0; buffer < MV_NUMBEROFBUFFERS; buffer++)
|
||||||
MV_MixBuffer[ buffer ] = NULL;
|
MV_MixBuffer[ buffer ] = nullptr;
|
||||||
|
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
MV_SetErrorCode(MV_NotInstalled);
|
||||||
|
|
||||||
return MV_Ok;
|
return MV_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MV_SetPrintf(void (*function)(const char *, ...)) { MV_Printf = function; }
|
|
||||||
|
|
||||||
const char *loopStartTags[loopStartTagCount] = { "LOOP_START", "LOOPSTART", "LOOP" };
|
const char *loopStartTags[loopStartTagCount] = { "LOOP_START", "LOOPSTART", "LOOP" };
|
||||||
const char *loopEndTags[loopEndTagCount] = { "LOOP_END", "LOOPEND" };
|
const char *loopEndTags[loopEndTagCount] = { "LOOP_END", "LOOPEND" };
|
||||||
const char *loopLengthTags[loopLengthTagCount] = { "LOOP_LENGTH", "LOOPLENGTH" };
|
const char *loopLengthTags[loopLengthTagCount] = { "LOOP_LENGTH", "LOOPLENGTH" };
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
#include "pragmas.h"
|
||||||
|
|
||||||
#ifdef HAVE_VORBIS
|
#ifdef HAVE_VORBIS
|
||||||
|
|
||||||
|
@ -58,17 +59,14 @@ typedef struct {
|
||||||
// designed with multiple calls in mind
|
// designed with multiple calls in mind
|
||||||
static void MV_GetVorbisCommentLoops(VoiceNode *voice, vorbis_comment *vc)
|
static void MV_GetVorbisCommentLoops(VoiceNode *voice, vorbis_comment *vc)
|
||||||
{
|
{
|
||||||
if (vc == NULL)
|
const char *vc_loopstart = nullptr;
|
||||||
return;
|
const char *vc_loopend = nullptr;
|
||||||
|
const char *vc_looplength = nullptr;
|
||||||
const char *vc_loopstart = NULL;
|
|
||||||
const char *vc_loopend = NULL;
|
|
||||||
const char *vc_looplength = NULL;
|
|
||||||
|
|
||||||
for (int comment = 0; comment < vc->comments; ++comment)
|
for (int comment = 0; comment < vc->comments; ++comment)
|
||||||
{
|
{
|
||||||
auto entry = (const char *)vc->user_comments[comment];
|
auto entry = (const char *)vc->user_comments[comment];
|
||||||
if (entry != NULL && entry[0] != '\0')
|
if (entry != nullptr && entry[0] != '\0')
|
||||||
{
|
{
|
||||||
const char *value = Bstrchr(entry, '=');
|
const char *value = Bstrchr(entry, '=');
|
||||||
|
|
||||||
|
@ -78,21 +76,21 @@ static void MV_GetVorbisCommentLoops(VoiceNode *voice, vorbis_comment *vc)
|
||||||
const size_t field = value - entry;
|
const size_t field = value - entry;
|
||||||
value += 1;
|
value += 1;
|
||||||
|
|
||||||
for (int t = 0; t < loopStartTagCount && vc_loopstart == NULL; ++t)
|
for (int t = 0; t < loopStartTagCount && vc_loopstart == nullptr; ++t)
|
||||||
{
|
{
|
||||||
auto tag = loopStartTags[t];
|
auto tag = loopStartTags[t];
|
||||||
if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
||||||
vc_loopstart = value;
|
vc_loopstart = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int t = 0; t < loopEndTagCount && vc_loopend == NULL; ++t)
|
for (int t = 0; t < loopEndTagCount && vc_loopend == nullptr; ++t)
|
||||||
{
|
{
|
||||||
auto tag = loopEndTags[t];
|
auto tag = loopEndTags[t];
|
||||||
if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
||||||
vc_loopend = value;
|
vc_loopend = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int t = 0; t < loopLengthTagCount && vc_looplength == NULL; ++t)
|
for (int t = 0; t < loopLengthTagCount && vc_looplength == nullptr; ++t)
|
||||||
{
|
{
|
||||||
auto tag = loopLengthTags[t];
|
auto tag = loopLengthTags[t];
|
||||||
if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0)
|
||||||
|
@ -101,7 +99,7 @@ static void MV_GetVorbisCommentLoops(VoiceNode *voice, vorbis_comment *vc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vc_loopstart != NULL)
|
if (vc_loopstart != nullptr)
|
||||||
{
|
{
|
||||||
const ogg_int64_t ov_loopstart = Batol(vc_loopstart);
|
const ogg_int64_t ov_loopstart = Batol(vc_loopstart);
|
||||||
if (ov_loopstart >= 0) // a loop starting at 0 is valid
|
if (ov_loopstart >= 0) // a loop starting at 0 is valid
|
||||||
|
@ -110,7 +108,7 @@ static void MV_GetVorbisCommentLoops(VoiceNode *voice, vorbis_comment *vc)
|
||||||
voice->LoopSize = 1;
|
voice->LoopSize = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vc_loopend != NULL)
|
if (vc_loopend != nullptr)
|
||||||
{
|
{
|
||||||
if (voice->LoopSize > 0)
|
if (voice->LoopSize > 0)
|
||||||
{
|
{
|
||||||
|
@ -119,7 +117,7 @@ static void MV_GetVorbisCommentLoops(VoiceNode *voice, vorbis_comment *vc)
|
||||||
voice->LoopEnd = (const char *) (intptr_t) ov_loopend;
|
voice->LoopEnd = (const char *) (intptr_t) ov_loopend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vc_looplength != NULL)
|
if (vc_looplength != nullptr)
|
||||||
{
|
{
|
||||||
if (voice->LoopSize > 0 && voice->LoopEnd == 0)
|
if (voice->LoopSize > 0 && voice->LoopEnd == 0)
|
||||||
{
|
{
|
||||||
|
@ -287,21 +285,20 @@ static playbackstatus MV_GetNextVorbisBlock(VoiceNode *voice)
|
||||||
|
|
||||||
if (bitstream != vd->lastbitstream)
|
if (bitstream != vd->lastbitstream)
|
||||||
{
|
{
|
||||||
vorbis_info *vi = 0;
|
vorbis_info *vi = ov_info(&vd->vf, -1);
|
||||||
|
|
||||||
vi = ov_info(&vd->vf, -1);
|
|
||||||
if (!vi || (vi->channels != 1 && vi->channels != 2))
|
if (!vi || (vi->channels != 1 && vi->channels != 2))
|
||||||
return NoMoreData;
|
return NoMoreData;
|
||||||
|
|
||||||
voice->channels = vi->channels;
|
voice->channels = vi->channels;
|
||||||
voice->SamplingRate = vi->rate;
|
voice->SamplingRate = vi->rate;
|
||||||
voice->RateScale = (voice->SamplingRate * voice->PitchScale) / MV_MixRate;
|
voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate);
|
||||||
|
|
||||||
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
||||||
MV_SetVoiceMixMode(voice);
|
|
||||||
vd->lastbitstream = bitstream;
|
vd->lastbitstream = bitstream;
|
||||||
|
MV_SetVoiceMixMode(voice);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t const samples = bytesread / ((voice->bits/8) * voice->channels);
|
uint32_t const samples = divideu32(bytesread, ((voice->bits>>3) * voice->channels));
|
||||||
|
|
||||||
voice->position = 0;
|
voice->position = 0;
|
||||||
voice->sound = vd->block;
|
voice->sound = vd->block;
|
||||||
|
@ -330,10 +327,7 @@ from listener.
|
||||||
int32_t MV_PlayVorbis3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchoffset, int32_t angle, int32_t distance, int32_t priority, float volume, intptr_t callbackval)
|
int32_t MV_PlayVorbis3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchoffset, int32_t angle, int32_t distance, int32_t priority, float volume, intptr_t callbackval)
|
||||||
{
|
{
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance < 0)
|
if (distance < 0)
|
||||||
{
|
{
|
||||||
|
@ -363,18 +357,12 @@ int32_t MV_PlayVorbis(char *ptr, uint32_t length, int32_t loopstart, int32_t loo
|
||||||
UNREFERENCED_PARAMETER(loopend);
|
UNREFERENCED_PARAMETER(loopend);
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto vd = (vorbis_data *)Xcalloc(1, sizeof(vorbis_data));
|
auto vd = (vorbis_data *)Xcalloc(1, sizeof(vorbis_data));
|
||||||
|
|
||||||
if (!vd)
|
if (voice == nullptr)
|
||||||
{
|
return MV_SetErrorCode(MV_NoVoices);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
vd->ptr = ptr;
|
vd->ptr = ptr;
|
||||||
vd->pos = 0;
|
vd->pos = 0;
|
||||||
|
@ -398,8 +386,7 @@ int32_t MV_PlayVorbis(char *ptr, uint32_t length, int32_t loopstart, int32_t loo
|
||||||
{
|
{
|
||||||
ov_clear(&vd->vf);
|
ov_clear(&vd->vf);
|
||||||
Xfree(vd);
|
Xfree(vd);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vi->channels != 1 && vi->channels != 2)
|
if (vi->channels != 1 && vi->channels != 2)
|
||||||
|
@ -430,17 +417,18 @@ int32_t MV_PlayVorbis(char *ptr, uint32_t length, int32_t loopstart, int32_t loo
|
||||||
voice->LoopCount = 0;
|
voice->LoopCount = 0;
|
||||||
voice->BlockLength = 0;
|
voice->BlockLength = 0;
|
||||||
voice->length = 0;
|
voice->length = 0;
|
||||||
voice->next = NULL;
|
voice->next = nullptr;
|
||||||
voice->prev = NULL;
|
voice->prev = nullptr;
|
||||||
voice->priority = priority;
|
voice->priority = priority;
|
||||||
voice->callbackval = callbackval;
|
voice->callbackval = callbackval;
|
||||||
|
|
||||||
voice->LoopStart = 0;
|
voice->LoopStart = nullptr;
|
||||||
voice->LoopEnd = 0;
|
voice->LoopEnd = nullptr;
|
||||||
voice->LoopSize = (loopstart >= 0 ? 1 : 0);
|
voice->LoopSize = (loopstart >= 0 ? 1 : 0);
|
||||||
|
|
||||||
// load loop tags from metadata
|
// load loop tags from metadata
|
||||||
MV_GetVorbisCommentLoops(voice, ov_comment(&vd->vf, 0));
|
if (auto comment = ov_comment(&vd->vf, 0))
|
||||||
|
MV_GetVorbisCommentLoops(voice, comment);
|
||||||
|
|
||||||
voice->Paused = FALSE;
|
voice->Paused = FALSE;
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
* Adapted and remixed from superxa2wav
|
* Adapted and remixed from superxa2wav
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "compat.h"
|
|
||||||
#include "pitch.h"
|
|
||||||
#include "multivoc.h"
|
|
||||||
#include "_multivc.h"
|
#include "_multivc.h"
|
||||||
|
#include "compat.h"
|
||||||
|
#include "multivoc.h"
|
||||||
|
#include "pitch.h"
|
||||||
|
#include "pragmas.h"
|
||||||
|
|
||||||
//#define NO_XA_HEADER
|
//#define NO_XA_HEADER
|
||||||
|
|
||||||
|
@ -324,7 +325,7 @@ static playbackstatus MV_GetNextXABlock
|
||||||
voice->SamplingRate = (((coding >> 2) & 3) == 1) ? 18900 : 37800;
|
voice->SamplingRate = (((coding >> 2) & 3) == 1) ? 18900 : 37800;
|
||||||
|
|
||||||
// CODEDUP multivoc.c MV_SetVoicePitch
|
// CODEDUP multivoc.c MV_SetVoicePitch
|
||||||
voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
|
voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate);
|
||||||
voice->FixedPointBufferSize = ( voice->RateScale * MV_MIXBUFFERSIZE ) - voice->RateScale;
|
voice->FixedPointBufferSize = ( voice->RateScale * MV_MIXBUFFERSIZE ) - voice->RateScale;
|
||||||
MV_SetVoiceMixMode( voice );
|
MV_SetVoiceMixMode( voice );
|
||||||
|
|
||||||
|
@ -378,10 +379,7 @@ int32_t MV_PlayXA3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchof
|
||||||
int32_t status;
|
int32_t status;
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance < 0)
|
if (distance < 0)
|
||||||
{
|
{
|
||||||
|
@ -419,17 +417,12 @@ int32_t MV_PlayXA(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(loopend);
|
UNREFERENCED_PARAMETER(loopend);
|
||||||
|
|
||||||
if ( !MV_Installed )
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode( MV_NotInstalled );
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
xad = (xa_data *) Xcalloc( 1, sizeof(xa_data) );
|
xad = (xa_data *) Xcalloc( 1, sizeof(xa_data) );
|
||||||
if (!xad) {
|
if (!xad)
|
||||||
MV_SetErrorCode( MV_InvalidFile );
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
xad->ptr = ptr;
|
xad->ptr = ptr;
|
||||||
xad->pos = XA_DATA_START;
|
xad->pos = XA_DATA_START;
|
||||||
|
@ -437,13 +430,11 @@ int32_t MV_PlayXA(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend
|
||||||
xad->length = length;
|
xad->length = length;
|
||||||
|
|
||||||
// Request a voice from the voice pool
|
// Request a voice from the voice pool
|
||||||
voice = MV_AllocVoice( priority );
|
voice = MV_AllocVoice(priority);
|
||||||
if ( voice == NULL )
|
if (voice == nullptr)
|
||||||
{
|
{
|
||||||
|
Xfree(xad);
|
||||||
Xfree(xad);
|
return MV_SetErrorCode(MV_NoVoices);
|
||||||
MV_SetErrorCode( MV_NoVoices );
|
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xad->owner = voice;
|
xad->owner = voice;
|
||||||
|
@ -455,8 +446,8 @@ int32_t MV_PlayXA(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend
|
||||||
voice->LoopCount = 0;
|
voice->LoopCount = 0;
|
||||||
voice->BlockLength = 0;
|
voice->BlockLength = 0;
|
||||||
voice->PitchScale = PITCH_GetScale( pitchoffset );
|
voice->PitchScale = PITCH_GetScale( pitchoffset );
|
||||||
voice->next = NULL;
|
voice->next = nullptr;
|
||||||
voice->prev = NULL;
|
voice->prev = nullptr;
|
||||||
voice->priority = priority;
|
voice->priority = priority;
|
||||||
voice->callbackval = callbackval;
|
voice->callbackval = callbackval;
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
|
|
||||||
#ifdef HAVE_XMP
|
#ifdef HAVE_XMP
|
||||||
|
|
||||||
#include "pitch.h"
|
|
||||||
#include "multivoc.h"
|
|
||||||
#include "_multivc.h"
|
#include "_multivc.h"
|
||||||
|
#include "multivoc.h"
|
||||||
|
#include "pitch.h"
|
||||||
|
#include "pragmas.h"
|
||||||
|
|
||||||
#include "libxmp-lite/xmp.h"
|
#include "libxmp-lite/xmp.h"
|
||||||
|
|
||||||
|
@ -72,10 +73,7 @@ int32_t MV_PlayXMP3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitcho
|
||||||
int32_t status;
|
int32_t status;
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distance < 0)
|
if (distance < 0)
|
||||||
{
|
{
|
||||||
|
@ -106,45 +104,36 @@ int32_t MV_PlayXMP(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
UNREFERENCED_PARAMETER(loopend);
|
UNREFERENCED_PARAMETER(loopend);
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
return MV_SetErrorCode(MV_NotInstalled);
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmpd = (xmp_data *)Xcalloc(1, sizeof(xmp_data));
|
xmpd = (xmp_data *)Xcalloc(1, sizeof(xmp_data));
|
||||||
if (!xmpd)
|
if (!xmpd)
|
||||||
{
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
|
||||||
return MV_Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmpd->ptr = ptr;
|
xmpd->ptr = ptr;
|
||||||
xmpd->length = length;
|
xmpd->length = length;
|
||||||
|
|
||||||
if ((xmpd->context = xmp_create_context()) == NULL)
|
if ((xmpd->context = xmp_create_context()) == nullptr)
|
||||||
{
|
{
|
||||||
Xfree(xmpd);
|
Xfree(xmpd);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((retval = xmp_load_module_from_memory(xmpd->context, ptr, length)) != 0)
|
if ((retval = xmp_load_module_from_memory(xmpd->context, ptr, length)) != 0)
|
||||||
{
|
{
|
||||||
Xfree(xmpd);
|
Xfree(xmpd);
|
||||||
MV_Printf("MV_PlayXMP: xmp_load_module_from_memory failed (%i)\n", retval);
|
MV_Printf("MV_PlayXMP: xmp_load_module_from_memory failed (%i)\n", retval);
|
||||||
MV_SetErrorCode(MV_InvalidFile);
|
return MV_SetErrorCode(MV_InvalidFile);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request a voice from the voice pool
|
// Request a voice from the voice pool
|
||||||
voice = MV_AllocVoice(priority);
|
voice = MV_AllocVoice(priority);
|
||||||
if (voice == NULL)
|
if (voice == nullptr)
|
||||||
{
|
{
|
||||||
xmp_release_module(xmpd->context);
|
xmp_release_module(xmpd->context);
|
||||||
xmp_free_context(xmpd->context);
|
xmp_free_context(xmpd->context);
|
||||||
Xfree(xmpd);
|
Xfree(xmpd);
|
||||||
MV_SetErrorCode(MV_NoVoices);
|
return MV_SetErrorCode(MV_NoVoices);
|
||||||
return MV_Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpd->owner = voice;
|
xmpd->owner = voice;
|
||||||
|
@ -158,8 +147,8 @@ int32_t MV_PlayXMP(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
voice->LoopCount = 0;
|
voice->LoopCount = 0;
|
||||||
voice->BlockLength = 0;
|
voice->BlockLength = 0;
|
||||||
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
||||||
voice->next = NULL;
|
voice->next = nullptr;
|
||||||
voice->prev = NULL;
|
voice->prev = nullptr;
|
||||||
voice->priority = priority;
|
voice->priority = priority;
|
||||||
voice->callbackval = callbackval;
|
voice->callbackval = callbackval;
|
||||||
|
|
||||||
|
@ -177,7 +166,7 @@ int32_t MV_PlayXMP(char *ptr, uint32_t length, int32_t loopstart, int32_t loopen
|
||||||
xmp_set_player(xmpd->context, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE);
|
xmp_set_player(xmpd->context, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE);
|
||||||
|
|
||||||
// CODEDUP multivoc.c MV_SetVoicePitch
|
// CODEDUP multivoc.c MV_SetVoicePitch
|
||||||
voice->RateScale = (voice->SamplingRate * voice->PitchScale) / MV_MixRate;
|
voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate);
|
||||||
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
||||||
MV_SetVoiceMixMode(voice);
|
MV_SetVoiceMixMode(voice);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue