123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "mpt/uuid/uuid.hpp"
- #include "../common/FileReader.h"
- #include "Loaders.h"
- #ifndef MODPLUG_NO_FILESAVE
- #include "mpt/io/io.hpp"
- #include "mpt/io/io_virtual_wrapper.hpp"
- #endif
- OPENMPT_NAMESPACE_BEGIN
- struct FileTags;
- struct RIFFHeader
- {
-
- enum RIFFMagic
- {
- idRIFF = MagicLE("RIFF"),
- idLIST = MagicLE("LIST"),
- idWAVE = MagicLE("WAVE"),
- idwave = MagicLE("wave"),
- };
- uint32le magic;
- uint32le length;
- uint32le type;
- };
- MPT_BINARY_STRUCT(RIFFHeader, 12)
- struct RIFFChunk
- {
-
- enum ChunkIdentifiers
- {
- idfmt_ = MagicLE("fmt "),
- iddata = MagicLE("data"),
- idpcm_ = MagicLE("pcm "),
- idfact = MagicLE("fact"),
- idsmpl = MagicLE("smpl"),
- idinst = MagicLE("inst"),
- idLIST = MagicLE("LIST"),
- idxtra = MagicLE("xtra"),
- idcue_ = MagicLE("cue "),
- idwsmp = MagicLE("wsmp"),
- idCSET = MagicLE("CSET"),
- id____ = 0x00000000,
-
- idINAM = MagicLE("INAM"),
- idISFT = MagicLE("ISFT"),
- idICOP = MagicLE("ICOP"),
- idIART = MagicLE("IART"),
- idIPRD = MagicLE("IPRD"),
- idICMT = MagicLE("ICMT"),
- idIENG = MagicLE("IENG"),
- idISBJ = MagicLE("ISBJ"),
- idIGNR = MagicLE("IGNR"),
- idICRD = MagicLE("ICRD"),
- idYEAR = MagicLE("YEAR"),
- idTRCK = MagicLE("TRCK"),
- idTURL = MagicLE("TURL"),
- };
- uint32le id;
- uint32le length;
- size_t GetLength() const
- {
- return length;
- }
- ChunkIdentifiers GetID() const
- {
- return static_cast<ChunkIdentifiers>(id.get());
- }
- };
- MPT_BINARY_STRUCT(RIFFChunk, 8)
- struct WAVFormatChunk
- {
-
- enum SampleFormats
- {
- fmtPCM = 1,
- fmtFloat = 3,
- fmtALaw = 6,
- fmtULaw = 7,
- fmtIMA_ADPCM = 17,
- fmtMP3 = 85,
- fmtExtensible = 0xFFFE,
- };
- uint16le format;
- uint16le numChannels;
- uint32le sampleRate;
- uint32le byteRate;
- uint16le blockAlign;
- uint16le bitsPerSample;
- };
- MPT_BINARY_STRUCT(WAVFormatChunk, 16)
- struct WAVFormatChunkExtension
- {
- uint16le size;
- uint16le validBitsPerSample;
- uint32le channelMask;
- mpt::GUIDms subFormat;
- };
- MPT_BINARY_STRUCT(WAVFormatChunkExtension, 24)
- struct WAVSampleInfoChunk
- {
- uint32le manufacturer;
- uint32le product;
- uint32le samplePeriod;
- uint32le baseNote;
- uint32le pitchFraction;
- uint32le SMPTEFormat;
- uint32le SMPTEOffset;
- uint32le numLoops;
- uint32le samplerData;
-
- void ConvertToWAV(uint32 freq, uint8 rootNote)
- {
- manufacturer = 0;
- product = 0;
- samplePeriod = 1000000000 / freq;
- if(rootNote != 0)
- baseNote = rootNote - NOTE_MIN;
- else
- baseNote = NOTE_MIDDLEC - NOTE_MIN;
- pitchFraction = 0;
- SMPTEFormat = 0;
- SMPTEOffset = 0;
- numLoops = 0;
- samplerData = 0;
- }
- };
- MPT_BINARY_STRUCT(WAVSampleInfoChunk, 36)
- struct WAVSampleLoop
- {
-
- enum LoopType
- {
- loopForward = 0,
- loopBidi = 1,
- loopBackward = 2,
- };
- uint32le identifier;
- uint32le loopType;
- uint32le loopStart;
- uint32le loopEnd;
- uint32le fraction;
- uint32le playCount;
-
- void ApplyToSample(SmpLength &start, SmpLength &end, SmpLength sampleLength, SampleFlags &flags, ChannelFlags enableFlag, ChannelFlags bidiFlag, bool mptLoopFix) const;
-
- void ConvertToWAV(SmpLength start, SmpLength end, bool bidi);
- };
- MPT_BINARY_STRUCT(WAVSampleLoop, 24)
- struct WAVInstrumentChunk
- {
- uint8 unshiftedNote;
- int8 finetune;
- int8 gain;
- uint8 lowNote;
- uint8 highNote;
- uint8 lowVelocity;
- uint8 highVelocity;
- };
- MPT_BINARY_STRUCT(WAVInstrumentChunk, 7)
- struct WAVExtraChunk
- {
- enum Flags
- {
- setPanning = 0x20,
- };
- uint32le flags;
- uint16le defaultPan;
- uint16le defaultVolume;
- uint16le globalVolume;
- uint16le reserved;
- uint8le vibratoType;
- uint8le vibratoSweep;
- uint8le vibratoDepth;
- uint8le vibratoRate;
-
- void ConvertToWAV(const ModSample &sample, MODTYPE modType)
- {
- if(sample.uFlags[CHN_PANNING])
- {
- flags = WAVExtraChunk::setPanning;
- } else
- {
- flags = 0;
- }
- defaultPan = sample.nPan;
- defaultVolume = sample.nVolume;
- globalVolume = sample.nGlobalVol;
- vibratoType = sample.nVibType;
- vibratoSweep = sample.nVibSweep;
- vibratoDepth = sample.nVibDepth;
- vibratoRate = sample.nVibRate;
- if((modType & MOD_TYPE_XM) && (vibratoDepth | vibratoRate))
- {
-
- vibratoSweep = 255 - vibratoSweep;
- }
- }
- };
- MPT_BINARY_STRUCT(WAVExtraChunk, 16)
- struct WAVCuePoint
- {
- uint32le id;
- uint32le position;
- uint32le riffChunkID;
- uint32le chunkStart;
- uint32le blockStart;
- uint32le offset;
-
- void ConvertToWAV(uint32 id_, SmpLength offset_)
- {
- id = id_;
- position = offset_;
- riffChunkID = static_cast<uint32>(RIFFChunk::iddata);
- chunkStart = 0;
- blockStart = 0;
- offset = offset_;
- }
- };
- MPT_BINARY_STRUCT(WAVCuePoint, 24)
- class WAVReader
- {
- protected:
- FileReader file;
- FileReader sampleData, smplChunk, instChunk, xtraChunk, wsmpChunk, cueChunk;
- FileReader::ChunkList<RIFFChunk> infoChunk;
- FileReader::off_t sampleLength;
- WAVFormatChunk formatInfo;
- uint16 subFormat;
- uint16 codePage;
- bool isDLS;
- bool mayBeCoolEdit16_8;
- uint16 GetFileCodePage(FileReader::ChunkList<RIFFChunk> &chunks);
- public:
- WAVReader(FileReader &inputFile);
- bool IsValid() const { return sampleData.IsValid(); }
- void FindMetadataChunks(FileReader::ChunkList<RIFFChunk> &chunks);
-
- WAVFormatChunk::SampleFormats GetSampleFormat() const { return IsExtensibleFormat() ? static_cast<WAVFormatChunk::SampleFormats>(subFormat) : static_cast<WAVFormatChunk::SampleFormats>(formatInfo.format.get()); }
- uint16 GetNumChannels() const { return formatInfo.numChannels; }
- uint16 GetBitsPerSample() const { return formatInfo.bitsPerSample; }
- uint32 GetSampleRate() const { return formatInfo.sampleRate; }
- uint16 GetBlockAlign() const { return formatInfo.blockAlign; }
- FileReader GetSampleData() const { return sampleData; }
- FileReader GetWsmpChunk() const { return wsmpChunk; }
- bool IsExtensibleFormat() const { return formatInfo.format == WAVFormatChunk::fmtExtensible; }
- bool MayBeCoolEdit16_8() const { return mayBeCoolEdit16_8; }
-
- uint16 GetSampleSize() const { return static_cast<uint16>(((static_cast<uint32>(GetNumChannels()) * static_cast<uint32>(GetBitsPerSample())) + 7) / 8); }
-
- SmpLength GetSampleLength() const { return mpt::saturate_cast<SmpLength>(sampleLength); }
-
- void ApplySampleSettings(ModSample &sample, mpt::Charset sampleCharset, mpt::charbuf<MAX_SAMPLENAME> &sampleName);
- };
- #ifndef MODPLUG_NO_FILESAVE
- class WAVWriter
- {
- protected:
-
- mpt::IO::OFileBase &s;
-
- std::size_t position = 0;
-
- std::size_t totalSize = 0;
-
- std::size_t chunkStartPos = 0;
- RIFFChunk chunkHeader;
- bool finalized = false;
- public:
-
- WAVWriter(mpt::IO::OFileBase &stream);
- ~WAVWriter();
-
- std::size_t Finalize();
-
- void StartChunk(RIFFChunk::ChunkIdentifiers id);
-
- void Skip(size_t numBytes) { Seek(position + numBytes); }
-
- std::size_t GetPosition() const { return position; }
-
- template<typename T>
- void Write(const T &data)
- {
- Write(mpt::as_raw_memory(data));
- }
-
- void Write(mpt::const_byte_span data);
-
- void WriteBeforeDirect();
-
- void WriteAfterDirect(bool success, std::size_t count);
-
- void WriteFormat(uint32 sampleRate, uint16 bitDepth, uint16 numChannels, WAVFormatChunk::SampleFormats encoding);
-
- void WriteMetatags(const FileTags &tags);
-
- void WriteLoopInformation(const ModSample &sample);
-
- void WriteCueInformation(const ModSample &sample);
-
- void WriteExtraInformation(const ModSample &sample, MODTYPE modType, const char *sampleName = nullptr);
- protected:
-
- void Seek(std::size_t pos);
-
- void FinalizeChunk();
-
- void WriteTag(RIFFChunk::ChunkIdentifiers id, const mpt::ustring &utext);
- };
- #endif
- OPENMPT_NAMESPACE_END
|