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