FNA-XNA / FAudio

FAudio - Accuracy-focused XAudio reimplementation for open platforms
https://fna-xna.github.io/
Other
534 stars 72 forks source link

Create fake codec data for WMA3 #327

Closed ivyl closed 6 months ago

ivyl commented 6 months ago

The extra codec data is not being passed by the METAL GEAR SOLID 3: Snake Eater - Master Collection Version. I've tried to make it work:

diff --git a/libs/faudio/src/FAudio.c b/libs/faudio/src/FAudio.c
index 7d34b666535..d235fd44a1a 100644
--- a/libs/faudio/src/FAudio.c
+++ b/libs/faudio/src/FAudio.c
@@ -297,7 +297,7 @@ uint32_t FAudio_CreateSourceVoice(
      pSourceFormat->wFormatTag == FAUDIO_FORMAT_WMAUDIO3   )
   {
      FAudioWaveFormatExtensible *fmtex = (FAudioWaveFormatExtensible*) audio->pMalloc(
-        sizeof(FAudioWaveFormatExtensible)
+        sizeof(FAudioWaveFormatExtensible) + pSourceFormat->cbSize
      );
      /* convert PCM to EXTENSIBLE */
      fmtex->Format.wFormatTag = FAUDIO_FORMAT_EXTENSIBLE;
@@ -306,7 +306,7 @@ uint32_t FAudio_CreateSourceVoice(
      fmtex->Format.nAvgBytesPerSec = pSourceFormat->nAvgBytesPerSec;
      fmtex->Format.nBlockAlign = pSourceFormat->nBlockAlign;
      fmtex->Format.wBitsPerSample = pSourceFormat->wBitsPerSample;
-     fmtex->Format.cbSize = sizeof(FAudioWaveFormatExtensible) - sizeof(FAudioWaveFormatEx);
+     fmtex->Format.cbSize = sizeof(FAudioWaveFormatExtensible) - sizeof(FAudioWaveFormatEx) + pSourceFormat->cbSize;
      fmtex->Samples.wValidBitsPerSample = pSourceFormat->wBitsPerSample;
      fmtex->dwChannelMask = 0;
      if (pSourceFormat->wFormatTag == FAUDIO_FORMAT_PCM)
@@ -325,6 +325,7 @@ uint32_t FAudio_CreateSourceVoice(
      {
         FAudio_memcpy(&fmtex->SubFormat, &DATAFORMAT_SUBTYPE_WMAUDIO3, sizeof(FAudioGUID));
      }
+     FAudio_memcpy(&fmtex[1], &pSourceFormat[1], pSourceFormat->cbSize);
      (*ppSourceVoice)->src.format = &fmtex->Format;
   }
   else if (pSourceFormat->wFormatTag == FAUDIO_FORMAT_MSADPCM)

(this bit seems to be missing in case the game / software actually passes any extra data past the format header)

But looks like we have to create a fake codec data for WMA3 too.

This makes it so that the passed data to Media Foundation is a correct WMA and can be played (after dumping into a file) both by Windows and by FFMPEG.