History

Big code change, read description

1) Don't calculate big LUTs for mixer deltas on init (was just a waste of RAM) 2) The mixer now uses a 64-bit division to calculate max number of safe samples to mix (branchless), instead of using a big hackish LUT for DIV->MUL 3) Module and sample loaders have been refactored so that it's much simpler to write new loaders (or modify the old ones) 4) Added support for importing DIGI Booster (non-Pro) modules 5) Added support for importing 8-channel StarTrekker modules 6) Updated help text 7) Some more minor code change 8) Updated the Visual Studio project and make scripts to include the new loaders * Sorry for not making individual commits for all the changes, but at this point it was simply too difficult for me to do so!

Olav Sørensen committed 5 years ago

Commit 12f28da1 parent 2c1dbb237 files · +6956 −6838Browse files

Showing the changes to src/ft2_sample_loader.c (1 of 37 files). Show all

Unified · Split

src/ft2_sample_loader.c+125−2071
@@ -16,1885 +16,124 @@ · 15 unmodified lines
1616 #include "ft2_diskop.h"
1717 #include "ft2_structs.h"
1818
19−/* All of these routines were written from scratch and were not present
20−** in original FT2.
21−*/
19+bool loadAIFF(FILE *f, uint32_t filesize);
20+bool loadIFF(FILE *f, uint32_t filesize);
21+bool loadRAW(FILE *f, uint32_t filesize);
22+bool loadWAV(FILE *f, uint32_t filesize);
2223
2324 enum
2425 {
25− STEREO_SAMPLE_READ_LEFT = 1,
26− STEREO_SAMPLE_READ_RIGHT = 2,
27− STEREO_SAMPLE_CONVERT = 3,
28−
29− WAV_FORMAT_PCM = 0x0001,
30− WAV_FORMAT_IEEE_FLOAT = 0x0003
31−};
32−
33−static volatile bool sampleIsLoading;
34−static bool loadAsInstrFlag;
35−static uint8_t sampleSlot;
36−static int16_t stereoSampleLoadMode;
37−static SDL_Thread *thread;
38−
39−static void normalize32bitSigned(int32_t *sampleData, uint32_t sampleLength);
40−static void normalize16bitFloatSigned(float *fSampleData, uint32_t sampleLength);
41−static void normalize64bitDoubleSigned(double *dSampleData, uint32_t sampleLength);
42−
43−void freeTmpSample(sampleTyp *s)
44−{
45− if (s->origPek != NULL)
46− {
47− free(s->origPek);
48− s->origPek = NULL;
49− s->pek = NULL;
50− }
51−
52− memset(s, 0, sizeof (sampleTyp));
53−}
54−
55−void removeSampleIsLoadingFlag(void)
56−{
57− sampleIsLoading = false;
58−}
59−
60−static int32_t getAIFFRate(uint8_t *in)
61−{
62− int32_t exp = (int32_t)(((in[0] & 0x7F) << 8) | in[1]);
63− uint32_t lo = (in[2] << 24) | (in[3] << 16) | (in[4] << 8) | in[5];
64− uint32_t hi = (in[6] << 24) | (in[7] << 16) | (in[8] << 8) | in[9];
65−
66− if (exp == 0 && lo == 0 && hi == 0)
67− return 0;
68−
69− exp -= 16383;
70−
71− double dOut = ldexp(lo, -31 + exp) + ldexp(hi, -63 + exp);
72− return (int32_t)(dOut + 0.5); // rounded
73−}
74−
75−static bool aiffIsStereo(FILE *f) // only ran on files that are confirmed to be AIFFs
76−{
77− uint16_t numChannels;
78− uint32_t chunkID, chunkSize;
79−
80− uint32_t oldPos = ftell(f);
81−
82− fseek(f, 0, SEEK_END);
83− int32_t filesize = ftell(f);
84−
85− if (filesize < 12)
86− {
87− fseek(f, oldPos, SEEK_SET);
88− return false;
89− }
90−
91− fseek(f, 12, SEEK_SET);
92−
93− uint32_t commPtr = 0;
94− uint32_t commLen = 0;
95−
96− int32_t bytesRead = 0;
97− while (!feof(f) && bytesRead < filesize-12)
98− {
99− fread(&chunkID, 4, 1, f); chunkID = SWAP32(chunkID); if (feof(f)) break;
100− fread(&chunkSize, 4, 1, f); chunkSize = SWAP32(chunkSize); if (feof(f)) break;
101−
102− int32_t endOfChunk = (ftell(f) + chunkSize) + (chunkSize & 1);
103− switch (chunkID)
104− {
105− case 0x434F4D4D: // "COMM"
106− {
107− commPtr = ftell(f);
108− commLen = chunkSize;
109− }
110− break;
111−
112− default: break;
113− }
114−
115− bytesRead += (chunkSize + (chunkSize & 1));
116− fseek(f, endOfChunk, SEEK_SET);
117− }
118−
119− if (commPtr == 0 || commLen < 2)
120− {
121− fseek(f, oldPos, SEEK_SET);
122− return false;
123− }
124−
125− fseek(f, commPtr, SEEK_SET);
126− fread(&numChannels, 2, 1, f); numChannels = SWAP16(numChannels);
127− fseek(f, oldPos, SEEK_SET);
128−
129− return (numChannels == 2);
130−}
131−
132−static bool wavIsStereo(FILE *f) // only ran on files that are confirmed to be WAVs
133−{
134− uint16_t numChannels;
135− uint32_t chunkID, chunkSize;
136−
137− uint32_t oldPos = ftell(f);
138−
139− fseek(f, 0, SEEK_END);
140− int32_t filesize = ftell(f);
141−
142− if (filesize < 12)
143− {
144− fseek(f, oldPos, SEEK_SET);
145− return false;
146− }
147−
148− fseek(f, 12, SEEK_SET);
149−
150− uint32_t fmtPtr = 0;
151− uint32_t fmtLen = 0;
152−
153− int32_t bytesRead = 0;
154− while (!feof(f) && bytesRead < filesize-12)
155− {
156− fread(&chunkID, 4, 1, f); if (feof(f)) break;
157− fread(&chunkSize, 4, 1, f); if (feof(f)) break;
158−
159− int32_t endOfChunk = (ftell(f) + chunkSize) + (chunkSize & 1);
160− switch (chunkID)
161− {
162− case 0x20746D66: // "fmt "
163− {
164− fmtPtr = ftell(f);
165− fmtLen = chunkSize;
166− }
167− break;
168−
169− default: break;
170− }
171−
172− bytesRead += (chunkSize + (chunkSize & 1));
173− fseek(f, endOfChunk, SEEK_SET);
174− }
175−
176− if (fmtPtr == 0 || fmtLen < 4)
177− {
178− fseek(f, oldPos, SEEK_SET);
179− return false;
180− }
181−
182− fseek(f, fmtPtr + 2, SEEK_SET);
183− fread(&numChannels, 2, 1, f);
184− fseek(f, oldPos, SEEK_SET);
185−
186− return (numChannels == 2);
187−}
188−
189−static int32_t SDLCALL loadAIFFSample(void *ptr)
190−{
191− char compType[4];
192− int8_t *audioDataS8;
193− uint8_t sampleRateBytes[10], *audioDataU8;
194− int16_t *audioDataS16, *audioDataS16_2, smp16;
195− uint16_t numChannels, bitDepth;
196− int32_t j, smp32, *audioDataS32;
197− uint32_t i, blockName, blockSize;
198− uint32_t offset, len32;
199− int64_t smp64;
200− sampleTyp tmpSmp;
201−
202− // this is important for the "goto" on load error
203− FILE *f = NULL;
204− memset(&tmpSmp, 0, sizeof (tmpSmp));
205−
206− if (editor.tmpFilenameU == NULL)
207− {
208− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
209− goto aiffLoadError;
210− }
211−
212− UNICHAR *filename = editor.tmpFilenameU;
213−
214− f = UNICHAR_FOPEN(filename, "rb");
215− if (f == NULL)
216− {
217− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
218− goto aiffLoadError;
219− }
220−
221− fseek(f, 0, SEEK_END);
222− int32_t filesize = ftell(f);
223− if (filesize < 12)
224− {
225− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
226− goto aiffLoadError;
227− }
228−
229− // handle chunks
230−
231− uint32_t commPtr = 0;
232− uint32_t commLen = 0;
233− uint32_t ssndPtr = 0;
234− uint32_t ssndLen = 0;
235−
236− fseek(f, 12, SEEK_SET);
237− while (!feof(f) && ftell(f) < filesize-12)
238− {
239− fread(&blockName, 4, 1, f); if (feof(f)) break;
240− fread(&blockSize, 4, 1, f); if (feof(f)) break;
241−
242− blockName = SWAP32(blockName);
243− blockSize = SWAP32(blockSize);
244−
245− switch (blockName)
246− {
247− case 0x434F4D4D: // "COMM"
248− {
249− commPtr = ftell(f);
250− commLen = blockSize;
251− }
252− break;
253−
254− case 0x53534E44: // "SSND"
255− {
256− ssndPtr = ftell(f);
257− ssndLen = blockSize;
258− }
259− break;
260−
261− default: break;
262− }
263−
264− fseek(f, blockSize + (blockSize & 1), SEEK_CUR);
265− }
266−
267− if (commPtr == 0 || commLen < 18 || ssndPtr == 0)
268− {
269− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
270− goto aiffLoadError;
271− }
272−
273− // kludge for some really strange AIFFs
274− if (ssndLen == 0)
275− ssndLen = filesize - ssndPtr;
276−
277− if (ssndPtr+ssndLen > (uint32_t)filesize)
278− ssndLen = filesize - ssndPtr;
279−
280− fseek(f, commPtr, SEEK_SET);
281− fread(&numChannels, 2, 1, f); numChannels = SWAP16(numChannels);
282− fseek(f, 4, SEEK_CUR);
283− fread(&bitDepth, 2, 1, f); bitDepth = SWAP16(bitDepth);
284− fread(sampleRateBytes, 1, 10, f);
285−
286− if (numChannels != 1 && numChannels != 2)
287− {
288− okBoxThreadSafe(0, "System message", "Error loading sample: Unsupported amounts of channels!");
289− goto aiffLoadError;
290− }
291−
292− if (bitDepth != 8 && bitDepth != 16 && bitDepth != 24 && bitDepth != 32)
293− {
294− okBoxThreadSafe(0, "System message", "Error loading sample: Unsupported bitdepth!");
295− goto aiffLoadError;
296− }
297−
298− // read compression type (if present)
299− if (commLen > 18)
300− {
301− fread(&compType, 1, 4, f);
302− if (memcmp(compType, "NONE", 4))
303− {
304− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
305− goto aiffLoadError;
306− }
307− }
308−
309− uint32_t sampleRate = getAIFFRate(sampleRateBytes);
310−
311− // sample data chunk
312−
313− fseek(f, ssndPtr, SEEK_SET);
314−
315− fread(&offset, 4, 1, f);
316− if (offset > 0)
317− {
318− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
319− goto aiffLoadError;
320− }
321−
322− fseek(f, 4, SEEK_CUR);
323−
324− ssndLen -= 8; // don't include offset and blockSize datas
325−
326− uint32_t sampleLength = ssndLen;
327− if (sampleLength > MAX_SAMPLE_LEN)
328− sampleLength = MAX_SAMPLE_LEN;
329−
330− freeTmpSample(&tmpSmp);
331−
332− // read sample data
333−
334− if (bitDepth == 8)
335− {
336− // 8-BIT SIGNED PCM
337−
338− tmpSmp.origPek = (int8_t *)malloc(sampleLength + LOOP_FIX_LEN);
339− if (tmpSmp.origPek == NULL)
340− {
341− okBoxThreadSafe(0, "System message", "Not enough memory!");
342− goto aiffLoadError;
343− }
344−
345− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
346−
347− if (fread(tmpSmp.pek, sampleLength, 1, f) != 1)
348− {
349− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
350− goto aiffLoadError;
351− }
352−
353− audioDataS8 = (int8_t *)tmpSmp.pek;
354−
355− // stereo conversion
356− if (numChannels == 2)
357− {
358− sampleLength /= 2;
359−
360− switch (stereoSampleLoadMode)
361− {
362− case STEREO_SAMPLE_READ_LEFT:
363− {
364− for (i = 1; i < sampleLength; i++)
365− audioDataS8[i] = audioDataS8[(i * 2) + 0];
366− }
367− break;
368−
369− case STEREO_SAMPLE_READ_RIGHT:
370− {
371− len32 = sampleLength - 1;
372− for (i = 0; i < len32; i++)
373− audioDataS8[i] = audioDataS8[(i * 2) + 1];
374−
375− audioDataS8[i] = 0;
376− }
377− break;
378−
379− default:
380− case STEREO_SAMPLE_CONVERT:
381− {
382− len32 = sampleLength - 1;
383− for (i = 0; i < len32; i++)
384− {
385− smp16 = (audioDataS8[(i * 2) + 0] + audioDataS8[(i * 2) + 1]) >> 1;
386− audioDataS8[i] = (int8_t)smp16;
387− }
388−
389− audioDataS8[i] = 0;
390− }
391− break;
392− }
393− }
394− }
395− else if (bitDepth == 16)
396− {
397− // 16-BIT SIGNED PCM
398−
399− sampleLength /= 2;
400−
401− tmpSmp.origPek = (int8_t *)malloc((sampleLength * 2) + LOOP_FIX_LEN);
402− if (tmpSmp.origPek == NULL)
403− {
404− okBoxThreadSafe(0, "System message", "Not enough memory!");
405− goto aiffLoadError;
406− }
407−
408− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
409−
410− if (fread(tmpSmp.pek, sampleLength, 2, f) != 2)
411− {
412− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
413− goto aiffLoadError;
414− }
415−
416− // fix endianness
417− audioDataS16 = (int16_t *)tmpSmp.pek;
418− for (i = 0; i < sampleLength; i++)
419− audioDataS16[i] = SWAP16(audioDataS16[i]);
420−
421− // stereo conversion
422− if (numChannels == 2)
423− {
424− sampleLength /= 2;
425−
426− switch (stereoSampleLoadMode)
427− {
428− case STEREO_SAMPLE_READ_LEFT:
429− {
430− for (i = 1; i < sampleLength; i++)
431− audioDataS16[i] = audioDataS16[(i * 2) + 0];
432− }
433− break;
434−
435− case STEREO_SAMPLE_READ_RIGHT:
436− {
437− len32 = sampleLength - 1;
438− for (i = 0; i < len32; i++)
439− audioDataS16[i] = audioDataS16[(i * 2) + 1];
440−
441− audioDataS16[i] = 0;
442− }
443− break;
444−
445− default:
446− case STEREO_SAMPLE_CONVERT:
447− {
448− len32 = sampleLength - 1;
449− for (i = 0; i < len32; i++)
450− {
451− smp32 = (audioDataS16[(i * 2) + 0] + audioDataS16[(i * 2) + 1]) >> 1;
452− audioDataS16[i] = (int16_t)smp32;
453− }
454−
455− audioDataS16[i] = 0;
456− }
457− break;
458− }
459− }
460−
461− sampleLength *= 2;
462− tmpSmp.typ |= 16;
463− }
464− else if (bitDepth == 24)
465− {
466− // 24-BIT SIGNED PCM
467−
468− sampleLength /= 3;
469−
470− tmpSmp.origPek = (int8_t *)malloc(((sampleLength * 4) * 2) + LOOP_FIX_LEN);
471− if (tmpSmp.origPek == NULL)
472− {
473− okBoxThreadSafe(0, "System message", "Not enough memory!");
474− goto aiffLoadError;
475− }
476−
477− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
478−
479− if (fread(&tmpSmp.pek[sampleLength], sampleLength, 3, f) != 3)
480− {
481− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
482− goto aiffLoadError;
483− }
484−
485− audioDataS32 = (int32_t *)tmpSmp.pek;
486−
487− // convert to 32-bit
488− audioDataU8 = (uint8_t *)tmpSmp.pek + sampleLength;
489− for (i = 0; i < sampleLength; i++)
490− {
491− audioDataS32[i] = (audioDataU8[0] << 24) | (audioDataU8[1] << 16) | (audioDataU8[2] << 8);
492− audioDataU8 += 3;
493− }
494−
495− // stereo conversion
496− if (numChannels == 2)
497− {
498− sampleLength /= 2;
499−
500− switch (stereoSampleLoadMode)
501− {
502− case STEREO_SAMPLE_READ_LEFT:
503− {
504− for (i = 1; i < sampleLength; i++)
505− audioDataS32[i] = audioDataS32[(i * 2) + 0];
506− }
507− break;
508−
509− case STEREO_SAMPLE_READ_RIGHT:
510− {
511− len32 = sampleLength - 1;
512− for (i = 0; i < len32; i++)
513− audioDataS32[i] = audioDataS32[(i * 2) + 1];
514−
515− audioDataS32[i] = 0;
516− }
517− break;
518−
519− default:
520− case STEREO_SAMPLE_CONVERT:
521− {
522− len32 = sampleLength - 1;
523− for (i = 0; i < len32; i++)
524− {
525− smp64 = audioDataS32[(i * 2) + 0];
526− smp64 += audioDataS32[(i * 2) + 1];
527− smp64 >>= 1;
528−
529− audioDataS32[i] = (int32_t)smp64;
530− }
531−
532− audioDataS32[i] = 0;
533− }
534− break;
535− }
536− }
537−
538− normalize32bitSigned(audioDataS32, sampleLength);
539−
540− // downscale to 16-bit (ultra fast method!)
541−
542− audioDataS16 = (int16_t *)tmpSmp.pek;
543− audioDataS16_2 = (int16_t *)tmpSmp.pek + 1;
544−
545− for (i = 0; i < sampleLength; i++)
546− {
547− audioDataS16[i] = audioDataS16_2[i];
548− audioDataS16_2++;
549− }
550−
551− sampleLength *= 2;
552− tmpSmp.typ |= 16;
553− }
554− else if (bitDepth == 32)
555− {
556− // 32-BIT SIGNED PCM
557−
558− sampleLength /= 4;
559−
560− tmpSmp.origPek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN);
561− if (tmpSmp.origPek == NULL)
562− {
563− okBoxThreadSafe(0, "System message", "Not enough memory!");
564− goto aiffLoadError;
565− }
566−
567− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
568−
569− if (fread(tmpSmp.pek, sampleLength, 4, f) != 4)
570− {
571− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
572− goto aiffLoadError;
573− }
574−
575− // fix endianness
576− audioDataS32 = (int32_t *)tmpSmp.pek;
577− for (i = 0; i < sampleLength; i++)
578− audioDataS32[i] = SWAP32(audioDataS32[i]);
579−
580− // stereo conversion
581− if (numChannels == 2)
582− {
583− sampleLength /= 2;
584−
585− switch (stereoSampleLoadMode)
586− {
587− case STEREO_SAMPLE_READ_LEFT:
588− {
589− for (i = 1; i < sampleLength; i++)
590− audioDataS32[i] = audioDataS32[(i * 2) + 0];
591− }
592− break;
593−
594− case STEREO_SAMPLE_READ_RIGHT:
595− {
596− len32 = sampleLength - 1;
597− for (i = 0; i < len32; i++)
598− audioDataS32[i] = audioDataS32[(i * 2) + 1];
599−
600− audioDataS32[i] = 0;
601− }
602− break;
603−
604− default:
605− case STEREO_SAMPLE_CONVERT:
606− {
607− len32 = sampleLength - 1;
608− for (i = 0; i < len32; i++)
609− {
610− smp64 = audioDataS32[(i * 2) + 0];
611− smp64 += audioDataS32[(i * 2) + 1];
612− smp64 >>= 1;
613−
614− audioDataS32[i] = (int32_t)smp64;
615− }
616−
617− audioDataS32[i] = 0;
618− }
619− break;
620− }
621− }
622−
623− normalize32bitSigned(audioDataS32, sampleLength);
624−
625− // downscale to 16-bit (ultra fast method!)
626−
627− audioDataS16 = (int16_t *)tmpSmp.pek;
628− audioDataS16_2 = (int16_t *)tmpSmp.pek + 1;
629−
630− for (i = 0; i < sampleLength; i++)
631− {
632− audioDataS16[i] = audioDataS16_2[i];
633− audioDataS16_2++;
634− }
635−
636− sampleLength *= 2;
637− tmpSmp.typ |= 16;
638− }
639−
640− // adjust memory needed
641− int8_t *newPtr = (int8_t *)realloc(tmpSmp.origPek, sampleLength + LOOP_FIX_LEN);
642− if (newPtr != NULL)
643− {
644− tmpSmp.origPek = newPtr;
645− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
646− }
647−
648− // set sample attributes
649− tmpSmp.len = sampleLength;
650− tmpSmp.vol = 64;
651− tmpSmp.pan = 128;
652−
653− tuneSample(&tmpSmp, sampleRate, audio.linearPeriodsFlag);
654−
655− // set sample name
656− char *tmpFilename = unicharToCp437(filename, true);
657− if (tmpFilename != NULL)
658− {
659− j = (int32_t)strlen(tmpFilename);
660− while (j--)
661− {
662− if (tmpFilename[j] == DIR_DELIMITER)
663− break;
664− }
665−
666− char *tmpPtr = tmpFilename;
667− if (j > 0)
668− tmpPtr += j + 1;
669−
670− sanitizeFilename(tmpPtr);
671−
672− uint32_t filenameLen = (uint32_t)strlen(tmpPtr);
673− for (i = 0; i < 22; i++)
674− {
675− if (i < filenameLen)
676− tmpSmp.name[i] = tmpPtr[i];
677− else
678− tmpSmp.name[i] = '\0';
679− }
680−
681− free(tmpFilename);
682− }
683−
684− fclose(f);
685−
686− lockMixerCallback();
687− if (loadAsInstrFlag) // if loaded in instrument mode
688− {
689− freeInstr(editor.curInstr);
690− memset(song.instrName[editor.curInstr], 0, 23);
691− }
692−
693− if (instr[editor.curInstr] == NULL)
694− allocateInstr(editor.curInstr);
695−
696− if (instr[editor.curInstr] != NULL)
697− {
698− sampleTyp *s = &instr[editor.curInstr]->samp[sampleSlot];
699−
700− freeSample(editor.curInstr, sampleSlot);
701− memcpy(s, &tmpSmp, sizeof (sampleTyp));
702− fixSample(s);
703− }
704− else
705− {
706− okBoxThreadSafe(0, "System message", "Not enough memory!");
707− goto aiffLoadError;
708− }
709− unlockMixerCallback();
710−
711− fixSampleName(editor.curInstr);
712− setSongModifiedFlag();
713− stereoSampleLoadMode = -1;
714−
715− // also sets mouse busy to false when done
716− editor.updateCurSmp = true;
717−
718− return true;
719−
720−aiffLoadError:
721− if (f != NULL) fclose(f);
722− if (tmpSmp.origPek != NULL) free(tmpSmp.origPek);
723−
724− stereoSampleLoadMode = -1;
725− sampleIsLoading = false;
726−
727− return false;
728−
729− (void)ptr;
730−}
731−
732−static int32_t SDLCALL loadIFFSample(void *ptr)
733−{
734− char hdr[4+1];
735− uint8_t i;
736− int32_t j;
737− uint32_t blockName, blockSize;
738− sampleTyp tmpSmp;
739−
740− // this is important for the "goto" on load error
741− FILE *f = NULL;
742− memset(&tmpSmp, 0, sizeof (tmpSmp));
743−
744− if (editor.tmpFilenameU == NULL)
745− {
746− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
747− goto iffLoadError;
748− }
749−
750− UNICHAR *filename = editor.tmpFilenameU;
751−
752− f = UNICHAR_FOPEN(filename, "rb");
753− if (f == NULL)
754− {
755− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
756− goto iffLoadError;
757− }
758−
759− fseek(f, 0, SEEK_END);
760− int32_t filesize = ftell(f);
761− if (filesize < 12)
762− {
763− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
764− goto iffLoadError;
765− }
766−
767− fseek(f, 8, SEEK_SET);
768− fread(hdr, 1, 4, f);
769− hdr[4] = '\0';
770− bool is16Bit = !strncmp(hdr, "16SV", 4);
771−
772− uint32_t sampleLength = 0;
773− uint32_t sampleVol = 64;
774− uint32_t sampleLoopStart = 0;
775− uint32_t sampleLoopLength = 0;
776− uint16_t sampleRate = 16726;
777−
778− uint32_t vhdrPtr = 0;
779− uint32_t vhdrLen = 0;
780− uint32_t bodyPtr = 0;
781− uint32_t bodyLen = 0;
782− uint32_t namePtr = 0;
783− uint32_t nameLen = 0;
784−
785− fseek(f, 12, SEEK_SET);
786− while (!feof(f) && ftell(f) < filesize-12)
787− {
788− fread(&blockName, 4, 1, f); if (feof(f)) break;
789− fread(&blockSize, 4, 1, f); if (feof(f)) break;
790−
791− blockName = SWAP32(blockName);
792− blockSize = SWAP32(blockSize);
793−
794− switch (blockName)
795− {
796− case 0x56484452: // VHDR
797− {
798− vhdrPtr = ftell(f);
799− vhdrLen = blockSize;
800− }
801− break;
802−
803− case 0x4E414D45: // NAME
804− {
805− namePtr = ftell(f);
806− nameLen = blockSize;
807− }
808− break;
809−
810− case 0x424F4459: // BODY
811− {
812− bodyPtr = ftell(f);
813− bodyLen = blockSize;
814− }
815− break;
816−
817− default: break;
818− }
819−
820− fseek(f, blockSize + (blockSize & 1), SEEK_CUR);
821− }
822−
823− if (vhdrPtr == 0 || vhdrLen < 20 || bodyPtr == 0)
824− {
825− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
826− goto iffLoadError;
827− }
828−
829− // kludge for some really strange IFFs
830− if (bodyLen == 0)
831− bodyLen = filesize - bodyPtr;
832−
833− if (bodyPtr+bodyLen > (uint32_t)filesize)
834− bodyLen = filesize - bodyPtr;
835−
836− fseek(f, vhdrPtr, SEEK_SET);
837− fread(&sampleLoopStart, 4, 1, f); sampleLoopStart = SWAP32(sampleLoopStart);
838− fread(&sampleLoopLength, 4, 1, f); sampleLoopLength = SWAP32(sampleLoopLength);
839− fseek(f, 4, SEEK_CUR);
840− fread(&sampleRate, 2, 1, f); sampleRate = SWAP16(sampleRate);
841− fseek(f, 1, SEEK_CUR);
842−
843− if (fgetc(f) != 0) // sample type
844− {
845− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported!");
846− goto iffLoadError;
847− }
848−
849− fread(&sampleVol, 4, 1, f); sampleVol = SWAP32(sampleVol);
850− if (sampleVol > 65535)
851− sampleVol = 65535;
852−
853− sampleVol = (int32_t)((sampleVol / 1024.0) + 0.5);
854− if (sampleVol > 64)
855− sampleVol = 64;
856−
857− sampleLength = bodyLen;
858− if (sampleLength > MAX_SAMPLE_LEN)
859− sampleLength = MAX_SAMPLE_LEN;
860−
861− if (sampleLoopStart >= MAX_SAMPLE_LEN || sampleLoopLength > MAX_SAMPLE_LEN)
862− {
863− sampleLoopStart = 0;
864− sampleLoopLength = 0;
865− }
866−
867− if (sampleLoopStart+sampleLoopLength > sampleLength)
868− {
869− sampleLoopStart = 0;
870− sampleLoopLength = 0;
871− }
872−
873− if (sampleLoopStart > sampleLength-2)
874− {
875− sampleLoopStart = 0;
876− sampleLoopLength = 0;
877− }
878−
879− tmpSmp.pan = 128;
880− tmpSmp.vol = 64;
881−
882− tmpSmp.origPek = (int8_t *)malloc(sampleLength + LOOP_FIX_LEN);
883− if (tmpSmp.origPek == NULL)
884− {
885− okBoxThreadSafe(0, "System message", "Not enough memory!");
886− goto iffLoadError;
887− }
888−
889− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
890−
891− fseek(f, bodyPtr, SEEK_SET);
892− if (fread(tmpSmp.pek, sampleLength, 1, f) != 1)
893− {
894− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
895− goto iffLoadError;
896− }
897−
898− // set sample attributes
899− tmpSmp.len = sampleLength;
900−
901− if (sampleLoopLength > 2)
902− {
903− tmpSmp.repS = sampleLoopStart;
904− tmpSmp.repL = sampleLoopLength;
905− tmpSmp.typ |= 1;
906− }
907−
908− if (is16Bit)
909− {
910− tmpSmp.len &= 0xFFFFFFFE;
911− tmpSmp.repS &= 0xFFFFFFFE;
912− tmpSmp.repL &= 0xFFFFFFFE;
913− tmpSmp.typ |= 16;
914− }
915−
916− tmpSmp.vol = (uint8_t)sampleVol;
917− tmpSmp.pan = 128;
918−
919− tuneSample(&tmpSmp, sampleRate, audio.linearPeriodsFlag);
920−
921− // set name
922− if (namePtr != 0 && nameLen > 0)
923− {
924− fseek(f, namePtr, SEEK_SET);
925− if (nameLen > 21)
926− {
927− tmpSmp.name[21] = '\0';
928− fread(tmpSmp.name, 1, 21, f);
929− }
930− else
931− {
932− memset(tmpSmp.name, 0, 22);
933− fread(tmpSmp.name, 1, nameLen, f);
934− }
935− }
936− else
937− {
938− // set sample name from filename if we didn't load name from .wav
939− char *tmpFilename = unicharToCp437(filename, true);
940− if (tmpFilename != NULL)
941− {
942− j = (int32_t)strlen(tmpFilename);
943− while (j--)
944− {
945− if (tmpFilename[j] == DIR_DELIMITER)
946− break;
947− }
948−
949− char *tmpPtr = tmpFilename;
950− if (j > 0)
951− tmpPtr += j + 1;
952−
953− sanitizeFilename(tmpPtr);
954−
955− uint32_t filenameLen = (uint32_t)strlen(tmpPtr);
956− for (i = 0; i < 22; i++)
957− {
958− if (i < filenameLen)
959− tmpSmp.name[i] = tmpPtr[i];
960− else
961− tmpSmp.name[i] = '\0';
962− }
963−
964− free(tmpFilename);
965− }
966− }
967−
968− fclose(f);
969−
970− lockMixerCallback();
971− if (loadAsInstrFlag) // if loaded in instrument mode
972− {
973− freeInstr(editor.curInstr);
974− memset(song.instrName[editor.curInstr], 0, 23);
975− }
976−
977− if (instr[editor.curInstr] == NULL)
978− allocateInstr(editor.curInstr);
979−
980− if (instr[editor.curInstr] != NULL)
981− {
982− sampleTyp *s = &instr[editor.curInstr]->samp[sampleSlot];
983−
984− freeSample(editor.curInstr, sampleSlot);
985− memcpy(s, &tmpSmp, sizeof (sampleTyp));
986− fixSample(s);
987− }
988− else
989− {
990− okBoxThreadSafe(0, "System message", "Not enough memory!");
991− goto iffLoadError;
992− }
993− unlockMixerCallback();
994−
995− fixSampleName(editor.curInstr);
996− setSongModifiedFlag();
997− stereoSampleLoadMode = -1;
998−
999− // also sets mouse busy to false when done
1000− editor.updateCurSmp = true;
1001−
1002− return true;
1003−
1004−iffLoadError:
1005− if (f != NULL) fclose(f);
1006− if (tmpSmp.origPek != NULL) free(tmpSmp.origPek);
1007−
1008− stereoSampleLoadMode = -1;
1009− sampleIsLoading = false;
1010−
1011− return false;
1012−
1013− (void)ptr;
1014−}
1015−
1016−static int32_t SDLCALL loadRawSample(void *ptr)
1017−{
1018− int32_t j;
1019− uint32_t i;
1020− sampleTyp tmpSmp;
1021−
1022− // this is important for the "goto" on load error
1023− FILE *f = NULL;
1024− memset(&tmpSmp, 0, sizeof (tmpSmp));
1025−
1026− if (editor.tmpFilenameU == NULL)
1027− {
1028− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1029− goto rawLoadError;
1030− }
1031−
1032− UNICHAR *filename = editor.tmpFilenameU;
1033−
1034− f = UNICHAR_FOPEN(filename, "rb");
1035− if (f == NULL)
1036− {
1037− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1038− goto rawLoadError;
1039− }
1040−
1041− fseek(f, 0, SEEK_END);
1042− uint32_t filesize = ftell(f);
1043− rewind(f);
1044−
1045− if (filesize > MAX_SAMPLE_LEN)
1046− filesize = MAX_SAMPLE_LEN;
1047−
1048− if (filesize == 0)
1049− {
1050− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
1051− goto rawLoadError;
1052− }
1053−
1054− tmpSmp.pan = 128;
1055− tmpSmp.vol = 64;
1056−
1057− tmpSmp.origPek = (int8_t *)malloc(filesize + LOOP_FIX_LEN);
1058− if (tmpSmp.origPek == NULL)
1059− {
1060− okBoxThreadSafe(0, "System message", "Not enough memory!");
1061− goto rawLoadError;
1062− }
1063−
1064− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
1065−
1066− if (fread(tmpSmp.pek, filesize, 1, f) != 1)
1067− {
1068− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1069− goto rawLoadError;
1070− }
1071−
1072− fclose(f);
1073−
1074− char *tmpFilename = unicharToCp437(filename, true);
1075− if (tmpFilename != NULL)
1076− {
1077− j = (int32_t)strlen(tmpFilename);
1078− while (j--)
1079− {
1080− if (tmpFilename[j] == DIR_DELIMITER)
1081− break;
1082− }
1083−
1084− char *tmpPtr = tmpFilename;
1085− if (j > 0)
1086− tmpPtr += j + 1;
1087−
1088− sanitizeFilename(tmpPtr);
1089−
1090− uint32_t filenameLen = (uint32_t)strlen(tmpPtr);
1091− for (i = 0; i < 22; i++)
1092− {
1093− if (i < filenameLen)
1094− tmpSmp.name[i] = tmpPtr[i];
1095− else
1096− tmpSmp.name[i] = '\0';
1097− }
1098−
1099− free(tmpFilename);
1100− }
1101−
1102− tmpSmp.len = filesize;
1103− tmpSmp.vol = 64;
1104− tmpSmp.pan = 128;
1105−
1106− lockMixerCallback();
1107− if (loadAsInstrFlag) // if loaded in instrument mode
1108− {
1109− freeInstr(editor.curInstr);
1110− memset(song.instrName[editor.curInstr], 0, 23);
1111− }
1112−
1113− if (instr[editor.curInstr] == NULL)
1114− allocateInstr(editor.curInstr);
1115−
1116− if (instr[editor.curInstr] != NULL)
1117− {
1118− sampleTyp *s = &instr[editor.curInstr]->samp[sampleSlot];
1119−
1120− freeSample(editor.curInstr, sampleSlot);
1121− memcpy(s, &tmpSmp, sizeof (sampleTyp));
1122− fixSample(s);
1123− }
1124− else
1125− {
1126− okBoxThreadSafe(0, "System message", "Not enough memory!");
1127− goto rawLoadError;
1128− }
1129− unlockMixerCallback();
1130−
1131− fixSampleName(editor.curInstr);
1132− setSongModifiedFlag();
1133− stereoSampleLoadMode = -1;
1134−
1135− // also sets mouse busy to false when done
1136− editor.updateCurSmp = true;
1137−
1138− return true;
1139−
1140−rawLoadError:
1141− if (f != NULL) fclose(f);
1142− if (tmpSmp.origPek != NULL) free(tmpSmp.origPek);
1143−
1144− stereoSampleLoadMode = -1;
1145− sampleIsLoading = false;
1146−
1147− return false;
1148−
1149− (void)ptr;
1150−}
1151−
1152−static int32_t SDLCALL loadWAVSample(void *ptr)
1153−{
1154− char chr, *tmpFilename, *tmpPtr;
1155− int8_t *newPtr;
1156− uint8_t *audioDataU8;
1157− int16_t *audioDataS16, *audioDataS16_2, *ptr16;
1158− uint16_t audioFormat, numChannels, bitsPerSample, tempPan, tempVol;
1159− int32_t j, *audioDataS32, smp32;
1160− uint32_t filenameLen, i, sampleRate, chunkID, chunkSize, sampleLength, filesize;
1161− uint32_t numLoops, loopType, loopStart, loopEnd, bytesRead, endOfChunk, dataPtr, dataLen, fmtPtr;
1162− uint32_t fmtLen, inamPtr, inamLen, smplPtr, smplLen, xtraPtr, xtraLen, xtraFlags, len32;
1163− int64_t smp64;
1164− float *fAudioDataFloat;
1165− double *dAudioDataDouble;
1166− sampleTyp tmpSmp, *s;
1167−
1168− // this is important for the "goto" on load error
1169− FILE *f = NULL;
1170− memset(&tmpSmp, 0, sizeof (tmpSmp));
1171−
1172− // zero out chunk pointers and lengths
1173− fmtPtr = 0; fmtLen = 0;
1174− dataPtr = 0; dataLen = 0;
1175− inamPtr = 0; inamLen = 0;
1176− xtraPtr = 0; xtraLen = 0;
1177− smplPtr = 0; smplLen = 0;
1178−
1179− if (editor.tmpFilenameU == NULL)
1180− {
1181− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1182− goto wavLoadError;
1183− }
1184−
1185− UNICHAR *filename = editor.tmpFilenameU;
1186−
1187− f = UNICHAR_FOPEN(filename, "rb");
1188− if (f == NULL)
1189− {
1190− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1191− goto wavLoadError;
1192− }
1193−
1194− // get and check filesize
1195− fseek(f, 0, SEEK_END);
1196− filesize = ftell(f);
1197− if (filesize < 12)
1198− {
1199− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
1200− goto wavLoadError;
1201− }
1202−
1203− // look for wanted chunks and set up pointers + lengths
1204− fseek(f, 12, SEEK_SET);
1205−
1206− bytesRead = 0;
1207− while (!feof(f) && bytesRead < filesize-12)
1208− {
1209− fread(&chunkID, 4, 1, f); if (feof(f)) break;
1210− fread(&chunkSize, 4, 1, f); if (feof(f)) break;
1211−
1212− endOfChunk = (ftell(f) + chunkSize) + (chunkSize & 1);
1213− switch (chunkID)
1214− {
1215− case 0x20746D66: // "fmt "
1216− {
1217− fmtPtr = ftell(f);
1218− fmtLen = chunkSize;
1219− }
1220− break;
1221−
1222− case 0x61746164: // "data"
1223− {
1224− dataPtr = ftell(f);
1225− dataLen = chunkSize;
1226− }
1227− break;
1228−
1229− case 0x5453494C: // "LIST"
1230− {
1231− if (chunkSize >= 4)
1232− {
1233− fread(&chunkID, 4, 1, f);
1234− if (chunkID == 0x4F464E49) // "INFO"
1235− {
1236− bytesRead = 0;
1237− while (!feof(f) && bytesRead < chunkSize)
1238− {
1239− fread(&chunkID, 4, 1, f);
1240− fread(&chunkSize, 4, 1, f);
1241−
1242− switch (chunkID)
1243− {
1244− case 0x4D414E49: // "INAM"
1245− {
1246− inamPtr = ftell(f);
1247− inamLen = chunkSize;
1248− }
1249− break;
1250−
1251− default: break;
1252− }
1253−
1254− bytesRead += (chunkSize + (chunkSize & 1));
1255− }
1256− }
1257− }
1258− }
1259− break;
1260−
1261− case 0x61727478: // "xtra"
1262− {
1263− xtraPtr = ftell(f);
1264− xtraLen = chunkSize;
1265− }
1266− break;
1267−
1268− case 0x6C706D73: // "smpl"
1269− {
1270− smplPtr = ftell(f);
1271− smplLen = chunkSize;
1272− }
1273− break;
1274−
1275− default: break;
1276− }
1277−
1278− bytesRead += (chunkSize + (chunkSize & 1));
1279− fseek(f, endOfChunk, SEEK_SET);
1280− }
1281−
1282− // we need at least "fmt " and "data" - check if we found them sanely
1283− if ((fmtPtr == 0 || fmtLen < 16) || (dataPtr == 0 || dataLen == 0))
1284− {
1285− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
1286− goto wavLoadError;
1287− }
1288−
1289− // ---- READ "fmt " CHUNK ----
1290− fseek(f, fmtPtr, SEEK_SET);
1291− fread(&audioFormat, 2, 1, f);
1292− fread(&numChannels, 2, 1, f);
1293− fread(&sampleRate, 4, 1, f);
1294− fseek(f, 6, SEEK_CUR); // unneeded
1295− fread(&bitsPerSample, 2, 1, f);
1296− sampleLength = dataLen;
1297− // ---------------------------
1298−
1299− // test if the WAV is compatible with our loader
1300−
1301− if (sampleRate == 0 || sampleLength == 0 || sampleLength >= filesize)
1302− {
1303− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported or is invalid!");
1304− goto wavLoadError;
1305− }
1306−
1307− if (audioFormat != WAV_FORMAT_PCM && audioFormat != WAV_FORMAT_IEEE_FLOAT)
1308− {
1309− okBoxThreadSafe(0, "System message", "Error loading sample: The sample is not supported!");
1310− goto wavLoadError;
1311− }
1312−
1313− if (numChannels == 0 || numChannels > 2)
1314− {
1315− okBoxThreadSafe(0, "System message", "Error loading sample: Unsupported number of channels!");
1316− goto wavLoadError;
1317− }
1318−
1319− if (audioFormat == WAV_FORMAT_IEEE_FLOAT && bitsPerSample != 32 && bitsPerSample != 64)
1320− {
1321− okBoxThreadSafe(0, "System message", "Error loading sample: Unsupported bitdepth!");
1322− goto wavLoadError;
1323− }
1324−
1325− if (bitsPerSample != 8 && bitsPerSample != 16 && bitsPerSample != 24 && bitsPerSample != 32 && bitsPerSample != 64)
1326− {
1327− okBoxThreadSafe(0, "System message", "Error loading sample: Unsupported bitdepth!");
1328− goto wavLoadError;
1329− }
1330−
1331− // ---- READ SAMPLE DATA ----
1332− fseek(f, dataPtr, SEEK_SET);
1333−
1334− s = &instr[editor.curInstr]->samp[editor.curSmp];
1335− tmpSmp.pan = 128;
1336− tmpSmp.vol = 64;
1337−
1338− if (sampleLength > MAX_SAMPLE_LEN)
1339− sampleLength = MAX_SAMPLE_LEN;
1340−
1341− if (bitsPerSample == 8) // 8-BIT INTEGER SAMPLE
1342− {
1343− tmpSmp.origPek = (int8_t *)malloc(sampleLength + LOOP_FIX_LEN);
1344− if (tmpSmp.origPek == NULL)
1345− {
1346− okBoxThreadSafe(0, "System message", "Not enough memory!");
1347− goto wavLoadError;
1348− }
1349−
1350− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
1351−
1352− if (fread(tmpSmp.pek, sampleLength, 1, f) != 1)
1353− {
1354− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1355− goto wavLoadError;
1356− }
1357−
1358− audioDataU8 = (uint8_t *)tmpSmp.pek;
1359−
1360− // stereo conversion
1361− if (numChannels == 2)
1362− {
1363− sampleLength /= 2;
1364− switch (stereoSampleLoadMode)
1365− {
1366− case STEREO_SAMPLE_READ_LEFT:
1367− {
1368− // remove right channel data
1369− for (i = 1; i < sampleLength; i++)
1370− audioDataU8[i] = audioDataU8[(i * 2) + 0];
1371− }
1372− break;
1373−
1374− case STEREO_SAMPLE_READ_RIGHT:
1375− {
1376− // remove left channel data
1377− len32 = sampleLength - 1;
1378− for (i = 0; i < len32; i++)
1379− audioDataU8[i] = audioDataU8[(i * 2) + 1];
1380−
1381− audioDataU8[i] = 128;
1382− }
1383− break;
1384−
1385− default:
1386− case STEREO_SAMPLE_CONVERT:
1387− {
1388− // mix stereo to mono
1389− len32 = sampleLength - 1;
1390− for (i = 0; i < len32; i++)
1391− audioDataU8[i] = (audioDataU8[(i * 2) + 0] + audioDataU8[(i * 2) + 1]) >> 1;
1392−
1393− audioDataU8[i] = 128;
1394− }
1395− break;
1396− }
1397− }
1398−
1399− // convert from unsigned to signed
1400− for (i = 0; i < sampleLength; i++)
1401− tmpSmp.pek[i] ^= 0x80;
1402−
1403− tmpSmp.typ &= ~16; // 8-bit
1404− }
1405− else if (bitsPerSample == 16) // 16-BIT INTEGER SAMPLE
1406− {
1407− sampleLength /= 2;
1408−
1409− tmpSmp.origPek = (int8_t *)malloc((sampleLength * 2) + LOOP_FIX_LEN);
1410− if (tmpSmp.origPek == NULL)
1411− {
1412− okBoxThreadSafe(0, "System message", "Not enough memory!");
1413− goto wavLoadError;
1414− }
1415−
1416− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
1417−
1418− if (fread(tmpSmp.pek, sampleLength, 2, f) != 2)
1419− {
1420− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1421− goto wavLoadError;
1422− }
1423−
1424− audioDataS16 = (int16_t *)tmpSmp.pek;
1425−
1426− // stereo conversion
1427− if (numChannels == 2)
1428− {
1429− sampleLength /= 2;
1430−
1431− switch (stereoSampleLoadMode)
1432− {
1433− case STEREO_SAMPLE_READ_LEFT:
1434− {
1435− // remove right channel data
1436− for (i = 1; i < sampleLength; i++)
1437− audioDataS16[i] = audioDataS16[(i * 2) + 0];
1438− }
1439− break;
1440−
1441− case STEREO_SAMPLE_READ_RIGHT:
1442− {
1443− // remove left channel data
1444− len32 = sampleLength - 1;
1445− for (i = 0; i < len32; i++)
1446− audioDataS16[i] = audioDataS16[(i * 2) + 1];
1447−
1448− audioDataS16[i] = 0;
1449− }
1450− break;
1451−
1452− default:
1453− case STEREO_SAMPLE_CONVERT:
1454− {
1455− // mix stereo to mono
1456− len32 = sampleLength - 1;
1457− for (i = 0; i < len32; i++)
1458− {
1459− smp32 = audioDataS16[(i * 2) + 0] + audioDataS16[(i * 2) + 1];
1460− audioDataS16[i] = (int16_t)(smp32 >> 1);
1461− }
1462−
1463− audioDataS16[i] = 0;
1464− }
1465− break;
1466− }
1467− }
1468−
1469− sampleLength *= 2;
1470− tmpSmp.typ |= 16; // 16-bit
1471− }
1472− else if (bitsPerSample == 24) // 24-BIT INTEGER SAMPLE
1473− {
1474− sampleLength /= 3;
1475−
1476− tmpSmp.origPek = (int8_t *)malloc(((sampleLength * 4) * 2) + LOOP_FIX_LEN);
1477− if (tmpSmp.origPek == NULL)
1478− {
1479− okBoxThreadSafe(0, "System message", "Not enough memory!");
1480− goto wavLoadError;
1481− }
1482−
1483− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
1484−
1485− if (fread(&tmpSmp.pek[sampleLength], sampleLength, 3, f) != 3)
1486− {
1487− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1488− goto wavLoadError;
1489− }
1490−
1491− audioDataS32 = (int32_t *)tmpSmp.pek;
1492−
1493− // convert to 32-bit
1494− audioDataU8 = (uint8_t *)tmpSmp.pek + sampleLength;
1495− for (i = 0; i < sampleLength; i++)
1496− {
1497− audioDataS32[i] = (audioDataU8[2] << 24) | (audioDataU8[1] << 16) | (audioDataU8[0] << 8);
1498− audioDataU8 += 3;
1499− }
1500−
1501− // stereo conversion
1502− if (numChannels == 2)
1503− {
1504− sampleLength /= 2;
1505− switch (stereoSampleLoadMode)
1506− {
1507− case STEREO_SAMPLE_READ_LEFT:
1508− {
1509− // remove right channel data
1510− for (i = 1; i < sampleLength; i++)
1511− audioDataS32[i] = audioDataS32[(i * 2) + 0];
1512− }
1513− break;
1514−
1515− case STEREO_SAMPLE_READ_RIGHT:
1516− {
1517− // remove left channel data
1518− len32 = sampleLength - 1;
1519− for (i = 0; i < len32; i++)
1520− audioDataS32[i] = audioDataS32[(i * 2) + 1];
1521−
1522− audioDataS32[i] = 0;
1523− }
1524− break;
1525−
1526− default:
1527− case STEREO_SAMPLE_CONVERT:
1528− {
1529− // mix stereo to mono
1530− len32 = sampleLength - 1;
1531− for (i = 0; i < len32; i++)
1532− {
1533− smp64 = audioDataS32[(i * 2) + 0];
1534− smp64 += audioDataS32[(i * 2) + 1];
1535− smp64 >>= 1;
1536−
1537− audioDataS32[i] = (int32_t)smp64;
1538− }
1539−
1540− audioDataS32[i] = 0;
1541− }
1542− break;
1543− }
1544− }
1545−
1546− normalize32bitSigned(audioDataS32, sampleLength);
1547−
1548− // downscale to 16-bit (ultra fast method!)
1549−
1550− audioDataS16 = (int16_t *)tmpSmp.pek;
1551− audioDataS16_2 = (int16_t *)tmpSmp.pek + 1;
1552−
1553− for (i = 0; i < sampleLength; i++)
1554− {
1555− audioDataS16[i] = audioDataS16_2[i];
1556− audioDataS16_2++;
1557− }
1558−
1559− sampleLength *= 2;
1560− tmpSmp.typ |= 16; // 16-bit
1561− }
1562− else if (audioFormat == WAV_FORMAT_PCM && bitsPerSample == 32) // 32-BIT INTEGER SAMPLE
1563− {
1564− sampleLength /= 4;
1565−
1566− tmpSmp.origPek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN);
1567− if (tmpSmp.origPek == NULL)
1568− {
1569− okBoxThreadSafe(0, "System message", "Not enough memory!");
1570− goto wavLoadError;
1571− }
1572−
1573− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
1574−
1575− if (fread(tmpSmp.pek, sampleLength, 4, f) != 4)
1576− {
1577− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1578− goto wavLoadError;
1579− }
1580−
1581− audioDataS32 = (int32_t *)tmpSmp.pek;
1582−
1583− // stereo conversion
1584− if (numChannels == 2)
1585− {
1586− sampleLength /= 2;
1587− switch (stereoSampleLoadMode)
1588− {
1589− case STEREO_SAMPLE_READ_LEFT:
1590− {
1591− // remove right channel data
1592− for (i = 1; i < sampleLength; i++)
1593− audioDataS32[i] = audioDataS32[(i * 2) + 0];
1594− }
1595− break;
1596−
1597− case STEREO_SAMPLE_READ_RIGHT:
1598− {
1599− // remove left channel data
1600− len32 = sampleLength - 1;
1601− for (i = 0; i < len32; i++)
1602− audioDataS32[i] = audioDataS32[(i * 2) + 1];
1603−
1604− audioDataS32[i] = 0;
1605− }
1606− break;
1607−
1608− default:
1609− case STEREO_SAMPLE_CONVERT:
1610− {
1611− // mix stereo to mono
1612− len32 = sampleLength - 1;
1613− for (i = 0; i < len32; i++)
1614− {
1615− smp64 = audioDataS32[(i * 2) + 0];
1616− smp64 += audioDataS32[(i * 2) + 1];
1617− smp64 >>= 1;
1618−
1619− audioDataS32[i] = (int32_t)smp64;
1620− }
1621−
1622− audioDataS32[i] = 0;
1623− }
1624− break;
1625− }
1626− }
1627−
1628− normalize32bitSigned(audioDataS32, sampleLength);
1629−
1630− // downscale to 16-bit (ultra fast method!)
1631−
1632− audioDataS16 = (int16_t *)tmpSmp.pek;
1633− audioDataS16_2 = (int16_t *)tmpSmp.pek + 1;
1634−
1635− for (i = 0; i < sampleLength; i++)
1636− {
1637− audioDataS16[i] = audioDataS16_2[i];
1638− audioDataS16_2++;
1639− }
1640−
1641− sampleLength *= 2;
1642− tmpSmp.typ |= 16; // 16-bit
1643− }
1644− else if (audioFormat == WAV_FORMAT_IEEE_FLOAT && bitsPerSample == 32) // 32-BIT FLOATING POINT SAMPLE
1645− {
1646− sampleLength /= 4;
26+ FORMAT_UNKNOWN = 0,
27+ FORMAT_IFF = 1,
28+ FORMAT_WAV = 2,
29+ FORMAT_AIFF = 3
30+};
164731
1648− tmpSmp.origPek = (int8_t *)malloc((sampleLength * 4) + LOOP_FIX_LEN);
1649− if (tmpSmp.origPek == NULL)
1650− {
1651− okBoxThreadSafe(0, "System message", "Not enough memory!");
1652− goto wavLoadError;
1653− }
32+// file extensions accepted by Disk Op. in sample mode
33+char *supportedSmpExtensions[] =
34+{
35+ "iff", "raw", "wav", "snd", "smp", "sam", "aif", "pat", "aiff",
165436
1655− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
37+ "END_OF_LIST" // do NOT move, remove or edit this line!
38+};
165639
1657− if (fread(tmpSmp.pek, sampleLength, 4, f) != 4)
1658− {
1659− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1660− goto wavLoadError;
1661− }
40+// globals for sample loaders
41+bool loadAsInstrFlag, smpFilenameSet;
42+char *smpFilename;
43+uint8_t sampleSlot;
44+sampleTyp tmpSmp;
45+// --------------------------
166246
1663− fAudioDataFloat = (float *)tmpSmp.pek;
47+static volatile bool sampleIsLoading;
48+static SDL_Thread *thread;
166449
1665− // stereo conversion
1666− if (numChannels == 2)
1667− {
1668− sampleLength /= 2;
1669− switch (stereoSampleLoadMode)
1670− {
1671− case STEREO_SAMPLE_READ_LEFT:
1672− {
1673− // remove right channel data
1674− for (i = 1; i < sampleLength; i++)
1675− fAudioDataFloat[i] = fAudioDataFloat[(i * 2) + 0];
1676− }
1677− break;
50+static void freeTmpSample(sampleTyp *s);
167851
1679− case STEREO_SAMPLE_READ_RIGHT:
1680− {
1681− // remove left channel data
1682− len32 = sampleLength - 1;
1683− for (i = 0; i < len32; i++)
1684− fAudioDataFloat[i] = fAudioDataFloat[(i * 2) + 1];
52+// Crude sample detection routine. These aren't always accurate detections!
53+static int8_t detectSample(FILE *f)
54+{
55+ uint8_t D[256];
168556
1686− fAudioDataFloat[i] = 0.0f;
1687− }
1688− break;
57+ uint32_t oldPos = ftell(f);
58+ rewind(f);
59+ memset(D, 0, sizeof (D));
60+ fread(D, 1, sizeof (D), f);
61+ fseek(f, oldPos, SEEK_SET);
168962
1690− default:
1691− case STEREO_SAMPLE_CONVERT:
1692− {
1693− // mix stereo to mono
1694− len32 = sampleLength - 1;
1695− for (i = 0; i < len32; i++)
1696− fAudioDataFloat[i] = (fAudioDataFloat[(i * 2) + 0] + fAudioDataFloat[(i * 2) + 1]) * 0.5f;
63+ if (!memcmp("FORM", &D[0], 4) && (!memcmp("8SVX", &D[8], 4) || !memcmp("16SV", &D[8], 4)))
64+ return FORMAT_IFF;
169765
1698− fAudioDataFloat[i] = 0.0f;
1699− }
1700− break;
1701− }
1702− }
66+ if (!memcmp("RIFF", &D[0], 4) && !memcmp("WAVE", &D[8], 4))
67+ return FORMAT_WAV;
170368
1704− normalize16bitFloatSigned(fAudioDataFloat, sampleLength);
69+ if (!memcmp("FORM", &D[0], 4) && (!memcmp("AIFF", &D[8], 4) || !memcmp("AIFC", &D[8], 4)))
70+ return FORMAT_AIFF;
170571
1706− ptr16 = (int16_t *)tmpSmp.pek;
1707− for (i = 0; i < sampleLength; i++)
1708− ptr16[i] = (int16_t)fAudioDataFloat[i]; // should use SIMD if available
72+ return FORMAT_UNKNOWN;
73+}
170974
1710− sampleLength *= 2;
1711− tmpSmp.typ |= 16; // 16-bit
1712− }
1713− else if (audioFormat == WAV_FORMAT_IEEE_FLOAT && bitsPerSample == 64) // 64-BIT FLOATING POINT SAMPLE
75+static int32_t SDLCALL loadSampleThread(void *ptr)
76+{
77+ if (editor.tmpFilenameU == NULL)
171478 {
1715− sampleLength /= 8;
1716−
1717− tmpSmp.origPek = (int8_t *)malloc((sampleLength * 8) + LOOP_FIX_LEN);
1718− if (tmpSmp.origPek == NULL)
1719− {
1720− okBoxThreadSafe(0, "System message", "Not enough memory!");
1721− goto wavLoadError;
1722− }
1723−
1724− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
1725−
1726− if (fread(tmpSmp.pek, sampleLength, 8, f) != 8)
1727− {
1728− okBoxThreadSafe(0, "System message", "General I/O error during loading! Is the file in use?");
1729− goto wavLoadError;
1730− }
1731−
1732− dAudioDataDouble = (double *)tmpSmp.pek;
1733−
1734− // stereo conversion
1735− if (numChannels == 2)
1736− {
1737− sampleLength /= 2;
1738− switch (stereoSampleLoadMode)
1739− {
1740− case STEREO_SAMPLE_READ_LEFT:
1741− {
1742− // remove right channel data
1743− for (i = 1; i < sampleLength; i++)
1744− dAudioDataDouble[i] = dAudioDataDouble[(i * 2) + 0];
1745− }
1746− break;
1747−
1748− case STEREO_SAMPLE_READ_RIGHT:
1749− {
1750− // remove left channel data
1751− len32 = sampleLength - 1;
1752− for (i = 0; i < len32; i++)
1753− dAudioDataDouble[i] = dAudioDataDouble[(i * 2) + 1];
1754−
1755− dAudioDataDouble[i] = 0.0;
1756− }
1757− break;
1758−
1759− default:
1760− case STEREO_SAMPLE_CONVERT:
1761− {
1762− // mix stereo to mono
1763− len32 = sampleLength - 1;
1764− for (i = 0; i < len32; i++)
1765− dAudioDataDouble[i] = (dAudioDataDouble[(i * 2) + 0] + dAudioDataDouble[(i * 2) + 1]) * 0.5;
1766−
1767− dAudioDataDouble[i] = 0.0;
1768− }
1769− break;
1770− }
1771− }
1772−
1773− normalize64bitDoubleSigned(dAudioDataDouble, sampleLength);
1774−
1775− ptr16 = (int16_t *)tmpSmp.pek;
1776− for (i = 0; i < sampleLength; i++)
1777− ptr16[i] = (int16_t)dAudioDataDouble[i]; // should use SIMD if available
1778−
1779− sampleLength *= 2;
1780− tmpSmp.typ |= 16; // 16-bit
79+ loaderMsgBox("General I/O error during loading!");
80+ return false;
178181 }
178282
1783− // adjust memory needed
1784− newPtr = (int8_t *)realloc(tmpSmp.origPek, sampleLength + LOOP_FIX_LEN);
1785− if (newPtr != NULL)
83+ FILE *f = UNICHAR_FOPEN(editor.tmpFilenameU, "rb");
84+ if (f == NULL)
178685 {
1787− tmpSmp.origPek = newPtr;
1788− tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
86+ loaderMsgBox("General I/O error during loading! Is the file in use?");
87+ return false;
178988 }
179089
1791− tuneSample(&tmpSmp, sampleRate, audio.linearPeriodsFlag);
1792−
1793− tmpSmp.vol = 64;
1794− tmpSmp.pan = 128;
1795− tmpSmp.len = sampleLength;
90+ int8_t format = detectSample(f);
91+ fseek(f, 0, SEEK_END);
92+ uint32_t filesize = ftell(f);
179693
1797− // ---- READ "smpl" chunk ----
1798− if (smplPtr != 0 && smplLen > 52)
94+ if (filesize == 0)
179995 {
1800− fseek(f, smplPtr + 28, SEEK_SET); // seek to first wanted byte
1801−
1802− fread(&numLoops, 4, 1, f);
1803− if (numLoops == 1)
1804− {
1805− fseek(f, 4 + 4, SEEK_CUR); // skip "samplerData" and "identifier"
1806−
1807− fread(&loopType, 4, 1, f);
1808− fread(&loopStart, 4, 1, f);
1809− fread(&loopEnd, 4, 1, f);
1810−
1811− loopEnd++;
1812−
1813− if (tmpSmp.typ & 16)
1814− {
1815− loopStart *= 2;
1816− loopEnd *= 2;
1817− }
1818−
1819− if (loopEnd <= sampleLength)
1820− {
1821− tmpSmp.repS = loopStart;
1822− tmpSmp.repL = loopEnd - loopStart;
1823− tmpSmp.typ |= ((loopType == 0) ? 1 : 2);
1824− }
1825− }
96+ fclose(f);
97+ loaderMsgBox("Error loading sample: The file is empty!");
98+ return false;
182699 }
1827− // ---------------------------
1828−
1829− // ---- READ "xtra" chunk ----
1830− if (xtraPtr != 0 && xtraLen >= 8)
1831− {
1832− fseek(f, xtraPtr, SEEK_SET);
1833−
1834− fread(&xtraFlags, 4, 1, f); // flags
1835100
1836− // panning (0..256)
1837− if (xtraFlags & 0x20) // set panning flag
1838− {
1839− fread(&tempPan, 2, 1, f);
1840− if (tempPan > 255)
1841− tempPan = 255;
1842−
1843− tmpSmp.pan = (uint8_t)tempPan;
1844− }
1845− else
1846− {
1847− // don't read panning, skip it
1848− fseek(f, 2, SEEK_CUR);
1849− }
1850−
1851− // volume (0..256)
1852− fread(&tempVol, 2, 1, f);
1853− if (tempVol > 256)
1854− tempVol = 256;
1855−
1856− tmpSmp.vol = (uint8_t)(tempVol / 4); // 0..256 -> 0..64
1857− }
1858− // ---------------------------
101+ bool sampleLoaded = false;
1859102
1860− // ---- READ "INAM" chunk ----
1861− if (inamPtr != 0 && inamLen > 0)
103+ rewind(f);
104+ switch (format)
1862105 {
1863− fseek(f, inamPtr, SEEK_SET);
106+ case FORMAT_IFF: sampleLoaded = loadIFF(f, filesize); break;
107+ case FORMAT_WAV: sampleLoaded = loadWAV(f, filesize); break;
108+ case FORMAT_AIFF: sampleLoaded = loadAIFF(f, filesize); break;
109+ default: sampleLoaded = loadRAW(f, filesize); break;
110+ }
111+ fclose(f);
1864112
1865− memset(tmpSmp.name, 0, sizeof (tmpSmp.name));
1866− for (i = 0; i < 22; i++)
1867− {
1868− if (i < inamLen)
1869− {
1870− chr = (char)fgetc(f);
1871− if (chr == '\0')
1872− break;
113+ if (!sampleLoaded)
114+ goto loadError;
1873115
1874− tmpSmp.name[i] = chr;
1875− }
1876− }
1877− }
1878− else
116+ // sample loaded successfully!
117+
118+ if (!smpFilenameSet) // if we didn't set a custom sample name in the loader, set it to its filename
1879119 {
1880− // set sample name from filename if we didn't load name from .wav
1881− tmpFilename = unicharToCp437(filename, true);
120+ char *tmpFilename = unicharToCp437(editor.tmpFilenameU, true);
1882121 if (tmpFilename != NULL)
1883122 {
1884− j = (int32_t)strlen(tmpFilename);
1885− while (j--)
123+ int32_t i = (int32_t)strlen(tmpFilename);
124+ while (i--)
1886125 {
1887− if (tmpFilename[j] == DIR_DELIMITER)
126+ if (tmpFilename[i] == DIR_DELIMITER)
1888127 break;
1889128 }
1890129
1891− tmpPtr = tmpFilename;
1892− if (j > 0)
1893− tmpPtr += j + 1;
130+ char *tmpPtr = tmpFilename;
131+ if (i > 0)
132+ tmpPtr += i+1;
1894133
1895134 sanitizeFilename(tmpPtr);
1896135
1897− filenameLen = (uint32_t)strlen(tmpPtr);
136+ int32_t filenameLen = (int32_t)strlen(tmpPtr);
1898137 for (i = 0; i < 22; i++)
1899138 {
1900139 if (i < filenameLen)
@@ -1907,7 +146,7 @@ static int32_t SDLCALL loadWAVSample(void *ptr) · 6 unmodified lines
1907146 }
1908147 }
1909148
1910− fclose(f);
149+ fixString(tmpSmp.name, 21); // remove leading spaces from sample filename
1911150
1912151 lockMixerCallback();
1913152 if (loadAsInstrFlag) // if loaded in instrument mode
@@ -1919,172 +158,82 @@ static int32_t SDLCALL loadWAVSample(void *ptr) · 5 unmodified lines
1919158 if (instr[editor.curInstr] == NULL)
1920159 allocateInstr(editor.curInstr);
1921160
1922− if (instr[editor.curInstr] != NULL)
1923− {
1924− s = &instr[editor.curInstr]->samp[sampleSlot];
1925−
1926− freeSample(editor.curInstr, sampleSlot);
1927− memcpy(s, &tmpSmp, sizeof (sampleTyp));
1928− fixSample(s);
1929− }
1930− else
161+ if (instr[editor.curInstr] == NULL)
1931162 {
1932− okBoxThreadSafe(0, "System message", "Not enough memory!");
1933− goto wavLoadError;
163+ loaderMsgBox("Not enough memory!");
164+ goto loadError;
1934165 }
166+
167+ sampleTyp *s = &instr[editor.curInstr]->samp[sampleSlot];
168+
169+ freeSample(editor.curInstr, sampleSlot);
170+ memcpy(s, &tmpSmp, sizeof (sampleTyp));
171+ fixSample(s); // prepares sample for branchless resampling interpolation
172+ fixInstrAndSampleNames(editor.curInstr);
173+
1935174 unlockMixerCallback();
1936175
1937− fixSampleName(editor.curInstr);
1938176 setSongModifiedFlag();
1939− stereoSampleLoadMode = -1;
1940177
1941− // also sets mouse busy to false when done
178+ // when caught in main/video thread, it disables busy mouse and sets sampleIsLoading to true
1942179 editor.updateCurSmp = true;
1943180
1944181 return true;
1945182
1946−wavLoadError:
1947− if (f != NULL) fclose(f);
1948− if (tmpSmp.origPek != NULL) free(tmpSmp.origPek);
1949−
1950− stereoSampleLoadMode = -1;
183+loadError:
184+ setMouseBusy(false);
185+ freeTmpSample(&tmpSmp);
1951186 sampleIsLoading = false;
1952−
1953187 return false;
1954188
1955189 (void)ptr;
1956190 }
1957191
1958−bool loadSample(UNICHAR *filenameU, uint8_t smpNr, bool instrFlag)
192+static void freeTmpSample(sampleTyp *s)
1959193 {
1960− char tmpBuffer[16+1];
1961−
1962− if (sampleIsLoading)
1963− return false;
1964−
1965− stereoSampleLoadMode = 0;
1966−
1967− sampleSlot = smpNr;
1968− loadAsInstrFlag = instrFlag;
1969−
1970− if (editor.curInstr == 0)
1971− {
1972− okBox(0, "System message", "The zero-instrument cannot hold intrument data.");
1973− return false;
1974− }
1975−
1976− FILE *f = UNICHAR_FOPEN(filenameU, "rb");
1977− if (f == NULL)
194+ if (s->origPek != NULL)
1978195 {
1979− okBox(0, "System message", "General I/O error during loading! Is the file in use?");
1980− return false;
196+ free(s->origPek);
197+ s->origPek = NULL;
1981198 }
1982199
1983− memset(tmpBuffer, 0, sizeof (tmpBuffer));
1984− if (fread(tmpBuffer, sizeof (tmpBuffer) - 1, 1, f) == 1)
1985− {
1986− tmpBuffer[sizeof (tmpBuffer) - 1] = '\0';
1987−
1988− // detect what sample format this is...
1989−
1990− // WAV
1991− if (!strncmp("RIFF", tmpBuffer, 4) && !strncmp("WAVE", tmpBuffer + 8, 4))
1992− {
1993− // let the user pick what to do with stereo samples...
1994− if (wavIsStereo(f))
1995− stereoSampleLoadMode = okBox(5, "System request", "This is a stereo sample...");
1996−
1997− sampleIsLoading = true;
1998−
1999− fclose(f);
2000− UNICHAR_STRCPY(editor.tmpFilenameU, filenameU);
2001−
2002− mouseAnimOn();
2003− thread = SDL_CreateThread(loadWAVSample, NULL, NULL);
2004− if (thread == NULL)
2005− {
2006− okBox(0, "System message", "Couldn't create thread!");
2007− sampleIsLoading = false;
2008− return false;
2009− }
2010−
2011− SDL_DetachThread(thread);
2012− return true;
2013− }
2014−
2015− // AIFF or IFF
2016− if (!strncmp("FORM", tmpBuffer, 4))
2017− {
2018− if (!strncmp("AIFC", tmpBuffer + 8, 4))
2019− {
2020− // AIFC (not supported)
2021−
2022− fclose(f);
2023− okBox(0, "System message", "Error loading sample: This AIFF type (AIFC) is not supported!");
2024− return true;
2025− }
2026− else if (!strncmp("AIFF", tmpBuffer + 8, 4))
2027− {
2028− // AIFF
2029−
2030− // let the user pick what to do with stereo samples...
2031− if (aiffIsStereo(f))
2032− stereoSampleLoadMode = okBox(5, "System request", "This is a stereo sample...");
2033−
2034− sampleIsLoading = true;
2035−
2036− fclose(f);
2037− UNICHAR_STRCPY(editor.tmpFilenameU, filenameU);
2038−
2039− mouseAnimOn();
2040− thread = SDL_CreateThread(loadAIFFSample, NULL, NULL);
2041− if (thread == NULL)
2042− {
2043− okBox(0, "System message", "Couldn't create thread!");
2044− sampleIsLoading = false;
2045− return false;
2046− }
2047−
2048− SDL_DetachThread(thread);
2049− return true;
2050− }
2051− else if (!strncmp("8SVX", tmpBuffer + 8, 4) || !strncmp("16SV", tmpBuffer + 8, 4))
2052− {
2053− // IFF
200+ s->pek = NULL;
201+}
2054202
2055− sampleIsLoading = true;
203+void removeSampleIsLoadingFlag(void)
204+{
205+ sampleIsLoading = false;
206+}
2056207
2057− fclose(f);
2058− UNICHAR_STRCPY(editor.tmpFilenameU, filenameU);
208+bool loadSample(UNICHAR *filenameU, uint8_t smpNr, bool instrFlag)
209+{
210+ if (sampleIsLoading || filenameU == NULL)
211+ return false;
2059212
2060− mouseAnimOn();
2061− thread = SDL_CreateThread(loadIFFSample, NULL, NULL);
2062− if (thread == NULL)
2063− {
2064− okBox(0, "System message", "Couldn't create thread!");
2065− sampleIsLoading = false;
2066− return false;
2067− }
213+ // setup message box functions
214+ loaderMsgBox = myLoaderMsgBoxThreadSafe;
215+ loaderSysReq = okBoxThreadSafe;
2068216
2069− SDL_DetachThread(thread);
2070− return true;
2071− }
2072− }
217+ if (editor.curInstr == 0)
218+ {
219+ loaderMsgBox("The zero-instrument cannot hold intrument data.");
220+ return false;
2073221 }
2074222
2075− // load as RAW sample
2076−
223+ sampleSlot = smpNr;
224+ loadAsInstrFlag = instrFlag;
2077225 sampleIsLoading = true;
226+ smpFilenameSet = false;
2078227
2079− fclose(f);
228+ memset(&tmpSmp, 0, sizeof (tmpSmp));
2080229 UNICHAR_STRCPY(editor.tmpFilenameU, filenameU);
2081230
2082231 mouseAnimOn();
2083− thread = SDL_CreateThread(loadRawSample, NULL, NULL);
232+ thread = SDL_CreateThread(loadSampleThread, NULL, NULL);
2084233 if (thread == NULL)
2085234 {
2086− okBox(0, "System message", "Couldn't create thread!");
2087235 sampleIsLoading = false;
236+ loaderMsgBox("Couldn't create thread!");
2088237 return false;
2089238 }
2090239
@@ -2092,7 +241,7 @@ bool loadSample(UNICHAR *filenameU, uint8_t smpNr, bool instrFlag) · 1 unmodified line
2092241 return true;
2093242 }
2094243
2095−static void normalize32bitSigned(int32_t *sampleData, uint32_t sampleLength)
244+void normalizeSigned32Bit(int32_t *sampleData, uint32_t sampleLength)
2096245 {
2097246 uint32_t i;
2098247
@@ -2112,7 +261,7 @@ static void normalize32bitSigned(int32_t *sampleData, uint32_t sampleLength) · 13 unmodified lines
2112261 sampleData[i] = (int32_t)(sampleData[i] * dGain);
2113262 }
2114263
2115−static void normalize16bitFloatSigned(float *fSampleData, uint32_t sampleLength)
264+void normalize32BitFloatToSigned16Bit(float *fSampleData, uint32_t sampleLength)
2116265 {
2117266 uint32_t i;
2118267
@@ -2132,7 +281,7 @@ static void normalize16bitFloatSigned(float *fSampleData, uint32_t sampleLength) · 13 unmodified lines
2132281 fSampleData[i] *= fGain;
2133282 }
2134283
2135−static void normalize64bitDoubleSigned(double *dSampleData, uint32_t sampleLength)
284+void normalize64BitFloatToSigned16Bit(double *dSampleData, uint32_t sampleLength)
2136285 {
2137286 uint32_t i;
2138287
@@ -2151,98 +300,3 @@ static void normalize64bitDoubleSigned(double *dSampleData, uint32_t sampleLengt · 12 unmodified lines
2151300 for (i = 0; i < sampleLength; i++)
2152301 dSampleData[i] *= dGain;
2153302 }
2154−
2155−bool fileIsInstrument(char *fullPath)
2156−{
2157− int32_t i, len;
2158−
2159− // this assumes that fullPath is not empty
2160−
2161− len = (int32_t)strlen(fullPath);
2162−
2163− // get filename from path
2164− i = len;
2165− while (i--)
2166− {
2167− if (fullPath[i] == DIR_DELIMITER)
2168− break;
2169− }
2170−
2171− char *filename = fullPath;
2172− if (i > 0)
2173− filename += i + 1;
2174− // --------------------------
2175−
2176− len = (int32_t)strlen(filename);
2177− if (len < 4)
2178− return true; // can't be an instrument
2179−
2180− if (!_strnicmp("xi.", filename, 3) || (len >= 4 && !_strnicmp("pat.", filename, 4)))
2181− return true;
2182−
2183− int32_t extOffset = getExtOffset(filename, len);
2184− if (extOffset != -1)
2185− {
2186− if ((extOffset <= len-4) && !_strnicmp(".pat", &filename[extOffset], 4)) return true;
2187− if ((extOffset <= len-3) && !_strnicmp(".xi", &filename[extOffset], 3)) return true;
2188− }
2189−
2190− return false;
2191−}
2192−
2193−bool fileIsSample(char *fullPath)
2194−{
2195− int32_t i, len;
2196−
2197− // this assumes that fullPath is not empty
2198−
2199− len = (int32_t)strlen(fullPath);
2200−
2201− // get filename from path
2202− i = len;
2203− while (i--)
2204− {
2205− if (fullPath[i] == DIR_DELIMITER)
2206− break;
2207− }
2208−
2209− char *filename = fullPath;
2210− if (i > 0)
2211− filename += i + 1;
2212− // --------------------------
2213−
2214− len = (int32_t)strlen(filename);
2215− if (len < 4)
2216− return true; // can't be a module
2217−
2218− if (!_strnicmp("xm.", filename, 3) || !_strnicmp("ft.", filename, 3) ||
2219− !_strnicmp("mod.", filename, 4) || !_strnicmp("nst.", filename, 4) ||
2220− !_strnicmp("s3m.", filename, 4) || !_strnicmp("stm.", filename, 4) ||
2221− !_strnicmp("fst.", filename, 4) || !_strnicmp("it.", filename, 3))
2222− {
2223− return false; // definitely a module
2224− }
2225−
2226− int32_t extOffset = getExtOffset(filename, len);
2227− if (extOffset != -1)
2228− {
2229− if (extOffset <= len-4)
2230− {
2231− filename = &filename[extOffset];
2232− if (!_strnicmp(".mod", filename, 4) || !_strnicmp(".nst", filename, 4) ||
2233− !_strnicmp(".s3m", filename, 4) || !_strnicmp(".stm", filename, 4) ||
2234− !_strnicmp(".fst", filename, 4))
2235− {
2236− return false; // definitely a module
2237− }
2238− }
2239− else if (extOffset <= len-3)
2240− {
2241− filename = &filename[extOffset];
2242− if (!_strnicmp(".xm", filename, 3) || !_strnicmp(".ft", filename, 3) || !_strnicmp(".it", filename, 3))
2243− return false; // definitely a module
2244− }
2245− }
2246−
2247− return true; // let's assume it's a sample
2248−}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t