1
0

SampleFormats.cpp 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652
  1. /*
  2. * SampleFormats.cpp
  3. * -----------------
  4. * Purpose: Code for loading various more or less common sample and instrument formats.
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "Sndfile.h"
  11. #include "mod_specifications.h"
  12. #ifdef MODPLUG_TRACKER
  13. #include "../mptrack/Moddoc.h"
  14. #include "Dlsbank.h"
  15. #endif // MODPLUG_TRACKER
  16. #include "../soundlib/AudioCriticalSection.h"
  17. #ifndef MODPLUG_NO_FILESAVE
  18. #include "mpt/io/base.hpp"
  19. #include "mpt/io/io.hpp"
  20. #include "mpt/io/io_stdstream.hpp"
  21. #include "../common/mptFileIO.h"
  22. #endif // !MODPLUG_NO_FILESAVE
  23. #include "../common/misc_util.h"
  24. #include "openmpt/base/Endian.hpp"
  25. #include "Tagging.h"
  26. #include "ITTools.h"
  27. #include "XMTools.h"
  28. #include "S3MTools.h"
  29. #include "WAVTools.h"
  30. #include "../common/version.h"
  31. #include "Loaders.h"
  32. #include "../common/FileReader.h"
  33. #include "../soundlib/ModSampleCopy.h"
  34. #include <functional>
  35. #include <map>
  36. OPENMPT_NAMESPACE_BEGIN
  37. using namespace mpt::uuid_literals;
  38. bool CSoundFile::ReadSampleFromFile(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize, bool includeInstrumentFormats)
  39. {
  40. if(!nSample || nSample >= MAX_SAMPLES) return false;
  41. if(!ReadWAVSample(nSample, file, mayNormalize)
  42. && !(includeInstrumentFormats && ReadXISample(nSample, file))
  43. && !(includeInstrumentFormats && ReadITISample(nSample, file))
  44. && !ReadW64Sample(nSample, file)
  45. && !ReadCAFSample(nSample, file)
  46. && !ReadAIFFSample(nSample, file, mayNormalize)
  47. && !ReadITSSample(nSample, file)
  48. && !(includeInstrumentFormats && ReadPATSample(nSample, file))
  49. && !ReadIFFSample(nSample, file)
  50. && !ReadS3ISample(nSample, file)
  51. && !ReadSBISample(nSample, file)
  52. && !ReadAUSample(nSample, file, mayNormalize)
  53. && !ReadBRRSample(nSample, file)
  54. && !ReadFLACSample(nSample, file)
  55. && !ReadOpusSample(nSample, file)
  56. && !ReadVorbisSample(nSample, file)
  57. && !ReadMP3Sample(nSample, file, false)
  58. && !ReadMediaFoundationSample(nSample, file)
  59. )
  60. {
  61. return false;
  62. }
  63. if(nSample > GetNumSamples())
  64. {
  65. m_nSamples = nSample;
  66. }
  67. if(Samples[nSample].uFlags[CHN_ADLIB])
  68. {
  69. InitOPL();
  70. }
  71. return true;
  72. }
  73. bool CSoundFile::ReadInstrumentFromFile(INSTRUMENTINDEX nInstr, FileReader &file, bool mayNormalize)
  74. {
  75. if ((!nInstr) || (nInstr >= MAX_INSTRUMENTS)) return false;
  76. if(!ReadITIInstrument(nInstr, file)
  77. && !ReadXIInstrument(nInstr, file)
  78. && !ReadPATInstrument(nInstr, file)
  79. && !ReadSFZInstrument(nInstr, file)
  80. // Generic read
  81. && !ReadSampleAsInstrument(nInstr, file, mayNormalize))
  82. {
  83. bool ok = false;
  84. #ifdef MODPLUG_TRACKER
  85. CDLSBank bank;
  86. if(bank.Open(file))
  87. {
  88. ok = bank.ExtractInstrument(*this, nInstr, 0, 0);
  89. }
  90. #endif // MODPLUG_TRACKER
  91. if(!ok) return false;
  92. }
  93. if(nInstr > GetNumInstruments()) m_nInstruments = nInstr;
  94. return true;
  95. }
  96. bool CSoundFile::ReadSampleAsInstrument(INSTRUMENTINDEX nInstr, FileReader &file, bool mayNormalize)
  97. {
  98. // Scanning free sample
  99. SAMPLEINDEX nSample = GetNextFreeSample(nInstr); // may also return samples which are only referenced by the current instrument
  100. if(nSample == SAMPLEINDEX_INVALID)
  101. {
  102. return false;
  103. }
  104. // Loading Instrument
  105. ModInstrument *pIns = new (std::nothrow) ModInstrument(nSample);
  106. if(pIns == nullptr)
  107. {
  108. return false;
  109. }
  110. if(!ReadSampleFromFile(nSample, file, mayNormalize, false))
  111. {
  112. delete pIns;
  113. return false;
  114. }
  115. // Remove all samples which are only referenced by the old instrument, except for the one we just loaded our new sample into.
  116. RemoveInstrumentSamples(nInstr, nSample);
  117. // Replace the instrument
  118. DestroyInstrument(nInstr, doNoDeleteAssociatedSamples);
  119. Instruments[nInstr] = pIns;
  120. #if defined(MPT_ENABLE_FILEIO) && defined(MPT_EXTERNAL_SAMPLES)
  121. SetSamplePath(nSample, file.GetOptionalFileName().value_or(P_("")));
  122. #endif
  123. return true;
  124. }
  125. bool CSoundFile::DestroyInstrument(INSTRUMENTINDEX nInstr, deleteInstrumentSamples removeSamples)
  126. {
  127. if(nInstr == 0 || nInstr >= MAX_INSTRUMENTS || !Instruments[nInstr]) return true;
  128. if(removeSamples == deleteAssociatedSamples)
  129. {
  130. RemoveInstrumentSamples(nInstr);
  131. }
  132. CriticalSection cs;
  133. ModInstrument *pIns = Instruments[nInstr];
  134. Instruments[nInstr] = nullptr;
  135. for(auto &chn : m_PlayState.Chn)
  136. {
  137. if(chn.pModInstrument == pIns)
  138. chn.pModInstrument = nullptr;
  139. }
  140. delete pIns;
  141. return true;
  142. }
  143. // Remove all unused samples from the given nInstr and keep keepSample if provided
  144. bool CSoundFile::RemoveInstrumentSamples(INSTRUMENTINDEX nInstr, SAMPLEINDEX keepSample)
  145. {
  146. if(Instruments[nInstr] == nullptr)
  147. {
  148. return false;
  149. }
  150. std::vector<bool> keepSamples(GetNumSamples() + 1, true);
  151. // Check which samples are used by the instrument we are going to nuke.
  152. auto referencedSamples = Instruments[nInstr]->GetSamples();
  153. for(auto sample : referencedSamples)
  154. {
  155. if(sample <= GetNumSamples())
  156. {
  157. keepSamples[sample] = false;
  158. }
  159. }
  160. // If we want to keep a specific sample, do so.
  161. if(keepSample != SAMPLEINDEX_INVALID)
  162. {
  163. if(keepSample <= GetNumSamples())
  164. {
  165. keepSamples[keepSample] = true;
  166. }
  167. }
  168. // Check if any of those samples are referenced by other instruments as well, in which case we want to keep them of course.
  169. for(INSTRUMENTINDEX nIns = 1; nIns <= GetNumInstruments(); nIns++) if (Instruments[nIns] != nullptr && nIns != nInstr)
  170. {
  171. Instruments[nIns]->GetSamples(keepSamples);
  172. }
  173. // Now nuke the selected samples.
  174. RemoveSelectedSamples(keepSamples);
  175. return true;
  176. }
  177. ////////////////////////////////////////////////////////////////////////////////
  178. //
  179. // I/O From another song
  180. //
  181. bool CSoundFile::ReadInstrumentFromSong(INSTRUMENTINDEX targetInstr, const CSoundFile &srcSong, INSTRUMENTINDEX sourceInstr)
  182. {
  183. if ((!sourceInstr) || (sourceInstr > srcSong.GetNumInstruments())
  184. || (targetInstr >= MAX_INSTRUMENTS) || (!srcSong.Instruments[sourceInstr]))
  185. {
  186. return false;
  187. }
  188. if (m_nInstruments < targetInstr) m_nInstruments = targetInstr;
  189. ModInstrument *pIns = new (std::nothrow) ModInstrument();
  190. if(pIns == nullptr)
  191. {
  192. return false;
  193. }
  194. DestroyInstrument(targetInstr, deleteAssociatedSamples);
  195. Instruments[targetInstr] = pIns;
  196. *pIns = *srcSong.Instruments[sourceInstr];
  197. std::vector<SAMPLEINDEX> sourceSample; // Sample index in source song
  198. std::vector<SAMPLEINDEX> targetSample; // Sample index in target song
  199. SAMPLEINDEX targetIndex = 0; // Next index for inserting sample
  200. for(auto &sample : pIns->Keyboard)
  201. {
  202. const SAMPLEINDEX sourceIndex = sample;
  203. if(sourceIndex > 0 && sourceIndex <= srcSong.GetNumSamples())
  204. {
  205. const auto entry = std::find(sourceSample.cbegin(), sourceSample.cend(), sourceIndex);
  206. if(entry == sourceSample.end())
  207. {
  208. // Didn't consider this sample yet, so add it to our map.
  209. targetIndex = GetNextFreeSample(targetInstr, targetIndex + 1);
  210. if(targetIndex <= GetModSpecifications().samplesMax)
  211. {
  212. sourceSample.push_back(sourceIndex);
  213. targetSample.push_back(targetIndex);
  214. sample = targetIndex;
  215. } else
  216. {
  217. sample = 0;
  218. }
  219. } else
  220. {
  221. // Sample reference has already been created, so only need to update the sample map.
  222. sample = *(entry - sourceSample.begin() + targetSample.begin());
  223. }
  224. } else
  225. {
  226. // Invalid or no source sample
  227. sample = 0;
  228. }
  229. }
  230. #ifdef MODPLUG_TRACKER
  231. if(pIns->filename.empty() && srcSong.GetpModDoc() != nullptr && &srcSong != this)
  232. {
  233. pIns->filename = srcSong.GetpModDoc()->GetPathNameMpt().GetFullFileName().ToLocale();
  234. }
  235. #endif
  236. pIns->Convert(srcSong.GetType(), GetType());
  237. // Copy all referenced samples over
  238. for(size_t i = 0; i < targetSample.size(); i++)
  239. {
  240. ReadSampleFromSong(targetSample[i], srcSong, sourceSample[i]);
  241. }
  242. return true;
  243. }
  244. bool CSoundFile::ReadSampleFromSong(SAMPLEINDEX targetSample, const CSoundFile &srcSong, SAMPLEINDEX sourceSample)
  245. {
  246. if(!sourceSample
  247. || sourceSample > srcSong.GetNumSamples()
  248. || (targetSample >= GetModSpecifications().samplesMax && targetSample > GetNumSamples()))
  249. {
  250. return false;
  251. }
  252. DestroySampleThreadsafe(targetSample);
  253. const ModSample &sourceSmp = srcSong.GetSample(sourceSample);
  254. ModSample &targetSmp = GetSample(targetSample);
  255. if(GetNumSamples() < targetSample) m_nSamples = targetSample;
  256. targetSmp = sourceSmp;
  257. m_szNames[targetSample] = srcSong.m_szNames[sourceSample];
  258. if(sourceSmp.HasSampleData())
  259. {
  260. if(targetSmp.CopyWaveform(sourceSmp))
  261. targetSmp.PrecomputeLoops(*this, false);
  262. // Remember on-disk path (for MPTM files), but don't implicitely enable on-disk storage
  263. // (we really don't want this for e.g. duplicating samples or splitting stereo samples)
  264. #ifdef MPT_EXTERNAL_SAMPLES
  265. SetSamplePath(targetSample, srcSong.GetSamplePath(sourceSample));
  266. #endif
  267. targetSmp.uFlags.reset(SMP_KEEPONDISK);
  268. }
  269. #ifdef MODPLUG_TRACKER
  270. if((targetSmp.filename.empty()) && srcSong.GetpModDoc() != nullptr && &srcSong != this)
  271. {
  272. targetSmp.filename = mpt::ToCharset(GetCharsetInternal(), srcSong.GetpModDoc()->GetTitle());
  273. }
  274. #endif
  275. if(targetSmp.uFlags[CHN_ADLIB] && !SupportsOPL())
  276. {
  277. AddToLog(LogInformation, U_("OPL instruments are not supported by this format."));
  278. }
  279. targetSmp.Convert(srcSong.GetType(), GetType());
  280. if(targetSmp.uFlags[CHN_ADLIB])
  281. {
  282. InitOPL();
  283. }
  284. return true;
  285. }
  286. ////////////////////////////////////////////////////////////////////////
  287. // IMA ADPCM Support for WAV files
  288. static bool IMAADPCMUnpack16(int16 *target, SmpLength sampleLen, FileReader file, uint16 blockAlign, uint32 numChannels)
  289. {
  290. static constexpr int8 IMAIndexTab[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
  291. static constexpr int16 IMAUnpackTable[90] =
  292. {
  293. 7, 8, 9, 10, 11, 12, 13, 14,
  294. 16, 17, 19, 21, 23, 25, 28, 31,
  295. 34, 37, 41, 45, 50, 55, 60, 66,
  296. 73, 80, 88, 97, 107, 118, 130, 143,
  297. 157, 173, 190, 209, 230, 253, 279, 307,
  298. 337, 371, 408, 449, 494, 544, 598, 658,
  299. 724, 796, 876, 963, 1060, 1166, 1282, 1411,
  300. 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
  301. 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
  302. 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  303. 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
  304. 32767, 0
  305. };
  306. if(target == nullptr || blockAlign < 4u * numChannels)
  307. return false;
  308. SmpLength samplePos = 0;
  309. sampleLen *= numChannels;
  310. while(file.CanRead(4u * numChannels) && samplePos < sampleLen)
  311. {
  312. FileReader block = file.ReadChunk(blockAlign);
  313. FileReader::PinnedView blockView = block.GetPinnedView();
  314. const std::byte *data = blockView.data();
  315. const uint32 blockSize = static_cast<uint32>(blockView.size());
  316. for(uint32 chn = 0; chn < numChannels; chn++)
  317. {
  318. // Block header
  319. int32 value = block.ReadInt16LE();
  320. int32 nIndex = block.ReadUint8();
  321. Limit(nIndex, 0, 89);
  322. block.Skip(1);
  323. SmpLength smpPos = samplePos + chn;
  324. uint32 dataPos = (numChannels + chn) * 4;
  325. // Block data
  326. while(smpPos <= (sampleLen - 8) && dataPos <= (blockSize - 4))
  327. {
  328. for(uint32 i = 0; i < 8; i++)
  329. {
  330. uint8 delta = mpt::byte_cast<uint8>(data[dataPos]);
  331. if(i & 1)
  332. {
  333. delta >>= 4;
  334. dataPos++;
  335. } else
  336. {
  337. delta &= 0x0F;
  338. }
  339. int32 v = IMAUnpackTable[nIndex] >> 3;
  340. if (delta & 1) v += IMAUnpackTable[nIndex] >> 2;
  341. if (delta & 2) v += IMAUnpackTable[nIndex] >> 1;
  342. if (delta & 4) v += IMAUnpackTable[nIndex];
  343. if (delta & 8) value -= v; else value += v;
  344. nIndex += IMAIndexTab[delta & 7];
  345. Limit(nIndex, 0, 88);
  346. Limit(value, -32768, 32767);
  347. target[smpPos] = static_cast<int16>(value);
  348. smpPos += numChannels;
  349. }
  350. dataPos += (numChannels - 1) * 4u;
  351. }
  352. }
  353. samplePos += ((blockSize - (numChannels * 4u)) * 2u);
  354. }
  355. return true;
  356. }
  357. ////////////////////////////////////////////////////////////////////////////////
  358. // WAV Open
  359. bool CSoundFile::ReadWAVSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize, FileReader *wsmpChunk)
  360. {
  361. WAVReader wavFile(file);
  362. static constexpr WAVFormatChunk::SampleFormats SupportedFormats[] = {WAVFormatChunk::fmtPCM, WAVFormatChunk::fmtFloat, WAVFormatChunk::fmtIMA_ADPCM, WAVFormatChunk::fmtMP3, WAVFormatChunk::fmtALaw, WAVFormatChunk::fmtULaw};
  363. if(!wavFile.IsValid()
  364. || wavFile.GetNumChannels() == 0
  365. || wavFile.GetNumChannels() > 2
  366. || (wavFile.GetBitsPerSample() == 0 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3)
  367. || (wavFile.GetBitsPerSample() < 32 && wavFile.GetSampleFormat() == WAVFormatChunk::fmtFloat)
  368. || (wavFile.GetBitsPerSample() > 64)
  369. || !mpt::contains(SupportedFormats, wavFile.GetSampleFormat()))
  370. {
  371. return false;
  372. }
  373. DestroySampleThreadsafe(nSample);
  374. m_szNames[nSample] = "";
  375. ModSample &sample = Samples[nSample];
  376. sample.Initialize();
  377. sample.nLength = wavFile.GetSampleLength();
  378. sample.nC5Speed = wavFile.GetSampleRate();
  379. wavFile.ApplySampleSettings(sample, GetCharsetInternal(), m_szNames[nSample]);
  380. FileReader sampleChunk = wavFile.GetSampleData();
  381. SampleIO sampleIO(
  382. SampleIO::_8bit,
  383. (wavFile.GetNumChannels() > 1) ? SampleIO::stereoInterleaved : SampleIO::mono,
  384. SampleIO::littleEndian,
  385. SampleIO::signedPCM);
  386. if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtIMA_ADPCM && wavFile.GetNumChannels() <= 2)
  387. {
  388. // IMA ADPCM 4:1
  389. LimitMax(sample.nLength, MAX_SAMPLE_LENGTH);
  390. sample.uFlags.set(CHN_16BIT);
  391. sample.uFlags.set(CHN_STEREO, wavFile.GetNumChannels() == 2);
  392. if(!sample.AllocateSample())
  393. {
  394. return false;
  395. }
  396. IMAADPCMUnpack16(sample.sample16(), sample.nLength, sampleChunk, wavFile.GetBlockAlign(), wavFile.GetNumChannels());
  397. sample.PrecomputeLoops(*this, false);
  398. } else if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtMP3)
  399. {
  400. // MP3 in WAV
  401. bool loadedMP3 = ReadMP3Sample(nSample, sampleChunk, false, true) || ReadMediaFoundationSample(nSample, sampleChunk, true);
  402. if(!loadedMP3)
  403. {
  404. return false;
  405. }
  406. } else if(!wavFile.IsExtensibleFormat() && wavFile.MayBeCoolEdit16_8() && wavFile.GetSampleFormat() == WAVFormatChunk::fmtPCM && wavFile.GetBitsPerSample() == 32 && wavFile.GetBlockAlign() == wavFile.GetNumChannels() * 4)
  407. {
  408. // Syntrillium Cool Edit hack to store IEEE 32bit floating point
  409. // Format is described as 32bit integer PCM contained in 32bit blocks and an WAVEFORMATEX extension size of 2 which contains a single 16 bit little endian value of 1.
  410. // (This is parsed in WAVTools.cpp and returned via MayBeCoolEdit16_8()).
  411. // The data actually stored in this case is little endian 32bit floating point PCM with 2**15 full scale.
  412. // Cool Edit calls this format "16.8 float".
  413. sampleIO |= SampleIO::_32bit;
  414. sampleIO |= SampleIO::floatPCM15;
  415. sampleIO.ReadSample(sample, sampleChunk);
  416. } else if(!wavFile.IsExtensibleFormat() && wavFile.GetSampleFormat() == WAVFormatChunk::fmtPCM && wavFile.GetBitsPerSample() == 24 && wavFile.GetBlockAlign() == wavFile.GetNumChannels() * 4)
  417. {
  418. // Syntrillium Cool Edit hack to store IEEE 32bit floating point
  419. // Format is described as 24bit integer PCM contained in 32bit blocks.
  420. // The data actually stored in this case is little endian 32bit floating point PCM with 2**23 full scale.
  421. // Cool Edit calls this format "24.0 float".
  422. sampleIO |= SampleIO::_32bit;
  423. sampleIO |= SampleIO::floatPCM23;
  424. sampleIO.ReadSample(sample, sampleChunk);
  425. } else if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtALaw || wavFile.GetSampleFormat() == WAVFormatChunk::fmtULaw)
  426. {
  427. // a-law / u-law
  428. sampleIO |= SampleIO::_16bit;
  429. sampleIO |= wavFile.GetSampleFormat() == WAVFormatChunk::fmtALaw ? SampleIO::aLaw : SampleIO::uLaw;
  430. sampleIO.ReadSample(sample, sampleChunk);
  431. } else
  432. {
  433. // PCM / Float
  434. SampleIO::Bitdepth bitDepth;
  435. switch((wavFile.GetBitsPerSample() - 1) / 8u)
  436. {
  437. default:
  438. case 0: bitDepth = SampleIO::_8bit; break;
  439. case 1: bitDepth = SampleIO::_16bit; break;
  440. case 2: bitDepth = SampleIO::_24bit; break;
  441. case 3: bitDepth = SampleIO::_32bit; break;
  442. case 7: bitDepth = SampleIO::_64bit; break;
  443. }
  444. sampleIO |= bitDepth;
  445. if(wavFile.GetBitsPerSample() <= 8)
  446. sampleIO |= SampleIO::unsignedPCM;
  447. if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtFloat)
  448. sampleIO |= SampleIO::floatPCM;
  449. if(mayNormalize)
  450. sampleIO.MayNormalize();
  451. sampleIO.ReadSample(sample, sampleChunk);
  452. }
  453. if(wsmpChunk != nullptr)
  454. {
  455. // DLS WSMP chunk
  456. *wsmpChunk = wavFile.GetWsmpChunk();
  457. }
  458. sample.Convert(MOD_TYPE_IT, GetType());
  459. sample.PrecomputeLoops(*this, false);
  460. return true;
  461. }
  462. ///////////////////////////////////////////////////////////////
  463. // Save WAV
  464. #ifndef MODPLUG_NO_FILESAVE
  465. bool CSoundFile::SaveWAVSample(SAMPLEINDEX nSample, std::ostream &f) const
  466. {
  467. const ModSample &sample = Samples[nSample];
  468. if(sample.uFlags[CHN_ADLIB])
  469. return false;
  470. mpt::IO::OFile<std::ostream> ff(f);
  471. WAVWriter file(ff);
  472. file.WriteFormat(sample.GetSampleRate(GetType()), sample.GetElementarySampleSize() * 8, sample.GetNumChannels(), WAVFormatChunk::fmtPCM);
  473. // Write sample data
  474. file.StartChunk(RIFFChunk::iddata);
  475. file.Skip(SampleIO(
  476. sample.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit,
  477. sample.uFlags[CHN_STEREO] ? SampleIO::stereoInterleaved : SampleIO::mono,
  478. SampleIO::littleEndian,
  479. sample.uFlags[CHN_16BIT] ? SampleIO::signedPCM : SampleIO::unsignedPCM)
  480. .WriteSample(f, sample));
  481. file.WriteLoopInformation(sample);
  482. file.WriteExtraInformation(sample, GetType());
  483. if(sample.HasCustomCuePoints())
  484. {
  485. file.WriteCueInformation(sample);
  486. }
  487. FileTags tags;
  488. tags.SetEncoder();
  489. tags.title = mpt::ToUnicode(GetCharsetInternal(), m_szNames[nSample]);
  490. file.WriteMetatags(tags);
  491. file.Finalize();
  492. return true;
  493. }
  494. #endif // MODPLUG_NO_FILESAVE
  495. /////////////////
  496. // Sony Wave64 //
  497. struct Wave64FileHeader
  498. {
  499. mpt::GUIDms GuidRIFF;
  500. uint64le FileSize;
  501. mpt::GUIDms GuidWAVE;
  502. };
  503. MPT_BINARY_STRUCT(Wave64FileHeader, 40)
  504. struct Wave64ChunkHeader
  505. {
  506. mpt::GUIDms GuidChunk;
  507. uint64le Size;
  508. };
  509. MPT_BINARY_STRUCT(Wave64ChunkHeader, 24)
  510. struct Wave64Chunk
  511. {
  512. Wave64ChunkHeader header;
  513. FileReader::off_t GetLength() const
  514. {
  515. uint64 length = header.Size;
  516. if(length < sizeof(Wave64ChunkHeader))
  517. {
  518. length = 0;
  519. } else
  520. {
  521. length -= sizeof(Wave64ChunkHeader);
  522. }
  523. return mpt::saturate_cast<FileReader::off_t>(length);
  524. }
  525. mpt::UUID GetID() const
  526. {
  527. return mpt::UUID(header.GuidChunk);
  528. }
  529. };
  530. MPT_BINARY_STRUCT(Wave64Chunk, 24)
  531. static void Wave64TagFromLISTINFO(mpt::ustring & dst, uint16 codePage, const FileReader::ChunkList<RIFFChunk> & infoChunk, RIFFChunk::ChunkIdentifiers id)
  532. {
  533. if(!infoChunk.ChunkExists(id))
  534. {
  535. return;
  536. }
  537. FileReader textChunk = infoChunk.GetChunk(id);
  538. if(!textChunk.IsValid())
  539. {
  540. return;
  541. }
  542. std::string str;
  543. textChunk.ReadString<mpt::String::maybeNullTerminated>(str, textChunk.GetLength());
  544. str = mpt::replace(str, std::string("\r\n"), std::string("\n"));
  545. str = mpt::replace(str, std::string("\r"), std::string("\n"));
  546. dst = mpt::ToUnicode(codePage, mpt::Charset::Windows1252, str);
  547. }
  548. bool CSoundFile::ReadW64Sample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize)
  549. {
  550. file.Rewind();
  551. constexpr mpt::UUID guidRIFF = "66666972-912E-11CF-A5D6-28DB04C10000"_uuid;
  552. constexpr mpt::UUID guidWAVE = "65766177-ACF3-11D3-8CD1-00C04F8EDB8A"_uuid;
  553. constexpr mpt::UUID guidLIST = "7473696C-912F-11CF-A5D6-28DB04C10000"_uuid;
  554. constexpr mpt::UUID guidFMT = "20746D66-ACF3-11D3-8CD1-00C04F8EDB8A"_uuid;
  555. //constexpr mpt::UUID guidFACT = "74636166-ACF3-11D3-8CD1-00C04F8EDB8A"_uuid;
  556. constexpr mpt::UUID guidDATA = "61746164-ACF3-11D3-8CD1-00C04F8EDB8A"_uuid;
  557. //constexpr mpt::UUID guidLEVL = "6C76656C-ACF3-11D3-8CD1-00C04F8EDB8A"_uuid;
  558. //constexpr mpt::UUID guidJUNK = "6b6E756A-ACF3-11D3-8CD1-00C04f8EDB8A"_uuid;
  559. //constexpr mpt::UUID guidBEXT = "74786562-ACF3-11D3-8CD1-00C04F8EDB8A"_uuid;
  560. //constexpr mpt::UUID guiMARKER = "ABF76256-392D-11D2-86C7-00C04F8EDB8A"_uuid;
  561. //constexpr mpt::UUID guiSUMMARYLIST = "925F94BC-525A-11D2-86DC-00C04F8EDB8A"_uuid;
  562. constexpr mpt::UUID guidCSET = "54455343-ACF3-11D3-8CD1-00C04F8EDB8A"_uuid;
  563. Wave64FileHeader fileHeader;
  564. if(!file.ReadStruct(fileHeader))
  565. {
  566. return false;
  567. }
  568. if(mpt::UUID(fileHeader.GuidRIFF) != guidRIFF)
  569. {
  570. return false;
  571. }
  572. if(mpt::UUID(fileHeader.GuidWAVE) != guidWAVE)
  573. {
  574. return false;
  575. }
  576. if(fileHeader.FileSize != file.GetLength())
  577. {
  578. return false;
  579. }
  580. FileReader chunkFile = file;
  581. auto chunkList = chunkFile.ReadChunks<Wave64Chunk>(8);
  582. if(!chunkList.ChunkExists(guidFMT))
  583. {
  584. return false;
  585. }
  586. FileReader formatChunk = chunkList.GetChunk(guidFMT);
  587. WAVFormatChunk format;
  588. if(!formatChunk.ReadStruct(format))
  589. {
  590. return false;
  591. }
  592. uint16 sampleFormat = format.format;
  593. if(format.format == WAVFormatChunk::fmtExtensible)
  594. {
  595. WAVFormatChunkExtension formatExt;
  596. if(!formatChunk.ReadStruct(formatExt))
  597. {
  598. return false;
  599. }
  600. sampleFormat = static_cast<uint16>(mpt::UUID(formatExt.subFormat).GetData1());
  601. }
  602. if(format.sampleRate == 0)
  603. {
  604. return false;
  605. }
  606. if(format.numChannels == 0)
  607. {
  608. return false;
  609. }
  610. if(format.numChannels > 2)
  611. {
  612. return false;
  613. }
  614. if(sampleFormat != WAVFormatChunk::fmtPCM && sampleFormat != WAVFormatChunk::fmtFloat)
  615. {
  616. return false;
  617. }
  618. if(sampleFormat == WAVFormatChunk::fmtFloat && format.bitsPerSample != 32 && format.bitsPerSample != 64)
  619. {
  620. return false;
  621. }
  622. if(sampleFormat == WAVFormatChunk::fmtPCM && format.bitsPerSample > 64)
  623. {
  624. return false;
  625. }
  626. SampleIO::Bitdepth bitDepth;
  627. switch((format.bitsPerSample - 1) / 8u)
  628. {
  629. default:
  630. case 0: bitDepth = SampleIO::_8bit ; break;
  631. case 1: bitDepth = SampleIO::_16bit; break;
  632. case 2: bitDepth = SampleIO::_24bit; break;
  633. case 3: bitDepth = SampleIO::_32bit; break;
  634. case 7: bitDepth = SampleIO::_64bit; break;
  635. }
  636. SampleIO sampleIO(
  637. bitDepth,
  638. (format.numChannels > 1) ? SampleIO::stereoInterleaved : SampleIO::mono,
  639. SampleIO::littleEndian,
  640. (sampleFormat == WAVFormatChunk::fmtFloat) ? SampleIO::floatPCM : SampleIO::signedPCM);
  641. if(format.bitsPerSample <= 8)
  642. {
  643. sampleIO |= SampleIO::unsignedPCM;
  644. }
  645. if(mayNormalize)
  646. {
  647. sampleIO.MayNormalize();
  648. }
  649. FileTags tags;
  650. uint16 codePage = 28591; // mpt::Charset::ISO8859_1
  651. FileReader csetChunk = chunkList.GetChunk(guidCSET);
  652. if(csetChunk.IsValid())
  653. {
  654. if(csetChunk.CanRead(2))
  655. {
  656. codePage = csetChunk.ReadUint16LE();
  657. }
  658. }
  659. if(chunkList.ChunkExists(guidLIST))
  660. {
  661. FileReader listChunk = chunkList.GetChunk(guidLIST);
  662. if(listChunk.ReadMagic("INFO"))
  663. {
  664. auto infoChunk = listChunk.ReadChunks<RIFFChunk>(2);
  665. Wave64TagFromLISTINFO(tags.title, codePage, infoChunk, RIFFChunk::idINAM);
  666. Wave64TagFromLISTINFO(tags.encoder, codePage, infoChunk, RIFFChunk::idISFT);
  667. //Wave64TagFromLISTINFO(void, codePage, infoChunk, RIFFChunk::idICOP);
  668. Wave64TagFromLISTINFO(tags.artist, codePage, infoChunk, RIFFChunk::idIART);
  669. Wave64TagFromLISTINFO(tags.album, codePage, infoChunk, RIFFChunk::idIPRD);
  670. Wave64TagFromLISTINFO(tags.comments, codePage, infoChunk, RIFFChunk::idICMT);
  671. //Wave64TagFromLISTINFO(void, codePage, infoChunk, RIFFChunk::idIENG);
  672. //Wave64TagFromLISTINFO(void, codePage, infoChunk, RIFFChunk::idISBJ);
  673. Wave64TagFromLISTINFO(tags.genre, codePage, infoChunk, RIFFChunk::idIGNR);
  674. //Wave64TagFromLISTINFO(void, codePage, infoChunk, RIFFChunk::idICRD);
  675. Wave64TagFromLISTINFO(tags.year, codePage, infoChunk, RIFFChunk::idYEAR);
  676. Wave64TagFromLISTINFO(tags.trackno, codePage, infoChunk, RIFFChunk::idTRCK);
  677. Wave64TagFromLISTINFO(tags.url, codePage, infoChunk, RIFFChunk::idTURL);
  678. //Wave64TagFromLISTINFO(tags.bpm, codePage, infoChunk, void);
  679. }
  680. }
  681. if(!chunkList.ChunkExists(guidDATA))
  682. {
  683. return false;
  684. }
  685. FileReader audioData = chunkList.GetChunk(guidDATA);
  686. SmpLength length = mpt::saturate_cast<SmpLength>(audioData.GetLength() / (sampleIO.GetEncodedBitsPerSample()/8));
  687. ModSample &mptSample = Samples[nSample];
  688. DestroySampleThreadsafe(nSample);
  689. mptSample.Initialize();
  690. mptSample.nLength = length;
  691. mptSample.nC5Speed = format.sampleRate;
  692. sampleIO.ReadSample(mptSample, audioData);
  693. m_szNames[nSample] = mpt::ToCharset(GetCharsetInternal(), GetSampleNameFromTags(tags));
  694. mptSample.Convert(MOD_TYPE_IT, GetType());
  695. mptSample.PrecomputeLoops(*this, false);
  696. return true;
  697. }
  698. #ifndef MODPLUG_NO_FILESAVE
  699. ///////////////////////////////////////////////////////////////
  700. // Save RAW
  701. bool CSoundFile::SaveRAWSample(SAMPLEINDEX nSample, std::ostream &f) const
  702. {
  703. const ModSample &sample = Samples[nSample];
  704. SampleIO(
  705. sample.uFlags[CHN_16BIT] ? SampleIO::_16bit : SampleIO::_8bit,
  706. sample.uFlags[CHN_STEREO] ? SampleIO::stereoInterleaved : SampleIO::mono,
  707. SampleIO::littleEndian,
  708. SampleIO::signedPCM)
  709. .WriteSample(f, sample);
  710. return true;
  711. }
  712. #endif // MODPLUG_NO_FILESAVE
  713. /////////////////////////////////////////////////////////////
  714. // GUS Patches
  715. struct GF1PatchFileHeader
  716. {
  717. char magic[8]; // "GF1PATCH"
  718. char version[4]; // "100", or "110"
  719. char id[10]; // "ID#000002"
  720. char copyright[60]; // Copyright
  721. uint8le numInstr; // Number of instruments in patch
  722. uint8le voices; // Number of voices, usually 14
  723. uint8le channels; // Number of wav channels that can be played concurently to the patch
  724. uint16le numSamples; // Total number of waveforms for all the .PAT
  725. uint16le volume; // Master volume
  726. uint32le dataSize;
  727. char reserved2[36];
  728. };
  729. MPT_BINARY_STRUCT(GF1PatchFileHeader, 129)
  730. struct GF1Instrument
  731. {
  732. uint16le id; // Instrument id: 0-65535
  733. char name[16]; // Name of instrument. Gravis doesn't seem to use it
  734. uint32le size; // Number of bytes for the instrument with header. (To skip to next instrument)
  735. uint8 layers; // Number of layers in instrument: 1-4
  736. char reserved[40];
  737. };
  738. MPT_BINARY_STRUCT(GF1Instrument, 63)
  739. struct GF1SampleHeader
  740. {
  741. char name[7]; // null terminated string. name of the wave.
  742. uint8le fractions; // Start loop point fraction in 4 bits + End loop point fraction in the 4 other bits.
  743. uint32le length; // total size of wavesample. limited to 65535 now by the drivers, not the card.
  744. uint32le loopstart; // start loop position in the wavesample
  745. uint32le loopend; // end loop position in the wavesample
  746. uint16le freq; // Rate at which the wavesample has been sampled
  747. uint32le low_freq; // check note.h for the correspondance.
  748. uint32le high_freq; // check note.h for the correspondance.
  749. uint32le root_freq; // check note.h for the correspondance.
  750. int16le finetune; // fine tune. -512 to +512, EXCLUDING 0 cause it is a multiplier. 512 is one octave off, and 1 is a neutral value
  751. uint8le balance; // Balance: 0-15. 0=full left, 15 = full right
  752. uint8le env_rate[6]; // attack rates
  753. uint8le env_volume[6]; // attack volumes
  754. uint8le tremolo_sweep, tremolo_rate, tremolo_depth;
  755. uint8le vibrato_sweep, vibrato_rate, vibrato_depth;
  756. uint8le flags;
  757. int16le scale_frequency; // Note
  758. uint16le scale_factor; // 0...2048 (1024 is normal) or 0...2
  759. char reserved[36];
  760. };
  761. MPT_BINARY_STRUCT(GF1SampleHeader, 96)
  762. // -- GF1 Envelopes --
  763. //
  764. // It can be represented like this (the envelope is totally bogus, it is
  765. // just to show the concept):
  766. //
  767. // |
  768. // | /----` | |
  769. // | /------/ `\ | | | | |
  770. // | / \ | | | | |
  771. // | / \ | | | | |
  772. // |/ \ | | | | |
  773. // ---------------------------- | | | | | |
  774. // <---> attack rate 0 0 1 2 3 4 5 amplitudes
  775. // <----> attack rate 1
  776. // <> attack rate 2
  777. // <--> attack rate 3
  778. // <> attack rate 4
  779. // <-----> attack rate 5
  780. //
  781. // -- GF1 Flags --
  782. //
  783. // bit 0: 8/16 bit
  784. // bit 1: Signed/Unsigned
  785. // bit 2: off/on looping
  786. // bit 3: off/on bidirectionnal looping
  787. // bit 4: off/on backward looping
  788. // bit 5: off/on sustaining (3rd point in env.)
  789. // bit 6: off/on envelopes
  790. // bit 7: off/on clamped release (6th point, env)
  791. struct GF1Layer
  792. {
  793. uint8le previous; // If !=0 the wavesample to use is from the previous layer. The waveheader is still needed
  794. uint8le id; // Layer id: 0-3
  795. uint32le size; // data size in bytes in the layer, without the header. to skip to next layer for example:
  796. uint8le samples; // number of wavesamples
  797. char reserved[40];
  798. };
  799. MPT_BINARY_STRUCT(GF1Layer, 47)
  800. static double PatchFreqToNote(uint32 nFreq)
  801. {
  802. return std::log(nFreq / 2044.0) * (12.0 * 1.44269504088896340736); // 1.0/std::log(2.0)
  803. }
  804. static int32 PatchFreqToNoteInt(uint32 nFreq)
  805. {
  806. return mpt::saturate_round<int32>(PatchFreqToNote(nFreq));
  807. }
  808. static void PatchToSample(CSoundFile *that, SAMPLEINDEX nSample, GF1SampleHeader &sampleHeader, FileReader &file)
  809. {
  810. ModSample &sample = that->GetSample(nSample);
  811. file.ReadStruct(sampleHeader);
  812. sample.Initialize();
  813. if(sampleHeader.flags & 4) sample.uFlags.set(CHN_LOOP);
  814. if(sampleHeader.flags & 8) sample.uFlags.set(CHN_PINGPONGLOOP);
  815. if(sampleHeader.flags & 16) sample.uFlags.set(CHN_REVERSE);
  816. sample.nLength = sampleHeader.length;
  817. sample.nLoopStart = sampleHeader.loopstart;
  818. sample.nLoopEnd = sampleHeader.loopend;
  819. sample.nC5Speed = sampleHeader.freq;
  820. sample.nPan = (sampleHeader.balance * 256 + 8) / 15;
  821. if(sample.nPan > 256) sample.nPan = 128;
  822. else sample.uFlags.set(CHN_PANNING);
  823. sample.nVibType = VIB_SINE;
  824. sample.nVibSweep = sampleHeader.vibrato_sweep;
  825. sample.nVibDepth = sampleHeader.vibrato_depth;
  826. sample.nVibRate = sampleHeader.vibrato_rate / 4;
  827. if(sampleHeader.scale_factor)
  828. {
  829. sample.Transpose((84.0 - PatchFreqToNote(sampleHeader.root_freq)) / 12.0);
  830. }
  831. SampleIO sampleIO(
  832. SampleIO::_8bit,
  833. SampleIO::mono,
  834. SampleIO::littleEndian,
  835. (sampleHeader.flags & 2) ? SampleIO::unsignedPCM : SampleIO::signedPCM);
  836. if(sampleHeader.flags & 1)
  837. {
  838. sampleIO |= SampleIO::_16bit;
  839. sample.nLength /= 2;
  840. sample.nLoopStart /= 2;
  841. sample.nLoopEnd /= 2;
  842. }
  843. sampleIO.ReadSample(sample, file);
  844. sample.Convert(MOD_TYPE_IT, that->GetType());
  845. sample.PrecomputeLoops(*that, false);
  846. that->m_szNames[nSample] = mpt::String::ReadBuf(mpt::String::maybeNullTerminated, sampleHeader.name);
  847. }
  848. bool CSoundFile::ReadPATSample(SAMPLEINDEX nSample, FileReader &file)
  849. {
  850. file.Rewind();
  851. GF1PatchFileHeader fileHeader;
  852. GF1Instrument instrHeader; // We only support one instrument
  853. GF1Layer layerHeader;
  854. if(!file.ReadStruct(fileHeader)
  855. || memcmp(fileHeader.magic, "GF1PATCH", 8)
  856. || (memcmp(fileHeader.version, "110\0", 4) && memcmp(fileHeader.version, "100\0", 4))
  857. || memcmp(fileHeader.id, "ID#000002\0", 10)
  858. || !fileHeader.numInstr || !fileHeader.numSamples
  859. || !file.ReadStruct(instrHeader)
  860. //|| !instrHeader.layers // DOO.PAT has 0 layers
  861. || !file.ReadStruct(layerHeader)
  862. || !layerHeader.samples)
  863. {
  864. return false;
  865. }
  866. DestroySampleThreadsafe(nSample);
  867. GF1SampleHeader sampleHeader;
  868. PatchToSample(this, nSample, sampleHeader, file);
  869. if(instrHeader.name[0] > ' ')
  870. {
  871. m_szNames[nSample] = mpt::String::ReadBuf(mpt::String::maybeNullTerminated, instrHeader.name);
  872. }
  873. return true;
  874. }
  875. // PAT Instrument
  876. bool CSoundFile::ReadPATInstrument(INSTRUMENTINDEX nInstr, FileReader &file)
  877. {
  878. file.Rewind();
  879. GF1PatchFileHeader fileHeader;
  880. GF1Instrument instrHeader; // We only support one instrument
  881. GF1Layer layerHeader;
  882. if(!file.ReadStruct(fileHeader)
  883. || memcmp(fileHeader.magic, "GF1PATCH", 8)
  884. || (memcmp(fileHeader.version, "110\0", 4) && memcmp(fileHeader.version, "100\0", 4))
  885. || memcmp(fileHeader.id, "ID#000002\0", 10)
  886. || !fileHeader.numInstr || !fileHeader.numSamples
  887. || !file.ReadStruct(instrHeader)
  888. //|| !instrHeader.layers // DOO.PAT has 0 layers
  889. || !file.ReadStruct(layerHeader)
  890. || !layerHeader.samples)
  891. {
  892. return false;
  893. }
  894. ModInstrument *pIns = new (std::nothrow) ModInstrument();
  895. if(pIns == nullptr)
  896. {
  897. return false;
  898. }
  899. DestroyInstrument(nInstr, deleteAssociatedSamples);
  900. if (nInstr > m_nInstruments) m_nInstruments = nInstr;
  901. Instruments[nInstr] = pIns;
  902. pIns->name = mpt::String::ReadBuf(mpt::String::maybeNullTerminated, instrHeader.name);
  903. pIns->nFadeOut = 2048;
  904. if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))
  905. {
  906. pIns->nNNA = NewNoteAction::NoteOff;
  907. pIns->nDNA = DuplicateNoteAction::NoteFade;
  908. }
  909. SAMPLEINDEX nextSample = 0;
  910. int32 nMinSmpNote = 0xFF;
  911. SAMPLEINDEX nMinSmp = 0;
  912. for(uint8 smp = 0; smp < layerHeader.samples; smp++)
  913. {
  914. // Find a free sample
  915. nextSample = GetNextFreeSample(nInstr, nextSample + 1);
  916. if(nextSample == SAMPLEINDEX_INVALID) break;
  917. if(m_nSamples < nextSample) m_nSamples = nextSample;
  918. if(!nMinSmp) nMinSmp = nextSample;
  919. // Load it
  920. GF1SampleHeader sampleHeader;
  921. PatchToSample(this, nextSample, sampleHeader, file);
  922. int32 nMinNote = (sampleHeader.low_freq > 100) ? PatchFreqToNoteInt(sampleHeader.low_freq) : 0;
  923. int32 nMaxNote = (sampleHeader.high_freq > 100) ? PatchFreqToNoteInt(sampleHeader.high_freq) : static_cast<uint8>(NOTE_MAX);
  924. int32 nBaseNote = (sampleHeader.root_freq > 100) ? PatchFreqToNoteInt(sampleHeader.root_freq) : -1;
  925. if(!sampleHeader.scale_factor && layerHeader.samples == 1) { nMinNote = 0; nMaxNote = NOTE_MAX; }
  926. // Fill Note Map
  927. for(int32 k = 0; k < NOTE_MAX; k++)
  928. {
  929. if(k == nBaseNote || (!pIns->Keyboard[k] && k >= nMinNote && k <= nMaxNote))
  930. {
  931. if(!sampleHeader.scale_factor)
  932. pIns->NoteMap[k] = NOTE_MIDDLEC;
  933. pIns->Keyboard[k] = nextSample;
  934. if(k < nMinSmpNote)
  935. {
  936. nMinSmpNote = k;
  937. nMinSmp = nextSample;
  938. }
  939. }
  940. }
  941. }
  942. if(nMinSmp)
  943. {
  944. // Fill note map and missing samples
  945. for(uint8 k = 0; k < NOTE_MAX; k++)
  946. {
  947. if(!pIns->NoteMap[k]) pIns->NoteMap[k] = k + 1;
  948. if(!pIns->Keyboard[k])
  949. {
  950. pIns->Keyboard[k] = nMinSmp;
  951. } else
  952. {
  953. nMinSmp = pIns->Keyboard[k];
  954. }
  955. }
  956. }
  957. pIns->Sanitize(MOD_TYPE_IT);
  958. pIns->Convert(MOD_TYPE_IT, GetType());
  959. return true;
  960. }
  961. /////////////////////////////////////////////////////////////
  962. // S3I Samples
  963. bool CSoundFile::ReadS3ISample(SAMPLEINDEX nSample, FileReader &file)
  964. {
  965. file.Rewind();
  966. S3MSampleHeader sampleHeader;
  967. if(!file.ReadStruct(sampleHeader)
  968. || (sampleHeader.sampleType != S3MSampleHeader::typePCM && sampleHeader.sampleType != S3MSampleHeader::typeAdMel)
  969. || (memcmp(sampleHeader.magic, "SCRS", 4) && memcmp(sampleHeader.magic, "SCRI", 4))
  970. || !file.Seek(sampleHeader.GetSampleOffset()))
  971. {
  972. return false;
  973. }
  974. DestroySampleThreadsafe(nSample);
  975. ModSample &sample = Samples[nSample];
  976. sampleHeader.ConvertToMPT(sample);
  977. m_szNames[nSample] = mpt::String::ReadBuf(mpt::String::nullTerminated, sampleHeader.name);
  978. if(sampleHeader.sampleType < S3MSampleHeader::typeAdMel)
  979. sampleHeader.GetSampleFormat(false).ReadSample(sample, file);
  980. else if(SupportsOPL())
  981. InitOPL();
  982. else
  983. AddToLog(LogInformation, U_("OPL instruments are not supported by this format."));
  984. sample.Convert(MOD_TYPE_S3M, GetType());
  985. sample.PrecomputeLoops(*this, false);
  986. return true;
  987. }
  988. #ifndef MODPLUG_NO_FILESAVE
  989. bool CSoundFile::SaveS3ISample(SAMPLEINDEX smp, std::ostream &f) const
  990. {
  991. const ModSample &sample = Samples[smp];
  992. S3MSampleHeader sampleHeader{};
  993. SmpLength length = sampleHeader.ConvertToS3M(sample);
  994. mpt::String::WriteBuf(mpt::String::nullTerminated, sampleHeader.name) = m_szNames[smp];
  995. mpt::String::WriteBuf(mpt::String::maybeNullTerminated, sampleHeader.reserved2) = mpt::ToCharset(mpt::Charset::UTF8, Version::Current().GetOpenMPTVersionString());
  996. if(length)
  997. sampleHeader.dataPointer[1] = sizeof(S3MSampleHeader) >> 4;
  998. mpt::IO::Write(f, sampleHeader);
  999. if(length)
  1000. sampleHeader.GetSampleFormat(false).WriteSample(f, sample, length);
  1001. return true;
  1002. }
  1003. #endif // MODPLUG_NO_FILESAVE
  1004. /////////////////////////////////////////////////////////////
  1005. // SBI OPL patch files
  1006. bool CSoundFile::ReadSBISample(SAMPLEINDEX sample, FileReader &file)
  1007. {
  1008. file.Rewind();
  1009. const auto magic = file.ReadArray<char, 4>();
  1010. if((memcmp(magic.data(), "SBI\x1A", 4) && memcmp(magic.data(), "SBI\x1D", 4)) // 1D = broken JuceOPLVSTi files
  1011. || !file.CanRead(32 + sizeof(OPLPatch))
  1012. || file.CanRead(64)) // Arbitrary threshold to reject files that are unlikely to be SBI files
  1013. return false;
  1014. if(!SupportsOPL())
  1015. {
  1016. AddToLog(LogInformation, U_("OPL instruments are not supported by this format."));
  1017. return true;
  1018. }
  1019. DestroySampleThreadsafe(sample);
  1020. InitOPL();
  1021. ModSample &mptSmp = Samples[sample];
  1022. mptSmp.Initialize(MOD_TYPE_S3M);
  1023. file.ReadString<mpt::String::nullTerminated>(m_szNames[sample], 32);
  1024. OPLPatch patch;
  1025. file.ReadArray(patch);
  1026. mptSmp.SetAdlib(true, patch);
  1027. mptSmp.Convert(MOD_TYPE_S3M, GetType());
  1028. return true;
  1029. }
  1030. /////////////////////////////////////////////////////////////
  1031. // XI Instruments
  1032. bool CSoundFile::ReadXIInstrument(INSTRUMENTINDEX nInstr, FileReader &file)
  1033. {
  1034. file.Rewind();
  1035. XIInstrumentHeader fileHeader;
  1036. if(!file.ReadStruct(fileHeader)
  1037. || memcmp(fileHeader.signature, "Extended Instrument: ", 21)
  1038. || fileHeader.version != XIInstrumentHeader::fileVersion
  1039. || fileHeader.eof != 0x1A)
  1040. {
  1041. return false;
  1042. }
  1043. ModInstrument *pIns = new (std::nothrow) ModInstrument();
  1044. if(pIns == nullptr)
  1045. {
  1046. return false;
  1047. }
  1048. DestroyInstrument(nInstr, deleteAssociatedSamples);
  1049. if(nInstr > m_nInstruments)
  1050. {
  1051. m_nInstruments = nInstr;
  1052. }
  1053. Instruments[nInstr] = pIns;
  1054. fileHeader.ConvertToMPT(*pIns);
  1055. // Translate sample map and find available sample slots
  1056. std::vector<SAMPLEINDEX> sampleMap(fileHeader.numSamples);
  1057. SAMPLEINDEX maxSmp = 0;
  1058. for(size_t i = 0 + 12; i < 96 + 12; i++)
  1059. {
  1060. if(pIns->Keyboard[i] >= fileHeader.numSamples)
  1061. {
  1062. continue;
  1063. }
  1064. if(sampleMap[pIns->Keyboard[i]] == 0)
  1065. {
  1066. // Find slot for this sample
  1067. maxSmp = GetNextFreeSample(nInstr, maxSmp + 1);
  1068. if(maxSmp != SAMPLEINDEX_INVALID)
  1069. {
  1070. sampleMap[pIns->Keyboard[i]] = maxSmp;
  1071. }
  1072. }
  1073. pIns->Keyboard[i] = sampleMap[pIns->Keyboard[i]];
  1074. }
  1075. if(m_nSamples < maxSmp)
  1076. {
  1077. m_nSamples = maxSmp;
  1078. }
  1079. std::vector<SampleIO> sampleFlags(fileHeader.numSamples);
  1080. // Read sample headers
  1081. for(SAMPLEINDEX i = 0; i < fileHeader.numSamples; i++)
  1082. {
  1083. XMSample sampleHeader;
  1084. if(!file.ReadStruct(sampleHeader)
  1085. || !sampleMap[i])
  1086. {
  1087. continue;
  1088. }
  1089. ModSample &mptSample = Samples[sampleMap[i]];
  1090. sampleHeader.ConvertToMPT(mptSample);
  1091. fileHeader.instrument.ApplyAutoVibratoToMPT(mptSample);
  1092. mptSample.Convert(MOD_TYPE_XM, GetType());
  1093. if(GetType() != MOD_TYPE_XM && fileHeader.numSamples == 1)
  1094. {
  1095. // No need to pan that single sample, thank you...
  1096. mptSample.uFlags &= ~CHN_PANNING;
  1097. }
  1098. mptSample.filename = mpt::String::ReadBuf(mpt::String::spacePadded, sampleHeader.name);
  1099. m_szNames[sampleMap[i]] = mpt::String::ReadBuf(mpt::String::spacePadded, sampleHeader.name);
  1100. sampleFlags[i] = sampleHeader.GetSampleFormat();
  1101. }
  1102. // Read sample data
  1103. for(SAMPLEINDEX i = 0; i < fileHeader.numSamples; i++)
  1104. {
  1105. if(sampleMap[i])
  1106. {
  1107. sampleFlags[i].ReadSample(Samples[sampleMap[i]], file);
  1108. Samples[sampleMap[i]].PrecomputeLoops(*this, false);
  1109. }
  1110. }
  1111. // Read MPT crap
  1112. ReadExtendedInstrumentProperties(pIns, file);
  1113. pIns->Convert(MOD_TYPE_XM, GetType());
  1114. pIns->Sanitize(GetType());
  1115. return true;
  1116. }
  1117. #ifndef MODPLUG_NO_FILESAVE
  1118. bool CSoundFile::SaveXIInstrument(INSTRUMENTINDEX nInstr, std::ostream &f) const
  1119. {
  1120. ModInstrument *pIns = Instruments[nInstr];
  1121. if(pIns == nullptr)
  1122. {
  1123. return false;
  1124. }
  1125. // Create file header
  1126. XIInstrumentHeader header;
  1127. header.ConvertToXM(*pIns, false);
  1128. const std::vector<SAMPLEINDEX> samples = header.instrument.GetSampleList(*pIns, false);
  1129. if(samples.size() > 0 && samples[0] <= GetNumSamples())
  1130. {
  1131. // Copy over auto-vibrato settings of first sample
  1132. header.instrument.ApplyAutoVibratoToXM(Samples[samples[0]], GetType());
  1133. }
  1134. mpt::IO::Write(f, header);
  1135. std::vector<SampleIO> sampleFlags(samples.size());
  1136. // XI Sample Headers
  1137. for(SAMPLEINDEX i = 0; i < samples.size(); i++)
  1138. {
  1139. XMSample xmSample;
  1140. if(samples[i] <= GetNumSamples())
  1141. {
  1142. xmSample.ConvertToXM(Samples[samples[i]], GetType(), false);
  1143. } else
  1144. {
  1145. MemsetZero(xmSample);
  1146. }
  1147. sampleFlags[i] = xmSample.GetSampleFormat();
  1148. mpt::String::WriteBuf(mpt::String::spacePadded, xmSample.name) = m_szNames[samples[i]];
  1149. mpt::IO::Write(f, xmSample);
  1150. }
  1151. // XI Sample Data
  1152. for(SAMPLEINDEX i = 0; i < samples.size(); i++)
  1153. {
  1154. if(samples[i] <= GetNumSamples())
  1155. {
  1156. sampleFlags[i].WriteSample(f, Samples[samples[i]]);
  1157. }
  1158. }
  1159. // Write 'MPTX' extension tag
  1160. mpt::IO::WriteText(f, "XTPM");
  1161. WriteInstrumentHeaderStructOrField(pIns, f); // Write full extended header.
  1162. return true;
  1163. }
  1164. #endif // MODPLUG_NO_FILESAVE
  1165. // Read first sample from XI file into a sample slot
  1166. bool CSoundFile::ReadXISample(SAMPLEINDEX nSample, FileReader &file)
  1167. {
  1168. file.Rewind();
  1169. XIInstrumentHeader fileHeader;
  1170. if(!file.ReadStruct(fileHeader)
  1171. || !file.CanRead(sizeof(XMSample))
  1172. || memcmp(fileHeader.signature, "Extended Instrument: ", 21)
  1173. || fileHeader.version != XIInstrumentHeader::fileVersion
  1174. || fileHeader.eof != 0x1A
  1175. || fileHeader.numSamples == 0)
  1176. {
  1177. return false;
  1178. }
  1179. if(m_nSamples < nSample)
  1180. {
  1181. m_nSamples = nSample;
  1182. }
  1183. uint16 numSamples = fileHeader.numSamples;
  1184. FileReader::off_t samplePos = sizeof(XIInstrumentHeader) + numSamples * sizeof(XMSample);
  1185. // Preferrably read the middle-C sample
  1186. auto sample = fileHeader.instrument.sampleMap[48];
  1187. if(sample >= fileHeader.numSamples)
  1188. sample = 0;
  1189. XMSample sampleHeader;
  1190. while(sample--)
  1191. {
  1192. file.ReadStruct(sampleHeader);
  1193. samplePos += sampleHeader.length;
  1194. }
  1195. file.ReadStruct(sampleHeader);
  1196. // Gotta skip 'em all!
  1197. file.Seek(samplePos);
  1198. DestroySampleThreadsafe(nSample);
  1199. ModSample &mptSample = Samples[nSample];
  1200. sampleHeader.ConvertToMPT(mptSample);
  1201. if(GetType() != MOD_TYPE_XM)
  1202. {
  1203. // No need to pan that single sample, thank you...
  1204. mptSample.uFlags.reset(CHN_PANNING);
  1205. }
  1206. fileHeader.instrument.ApplyAutoVibratoToMPT(mptSample);
  1207. mptSample.Convert(MOD_TYPE_XM, GetType());
  1208. mptSample.filename = mpt::String::ReadBuf(mpt::String::spacePadded, sampleHeader.name);
  1209. m_szNames[nSample] = mpt::String::ReadBuf(mpt::String::spacePadded, sampleHeader.name);
  1210. // Read sample data
  1211. sampleHeader.GetSampleFormat().ReadSample(Samples[nSample], file);
  1212. Samples[nSample].PrecomputeLoops(*this, false);
  1213. return true;
  1214. }
  1215. ///////////////
  1216. // Apple CAF //
  1217. struct CAFFileHeader
  1218. {
  1219. uint32be mFileType;
  1220. uint16be mFileVersion;
  1221. uint16be mFileFlags;
  1222. };
  1223. MPT_BINARY_STRUCT(CAFFileHeader, 8)
  1224. struct CAFChunkHeader
  1225. {
  1226. uint32be mChunkType;
  1227. int64be mChunkSize;
  1228. };
  1229. MPT_BINARY_STRUCT(CAFChunkHeader, 12)
  1230. struct CAFChunk
  1231. {
  1232. enum ChunkIdentifiers
  1233. {
  1234. iddesc = MagicBE("desc"),
  1235. iddata = MagicBE("data"),
  1236. idstrg = MagicBE("strg"),
  1237. idinfo = MagicBE("info")
  1238. };
  1239. CAFChunkHeader header;
  1240. FileReader::off_t GetLength() const
  1241. {
  1242. int64 length = header.mChunkSize;
  1243. if(length == -1)
  1244. {
  1245. length = std::numeric_limits<int64>::max(); // spec
  1246. }
  1247. if(length < 0)
  1248. {
  1249. length = std::numeric_limits<int64>::max(); // heuristic
  1250. }
  1251. return mpt::saturate_cast<FileReader::off_t>(length);
  1252. }
  1253. ChunkIdentifiers GetID() const
  1254. {
  1255. return static_cast<ChunkIdentifiers>(header.mChunkType.get());
  1256. }
  1257. };
  1258. MPT_BINARY_STRUCT(CAFChunk, 12)
  1259. enum {
  1260. CAFkAudioFormatLinearPCM = MagicBE("lpcm"),
  1261. CAFkAudioFormatAppleIMA4 = MagicBE("ima4"),
  1262. CAFkAudioFormatMPEG4AAC = MagicBE("aac "),
  1263. CAFkAudioFormatMACE3 = MagicBE("MAC3"),
  1264. CAFkAudioFormatMACE6 = MagicBE("MAC6"),
  1265. CAFkAudioFormatULaw = MagicBE("ulaw"),
  1266. CAFkAudioFormatALaw = MagicBE("alaw"),
  1267. CAFkAudioFormatMPEGLayer1 = MagicBE(".mp1"),
  1268. CAFkAudioFormatMPEGLayer2 = MagicBE(".mp2"),
  1269. CAFkAudioFormatMPEGLayer3 = MagicBE(".mp3"),
  1270. CAFkAudioFormatAppleLossless = MagicBE("alac")
  1271. };
  1272. enum {
  1273. CAFkCAFLinearPCMFormatFlagIsFloat = (1L << 0),
  1274. CAFkCAFLinearPCMFormatFlagIsLittleEndian = (1L << 1)
  1275. };
  1276. struct CAFAudioFormat
  1277. {
  1278. float64be mSampleRate;
  1279. uint32be mFormatID;
  1280. uint32be mFormatFlags;
  1281. uint32be mBytesPerPacket;
  1282. uint32be mFramesPerPacket;
  1283. uint32be mChannelsPerFrame;
  1284. uint32be mBitsPerChannel;
  1285. };
  1286. MPT_BINARY_STRUCT(CAFAudioFormat, 32)
  1287. static void CAFSetTagFromInfoKey(mpt::ustring & dst, const std::map<std::string,std::string> & infoMap, const std::string & key)
  1288. {
  1289. auto item = infoMap.find(key);
  1290. if(item == infoMap.end())
  1291. {
  1292. return;
  1293. }
  1294. if(item->second.empty())
  1295. {
  1296. return;
  1297. }
  1298. dst = mpt::ToUnicode(mpt::Charset::UTF8, item->second);
  1299. }
  1300. bool CSoundFile::ReadCAFSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize)
  1301. {
  1302. file.Rewind();
  1303. CAFFileHeader fileHeader;
  1304. if(!file.ReadStruct(fileHeader))
  1305. {
  1306. return false;
  1307. }
  1308. if(fileHeader.mFileType != MagicBE("caff"))
  1309. {
  1310. return false;
  1311. }
  1312. if(fileHeader.mFileVersion != 1)
  1313. {
  1314. return false;
  1315. }
  1316. auto chunkList = file.ReadChunks<CAFChunk>(0);
  1317. CAFAudioFormat audioFormat;
  1318. if(!chunkList.GetChunk(CAFChunk::iddesc).ReadStruct(audioFormat))
  1319. {
  1320. return false;
  1321. }
  1322. if(audioFormat.mSampleRate <= 0.0)
  1323. {
  1324. return false;
  1325. }
  1326. if(audioFormat.mChannelsPerFrame == 0)
  1327. {
  1328. return false;
  1329. }
  1330. if(audioFormat.mChannelsPerFrame > 2)
  1331. {
  1332. return false;
  1333. }
  1334. if(!mpt::in_range<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate)))
  1335. {
  1336. return false;
  1337. }
  1338. uint32 sampleRate = static_cast<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate));
  1339. if(sampleRate <= 0)
  1340. {
  1341. return false;
  1342. }
  1343. SampleIO sampleIO;
  1344. if(audioFormat.mFormatID == CAFkAudioFormatLinearPCM)
  1345. {
  1346. if(audioFormat.mFramesPerPacket != 1)
  1347. {
  1348. return false;
  1349. }
  1350. if(audioFormat.mBytesPerPacket == 0)
  1351. {
  1352. return false;
  1353. }
  1354. if(audioFormat.mBitsPerChannel == 0)
  1355. {
  1356. return false;
  1357. }
  1358. if(audioFormat.mFormatFlags & CAFkCAFLinearPCMFormatFlagIsFloat)
  1359. {
  1360. if(audioFormat.mBitsPerChannel != 32 && audioFormat.mBitsPerChannel != 64)
  1361. {
  1362. return false;
  1363. }
  1364. if(audioFormat.mBytesPerPacket != audioFormat.mChannelsPerFrame * audioFormat.mBitsPerChannel/8)
  1365. {
  1366. return false;
  1367. }
  1368. }
  1369. if(audioFormat.mBytesPerPacket % audioFormat.mChannelsPerFrame != 0)
  1370. {
  1371. return false;
  1372. }
  1373. if(audioFormat.mBytesPerPacket / audioFormat.mChannelsPerFrame != 1
  1374. && audioFormat.mBytesPerPacket / audioFormat.mChannelsPerFrame != 2
  1375. && audioFormat.mBytesPerPacket / audioFormat.mChannelsPerFrame != 3
  1376. && audioFormat.mBytesPerPacket / audioFormat.mChannelsPerFrame != 4
  1377. && audioFormat.mBytesPerPacket / audioFormat.mChannelsPerFrame != 8
  1378. )
  1379. {
  1380. return false;
  1381. }
  1382. SampleIO::Channels channels = (audioFormat.mChannelsPerFrame == 2) ? SampleIO::stereoInterleaved : SampleIO::mono;
  1383. SampleIO::Endianness endianness = (audioFormat.mFormatFlags & CAFkCAFLinearPCMFormatFlagIsLittleEndian) ? SampleIO::littleEndian : SampleIO::bigEndian;
  1384. SampleIO::Encoding encoding = (audioFormat.mFormatFlags & CAFkCAFLinearPCMFormatFlagIsFloat) ? SampleIO::floatPCM : SampleIO::signedPCM;
  1385. SampleIO::Bitdepth bitdepth = static_cast<SampleIO::Bitdepth>((audioFormat.mBytesPerPacket / audioFormat.mChannelsPerFrame) * 8);
  1386. sampleIO = SampleIO(bitdepth, channels, endianness, encoding);
  1387. } else
  1388. {
  1389. return false;
  1390. }
  1391. if(mayNormalize)
  1392. {
  1393. sampleIO.MayNormalize();
  1394. }
  1395. /*
  1396. std::map<uint32, std::string> stringMap; // UTF-8
  1397. if(chunkList.ChunkExists(CAFChunk::idstrg))
  1398. {
  1399. FileReader stringsChunk = chunkList.GetChunk(CAFChunk::idstrg);
  1400. uint32 numEntries = stringsChunk.ReadUint32BE();
  1401. if(stringsChunk.Skip(12 * numEntries))
  1402. {
  1403. FileReader stringData = stringsChunk.ReadChunk(stringsChunk.BytesLeft());
  1404. stringsChunk.Seek(4);
  1405. for(uint32 entry = 0; entry < numEntries && stringsChunk.CanRead(12); entry++)
  1406. {
  1407. uint32 stringID = stringsChunk.ReadUint32BE();
  1408. int64 offset = stringsChunk.ReadIntBE<int64>();
  1409. if(offset >= 0 && mpt::in_range<FileReader::off_t>(offset))
  1410. {
  1411. stringData.Seek(mpt::saturate_cast<FileReader::off_t>(offset));
  1412. std::string str;
  1413. if(stringData.ReadNullString(str))
  1414. {
  1415. stringMap[stringID] = str;
  1416. }
  1417. }
  1418. }
  1419. }
  1420. }
  1421. */
  1422. std::map<std::string, std::string> infoMap; // UTF-8
  1423. if(chunkList.ChunkExists(CAFChunk::idinfo))
  1424. {
  1425. FileReader informationChunk = chunkList.GetChunk(CAFChunk::idinfo);
  1426. uint32 numEntries = informationChunk.ReadUint32BE();
  1427. for(uint32 entry = 0; entry < numEntries && informationChunk.CanRead(2); entry++)
  1428. {
  1429. std::string key;
  1430. std::string value;
  1431. if(!informationChunk.ReadNullString(key))
  1432. {
  1433. break;
  1434. }
  1435. if(!informationChunk.ReadNullString(value))
  1436. {
  1437. break;
  1438. }
  1439. if(!key.empty() && !value.empty())
  1440. {
  1441. infoMap[key] = value;
  1442. }
  1443. }
  1444. }
  1445. FileTags tags;
  1446. CAFSetTagFromInfoKey(tags.bpm, infoMap, "tempo");
  1447. //CAFSetTagFromInfoKey(void, infoMap, "key signature");
  1448. //CAFSetTagFromInfoKey(void, infoMap, "time signature");
  1449. CAFSetTagFromInfoKey(tags.artist, infoMap, "artist");
  1450. CAFSetTagFromInfoKey(tags.album, infoMap, "album");
  1451. CAFSetTagFromInfoKey(tags.trackno, infoMap, "track number");
  1452. CAFSetTagFromInfoKey(tags.year, infoMap, "year");
  1453. //CAFSetTagFromInfoKey(void, infoMap, "composer");
  1454. //CAFSetTagFromInfoKey(void, infoMap, "lyricist");
  1455. CAFSetTagFromInfoKey(tags.genre, infoMap, "genre");
  1456. CAFSetTagFromInfoKey(tags.title, infoMap, "title");
  1457. //CAFSetTagFromInfoKey(void, infoMap, "recorded date");
  1458. CAFSetTagFromInfoKey(tags.comments, infoMap, "comments");
  1459. //CAFSetTagFromInfoKey(void, infoMap, "copyright");
  1460. //CAFSetTagFromInfoKey(void, infoMap, "source encoder");
  1461. CAFSetTagFromInfoKey(tags.encoder, infoMap, "encoding application");
  1462. //CAFSetTagFromInfoKey(void, infoMap, "nominal bit rate");
  1463. //CAFSetTagFromInfoKey(void, infoMap, "channel layout");
  1464. //CAFSetTagFromInfoKey(tags.url, infoMap, void);
  1465. if(!chunkList.ChunkExists(CAFChunk::iddata))
  1466. {
  1467. return false;
  1468. }
  1469. FileReader dataChunk = chunkList.GetChunk(CAFChunk::iddata);
  1470. dataChunk.Skip(4); // edit count
  1471. FileReader audioData = dataChunk.ReadChunk(dataChunk.BytesLeft());
  1472. SmpLength length = mpt::saturate_cast<SmpLength>((audioData.GetLength() / audioFormat.mBytesPerPacket) * audioFormat.mFramesPerPacket);
  1473. ModSample &mptSample = Samples[nSample];
  1474. DestroySampleThreadsafe(nSample);
  1475. mptSample.Initialize();
  1476. mptSample.nLength = length;
  1477. mptSample.nC5Speed = sampleRate;
  1478. sampleIO.ReadSample(mptSample, audioData);
  1479. m_szNames[nSample] = mpt::ToCharset(GetCharsetInternal(), GetSampleNameFromTags(tags));
  1480. mptSample.Convert(MOD_TYPE_IT, GetType());
  1481. mptSample.PrecomputeLoops(*this, false);
  1482. return true;
  1483. }
  1484. /////////////////////////////////////////////////////////////////////////////////////////
  1485. // AIFF File I/O
  1486. // AIFF header
  1487. struct AIFFHeader
  1488. {
  1489. char magic[4]; // FORM
  1490. uint32be length; // Size of the file, not including magic and length
  1491. char type[4]; // AIFF or AIFC
  1492. };
  1493. MPT_BINARY_STRUCT(AIFFHeader, 12)
  1494. // General IFF Chunk header
  1495. struct AIFFChunk
  1496. {
  1497. // 32-Bit chunk identifiers
  1498. enum ChunkIdentifiers
  1499. {
  1500. idCOMM = MagicBE("COMM"),
  1501. idSSND = MagicBE("SSND"),
  1502. idINST = MagicBE("INST"),
  1503. idMARK = MagicBE("MARK"),
  1504. idNAME = MagicBE("NAME"),
  1505. };
  1506. uint32be id; // See ChunkIdentifiers
  1507. uint32be length; // Chunk size without header
  1508. size_t GetLength() const
  1509. {
  1510. return length;
  1511. }
  1512. ChunkIdentifiers GetID() const
  1513. {
  1514. return static_cast<ChunkIdentifiers>(id.get());
  1515. }
  1516. };
  1517. MPT_BINARY_STRUCT(AIFFChunk, 8)
  1518. // "Common" chunk (in AIFC, a compression ID and compression name follows this header, but apart from that it's identical)
  1519. struct AIFFCommonChunk
  1520. {
  1521. uint16be numChannels;
  1522. uint32be numSampleFrames;
  1523. uint16be sampleSize;
  1524. uint8be sampleRate[10]; // Sample rate in 80-Bit floating point
  1525. // Convert sample rate to integer
  1526. uint32 GetSampleRate() const
  1527. {
  1528. uint32 mantissa = (sampleRate[2] << 24) | (sampleRate[3] << 16) | (sampleRate[4] << 8) | (sampleRate[5] << 0);
  1529. uint32 last = 0;
  1530. uint8 exp = 30 - sampleRate[1];
  1531. while(exp--)
  1532. {
  1533. last = mantissa;
  1534. mantissa >>= 1;
  1535. }
  1536. if(last & 1) mantissa++;
  1537. return mantissa;
  1538. }
  1539. };
  1540. MPT_BINARY_STRUCT(AIFFCommonChunk, 18)
  1541. // Sound chunk
  1542. struct AIFFSoundChunk
  1543. {
  1544. uint32be offset;
  1545. uint32be blockSize;
  1546. };
  1547. MPT_BINARY_STRUCT(AIFFSoundChunk, 8)
  1548. // Marker
  1549. struct AIFFMarker
  1550. {
  1551. uint16be id;
  1552. uint32be position; // Position in sample
  1553. uint8be nameLength; // Not counting eventually existing padding byte in name string
  1554. };
  1555. MPT_BINARY_STRUCT(AIFFMarker, 7)
  1556. // Instrument loop
  1557. struct AIFFInstrumentLoop
  1558. {
  1559. enum PlayModes
  1560. {
  1561. noLoop = 0,
  1562. loopNormal = 1,
  1563. loopBidi = 2,
  1564. };
  1565. uint16be playMode;
  1566. uint16be beginLoop; // Marker index
  1567. uint16be endLoop; // Marker index
  1568. };
  1569. MPT_BINARY_STRUCT(AIFFInstrumentLoop, 6)
  1570. struct AIFFInstrumentChunk
  1571. {
  1572. uint8be baseNote;
  1573. uint8be detune;
  1574. uint8be lowNote;
  1575. uint8be highNote;
  1576. uint8be lowVelocity;
  1577. uint8be highVelocity;
  1578. uint16be gain;
  1579. AIFFInstrumentLoop sustainLoop;
  1580. AIFFInstrumentLoop releaseLoop;
  1581. };
  1582. MPT_BINARY_STRUCT(AIFFInstrumentChunk, 20)
  1583. bool CSoundFile::ReadAIFFSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize)
  1584. {
  1585. file.Rewind();
  1586. // Verify header
  1587. AIFFHeader fileHeader;
  1588. if(!file.ReadStruct(fileHeader)
  1589. || memcmp(fileHeader.magic, "FORM", 4)
  1590. || (memcmp(fileHeader.type, "AIFF", 4) && memcmp(fileHeader.type, "AIFC", 4)))
  1591. {
  1592. return false;
  1593. }
  1594. auto chunks = file.ReadChunks<AIFFChunk>(2);
  1595. // Read COMM chunk
  1596. FileReader commChunk(chunks.GetChunk(AIFFChunk::idCOMM));
  1597. AIFFCommonChunk sampleInfo;
  1598. if(!commChunk.ReadStruct(sampleInfo))
  1599. {
  1600. return false;
  1601. }
  1602. // Is this a proper sample?
  1603. if(sampleInfo.numSampleFrames == 0
  1604. || sampleInfo.numChannels < 1 || sampleInfo.numChannels > 2
  1605. || sampleInfo.sampleSize < 1 || sampleInfo.sampleSize > 64)
  1606. {
  1607. return false;
  1608. }
  1609. // Read compression type in AIFF-C files.
  1610. uint8 compression[4] = { 'N', 'O', 'N', 'E' };
  1611. SampleIO::Endianness endian = SampleIO::bigEndian;
  1612. if(!memcmp(fileHeader.type, "AIFC", 4))
  1613. {
  1614. if(!commChunk.ReadArray(compression))
  1615. {
  1616. return false;
  1617. }
  1618. if(!memcmp(compression, "twos", 4))
  1619. {
  1620. endian = SampleIO::littleEndian;
  1621. }
  1622. }
  1623. // Read SSND chunk
  1624. FileReader soundChunk(chunks.GetChunk(AIFFChunk::idSSND));
  1625. AIFFSoundChunk sampleHeader;
  1626. if(!soundChunk.ReadStruct(sampleHeader))
  1627. {
  1628. return false;
  1629. }
  1630. SampleIO::Bitdepth bitDepth;
  1631. switch((sampleInfo.sampleSize - 1) / 8)
  1632. {
  1633. default:
  1634. case 0: bitDepth = SampleIO::_8bit; break;
  1635. case 1: bitDepth = SampleIO::_16bit; break;
  1636. case 2: bitDepth = SampleIO::_24bit; break;
  1637. case 3: bitDepth = SampleIO::_32bit; break;
  1638. case 7: bitDepth = SampleIO::_64bit; break;
  1639. }
  1640. SampleIO sampleIO(bitDepth,
  1641. (sampleInfo.numChannels == 2) ? SampleIO::stereoInterleaved : SampleIO::mono,
  1642. endian,
  1643. SampleIO::signedPCM);
  1644. if(!memcmp(compression, "fl32", 4) || !memcmp(compression, "FL32", 4) || !memcmp(compression, "fl64", 4) || !memcmp(compression, "FL64", 4))
  1645. {
  1646. sampleIO |= SampleIO::floatPCM;
  1647. } else if(!memcmp(compression, "alaw", 4) || !memcmp(compression, "ALAW", 4))
  1648. {
  1649. sampleIO |= SampleIO::aLaw;
  1650. sampleIO |= SampleIO::_16bit;
  1651. } else if(!memcmp(compression, "ulaw", 4) || !memcmp(compression, "ULAW", 4))
  1652. {
  1653. sampleIO |= SampleIO::uLaw;
  1654. sampleIO |= SampleIO::_16bit;
  1655. } else if(!memcmp(compression, "raw ", 4))
  1656. {
  1657. sampleIO |= SampleIO::unsignedPCM;
  1658. }
  1659. if(mayNormalize)
  1660. {
  1661. sampleIO.MayNormalize();
  1662. }
  1663. if(soundChunk.CanRead(sampleHeader.offset))
  1664. {
  1665. soundChunk.Skip(sampleHeader.offset);
  1666. }
  1667. ModSample &mptSample = Samples[nSample];
  1668. DestroySampleThreadsafe(nSample);
  1669. mptSample.Initialize();
  1670. mptSample.nLength = sampleInfo.numSampleFrames;
  1671. mptSample.nC5Speed = sampleInfo.GetSampleRate();
  1672. sampleIO.ReadSample(mptSample, soundChunk);
  1673. // Read MARK and INST chunk to extract sample loops
  1674. FileReader markerChunk(chunks.GetChunk(AIFFChunk::idMARK));
  1675. AIFFInstrumentChunk instrHeader;
  1676. if(markerChunk.IsValid() && chunks.GetChunk(AIFFChunk::idINST).ReadStruct(instrHeader))
  1677. {
  1678. uint16 numMarkers = markerChunk.ReadUint16BE();
  1679. std::vector<AIFFMarker> markers;
  1680. markers.reserve(numMarkers);
  1681. for(size_t i = 0; i < numMarkers; i++)
  1682. {
  1683. AIFFMarker marker;
  1684. if(!markerChunk.ReadStruct(marker))
  1685. {
  1686. break;
  1687. }
  1688. markers.push_back(marker);
  1689. markerChunk.Skip(marker.nameLength + ((marker.nameLength % 2u) == 0 ? 1 : 0));
  1690. }
  1691. if(instrHeader.sustainLoop.playMode != AIFFInstrumentLoop::noLoop)
  1692. {
  1693. mptSample.uFlags.set(CHN_SUSTAINLOOP);
  1694. mptSample.uFlags.set(CHN_PINGPONGSUSTAIN, instrHeader.sustainLoop.playMode == AIFFInstrumentLoop::loopBidi);
  1695. }
  1696. if(instrHeader.releaseLoop.playMode != AIFFInstrumentLoop::noLoop)
  1697. {
  1698. mptSample.uFlags.set(CHN_LOOP);
  1699. mptSample.uFlags.set(CHN_PINGPONGLOOP, instrHeader.releaseLoop.playMode == AIFFInstrumentLoop::loopBidi);
  1700. }
  1701. // Read markers
  1702. for(const auto &m : markers)
  1703. {
  1704. if(m.id == instrHeader.sustainLoop.beginLoop)
  1705. mptSample.nSustainStart = m.position;
  1706. if(m.id == instrHeader.sustainLoop.endLoop)
  1707. mptSample.nSustainEnd = m.position;
  1708. if(m.id == instrHeader.releaseLoop.beginLoop)
  1709. mptSample.nLoopStart = m.position;
  1710. if(m.id == instrHeader.releaseLoop.endLoop)
  1711. mptSample.nLoopEnd = m.position;
  1712. }
  1713. mptSample.SanitizeLoops();
  1714. }
  1715. // Extract sample name
  1716. FileReader nameChunk(chunks.GetChunk(AIFFChunk::idNAME));
  1717. if(nameChunk.IsValid())
  1718. {
  1719. nameChunk.ReadString<mpt::String::spacePadded>(m_szNames[nSample], nameChunk.GetLength());
  1720. } else
  1721. {
  1722. m_szNames[nSample] = "";
  1723. }
  1724. mptSample.Convert(MOD_TYPE_IT, GetType());
  1725. mptSample.PrecomputeLoops(*this, false);
  1726. return true;
  1727. }
  1728. static bool AUIsAnnotationLineWithField(const std::string &line)
  1729. {
  1730. std::size_t pos = line.find('=');
  1731. if(pos == std::string::npos)
  1732. {
  1733. return false;
  1734. }
  1735. if(pos == 0)
  1736. {
  1737. return false;
  1738. }
  1739. const auto field = std::string_view(line).substr(0, pos);
  1740. // Scan for invalid chars
  1741. for(auto c : field)
  1742. {
  1743. if(!mpt::is_in_range(c, 'a', 'z') && !mpt::is_in_range(c, 'A', 'Z') && !mpt::is_in_range(c, '0', '9') && c != '-' && c != '_')
  1744. {
  1745. return false;
  1746. }
  1747. }
  1748. return true;
  1749. }
  1750. static std::string AUTrimFieldFromAnnotationLine(const std::string &line)
  1751. {
  1752. if(!AUIsAnnotationLineWithField(line))
  1753. {
  1754. return line;
  1755. }
  1756. std::size_t pos = line.find('=');
  1757. return line.substr(pos + 1);
  1758. }
  1759. static std::string AUGetAnnotationFieldFromLine(const std::string &line)
  1760. {
  1761. if(!AUIsAnnotationLineWithField(line))
  1762. {
  1763. return std::string();
  1764. }
  1765. std::size_t pos = line.find('=');
  1766. return line.substr(0, pos);
  1767. }
  1768. bool CSoundFile::ReadAUSample(SAMPLEINDEX nSample, FileReader &file, bool mayNormalize)
  1769. {
  1770. file.Rewind();
  1771. // Verify header
  1772. const auto magic = file.ReadArray<char, 4>();
  1773. const bool bigEndian = !std::memcmp(magic.data(), ".snd", 4);
  1774. const bool littleEndian = !std::memcmp(magic.data(), "dns.", 4);
  1775. if(!bigEndian && !littleEndian)
  1776. return false;
  1777. auto readUint32 = std::bind(bigEndian ? &FileReader::ReadUint32BE : &FileReader::ReadUint32LE, file);
  1778. uint32 dataOffset = readUint32(); // must be divisible by 8 according to spec, however, there are files that ignore this requirement
  1779. uint32 dataSize = readUint32();
  1780. uint32 encoding = readUint32();
  1781. uint32 sampleRate = readUint32();
  1782. uint32 channels = readUint32();
  1783. // According to spec, a minimum 8 byte annotation field after the header fields is required,
  1784. // however, there are files in the wild that violate this requirement.
  1785. // Thus, check for 24 instead of 32 here.
  1786. if(dataOffset < 24) // data offset points inside header
  1787. {
  1788. return false;
  1789. }
  1790. if(channels < 1 || channels > 2)
  1791. return false;
  1792. SampleIO sampleIO(SampleIO::_8bit, channels == 1 ? SampleIO::mono : SampleIO::stereoInterleaved, bigEndian ? SampleIO::bigEndian : SampleIO::littleEndian, SampleIO::signedPCM);
  1793. switch(encoding)
  1794. {
  1795. case 1: sampleIO |= SampleIO::_16bit; // u-law
  1796. sampleIO |= SampleIO::uLaw; break;
  1797. case 2: break; // 8-bit linear PCM
  1798. case 3: sampleIO |= SampleIO::_16bit; break; // 16-bit linear PCM
  1799. case 4: sampleIO |= SampleIO::_24bit; break; // 24-bit linear PCM
  1800. case 5: sampleIO |= SampleIO::_32bit; break; // 32-bit linear PCM
  1801. case 6: sampleIO |= SampleIO::_32bit; // 32-bit IEEE floating point
  1802. sampleIO |= SampleIO::floatPCM;
  1803. break;
  1804. case 7: sampleIO |= SampleIO::_64bit; // 64-bit IEEE floating point
  1805. sampleIO |= SampleIO::floatPCM;
  1806. break;
  1807. case 27: sampleIO |= SampleIO::_16bit; // a-law
  1808. sampleIO |= SampleIO::aLaw; break;
  1809. default: return false;
  1810. }
  1811. if(!file.LengthIsAtLeast(dataOffset))
  1812. {
  1813. return false;
  1814. }
  1815. FileTags tags;
  1816. // This reads annotation metadata as written by OpenMPT, sox, ffmpeg.
  1817. // Additionally, we fall back to just reading the whole field as a single comment.
  1818. // We only read up to the first \0 byte.
  1819. file.Seek(24);
  1820. std::string annotation;
  1821. file.ReadString<mpt::String::maybeNullTerminated>(annotation, dataOffset - 24);
  1822. annotation = mpt::replace(annotation, std::string("\r\n"), std::string("\n"));
  1823. annotation = mpt::replace(annotation, std::string("\r"), std::string("\n"));
  1824. mpt::Charset charset = mpt::IsUTF8(annotation) ? mpt::Charset::UTF8 : mpt::Charset::ISO8859_1;
  1825. const auto lines = mpt::String::Split<std::string>(annotation, "\n");
  1826. bool hasFields = false;
  1827. for(const auto &line : lines)
  1828. {
  1829. if(AUIsAnnotationLineWithField(line))
  1830. {
  1831. hasFields = true;
  1832. break;
  1833. }
  1834. }
  1835. if(hasFields)
  1836. {
  1837. std::map<std::string, std::vector<std::string>> linesPerField;
  1838. std::string lastField = "comment";
  1839. for(const auto &line : lines)
  1840. {
  1841. if(AUIsAnnotationLineWithField(line))
  1842. {
  1843. lastField = mpt::ToLowerCaseAscii(mpt::trim(AUGetAnnotationFieldFromLine(line)));
  1844. }
  1845. linesPerField[lastField].push_back(AUTrimFieldFromAnnotationLine(line));
  1846. }
  1847. tags.title = mpt::ToUnicode(charset, mpt::String::Combine(linesPerField["title" ], std::string("\n")));
  1848. tags.artist = mpt::ToUnicode(charset, mpt::String::Combine(linesPerField["artist" ], std::string("\n")));
  1849. tags.album = mpt::ToUnicode(charset, mpt::String::Combine(linesPerField["album" ], std::string("\n")));
  1850. tags.trackno = mpt::ToUnicode(charset, mpt::String::Combine(linesPerField["track" ], std::string("\n")));
  1851. tags.genre = mpt::ToUnicode(charset, mpt::String::Combine(linesPerField["genre" ], std::string("\n")));
  1852. tags.comments = mpt::ToUnicode(charset, mpt::String::Combine(linesPerField["comment"], std::string("\n")));
  1853. } else
  1854. {
  1855. // Most applications tend to write their own name here,
  1856. // thus there is little use in interpreting the string as a title.
  1857. annotation = mpt::trim_right(annotation, std::string("\r\n"));
  1858. tags.comments = mpt::ToUnicode(charset, annotation);
  1859. }
  1860. file.Seek(dataOffset);
  1861. ModSample &mptSample = Samples[nSample];
  1862. DestroySampleThreadsafe(nSample);
  1863. mptSample.Initialize();
  1864. SmpLength length = mpt::saturate_cast<SmpLength>(file.BytesLeft());
  1865. if(dataSize != 0xFFFFFFFF)
  1866. LimitMax(length, dataSize);
  1867. mptSample.nLength = (length * 8u) / (sampleIO.GetEncodedBitsPerSample() * channels);
  1868. mptSample.nC5Speed = sampleRate;
  1869. m_szNames[nSample] = mpt::ToCharset(GetCharsetInternal(), GetSampleNameFromTags(tags));
  1870. if(mayNormalize)
  1871. {
  1872. sampleIO.MayNormalize();
  1873. }
  1874. sampleIO.ReadSample(mptSample, file);
  1875. mptSample.Convert(MOD_TYPE_IT, GetType());
  1876. mptSample.PrecomputeLoops(*this, false);
  1877. return true;
  1878. }
  1879. /////////////////////////////////////////////////////////////////////////////////////////
  1880. // ITS Samples
  1881. bool CSoundFile::ReadITSSample(SAMPLEINDEX nSample, FileReader &file, bool rewind)
  1882. {
  1883. if(rewind)
  1884. {
  1885. file.Rewind();
  1886. }
  1887. ITSample sampleHeader;
  1888. if(!file.ReadStruct(sampleHeader)
  1889. || memcmp(sampleHeader.id, "IMPS", 4))
  1890. {
  1891. return false;
  1892. }
  1893. DestroySampleThreadsafe(nSample);
  1894. ModSample &sample = Samples[nSample];
  1895. file.Seek(sampleHeader.ConvertToMPT(sample));
  1896. m_szNames[nSample] = mpt::String::ReadBuf(mpt::String::spacePaddedNull, sampleHeader.name);
  1897. if(sample.uFlags[CHN_ADLIB])
  1898. {
  1899. OPLPatch patch;
  1900. file.ReadArray(patch);
  1901. sample.SetAdlib(true, patch);
  1902. InitOPL();
  1903. if(!SupportsOPL())
  1904. {
  1905. AddToLog(LogInformation, U_("OPL instruments are not supported by this format."));
  1906. }
  1907. } else if(!sample.uFlags[SMP_KEEPONDISK])
  1908. {
  1909. sampleHeader.GetSampleFormat().ReadSample(sample, file);
  1910. } else
  1911. {
  1912. // External sample
  1913. size_t strLen;
  1914. file.ReadVarInt(strLen);
  1915. #ifdef MPT_EXTERNAL_SAMPLES
  1916. std::string filenameU8;
  1917. file.ReadString<mpt::String::maybeNullTerminated>(filenameU8, strLen);
  1918. mpt::PathString filename = mpt::PathString::FromUTF8(filenameU8);
  1919. if(!filename.empty())
  1920. {
  1921. if(file.GetOptionalFileName())
  1922. {
  1923. filename = filename.RelativePathToAbsolute(file.GetOptionalFileName()->GetPath());
  1924. }
  1925. if(!LoadExternalSample(nSample, filename))
  1926. {
  1927. AddToLog(LogWarning, U_("Unable to load sample: ") + filename.ToUnicode());
  1928. }
  1929. } else
  1930. {
  1931. sample.uFlags.reset(SMP_KEEPONDISK);
  1932. }
  1933. #else
  1934. file.Skip(strLen);
  1935. #endif // MPT_EXTERNAL_SAMPLES
  1936. }
  1937. sample.Convert(MOD_TYPE_IT, GetType());
  1938. sample.PrecomputeLoops(*this, false);
  1939. return true;
  1940. }
  1941. bool CSoundFile::ReadITISample(SAMPLEINDEX nSample, FileReader &file)
  1942. {
  1943. ITInstrument instrumentHeader;
  1944. file.Rewind();
  1945. if(!file.ReadStruct(instrumentHeader)
  1946. || memcmp(instrumentHeader.id, "IMPI", 4))
  1947. {
  1948. return false;
  1949. }
  1950. file.Rewind();
  1951. ModInstrument dummy;
  1952. ITInstrToMPT(file, dummy, instrumentHeader.trkvers);
  1953. // Old SchismTracker versions set nos=0
  1954. const SAMPLEINDEX nsamples = std::max(static_cast<SAMPLEINDEX>(instrumentHeader.nos), *std::max_element(std::begin(dummy.Keyboard), std::end(dummy.Keyboard)));
  1955. if(!nsamples)
  1956. return false;
  1957. // Preferrably read the middle-C sample
  1958. auto sample = dummy.Keyboard[NOTE_MIDDLEC - NOTE_MIN];
  1959. if(sample > 0)
  1960. sample--;
  1961. else
  1962. sample = 0;
  1963. file.Seek(file.GetPosition() + sample * sizeof(ITSample));
  1964. return ReadITSSample(nSample, file, false);
  1965. }
  1966. bool CSoundFile::ReadITIInstrument(INSTRUMENTINDEX nInstr, FileReader &file)
  1967. {
  1968. ITInstrument instrumentHeader;
  1969. SAMPLEINDEX smp = 0;
  1970. file.Rewind();
  1971. if(!file.ReadStruct(instrumentHeader)
  1972. || memcmp(instrumentHeader.id, "IMPI", 4))
  1973. {
  1974. return false;
  1975. }
  1976. if(nInstr > GetNumInstruments()) m_nInstruments = nInstr;
  1977. ModInstrument *pIns = new (std::nothrow) ModInstrument();
  1978. if(pIns == nullptr)
  1979. {
  1980. return false;
  1981. }
  1982. DestroyInstrument(nInstr, deleteAssociatedSamples);
  1983. Instruments[nInstr] = pIns;
  1984. file.Rewind();
  1985. ITInstrToMPT(file, *pIns, instrumentHeader.trkvers);
  1986. // Old SchismTracker versions set nos=0
  1987. const SAMPLEINDEX nsamples = std::max(static_cast<SAMPLEINDEX>(instrumentHeader.nos), *std::max_element(std::begin(pIns->Keyboard), std::end(pIns->Keyboard)));
  1988. // In order to properly compute the position, in file, of eventual extended settings
  1989. // such as "attack" we need to keep the "real" size of the last sample as those extra
  1990. // setting will follow this sample in the file
  1991. FileReader::off_t extraOffset = file.GetPosition();
  1992. // Reading Samples
  1993. std::vector<SAMPLEINDEX> samplemap(nsamples, 0);
  1994. for(SAMPLEINDEX i = 0; i < nsamples; i++)
  1995. {
  1996. smp = GetNextFreeSample(nInstr, smp + 1);
  1997. if(smp == SAMPLEINDEX_INVALID) break;
  1998. samplemap[i] = smp;
  1999. const FileReader::off_t offset = file.GetPosition();
  2000. if(!ReadITSSample(smp, file, false))
  2001. smp--;
  2002. extraOffset = std::max(extraOffset, file.GetPosition());
  2003. file.Seek(offset + sizeof(ITSample));
  2004. }
  2005. if(GetNumSamples() < smp) m_nSamples = smp;
  2006. // Adjust sample assignment
  2007. for(auto &sample : pIns->Keyboard)
  2008. {
  2009. if(sample > 0 && sample <= nsamples)
  2010. {
  2011. sample = samplemap[sample - 1];
  2012. }
  2013. }
  2014. if(file.Seek(extraOffset))
  2015. {
  2016. // Read MPT crap
  2017. ReadExtendedInstrumentProperties(pIns, file);
  2018. }
  2019. pIns->Convert(MOD_TYPE_IT, GetType());
  2020. pIns->Sanitize(GetType());
  2021. return true;
  2022. }
  2023. #ifndef MODPLUG_NO_FILESAVE
  2024. bool CSoundFile::SaveITIInstrument(INSTRUMENTINDEX nInstr, std::ostream &f, const mpt::PathString &filename, bool compress, bool allowExternal) const
  2025. {
  2026. ITInstrument iti;
  2027. ModInstrument *pIns = Instruments[nInstr];
  2028. if((!pIns) || (filename.empty() && allowExternal)) return false;
  2029. auto instSize = iti.ConvertToIT(*pIns, false, *this);
  2030. // Create sample assignment table
  2031. std::vector<SAMPLEINDEX> smptable;
  2032. std::vector<uint8> smpmap(GetNumSamples(), 0);
  2033. for(size_t i = 0; i < NOTE_MAX; i++)
  2034. {
  2035. const SAMPLEINDEX smp = pIns->Keyboard[i];
  2036. if(smp && smp <= GetNumSamples())
  2037. {
  2038. if(!smpmap[smp - 1])
  2039. {
  2040. // We haven't considered this sample yet.
  2041. smptable.push_back(smp);
  2042. smpmap[smp - 1] = static_cast<uint8>(smptable.size());
  2043. }
  2044. iti.keyboard[i * 2 + 1] = smpmap[smp - 1];
  2045. } else
  2046. {
  2047. iti.keyboard[i * 2 + 1] = 0;
  2048. }
  2049. }
  2050. iti.nos = static_cast<uint8>(smptable.size());
  2051. smpmap.clear();
  2052. uint32 filePos = instSize;
  2053. mpt::IO::WritePartial(f, iti, instSize);
  2054. filePos += mpt::saturate_cast<uint32>(smptable.size() * sizeof(ITSample));
  2055. // Writing sample headers + data
  2056. std::vector<SampleIO> sampleFlags;
  2057. for(auto smp : smptable)
  2058. {
  2059. ITSample itss;
  2060. itss.ConvertToIT(Samples[smp], GetType(), compress, compress, allowExternal);
  2061. const bool isExternal = itss.cvt == ITSample::cvtExternalSample;
  2062. mpt::String::WriteBuf(mpt::String::nullTerminated, itss.name) = m_szNames[smp];
  2063. itss.samplepointer = filePos;
  2064. mpt::IO::Write(f, itss);
  2065. // Write sample
  2066. auto curPos = mpt::IO::TellWrite(f);
  2067. mpt::IO::SeekAbsolute(f, filePos);
  2068. if(!isExternal)
  2069. {
  2070. filePos += mpt::saturate_cast<uint32>(itss.GetSampleFormat(0x0214).WriteSample(f, Samples[smp]));
  2071. } else
  2072. {
  2073. #ifdef MPT_EXTERNAL_SAMPLES
  2074. const std::string filenameU8 = GetSamplePath(smp).AbsolutePathToRelative(filename.GetPath()).ToUTF8();
  2075. const size_t strSize = filenameU8.size();
  2076. size_t intBytes = 0;
  2077. if(mpt::IO::WriteVarInt(f, strSize, &intBytes))
  2078. {
  2079. filePos += mpt::saturate_cast<uint32>(intBytes + strSize);
  2080. mpt::IO::WriteRaw(f, filenameU8.data(), strSize);
  2081. }
  2082. #endif // MPT_EXTERNAL_SAMPLES
  2083. }
  2084. mpt::IO::SeekAbsolute(f, curPos);
  2085. }
  2086. mpt::IO::SeekEnd(f);
  2087. // Write 'MPTX' extension tag
  2088. mpt::IO::WriteRaw(f, "XTPM", 4);
  2089. WriteInstrumentHeaderStructOrField(pIns, f); // Write full extended header.
  2090. return true;
  2091. }
  2092. #endif // MODPLUG_NO_FILESAVE
  2093. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2094. // 8SVX / 16SVX / MAUD Samples
  2095. // IFF File Header
  2096. struct IFFHeader
  2097. {
  2098. char form[4]; // "FORM"
  2099. uint32be size;
  2100. char magic[4]; // "8SVX", "16SV", "MAUD"
  2101. };
  2102. MPT_BINARY_STRUCT(IFFHeader, 12)
  2103. // General IFF Chunk header
  2104. struct IFFChunk
  2105. {
  2106. // 32-Bit chunk identifiers
  2107. enum ChunkIdentifiers
  2108. {
  2109. // 8SVX / 16SV
  2110. idVHDR = MagicBE("VHDR"),
  2111. idBODY = MagicBE("BODY"),
  2112. idCHAN = MagicBE("CHAN"),
  2113. // MAUD
  2114. idMHDR = MagicBE("MHDR"),
  2115. idMDAT = MagicBE("MDAT"),
  2116. idNAME = MagicBE("NAME"),
  2117. };
  2118. uint32be id; // See ChunkIdentifiers
  2119. uint32be length; // Chunk size without header
  2120. size_t GetLength() const
  2121. {
  2122. if(length == 0) // Broken files
  2123. return std::numeric_limits<size_t>::max();
  2124. return length;
  2125. }
  2126. ChunkIdentifiers GetID() const
  2127. {
  2128. return static_cast<ChunkIdentifiers>(id.get());
  2129. }
  2130. };
  2131. MPT_BINARY_STRUCT(IFFChunk, 8)
  2132. struct IFFSampleHeader
  2133. {
  2134. uint32be oneShotHiSamples; // Samples in the high octave 1-shot part
  2135. uint32be repeatHiSamples; // Samples in the high octave repeat part
  2136. uint32be samplesPerHiCycle; // Samples/cycle in high octave, else 0
  2137. uint16be samplesPerSec; // Data sampling rate
  2138. uint8be octave; // Octaves of waveforms
  2139. uint8be compression; // Data compression technique used
  2140. uint32be volume;
  2141. };
  2142. MPT_BINARY_STRUCT(IFFSampleHeader, 20)
  2143. bool CSoundFile::ReadIFFSample(SAMPLEINDEX nSample, FileReader &file)
  2144. {
  2145. file.Rewind();
  2146. IFFHeader fileHeader;
  2147. if(!file.ReadStruct(fileHeader)
  2148. || memcmp(fileHeader.form, "FORM", 4)
  2149. || (memcmp(fileHeader.magic, "8SVX", 4) && memcmp(fileHeader.magic, "16SV", 4) && memcmp(fileHeader.magic, "MAUD", 4)))
  2150. {
  2151. return false;
  2152. }
  2153. const auto chunks = file.ReadChunks<IFFChunk>(2);
  2154. FileReader sampleData;
  2155. SampleIO sampleIO(SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM);
  2156. uint32 numSamples = 0, sampleRate = 0, loopStart = 0, loopLength = 0, volume = 0;
  2157. if(!memcmp(fileHeader.magic, "MAUD", 4))
  2158. {
  2159. FileReader mhdrChunk = chunks.GetChunk(IFFChunk::idMHDR);
  2160. sampleData = chunks.GetChunk(IFFChunk::idMDAT);
  2161. if(!mhdrChunk.LengthIs(32)
  2162. || !sampleData.IsValid())
  2163. {
  2164. return false;
  2165. }
  2166. numSamples = mhdrChunk.ReadUint32BE();
  2167. const uint16 bitsPerSample = mhdrChunk.ReadUint16BE();
  2168. mhdrChunk.Skip(2); // bits per sample after decompression
  2169. sampleRate = mhdrChunk.ReadUint32BE();
  2170. const auto [clockDivide, channelInformation, numChannels, compressionType] = mhdrChunk.ReadArray<uint16be, 4>();
  2171. if(!clockDivide)
  2172. return false;
  2173. else
  2174. sampleRate /= clockDivide;
  2175. if(numChannels != (channelInformation + 1))
  2176. return false;
  2177. if(numChannels == 2)
  2178. sampleIO |= SampleIO::stereoInterleaved;
  2179. if(bitsPerSample == 8 && compressionType == 0)
  2180. sampleIO |= SampleIO::unsignedPCM;
  2181. else if(bitsPerSample == 8 && compressionType == 2)
  2182. sampleIO |= SampleIO::aLaw;
  2183. else if(bitsPerSample == 8 && compressionType == 3)
  2184. sampleIO |= SampleIO::uLaw;
  2185. else if(bitsPerSample == 16 && compressionType == 0)
  2186. sampleIO |= SampleIO::_16bit;
  2187. else
  2188. return false;
  2189. } else
  2190. {
  2191. FileReader vhdrChunk = chunks.GetChunk(IFFChunk::idVHDR);
  2192. FileReader chanChunk = chunks.GetChunk(IFFChunk::idCHAN);
  2193. sampleData = chunks.GetChunk(IFFChunk::idBODY);
  2194. IFFSampleHeader sampleHeader;
  2195. if(!sampleData.IsValid()
  2196. || !vhdrChunk.IsValid()
  2197. || !vhdrChunk.ReadStruct(sampleHeader))
  2198. {
  2199. return false;
  2200. }
  2201. const uint8 bytesPerSample = memcmp(fileHeader.magic, "8SVX", 4) ? 2 : 1;
  2202. const uint8 numChannels = chanChunk.ReadUint32BE() == 6 ? 2 : 1;
  2203. const uint8 bytesPerFrame = bytesPerSample * numChannels;
  2204. // While this is an Amiga format, the 16SV version appears to be only used on PC, and only with little-endian sample data.
  2205. if(bytesPerSample == 2)
  2206. sampleIO = SampleIO(SampleIO::_16bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM);
  2207. if(numChannels == 2)
  2208. sampleIO |= SampleIO::stereoSplit;
  2209. loopStart = sampleHeader.oneShotHiSamples / bytesPerFrame;
  2210. loopLength = sampleHeader.repeatHiSamples / bytesPerFrame;
  2211. sampleRate = sampleHeader.samplesPerSec;
  2212. volume = sampleHeader.volume;
  2213. numSamples = mpt::saturate_cast<SmpLength>(sampleData.GetLength() / bytesPerFrame);
  2214. }
  2215. DestroySampleThreadsafe(nSample);
  2216. ModSample &sample = Samples[nSample];
  2217. sample.Initialize();
  2218. sample.nLength = numSamples;
  2219. sample.nLoopStart = loopStart;
  2220. sample.nLoopEnd = sample.nLoopStart + loopLength;
  2221. if((sample.nLoopStart + 4 < sample.nLoopEnd) && (sample.nLoopEnd <= sample.nLength))
  2222. sample.uFlags.set(CHN_LOOP);
  2223. sample.nC5Speed = sampleRate;
  2224. if(!sample.nC5Speed)
  2225. sample.nC5Speed = 22050;
  2226. sample.nVolume = static_cast<uint16>(volume / 256);
  2227. if(!sample.nVolume || sample.nVolume > 256)
  2228. sample.nVolume = 256;
  2229. sample.Convert(MOD_TYPE_IT, GetType());
  2230. FileReader nameChunk = chunks.GetChunk(IFFChunk::idNAME);
  2231. if(nameChunk.IsValid())
  2232. nameChunk.ReadString<mpt::String::maybeNullTerminated>(m_szNames[nSample], nameChunk.GetLength());
  2233. else
  2234. m_szNames[nSample] = "";
  2235. sampleIO.ReadSample(sample, sampleData);
  2236. sample.PrecomputeLoops(*this, false);
  2237. return true;
  2238. }
  2239. OPENMPT_NAMESPACE_END