1
0

SampleFormatMP3.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /*
  2. * SampleFormatMP3.cpp
  3. * -------------------
  4. * Purpose: MP3 sample import.
  5. * Notes :
  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. #ifndef MODPLUG_NO_FILESAVE
  12. #include "../common/mptFileIO.h"
  13. #endif
  14. #include "../common/misc_util.h"
  15. #include "Tagging.h"
  16. #include "Loaders.h"
  17. #include "../common/FileReader.h"
  18. #include "modsmp_ctrl.h"
  19. #include "openmpt/soundbase/Copy.hpp"
  20. #include "../soundlib/ModSampleCopy.h"
  21. #include "../common/ComponentManager.h"
  22. #ifdef MPT_ENABLE_MP3_SAMPLES
  23. #include "MPEGFrame.h"
  24. #endif // MPT_ENABLE_MP3_SAMPLES
  25. #if defined(MPT_WITH_MINIMP3)
  26. #include "mpt/base/alloc.hpp"
  27. #endif // MPT_WITH_MINIMP3
  28. #if defined(MPT_WITH_MINIMP3)
  29. #include <minimp3/minimp3.h>
  30. #endif // MPT_WITH_MINIMP3
  31. // mpg123 must be last because of mpg123 large file support insanity
  32. #if defined(MPT_WITH_MPG123)
  33. #include <stddef.h>
  34. #include <stdlib.h>
  35. #include <sys/types.h>
  36. #if MPT_OS_OPENBSD
  37. // This is kind-of a hack.
  38. // See <https://sourceforge.net/p/mpg123/bugs/330/>.
  39. #if MPT_COMPILER_CLANG
  40. #pragma clang diagnostic push
  41. #pragma clang diagnostic ignored "-Wreserved-id-macro"
  42. #endif
  43. #ifdef _FILE_OFFSET_BITS
  44. #undef _FILE_OFFSET_BITS
  45. #endif
  46. #if MPT_COMPILER_CLANG
  47. #pragma clang diagnostic pop
  48. #endif
  49. #endif
  50. #include <mpg123.h>
  51. #endif
  52. OPENMPT_NAMESPACE_BEGIN
  53. ///////////////////////////////////////////////////////////////////////////////////////////////////
  54. // MP3 Samples
  55. #if defined(MPT_WITH_MPG123)
  56. typedef off_t mpg123_off_t;
  57. typedef size_t mpg123_size_t;
  58. // Check for exactly _MSC_VER as libmpg123 does, in order to also catch clang-cl.
  59. #ifdef _MSC_VER
  60. // ssize_t definition in libmpg123.h.in should never have existed at all.
  61. // It got removed from libmpg23.h.in after 1.28.0 and before 1.28.1.
  62. typedef ptrdiff_t mpg123_ssize_t;
  63. #else
  64. typedef ssize_t mpg123_ssize_t;
  65. #endif
  66. class ComponentMPG123
  67. : public ComponentBuiltin
  68. {
  69. MPT_DECLARE_COMPONENT_MEMBERS(ComponentMPG123, "")
  70. public:
  71. static mpg123_ssize_t FileReaderRead(void *fp, void *buf, mpg123_size_t count)
  72. {
  73. FileReader &file = *static_cast<FileReader *>(fp);
  74. std::size_t readBytes = std::min(count, static_cast<size_t>(file.BytesLeft()));
  75. file.ReadRaw(mpt::span(mpt::void_cast<std::byte*>(buf), readBytes));
  76. return readBytes;
  77. }
  78. static mpg123_off_t FileReaderLSeek(void *fp, mpg123_off_t offset, int whence)
  79. {
  80. FileReader &file = *static_cast<FileReader *>(fp);
  81. FileReader::off_t oldpos = file.GetPosition();
  82. if(whence == SEEK_CUR) file.Seek(file.GetPosition() + offset);
  83. else if(whence == SEEK_END) file.Seek(file.GetLength() + offset);
  84. else file.Seek(offset);
  85. MPT_MAYBE_CONSTANT_IF(!mpt::in_range<mpg123_off_t>(file.GetPosition()))
  86. {
  87. file.Seek(oldpos);
  88. return static_cast<mpg123_off_t>(-1);
  89. }
  90. return static_cast<mpg123_off_t>(file.GetPosition());
  91. }
  92. public:
  93. ComponentMPG123()
  94. : ComponentBuiltin()
  95. {
  96. return;
  97. }
  98. bool DoInitialize() override
  99. {
  100. if(mpg123_init() != 0)
  101. {
  102. return false;
  103. }
  104. return true;
  105. }
  106. virtual ~ComponentMPG123()
  107. {
  108. if(IsAvailable())
  109. {
  110. mpg123_exit();
  111. }
  112. }
  113. };
  114. static mpt::ustring ReadMPG123String(const mpg123_string &str)
  115. {
  116. mpt::ustring result;
  117. if(!str.p)
  118. {
  119. return result;
  120. }
  121. if(str.fill < 1)
  122. {
  123. return result;
  124. }
  125. result = mpt::ToUnicode(mpt::Charset::UTF8, std::string(str.p, str.p + str.fill - 1));
  126. return result;
  127. }
  128. static mpt::ustring ReadMPG123String(const mpg123_string *str)
  129. {
  130. mpt::ustring result;
  131. if(!str)
  132. {
  133. return result;
  134. }
  135. result = ReadMPG123String(*str);
  136. return result;
  137. }
  138. template <std::size_t N>
  139. static mpt::ustring ReadMPG123String(const char (&str)[N])
  140. {
  141. return mpt::ToUnicode(mpt::Charset::ISO8859_1, mpt::String::ReadBuf(mpt::String::spacePadded, str));
  142. }
  143. #endif // MPT_WITH_MPG123
  144. #if defined(MPT_WITH_MINIMP3)
  145. #if MPT_COMPILER_GCC
  146. #pragma GCC diagnostic push
  147. #pragma GCC diagnostic ignored "-Wframe-larger-than=16000"
  148. #endif // MPT_COMPILER_GCC
  149. #if MPT_CLANG_AT_LEAST(13,0,0)
  150. #pragma clang diagnostic push
  151. #pragma clang diagnostic ignored "-Wframe-larger-than"
  152. #endif // MPT_COMPILER_CLANG
  153. static MPT_NOINLINE int mp3dec_decode_frame_no_inline(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info)
  154. {
  155. return mp3dec_decode_frame(dec, mp3, mp3_bytes, pcm, info);
  156. }
  157. #if MPT_CLANG_AT_LEAST(13,0,0)
  158. #pragma clang diagnostic pop
  159. #endif // MPT_COMPILER_CLANG
  160. #if MPT_COMPILER_GCC
  161. #pragma GCC diagnostic pop
  162. #endif // MPT_COMPILER_GCC
  163. #endif // MPT_WITH_MINIMP3
  164. bool CSoundFile::ReadMP3Sample(SAMPLEINDEX sample, FileReader &file, bool raw, bool mo3Decode)
  165. {
  166. #if defined(MPT_WITH_MPG123) || defined(MPT_WITH_MINIMP3)
  167. // Check file for validity, or else mpg123 will happily munch many files that start looking vaguely resemble an MPEG stream mid-file.
  168. file.Rewind();
  169. while(file.CanRead(4))
  170. {
  171. uint8 magic[3];
  172. file.ReadArray(magic);
  173. if(!memcmp(magic, "ID3", 3))
  174. {
  175. // Skip ID3 tags
  176. uint8 header[7];
  177. file.ReadArray(header);
  178. uint32 size = 0;
  179. for(int i = 3; i < 7; i++)
  180. {
  181. if(header[i] & 0x80)
  182. return false;
  183. size = (size << 7) | header[i];
  184. }
  185. file.Skip(size);
  186. } else if(!memcmp(magic, "APE", 3) && file.ReadMagic("TAGEX"))
  187. {
  188. // Skip APE tags
  189. uint32 size = file.ReadUint32LE();
  190. file.Skip(16 + size);
  191. } else if(!memcmp(magic, "\x00\x00\x00", 3) || !memcmp(magic, "\xFF\x00\x00", 3))
  192. {
  193. // Some MP3 files are padded with zeroes...
  194. } else if(magic[0] == 0)
  195. {
  196. // This might be some padding, followed by an MPEG header, so try again.
  197. file.SkipBack(2);
  198. } else if(MPEGFrame::IsMPEGHeader(magic))
  199. {
  200. // This is what we want!
  201. break;
  202. } else
  203. {
  204. // This, on the other hand, isn't.
  205. return false;
  206. }
  207. }
  208. #endif // MPT_WITH_MPG123 || MPT_WITH_MINIMP3
  209. #if defined(MPT_WITH_MPG123)
  210. ComponentHandle<ComponentMPG123> mpg123;
  211. if(!IsComponentAvailable(mpg123))
  212. {
  213. return false;
  214. }
  215. struct MPG123Handle
  216. {
  217. mpg123_handle *mh;
  218. MPG123Handle() : mh(mpg123_new(0, nullptr)) { }
  219. ~MPG123Handle() { mpg123_delete(mh); }
  220. operator mpg123_handle *() { return mh; }
  221. };
  222. bool hasLameXingVbriHeader = false;
  223. if(!raw)
  224. {
  225. mpg123_off_t length_raw = 0;
  226. mpg123_off_t length_hdr = 0;
  227. // libmpg123 provides no way to determine whether it parsed ID3V2 or VBR tags.
  228. // Thus, we use a pre-scan with those disabled and compare the resulting length.
  229. // We ignore ID3V2 stream length here, althrough we parse the ID3V2 header.
  230. // libmpg123 only accounts for the VBR info frame if gapless &&!ignore_infoframe,
  231. // thus we switch both of those for comparison.
  232. {
  233. MPG123Handle mh;
  234. if(!mh)
  235. {
  236. return false;
  237. }
  238. file.Rewind();
  239. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0))
  240. {
  241. return false;
  242. }
  243. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_AUTO_RESAMPLE, 0.0))
  244. {
  245. return false;
  246. }
  247. if(mpg123_param(mh, MPG123_REMOVE_FLAGS, MPG123_GAPLESS, 0.0))
  248. {
  249. return false;
  250. }
  251. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_IGNORE_INFOFRAME, 0.0))
  252. {
  253. return false;
  254. }
  255. if(mpg123_param(mh, MPG123_REMOVE_FLAGS, MPG123_SKIP_ID3V2, 0.0))
  256. {
  257. return false;
  258. }
  259. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_IGNORE_STREAMLENGTH, 0.0))
  260. {
  261. return false;
  262. }
  263. if(mpg123_param(mh, MPG123_INDEX_SIZE, -1000, 0.0)) // auto-grow
  264. {
  265. return false;
  266. }
  267. if(mpg123_replace_reader_handle(mh, ComponentMPG123::FileReaderRead, ComponentMPG123::FileReaderLSeek, 0))
  268. {
  269. return false;
  270. }
  271. if(mpg123_open_handle(mh, &file))
  272. {
  273. return false;
  274. }
  275. if(mpg123_scan(mh))
  276. {
  277. return false;
  278. }
  279. long rate = 0;
  280. int channels = 0;
  281. int encoding = 0;
  282. if(mpg123_getformat(mh, &rate, &channels, &encoding))
  283. {
  284. return false;
  285. }
  286. if((channels != 1 && channels != 2) || (encoding & (MPG123_ENC_16 | MPG123_ENC_SIGNED)) != (MPG123_ENC_16 | MPG123_ENC_SIGNED))
  287. {
  288. return false;
  289. }
  290. mpg123_frameinfo frameinfo;
  291. MemsetZero(frameinfo);
  292. if(mpg123_info(mh, &frameinfo))
  293. {
  294. return false;
  295. }
  296. if(frameinfo.layer < 1 || frameinfo.layer > 3)
  297. {
  298. return false;
  299. }
  300. if(mpg123_param(mh, MPG123_FORCE_RATE, rate, 0.0))
  301. {
  302. return false;
  303. }
  304. if(mpg123_param(mh, MPG123_ADD_FLAGS, (channels > 1) ? MPG123_FORCE_STEREO : MPG123_FORCE_MONO, 0.0))
  305. {
  306. return false;
  307. }
  308. length_raw = mpg123_length(mh);
  309. }
  310. {
  311. MPG123Handle mh;
  312. if(!mh)
  313. {
  314. return false;
  315. }
  316. file.Rewind();
  317. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0))
  318. {
  319. return false;
  320. }
  321. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_AUTO_RESAMPLE, 0.0))
  322. {
  323. return false;
  324. }
  325. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_GAPLESS, 0.0))
  326. {
  327. return false;
  328. }
  329. if(mpg123_param(mh, MPG123_REMOVE_FLAGS, MPG123_IGNORE_INFOFRAME, 0.0))
  330. {
  331. return false;
  332. }
  333. if(mpg123_param(mh, MPG123_REMOVE_FLAGS, MPG123_SKIP_ID3V2, 0.0))
  334. {
  335. return false;
  336. }
  337. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_IGNORE_STREAMLENGTH, 0.0))
  338. {
  339. return false;
  340. }
  341. if(mpg123_param(mh, MPG123_INDEX_SIZE, -1000, 0.0)) // auto-grow
  342. {
  343. return false;
  344. }
  345. if(mpg123_replace_reader_handle(mh, ComponentMPG123::FileReaderRead, ComponentMPG123::FileReaderLSeek, 0))
  346. {
  347. return false;
  348. }
  349. if(mpg123_open_handle(mh, &file))
  350. {
  351. return false;
  352. }
  353. if(mpg123_scan(mh))
  354. {
  355. return false;
  356. }
  357. long rate = 0;
  358. int channels = 0;
  359. int encoding = 0;
  360. if(mpg123_getformat(mh, &rate, &channels, &encoding))
  361. {
  362. return false;
  363. }
  364. if((channels != 1 && channels != 2) || (encoding & (MPG123_ENC_16 | MPG123_ENC_SIGNED)) != (MPG123_ENC_16 | MPG123_ENC_SIGNED))
  365. {
  366. return false;
  367. }
  368. mpg123_frameinfo frameinfo;
  369. MemsetZero(frameinfo);
  370. if(mpg123_info(mh, &frameinfo))
  371. {
  372. return false;
  373. }
  374. if(frameinfo.layer < 1 || frameinfo.layer > 3)
  375. {
  376. return false;
  377. }
  378. if(mpg123_param(mh, MPG123_FORCE_RATE, rate, 0.0))
  379. {
  380. return false;
  381. }
  382. if(mpg123_param(mh, MPG123_ADD_FLAGS, (channels > 1) ? MPG123_FORCE_STEREO : MPG123_FORCE_MONO, 0.0))
  383. {
  384. return false;
  385. }
  386. length_hdr = mpg123_length(mh);
  387. }
  388. hasLameXingVbriHeader = (length_raw != length_hdr);
  389. }
  390. // Set up decoder...
  391. MPG123Handle mh;
  392. if(!mh)
  393. {
  394. return false;
  395. }
  396. file.Rewind();
  397. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0))
  398. {
  399. return false;
  400. }
  401. if(mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_AUTO_RESAMPLE, 0.0))
  402. {
  403. return false;
  404. }
  405. if(mpg123_param(mh, raw ? MPG123_REMOVE_FLAGS : MPG123_ADD_FLAGS, MPG123_GAPLESS, 0.0))
  406. {
  407. return false;
  408. }
  409. if(mpg123_param(mh, raw ? MPG123_ADD_FLAGS : MPG123_REMOVE_FLAGS, MPG123_IGNORE_INFOFRAME, 0.0))
  410. {
  411. return false;
  412. }
  413. if(mpg123_param(mh, MPG123_REMOVE_FLAGS, MPG123_SKIP_ID3V2, 0.0))
  414. {
  415. return false;
  416. }
  417. if(mpg123_param(mh, raw ? MPG123_ADD_FLAGS : MPG123_REMOVE_FLAGS, MPG123_IGNORE_STREAMLENGTH, 0.0))
  418. {
  419. return false;
  420. }
  421. if(mpg123_param(mh, MPG123_INDEX_SIZE, -1000, 0.0)) // auto-grow
  422. {
  423. return false;
  424. }
  425. if(mpg123_replace_reader_handle(mh, ComponentMPG123::FileReaderRead, ComponentMPG123::FileReaderLSeek, 0))
  426. {
  427. return false;
  428. }
  429. if(mpg123_open_handle(mh, &file))
  430. {
  431. return false;
  432. }
  433. if(mpg123_scan(mh))
  434. {
  435. return false;
  436. }
  437. long rate = 0;
  438. int channels = 0;
  439. int encoding = 0;
  440. if(mpg123_getformat(mh, &rate, &channels, &encoding))
  441. {
  442. return false;
  443. }
  444. if((channels != 1 && channels != 2) || (encoding & (MPG123_ENC_16 | MPG123_ENC_SIGNED)) != (MPG123_ENC_16 | MPG123_ENC_SIGNED))
  445. {
  446. return false;
  447. }
  448. mpg123_frameinfo frameinfo;
  449. MemsetZero(frameinfo);
  450. if(mpg123_info(mh, &frameinfo))
  451. {
  452. return false;
  453. }
  454. if(frameinfo.layer < 1 || frameinfo.layer > 3)
  455. {
  456. return false;
  457. }
  458. // We force samplerate, channels and sampleformat, which in
  459. // combination with auto-resample (set above) will cause libmpg123
  460. // to stay with the given format even for completely confused
  461. // MPG123_FRANKENSTEIN streams.
  462. // Note that we cannot rely on mpg123_length() for the way we
  463. // decode the mpeg streams because it depends on the actual frame
  464. // sample rate instead of the returned sample rate.
  465. if(mpg123_param(mh, MPG123_FORCE_RATE, rate, 0.0))
  466. {
  467. return false;
  468. }
  469. if(mpg123_param(mh, MPG123_ADD_FLAGS, (channels > 1) ? MPG123_FORCE_STEREO : MPG123_FORCE_MONO, 0.0))
  470. {
  471. return false;
  472. }
  473. std::vector<int16> data;
  474. // decoder delay
  475. std::size_t data_skip_frames = 0;
  476. if(!raw && !hasLameXingVbriHeader)
  477. {
  478. if(frameinfo.layer == 1)
  479. {
  480. data_skip_frames = 240 + 1;
  481. } else if(frameinfo.layer == 2)
  482. {
  483. data_skip_frames = 240 + 1;
  484. } else if(frameinfo.layer == 3)
  485. {
  486. data_skip_frames = 528 + 1;
  487. }
  488. }
  489. std::vector<std::byte> buf_bytes;
  490. std::vector<int16> buf_samples;
  491. bool decode_error = false;
  492. bool decode_done = false;
  493. while(!decode_error && !decode_done)
  494. {
  495. buf_bytes.resize(mpg123_outblock(mh));
  496. buf_samples.resize(buf_bytes.size() / sizeof(int16));
  497. mpg123_size_t buf_bytes_decoded = 0;
  498. int mpg123_read_result = mpg123_read(mh, mpt::byte_cast<unsigned char*>(buf_bytes.data()), buf_bytes.size(), &buf_bytes_decoded);
  499. std::memcpy(buf_samples.data(), buf_bytes.data(), buf_bytes_decoded);
  500. mpt::append(data, buf_samples.data(), buf_samples.data() + buf_bytes_decoded / sizeof(int16));
  501. if((data.size() / channels) > MAX_SAMPLE_LENGTH)
  502. {
  503. break;
  504. }
  505. if(mpg123_read_result == MPG123_OK)
  506. {
  507. // continue
  508. } else if(mpg123_read_result == MPG123_NEW_FORMAT)
  509. {
  510. // continue
  511. } else if(mpg123_read_result == MPG123_DONE)
  512. {
  513. decode_done = true;
  514. } else
  515. {
  516. decode_error = true;
  517. }
  518. }
  519. if((data.size() / channels) > MAX_SAMPLE_LENGTH)
  520. {
  521. return false;
  522. }
  523. FileTags tags;
  524. mpg123_id3v1 *id3v1 = nullptr;
  525. mpg123_id3v2 *id3v2 = nullptr;
  526. if(mpg123_id3(mh, &id3v1, &id3v2) == MPG123_OK)
  527. {
  528. if(id3v2)
  529. {
  530. if(tags.title.empty()) tags.title = ReadMPG123String(id3v2->title);
  531. if(tags.artist.empty()) tags.artist = ReadMPG123String(id3v2->artist);
  532. if(tags.album.empty()) tags.album = ReadMPG123String(id3v2->album);
  533. if(tags.year.empty()) tags.year = ReadMPG123String(id3v2->year);
  534. if(tags.genre.empty()) tags.genre = ReadMPG123String(id3v2->genre);
  535. if(tags.comments.empty()) tags.comments = ReadMPG123String(id3v2->comment);
  536. }
  537. if(id3v1)
  538. {
  539. if(tags.title.empty()) tags.title = ReadMPG123String(id3v1->title);
  540. if(tags.artist.empty()) tags.artist = ReadMPG123String(id3v1->artist);
  541. if(tags.album.empty()) tags.album = ReadMPG123String(id3v1->album);
  542. if(tags.year.empty()) tags.year = ReadMPG123String(id3v1->year);
  543. if(tags.comments.empty()) tags.comments = ReadMPG123String(id3v1->comment);
  544. }
  545. }
  546. mpt::ustring sampleName = GetSampleNameFromTags(tags);
  547. DestroySampleThreadsafe(sample);
  548. if(!mo3Decode)
  549. {
  550. m_szNames[sample] = mpt::ToCharset(GetCharsetInternal(), sampleName);
  551. Samples[sample].Initialize();
  552. Samples[sample].nC5Speed = rate;
  553. }
  554. Samples[sample].nLength = mpt::saturate_cast<SmpLength>((data.size() / channels) - data_skip_frames);
  555. Samples[sample].uFlags.set(CHN_16BIT);
  556. Samples[sample].uFlags.set(CHN_STEREO, channels == 2);
  557. Samples[sample].AllocateSample();
  558. if(Samples[sample].HasSampleData())
  559. {
  560. std::memcpy(Samples[sample].sampleb(), data.data() + (data_skip_frames * channels), (data.size() - (data_skip_frames * channels)) * sizeof(int16));
  561. }
  562. if(!mo3Decode)
  563. {
  564. Samples[sample].Convert(MOD_TYPE_IT, GetType());
  565. Samples[sample].PrecomputeLoops(*this, false);
  566. }
  567. return Samples[sample].HasSampleData();
  568. #elif defined(MPT_WITH_MINIMP3)
  569. MPT_UNREFERENCED_PARAMETER(raw);
  570. file.Rewind();
  571. FileReader::PinnedView rawDataView = file.GetPinnedView();
  572. int64 bytes_left = rawDataView.size();
  573. const uint8 *stream_pos = mpt::byte_cast<const uint8 *>(rawDataView.data());
  574. std::vector<int16> raw_sample_data;
  575. mpt::heap_value<mp3dec_t> mp3;
  576. std::memset(&*mp3, 0, sizeof(mp3dec_t));
  577. mp3dec_init(&*mp3);
  578. int rate = 0;
  579. int channels = 0;
  580. mp3dec_frame_info_t info;
  581. std::memset(&info, 0, sizeof(mp3dec_frame_info_t));
  582. std::vector<int16> sample_buf(MINIMP3_MAX_SAMPLES_PER_FRAME);
  583. do
  584. {
  585. int frame_samples = mp3dec_decode_frame_no_inline(&*mp3, stream_pos, mpt::saturate_cast<int>(bytes_left), sample_buf.data(), &info);
  586. if(frame_samples < 0 || info.frame_bytes < 0) break; // internal error in minimp3
  587. if(frame_samples > 0 && info.frame_bytes == 0) break; // internal error in minimp3
  588. if(frame_samples == 0 && info.frame_bytes == 0) break; // end of stream, no progress
  589. if(frame_samples == 0 && info.frame_bytes > 0) do { } while(0); // decoder skipped non-mp3 data
  590. if(frame_samples > 0 && info.frame_bytes > 0) do { } while(0); // normal
  591. if(info.frame_bytes > 0)
  592. {
  593. if(rate != 0 && rate != info.hz) break; // inconsistent stream
  594. if(channels != 0 && channels != info.channels) break; // inconsistent stream
  595. rate = info.hz;
  596. channels = info.channels;
  597. if(rate <= 0) break; // broken stream
  598. if(channels != 1 && channels != 2) break; // broken stream
  599. stream_pos += std::clamp(info.frame_bytes, 0, mpt::saturate_cast<int>(bytes_left));
  600. bytes_left -= std::clamp(info.frame_bytes, 0, mpt::saturate_cast<int>(bytes_left));
  601. if(frame_samples > 0)
  602. {
  603. try
  604. {
  605. mpt::append(raw_sample_data, sample_buf.data(), sample_buf.data() + frame_samples * channels);
  606. } catch(mpt::out_of_memory e)
  607. {
  608. mpt::delete_out_of_memory(e);
  609. break;
  610. }
  611. }
  612. }
  613. if((raw_sample_data.size() / channels) > MAX_SAMPLE_LENGTH)
  614. {
  615. break;
  616. }
  617. } while(bytes_left > 0);
  618. if(rate == 0 || channels == 0 || raw_sample_data.empty())
  619. {
  620. return false;
  621. }
  622. if((raw_sample_data.size() / channels) > MAX_SAMPLE_LENGTH)
  623. {
  624. return false;
  625. }
  626. DestroySampleThreadsafe(sample);
  627. if(!mo3Decode)
  628. {
  629. m_szNames[sample] = "";
  630. Samples[sample].Initialize();
  631. Samples[sample].nC5Speed = rate;
  632. }
  633. Samples[sample].nLength = mpt::saturate_cast<SmpLength>(raw_sample_data.size() / channels);
  634. Samples[sample].uFlags.set(CHN_16BIT);
  635. Samples[sample].uFlags.set(CHN_STEREO, channels == 2);
  636. Samples[sample].AllocateSample();
  637. if(Samples[sample].HasSampleData())
  638. {
  639. std::copy(raw_sample_data.begin(), raw_sample_data.end(), Samples[sample].sample16());
  640. }
  641. if(!mo3Decode)
  642. {
  643. Samples[sample].Convert(MOD_TYPE_IT, GetType());
  644. Samples[sample].PrecomputeLoops(*this, false);
  645. }
  646. return Samples[sample].HasSampleData();
  647. #else
  648. MPT_UNREFERENCED_PARAMETER(sample);
  649. MPT_UNREFERENCED_PARAMETER(file);
  650. MPT_UNREFERENCED_PARAMETER(raw);
  651. MPT_UNREFERENCED_PARAMETER(mo3Decode);
  652. #endif // MPT_WITH_MPG123 || MPT_WITH_MINIMP3
  653. return false;
  654. }
  655. OPENMPT_NAMESPACE_END