chore(fmod): add files from Chensne/DragonNest

This commit is contained in:
phaneron 2025-08-19 10:12:56 -04:00
commit 50fb3c6b1c
544 changed files with 315778 additions and 0 deletions

610
src/fmod_sample_software.cpp Executable file
View file

@ -0,0 +1,610 @@
#include "fmod_settings.h"
#ifdef FMOD_SUPPORT_SOFTWARE
#include "fmod_dsp_codec.h"
#include "fmod_memory.h"
#include "fmod_output.h"
#include "fmod_output_software.h"
#include "fmod_sample_software.h"
#include "fmod_systemi.h"
#ifdef PLATFORM_PS3
#include "fmod_output_ps3.h"
#endif
namespace FMOD
{
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
SampleSoftware::SampleSoftware()
{
mBuffer = 0;
mBufferMemory = 0;
mLoopPointDataEndOffset = 0;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::release(bool freethis)
{
FMOD_RESULT result;
if (mFlags & FMOD_SOUND_FLAG_PRELOADEDFSB)
{
return FMOD_ERR_PRELOADED;
}
if (mFlags & FMOD_SOUND_FLAG_PROGRAMMERSOUND)
{
return FMOD_ERR_PROGRAMMERSOUND;
}
/*
The reason there is a sleep loop here and not a criticalsection is that we don't want one sound release stalling on other non blocking sounds,
and we also don't want the non blocking thread stalling on release calls (not such a huge issue but it slows loading down unescessarily).
*/
while ((mOpenState != FMOD_OPENSTATE_READY && mOpenState != FMOD_OPENSTATE_ERROR) || (mFlags & FMOD_SOUND_FLAG_DONOTRELEASE))
{
FMOD_OS_Time_Sleep(2);
}
if (mSystem)
{
result = mSystem->stopSound(this);
if (result != FMOD_OK)
{
return result;
}
}
if (mBufferMemory)
{
if (0)
{}
#ifdef PLATFORM_PS3
else if ((mMode & FMOD_LOADSECONDARYRAM) && OutputPS3::mRSXPoolInitialised)
{
OutputPS3::mRSXPool.free(mBufferMemory, __FILE__, __LINE__);
}
#endif
else if ((mMode & FMOD_LOADSECONDARYRAM) && (FMOD::gGlobal->gMemoryTypeFlags & FMOD_MEMORY_SECONDARY))
{
FMOD_Memory_FreeType(mBufferMemory, FMOD_MEMORY_SECONDARY);
}
else
{
FMOD_Memory_Free(mBufferMemory);
}
mBufferMemory = 0;
}
if (mLoopPointDataEnd && mLoopPointDataEnd != mLoopPointDataEndMemory)
{
FMOD_Memory_Free(mLoopPointDataEnd);
mLoopPointDataEnd = 0;
}
mBuffer = 0;
return Sample::release(freethis);
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::setMode(FMOD_MODE mode)
{
FMOD_RESULT result;
result = Sample::setMode(mode);
if (result != FMOD_OK)
{
return result;
}
result = setLoopPointData();
if (result != FMOD_OK)
{
return result;
}
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::lockInternal(unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2)
{
FMOD_RESULT result;
char *src = 0;
unsigned int overflowbytes, pointB;
/*
If we're locking part of the sample that has been modified by the loop point stuff, restore the old data first.
*/
result = getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes);
if (result != FMOD_OK)
{
return result;
}
result = getBytesFromSamples(mLoopStart + mLoopLength, &pointB);
if (result != FMOD_OK)
{
return result;
}
if (offset >= pointB && offset < pointB + overflowbytes)
{
result = restoreLoopPointData();
if (result != FMOD_OK)
{
return result;
}
}
src = (char *)mBuffer;
if (offset >= mLengthBytes || offset < 0 || length < 0 || length > mLengthBytes)
{
*ptr1 = 0;
if (ptr2)
{
*ptr2 = 0;
}
*len1 = 0;
if (len2)
{
*len2 = 0;
}
return FMOD_ERR_INVALID_PARAM;
}
if (offset + length <= mLengthBytes)
{
*ptr1 = src + offset;
*len1 = length;
if (ptr2)
{
*ptr2 = 0;
}
if (len2)
{
*len2 = 0;
}
}
/*
Otherwise return wrapped pointers in pt1 and ptr2
*/
else
{
*ptr1 = src + offset;
*len1 = mLengthBytes - offset;
if (ptr2)
{
*ptr2 = src;
}
if (len2)
{
*len2 = length - (mLengthBytes - offset);
}
}
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::unlockInternal(void *ptr1, void *ptr2, unsigned int len1, unsigned int len2)
{
FMOD_RESULT result;
result = setLoopPointData();
if (result != FMOD_OK)
{
return result;
}
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::setBufferData(void *data)
{
#ifdef PLATFORM_PS3
if ((unsigned int)data % 16)
{
FLOG((FMOD_DEBUG_LEVEL_ERROR, __FILE__, __LINE__, "SampleSoftware::setBufferData", "data: %08x not 16 byte aligned!\n", data));
return FMOD_ERR_MEMORY_CANTPOINT;
}
#endif
mBuffer = data;
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::setLoopPoints(unsigned int loopstart, unsigned int looplength)
{
if (loopstart >= mLength || loopstart + looplength > mLength)
{
return FMOD_ERR_INVALID_PARAM;
}
restoreLoopPointData();
mLoopStart = loopstart;
mLoopLength = looplength;
setLoopPointData();
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::setLoopPointData()
{
FMOD_RESULT result;
unsigned int overflowbytes, pointA, pointB;
if ((mFormat != FMOD_SOUND_FORMAT_PCM8 &&
mFormat != FMOD_SOUND_FORMAT_PCM16 &&
mFormat != FMOD_SOUND_FORMAT_PCM24 &&
mFormat != FMOD_SOUND_FORMAT_PCM32 &&
mFormat != FMOD_SOUND_FORMAT_PCMFLOAT) || !mLoopPointDataEnd)
{
return FMOD_OK;
}
result = getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes);
if (result != FMOD_OK)
{
return result;
}
result = getBytesFromSamples(mLoopStart, &pointA);
if (result != FMOD_OK)
{
return result;
}
result = getBytesFromSamples(mLoopStart + mLoopLength, &pointB);
if (result != FMOD_OK)
{
return result;
}
if (mMode & FMOD_LOOP_BIDI)
{
int count;
FMOD_memcpy(mLoopPointDataEnd, (char *)mBuffer + pointB, overflowbytes); /* backup the data first */
mLoopPointDataEndOffset = pointB;
switch (mFormat)
{
case FMOD_SOUND_FORMAT_PCM8:
{
char *srcptr, *destptr;
srcptr = destptr = (char *)mBuffer + pointB;
srcptr -= mChannels;
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
{
*destptr = *srcptr;
destptr++;
srcptr--;
}
break;
}
case FMOD_SOUND_FORMAT_PCM16:
{
short *srcptr, *destptr;
srcptr = destptr = (short *)((char *)mBuffer + pointB);
srcptr -= mChannels;
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
{
*destptr = *srcptr;
destptr++;
srcptr--;
}
break;
}
case FMOD_SOUND_FORMAT_PCM24:
{
char *srcptr, *destptr;
srcptr = destptr = (char *)mBuffer + pointB;
srcptr -= (mChannels * 3);
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
{
destptr[0] = srcptr[0];
destptr[1] = srcptr[1];
destptr[2] = srcptr[2];
destptr += 3;
srcptr -= 3;
}
break;
}
case FMOD_SOUND_FORMAT_PCM32:
case FMOD_SOUND_FORMAT_PCMFLOAT:
{
int *srcptr, *destptr;
srcptr = destptr = (int *)((char *)mBuffer + pointB);
srcptr -= mChannels;
for (count=0; count < FMOD_DSP_RESAMPLER_OVERFLOWLENGTH * mChannels; count++)
{
*destptr = *srcptr;
destptr++;
srcptr--;
}
break;
}
default:
{
break;
}
}
}
else if (mMode & FMOD_LOOP_NORMAL)
{
if (mLoopPointDataEndOffset)
{
FMOD_memcpy((char *)mBuffer + mLoopPointDataEndOffset, mLoopPointDataEnd, overflowbytes);
}
FMOD_memcpy(mLoopPointDataEnd, (char *)mBuffer + pointB, overflowbytes);
mLoopPointDataEndOffset = pointB;
FMOD_memcpy((char *)mBuffer + pointB, (char *)mBuffer + pointA, overflowbytes);
}
else if (mMode & FMOD_LOOP_OFF)
{
if (mLoopPointDataEndOffset)
{
FMOD_memcpy((char *)mBuffer + mLoopPointDataEndOffset, mLoopPointDataEnd, overflowbytes);
mLoopPointDataEndOffset = 0;
}
}
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
FMOD_RESULT SampleSoftware::restoreLoopPointData()
{
FMOD_RESULT result;
unsigned int overflowbytes, pointA, pointB;
if ((mFormat != FMOD_SOUND_FORMAT_PCM8 &&
mFormat != FMOD_SOUND_FORMAT_PCM16 &&
mFormat != FMOD_SOUND_FORMAT_PCM24 &&
mFormat != FMOD_SOUND_FORMAT_PCM32 &&
mFormat != FMOD_SOUND_FORMAT_PCMFLOAT) || !mLoopPointDataEnd)
{
return FMOD_OK;
}
result = getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes);
if (result != FMOD_OK)
{
return result;
}
result = getBytesFromSamples(mLoopStart, &pointA);
if (result != FMOD_OK)
{
return result;
}
result = getBytesFromSamples(mLoopStart + mLoopLength, &pointB);
if (result != FMOD_OK)
{
return result;
}
if (mLoopPointDataEndOffset)
{
FMOD_memcpy((char *)mBuffer + mLoopPointDataEndOffset, mLoopPointDataEnd, overflowbytes);
mLoopPointDataEndOffset = 0;
}
return FMOD_OK;
}
/*
[
[DESCRIPTION]
[PARAMETERS]
[RETURN_VALUE]
[REMARKS]
[PLATFORMS]
[SEE_ALSO]
]
*/
#ifdef FMOD_SUPPORT_MEMORYTRACKER
FMOD_RESULT SampleSoftware::getMemoryUsedImpl(MemoryTracker *tracker)
{
tracker->add(false, FMOD_MEMBITS_SOUND, sizeof(SampleSoftware) - sizeof(Sample));
if (mBuffer)
{
unsigned int overflowbytes;
if (mFormat == FMOD_SOUND_FORMAT_IMAADPCM || mFormat == FMOD_SOUND_FORMAT_XMA || mFormat == FMOD_SOUND_FORMAT_MPEG)
{
overflowbytes = 0;
}
else
{
SoundI::getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes, mChannels, mFormat);
}
if (0){}
#ifdef PLATFORM_PS3
else if ((mMode & FMOD_LOADSECONDARYRAM) && OutputPS3::mRSXPoolInitialised)
{
tracker->add(false, FMOD_MEMBITS_SOUND_SECONDARYRAM, mLengthBytes + (overflowbytes * 2) + 16);
}
#endif
else if ((mMode & FMOD_LOADSECONDARYRAM) && (FMOD::gGlobal->gMemoryTypeFlags & FMOD_MEMORY_SECONDARY))
{
tracker->add(false, FMOD_MEMBITS_SOUND_SECONDARYRAM, mLengthBytes + (overflowbytes * 2) + 16);
}
else if (!(mMode & FMOD_OPENMEMORY_POINT))
{
tracker->add(false, FMOD_MEMBITS_SOUND, mLengthBytes + (overflowbytes * 2) + 16);
}
}
if (mLoopPointDataEnd != mLoopPointDataEndMemory)
{
unsigned int overflowbytes = 0;
SoundI::getBytesFromSamples(FMOD_DSP_RESAMPLER_OVERFLOWLENGTH, &overflowbytes, mChannels, mFormat);
tracker->add(false, FMOD_MEMBITS_SOUND, overflowbytes);
}
return Sample::getMemoryUsedImpl(tracker);
}
#endif
}
#endif