2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-06-21 03:45:38 +00:00

fix: WavWriter outputting invalid files when compiled as x64

This commit is contained in:
Jan 2025-06-19 13:27:18 +01:00
parent d30e2e6532
commit d612d8f1a6
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
7 changed files with 49 additions and 68 deletions

View File

@ -1,6 +1,9 @@
#include "AssetDumperLoadedSound.h" #include "AssetDumperLoadedSound.h"
#include "Sound/WavTypes.h" #include "Sound/WavTypes.h"
#include "Sound/WavWriter.h"
#include <format>
using namespace IW3; using namespace IW3;
@ -9,37 +12,22 @@ bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
return true; return true;
} }
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream) void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream)
{ {
const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader) + sizeof(WavFormatChunkPcm) const WavWriter writer(stream);
+ sizeof(WavChunkHeader) + sizeof(asset->sound.info.data_len);
stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF)); const WavMetaData metaData{.channelCount = static_cast<unsigned>(asset->sound.info.channels),
stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize)); .samplesPerSec = static_cast<unsigned>(asset->sound.info.rate),
stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID)); .bitsPerSample = static_cast<unsigned>(asset->sound.info.bits)};
const WavChunkHeader formatChunkHeader{WAV_CHUNK_ID_FMT, sizeof(WavFormatChunkPcm)}; writer.WritePcmHeader(metaData, asset->sound.info.data_len);
stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader)); writer.WritePcmData(asset->sound.data, asset->sound.info.data_len);
WavFormatChunkPcm formatChunk{
WavFormat::PCM,
static_cast<uint16_t>(asset->sound.info.channels),
asset->sound.info.rate,
asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8,
static_cast<uint16_t>(asset->sound.info.block_size),
static_cast<uint16_t>(asset->sound.info.bits),
};
stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
const WavChunkHeader dataChunkHeader{WAV_CHUNK_ID_DATA, asset->sound.info.data_len};
stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
stream.write(asset->sound.data, asset->sound.info.data_len);
} }
void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset) void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset)
{ {
const auto* loadedSound = asset->Asset(); const auto* loadedSound = asset->Asset();
const auto assetFile = context.OpenAssetFile("sound/" + asset->m_name); const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name));
if (!assetFile) if (!assetFile)
return; return;
@ -48,11 +36,11 @@ void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<
switch (static_cast<WavFormat>(loadedSound->sound.info.format)) switch (static_cast<WavFormat>(loadedSound->sound.info.format))
{ {
case WavFormat::PCM: case WavFormat::PCM:
DumpWavPcm(context, loadedSound, stream); DumpWavPcm(loadedSound, stream);
break; break;
default: default:
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name); std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name);
break; break;
} }
} }

View File

@ -7,7 +7,7 @@ namespace IW3
{ {
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound> class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
{ {
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream); static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream);
protected: protected:
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override; bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;

View File

@ -3,6 +3,8 @@
#include "Sound/WavTypes.h" #include "Sound/WavTypes.h"
#include "Sound/WavWriter.h" #include "Sound/WavWriter.h"
#include <format>
using namespace IW4; using namespace IW4;
bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset) bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
@ -10,12 +12,13 @@ bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
return true; return true;
} }
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream) void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream)
{ {
const WavWriter writer(stream); const WavWriter writer(stream);
const WavMetaData metaData{ const WavMetaData metaData{.channelCount = static_cast<unsigned>(asset->sound.info.channels),
static_cast<unsigned>(asset->sound.info.channels), static_cast<unsigned>(asset->sound.info.rate), static_cast<unsigned>(asset->sound.info.bits)}; .samplesPerSec = static_cast<unsigned>(asset->sound.info.rate),
.bitsPerSample = static_cast<unsigned>(asset->sound.info.bits)};
writer.WritePcmHeader(metaData, asset->sound.info.data_len); writer.WritePcmHeader(metaData, asset->sound.info.data_len);
writer.WritePcmData(asset->sound.data, asset->sound.info.data_len); writer.WritePcmData(asset->sound.data, asset->sound.info.data_len);
@ -24,7 +27,7 @@ void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const Load
void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset) void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset)
{ {
const auto* loadedSound = asset->Asset(); const auto* loadedSound = asset->Asset();
const auto assetFile = context.OpenAssetFile("sound/" + asset->m_name); const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name));
if (!assetFile) if (!assetFile)
return; return;
@ -33,11 +36,11 @@ void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<
switch (static_cast<WavFormat>(loadedSound->sound.info.format)) switch (static_cast<WavFormat>(loadedSound->sound.info.format))
{ {
case WavFormat::PCM: case WavFormat::PCM:
DumpWavPcm(context, loadedSound, stream); DumpWavPcm(loadedSound, stream);
break; break;
default: default:
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name); std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name);
break; break;
} }
} }

View File

@ -7,7 +7,7 @@ namespace IW4
{ {
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound> class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
{ {
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream); static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream);
protected: protected:
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override; bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;

View File

@ -1,6 +1,9 @@
#include "AssetDumperLoadedSound.h" #include "AssetDumperLoadedSound.h"
#include "Sound/WavTypes.h" #include "Sound/WavTypes.h"
#include "Sound/WavWriter.h"
#include <format>
using namespace IW5; using namespace IW5;
@ -9,35 +12,22 @@ bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
return true; return true;
} }
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream) void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream)
{ {
const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader) + sizeof(WavFormatChunkPcm) const WavWriter writer(stream);
+ sizeof(WavChunkHeader) + sizeof(asset->sound.info.data_len);
stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF)); const WavMetaData metaData{.channelCount = static_cast<unsigned>(asset->sound.info.channels),
stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize)); .samplesPerSec = static_cast<unsigned>(asset->sound.info.rate),
stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID)); .bitsPerSample = static_cast<unsigned>(asset->sound.info.bits)};
const WavChunkHeader formatChunkHeader{WAV_CHUNK_ID_FMT, sizeof(WavFormatChunkPcm)}; writer.WritePcmHeader(metaData, asset->sound.info.data_len);
stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader)); writer.WritePcmData(asset->sound.data, asset->sound.info.data_len);
WavFormatChunkPcm formatChunk{WavFormat::PCM,
static_cast<uint16_t>(asset->sound.info.channels),
asset->sound.info.rate,
asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8,
static_cast<uint16_t>(asset->sound.info.block_size),
static_cast<uint16_t>(asset->sound.info.bits)};
stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
const WavChunkHeader dataChunkHeader{WAV_CHUNK_ID_DATA, asset->sound.info.data_len};
stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
stream.write(asset->sound.data, asset->sound.info.data_len);
} }
void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset) void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset)
{ {
const auto* loadedSound = asset->Asset(); const auto* loadedSound = asset->Asset();
const auto assetFile = context.OpenAssetFile("sound/" + asset->m_name); const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name));
if (!assetFile) if (!assetFile)
return; return;
@ -46,11 +36,11 @@ void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<
switch (static_cast<WavFormat>(loadedSound->sound.info.format)) switch (static_cast<WavFormat>(loadedSound->sound.info.format))
{ {
case WavFormat::PCM: case WavFormat::PCM:
DumpWavPcm(context, loadedSound, stream); DumpWavPcm(loadedSound, stream);
break; break;
default: default:
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name); std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name);
break; break;
} }
} }

View File

@ -7,7 +7,7 @@ namespace IW5
{ {
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound> class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
{ {
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream); static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream);
protected: protected:
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override; bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;

View File

@ -7,31 +7,31 @@ WavWriter::WavWriter(std::ostream& stream)
void WavWriter::WritePcmHeader(const WavMetaData& metaData, const size_t dataLen) const void WavWriter::WritePcmHeader(const WavMetaData& metaData, const size_t dataLen) const
{ {
constexpr auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader) + sizeof(WavFormatChunkPcm) constexpr auto riffMasterChunkSize = static_cast<uint32_t>(sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader)
+ sizeof(WavChunkHeader) + sizeof(dataLen); + sizeof(WavFormatChunkPcm) + sizeof(WavChunkHeader) + sizeof(uint32_t));
m_stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF)); m_stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF));
m_stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize)); m_stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize));
m_stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID)); m_stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID));
constexpr WavChunkHeader formatChunkHeader{WAV_CHUNK_ID_FMT, sizeof(WavFormatChunkPcm)}; constexpr WavChunkHeader formatChunkHeader{.chunkID = WAV_CHUNK_ID_FMT, .chunkSize = sizeof(WavFormatChunkPcm)};
m_stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader)); m_stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader));
const WavFormatChunkPcm formatChunk{ const WavFormatChunkPcm formatChunk{
WavFormat::PCM, .wFormatTag = WavFormat::PCM,
static_cast<uint16_t>(metaData.channelCount), .nChannels = static_cast<uint16_t>(metaData.channelCount),
metaData.samplesPerSec, .nSamplesPerSec = metaData.samplesPerSec,
metaData.samplesPerSec * metaData.channelCount * metaData.bitsPerSample / 8, .nAvgBytesPerSec = metaData.samplesPerSec * metaData.channelCount * metaData.bitsPerSample / 8,
static_cast<uint16_t>(metaData.channelCount * (metaData.bitsPerSample / 8)), .nBlockAlign = static_cast<uint16_t>(metaData.channelCount * (metaData.bitsPerSample / 8)),
static_cast<uint16_t>(metaData.bitsPerSample), .wBitsPerSample = static_cast<uint16_t>(metaData.bitsPerSample),
}; };
m_stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk)); m_stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
const WavChunkHeader dataChunkHeader{WAV_CHUNK_ID_DATA, static_cast<unsigned>(dataLen)}; const WavChunkHeader dataChunkHeader{.chunkID = WAV_CHUNK_ID_DATA, .chunkSize = static_cast<uint32_t>(dataLen)};
m_stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader)); m_stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
} }
void WavWriter::WritePcmData(const void* data, const size_t dataLen) const void WavWriter::WritePcmData(const void* data, const size_t dataLen) const
{ {
m_stream.write(static_cast<const char*>(data), dataLen); m_stream.write(static_cast<const char*>(data), static_cast<std::streamsize>(dataLen));
} }