1 /* MikMod sound library
\r
2 (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file
\r
3 AUTHORS for complete list.
\r
5 This library is free software; you can redistribute it and/or modify
\r
6 it under the terms of the GNU Library General Public License as
\r
7 published by the Free Software Foundation; either version 2 of
\r
8 the License, or (at your option) any later version.
\r
10 This program is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 GNU Library General Public License for more details.
\r
15 You should have received a copy of the GNU Library General Public
\r
16 License along with this library; if not, write to the Free Software
\r
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
\r
21 /*==============================================================================
\r
23 $Id: load_imf.c,v 1.2 2004/02/06 19:29:03 raph Exp $
\r
25 Imago Orpheus (IMF) module loader
\r
27 ==============================================================================*/
\r
29 #ifdef HAVE_CONFIG_H
\r
33 #ifdef HAVE_UNISTD_H
\r
38 #ifdef HAVE_MEMORY_H
\r
43 #include "mikmod_internals.h"
\r
46 extern int fprintf(FILE *, const char *, ...);
\r
49 /*========== Module structure */
\r
52 typedef struct IMFHEADER {
\r
65 /* channel settings */
\r
66 typedef struct IMFCHANNEL {
\r
74 /* instrument header */
\r
75 #define IMFNOTECNT (10*OCTAVE)
\r
76 #define IMFENVCNT (16*2)
\r
77 typedef struct IMFINSTHEADER {
\r
79 UBYTE what[IMFNOTECNT];
\r
80 UWORD volenv[IMFENVCNT];
\r
81 UWORD panenv[IMFENVCNT];
\r
82 UWORD pitenv[IMFENVCNT];
\r
103 /* sample header */
\r
104 typedef struct IMFWAVHEADER {
\r
105 CHAR samplename[13];
\r
115 typedef struct IMFNOTE {
\r
116 UBYTE note,ins,eff1,dat1,eff2,dat2;
\r
119 /*========== Loader variables */
\r
121 static CHAR IMF_Version[]="Imago Orpheus";
\r
123 static IMFNOTE *imfpat=NULL;
\r
124 static IMFHEADER *mh=NULL;
\r
126 /*========== Loader code */
\r
128 BOOL IMF_Test(void)
\r
132 _mm_fseek(modreader,0x3c,SEEK_SET);
\r
133 if(!_mm_read_UBYTES(id,4,modreader)) return 0;
\r
134 if(!memcmp(id,"IM10",4)) return 1;
\r
138 BOOL IMF_Init(void)
\r
140 if(!(imfpat=(IMFNOTE*)_mm_malloc(32*256*sizeof(IMFNOTE)))) return 0;
\r
141 if(!(mh=(IMFHEADER*)_mm_malloc(sizeof(IMFHEADER)))) return 0;
\r
146 void IMF_Cleanup(void)
\r
154 static BOOL IMF_ReadPattern(SLONG size,UWORD rows)
\r
159 /* clear pattern data */
\r
160 memset(imfpat,255,32*256*sizeof(IMFNOTE));
\r
162 while((size>0)&&(row<rows)) {
\r
163 flag=_mm_read_UBYTE(modreader);size--;
\r
165 if(_mm_eof(modreader)) {
\r
166 _mm_errno=MMERR_LOADING_PATTERN;
\r
174 n=&imfpat[256*ch+row];
\r
179 n->note=_mm_read_UBYTE(modreader);
\r
180 if(n->note>=0xa0) n->note=0xa0; /* note off */
\r
181 n->ins =_mm_read_UBYTE(modreader);
\r
186 n->eff2=_mm_read_UBYTE(modreader);
\r
187 n->dat2=_mm_read_UBYTE(modreader);
\r
190 n->eff1=_mm_read_UBYTE(modreader);
\r
191 n->dat1=_mm_read_UBYTE(modreader);
\r
196 if((size)||(row!=rows)) {
\r
197 _mm_errno=MMERR_LOADING_PATTERN;
\r
203 static void IMF_ProcessCmd(UBYTE eff,UBYTE inf)
\r
205 if((eff)&&(eff!=255))
\r
207 case 0x01: /* set tempo */
\r
208 UniEffect(UNI_S3MEFFECTA,inf);
\r
210 case 0x02: /* set BPM */
\r
211 if(inf>=0x20) UniEffect(UNI_S3MEFFECTT,inf);
\r
213 case 0x03: /* tone portamento */
\r
214 UniEffect(UNI_ITEFFECTG,inf);
\r
216 case 0x04: /* porta + volslide */
\r
217 UniEffect(UNI_ITEFFECTG,inf);
\r
218 UniEffect(UNI_S3MEFFECTD,0);
\r
220 case 0x05: /* vibrato */
\r
221 UniEffect(UNI_XMEFFECT4,inf);
\r
223 case 0x06: /* vibrato + volslide */
\r
224 UniEffect(UNI_XMEFFECT6,inf);
\r
226 case 0x07: /* fine vibrato */
\r
227 UniEffect(UNI_ITEFFECTU,inf);
\r
229 case 0x08: /* tremolo */
\r
230 UniEffect(UNI_S3MEFFECTR,inf);
\r
232 case 0x09: /* arpeggio */
\r
233 UniPTEffect(0x0,inf);
\r
235 case 0x0a: /* panning */
\r
236 UniPTEffect(0x8,(inf>=128)?255:(inf<<1));
\r
238 case 0x0b: /* pan slide */
\r
239 UniEffect(UNI_XMEFFECTP,inf);
\r
241 case 0x0c: /* set channel volume */
\r
242 if(inf<=64) UniPTEffect(0xc,inf);
\r
244 case 0x0d: /* volume slide */
\r
245 UniEffect(UNI_S3MEFFECTD,inf);
\r
247 case 0x0e: /* fine volume slide */
\r
250 UniEffect(UNI_S3MEFFECTD,0x0f|inf);
\r
252 UniEffect(UNI_S3MEFFECTD,0xf0|inf);
\r
254 UniEffect(UNI_S3MEFFECTD,0);
\r
256 case 0x0f: /* set finetune */
\r
257 UniPTEffect(0xe,0x50|(inf>>4));
\r
259 #ifdef MIKMOD_DEBUG
\r
260 case 0x10: /* note slide up */
\r
261 case 0x11: /* not slide down */
\r
262 fprintf(stderr,"\rIMF effect 0x10/0x11 (note slide)"
\r
263 " not implemented (eff=%2X inf=%2X)\n",eff,inf);
\r
266 case 0x12: /* slide up */
\r
267 UniEffect(UNI_S3MEFFECTF,inf);
\r
269 case 0x13: /* slide down */
\r
270 UniEffect(UNI_S3MEFFECTE,inf);
\r
272 case 0x14: /* fine slide up */
\r
275 UniEffect(UNI_S3MEFFECTF,0xe0|(inf>>2));
\r
277 UniEffect(UNI_S3MEFFECTF,0xf0|(inf>>4));
\r
279 UniEffect(UNI_S3MEFFECTF,0);
\r
281 case 0x15: /* fine slide down */
\r
284 UniEffect(UNI_S3MEFFECTE,0xe0|(inf>>2));
\r
286 UniEffect(UNI_S3MEFFECTE,0xf0|(inf>>4));
\r
288 UniEffect(UNI_S3MEFFECTE,0);
\r
290 /* 0x16 set filter cutoff (awe32) */
\r
291 /* 0x17 filter side + resonance (awe32) */
\r
292 case 0x18: /* sample offset */
\r
293 UniPTEffect(0x9,inf);
\r
295 #ifdef MIKMOD_DEBUG
\r
296 case 0x19: /* set fine sample offset */
\r
297 fprintf(stderr,"\rIMF effect 0x19 (fine sample offset)"
\r
298 " not implemented (inf=%2X)\n",inf);
\r
301 case 0x1a: /* keyoff */
\r
302 UniWriteByte(UNI_KEYOFF);
\r
304 case 0x1b: /* retrig */
\r
305 UniEffect(UNI_S3MEFFECTQ,inf);
\r
307 case 0x1c: /* tremor */
\r
308 UniEffect(UNI_S3MEFFECTI,inf);
\r
310 case 0x1d: /* position jump */
\r
311 UniPTEffect(0xb,inf);
\r
313 case 0x1e: /* pattern break */
\r
314 UniPTEffect(0xd,(inf>>4)*10+(inf&0xf));
\r
316 case 0x1f: /* set master volume */
\r
317 if(inf<=64) UniEffect(UNI_XMEFFECTG,inf<<1);
\r
319 case 0x20: /* master volume slide */
\r
320 UniEffect(UNI_XMEFFECTH,inf);
\r
322 case 0x21: /* extended effects */
\r
324 case 0x1: /* set filter */
\r
325 case 0x5: /* vibrato waveform */
\r
326 case 0x8: /* tremolo waveform */
\r
327 UniPTEffect(0xe,inf-0x10);
\r
329 case 0xa: /* pattern loop */
\r
330 UniPTEffect(0xe,0x60|(inf&0xf));
\r
332 case 0xb: /* pattern delay */
\r
333 UniPTEffect(0xe,0xe0|(inf&0xf));
\r
335 case 0x3: /* glissando */
\r
336 case 0xc: /* note cut */
\r
337 case 0xd: /* note delay */
\r
338 case 0xf: /* invert loop */
\r
339 UniPTEffect(0xe,inf);
\r
341 case 0xe: /* ignore envelope */
\r
342 UniEffect(UNI_ITEFFECTS0, 0x77); /* vol */
\r
343 UniEffect(UNI_ITEFFECTS0, 0x79); /* pan */
\r
344 UniEffect(UNI_ITEFFECTS0, 0x7b); /* pit */
\r
348 /* 0x22 chorus (awe32) */
\r
349 /* 0x23 reverb (awe32) */
\r
353 static UBYTE* IMF_ConvertTrack(IMFNOTE* tr,UWORD rows)
\r
359 for(t=0;t<rows;t++) {
\r
363 if((ins)&&(ins!=255)) UniInstrument(ins-1);
\r
366 UniPTEffect(0xc,0); /* Note cut */
\r
367 if(tr[t].eff1==0x0c) tr[t].eff1=0;
\r
368 if(tr[t].eff2==0x0c) tr[t].eff2=0;
\r
370 UniNote(((note>>4)*OCTAVE)+(note&0xf));
\r
373 IMF_ProcessCmd(tr[t].eff1,tr[t].dat1);
\r
374 IMF_ProcessCmd(tr[t].eff2,tr[t].dat2);
\r
380 BOOL IMF_Load(BOOL curious)
\r
382 #define IMF_SMPINCR 64
\r
383 int t,u,track=0,oldnumsmp;
\r
384 IMFCHANNEL channels[32];
\r
387 IMFWAVHEADER *wh=NULL,*s=NULL;
\r
388 ULONG *nextwav=NULL;
\r
393 /* try to read the module header */
\r
394 _mm_read_string(mh->songname,32,modreader);
\r
395 mh->ordnum=_mm_read_I_UWORD(modreader);
\r
396 mh->patnum=_mm_read_I_UWORD(modreader);
\r
397 mh->insnum=_mm_read_I_UWORD(modreader);
\r
398 mh->flags =_mm_read_I_UWORD(modreader);
\r
399 _mm_fseek(modreader,8,SEEK_CUR);
\r
400 mh->initspeed =_mm_read_UBYTE(modreader);
\r
401 mh->inittempo =_mm_read_UBYTE(modreader);
\r
402 mh->mastervol =_mm_read_UBYTE(modreader);
\r
403 mh->mastermult=_mm_read_UBYTE(modreader);
\r
404 _mm_fseek(modreader,64,SEEK_SET);
\r
406 if(_mm_eof(modreader)) {
\r
407 _mm_errno = MMERR_LOADING_HEADER;
\r
411 /* set module variables */
\r
412 of.songname=DupStr(mh->songname,31,1);
\r
413 of.modtype=strdup(IMF_Version);
\r
414 of.numpat=mh->patnum;
\r
415 of.numins=mh->insnum;
\r
417 of.initspeed=mh->initspeed;
\r
418 of.inittempo=mh->inittempo;
\r
419 of.initvolume=mh->mastervol<<1;
\r
420 of.flags |= UF_INST | UF_ARPMEM | UF_PANNING;
\r
421 if(mh->flags&1) of.flags |= UF_LINEAR;
\r
424 /* read channel information */
\r
426 memset(remap,-1,32*sizeof(UBYTE));
\r
427 for(t=0;t<32;t++) {
\r
428 _mm_read_string(channels[t].name,12,modreader);
\r
429 channels[t].chorus=_mm_read_UBYTE(modreader);
\r
430 channels[t].reverb=_mm_read_UBYTE(modreader);
\r
431 channels[t].pan =_mm_read_UBYTE(modreader);
\r
432 channels[t].status=_mm_read_UBYTE(modreader);
\r
434 /* bug in Imago Orpheus ? If only channel 1 is enabled, in fact we have to
\r
435 enable 16 channels */
\r
436 if(!channels[0].status) {
\r
437 for(t=1;t<16;t++) if(channels[t].status!=1) break;
\r
438 if(t==16) for(t=1;t<16;t++) channels[t].status=0;
\r
440 for(t=0;t<32;t++) {
\r
441 if(channels[t].status!=2)
\r
442 remap[t]=of.numchn++;
\r
448 of.panning[remap[t]]=channels[t].pan;
\r
449 of.chanvol[remap[t]]=channels[t].status?0:64;
\r
452 if(_mm_eof(modreader)) {
\r
453 _mm_errno = MMERR_LOADING_HEADER;
\r
457 /* read order list */
\r
458 _mm_read_UBYTES(mh->orders,256,modreader);
\r
459 if(_mm_eof(modreader)) {
\r
460 _mm_errno = MMERR_LOADING_HEADER;
\r
465 for(t=0;t<mh->ordnum;t++)
\r
466 if(mh->orders[t]!=0xff) of.numpos++;
\r
467 if(!AllocPositions(of.numpos)) return 0;
\r
468 for(t=u=0;t<mh->ordnum;t++)
\r
469 if(mh->orders[t]!=0xff) of.positions[u++]=mh->orders[t];
\r
471 /* load pattern info */
\r
472 of.numtrk=of.numpat*of.numchn;
\r
473 if(!AllocTracks()) return 0;
\r
474 if(!AllocPatterns()) return 0;
\r
476 for(t=0;t<of.numpat;t++) {
\r
480 size=(SLONG)_mm_read_I_UWORD(modreader);
\r
481 rows=_mm_read_I_UWORD(modreader);
\r
482 if((rows>256)||(size<4)) {
\r
483 _mm_errno=MMERR_LOADING_PATTERN;
\r
487 of.pattrows[t]=rows;
\r
488 if(!IMF_ReadPattern(size-4,rows)) return 0;
\r
489 for(u=0;u<of.numchn;u++)
\r
490 if(!(of.tracks[track++]=IMF_ConvertTrack(&imfpat[u*256],rows)))
\r
494 /* load instruments */
\r
495 if(!AllocInstruments()) return 0;
\r
498 for(oldnumsmp=t=0;t<of.numins;t++) {
\r
501 memset(d->samplenumber,0xff,INSTNOTES*sizeof(UWORD));
\r
503 /* read instrument header */
\r
504 _mm_read_string(ih.name,32,modreader);
\r
505 d->insname=DupStr(ih.name,31,1);
\r
506 _mm_read_UBYTES(ih.what,IMFNOTECNT,modreader);
\r
507 _mm_fseek(modreader,8,SEEK_CUR);
\r
508 _mm_read_I_UWORDS(ih.volenv,IMFENVCNT,modreader);
\r
509 _mm_read_I_UWORDS(ih.panenv,IMFENVCNT,modreader);
\r
510 _mm_read_I_UWORDS(ih.pitenv,IMFENVCNT,modreader);
\r
512 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
\r
513 #define IMF_FinishLoadingEnvelope(name) \
\r
514 ih. name##pts=_mm_read_UBYTE(modreader); \
\r
515 ih. name##sus=_mm_read_UBYTE(modreader); \
\r
516 ih. name##beg=_mm_read_UBYTE(modreader); \
\r
517 ih. name##end=_mm_read_UBYTE(modreader); \
\r
518 ih. name##flg=_mm_read_UBYTE(modreader); \
\r
519 _mm_read_UBYTE(modreader); \
\r
520 _mm_read_UBYTE(modreader); \
\r
521 _mm_read_UBYTE(modreader)
\r
523 #define IMF_FinishLoadingEnvelope(name) \
\r
524 ih. name/**/pts=_mm_read_UBYTE(modreader); \
\r
525 ih. name/**/sus=_mm_read_UBYTE(modreader); \
\r
526 ih. name/**/beg=_mm_read_UBYTE(modreader); \
\r
527 ih. name/**/end=_mm_read_UBYTE(modreader); \
\r
528 ih. name/**/flg=_mm_read_UBYTE(modreader); \
\r
529 _mm_read_UBYTE(modreader); \
\r
530 _mm_read_UBYTE(modreader); \
\r
531 _mm_read_UBYTE(modreader)
\r
534 IMF_FinishLoadingEnvelope(vol);
\r
535 IMF_FinishLoadingEnvelope(pan);
\r
536 IMF_FinishLoadingEnvelope(pit);
\r
538 ih.volfade=_mm_read_I_UWORD(modreader);
\r
539 ih.numsmp =_mm_read_I_UWORD(modreader);
\r
541 _mm_read_UBYTES(id,4,modreader);
\r
542 /* Looks like Imago Orpheus forgets the signature for empty
\r
543 instruments following a multi-sample instrument... */
\r
544 if(memcmp(id,"II10",4) &&
\r
545 (oldnumsmp && memcmp(id,"\x0\x0\x0\x0",4))) {
\r
546 if(nextwav) free(nextwav);
\r
548 _mm_errno=MMERR_LOADING_SAMPLEINFO;
\r
551 oldnumsmp=ih.numsmp;
\r
553 if((ih.numsmp>16)||(ih.volpts>IMFENVCNT/2)||(ih.panpts>IMFENVCNT/2)||
\r
554 (ih.pitpts>IMFENVCNT/2)||(_mm_eof(modreader))) {
\r
555 if(nextwav) free(nextwav);
\r
557 _mm_errno=MMERR_LOADING_SAMPLEINFO;
\r
561 for(u=0;u<IMFNOTECNT;u++)
\r
562 d->samplenumber[u]=ih.what[u]>ih.numsmp?0xffff:ih.what[u]+of.numsmp;
\r
563 d->volfade=ih.volfade;
\r
565 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
\r
566 #define IMF_ProcessEnvelope(name) \
\r
567 for (u = 0; u < (IMFENVCNT >> 1); u++) { \
\r
568 d-> name##env[u].pos = ih. name##env[u << 1]; \
\r
569 d-> name##env[u].val = ih. name##env[(u << 1)+ 1]; \
\r
571 if (ih. name##flg&1) d-> name##flg|=EF_ON; \
\r
572 if (ih. name##flg&2) d-> name##flg|=EF_SUSTAIN; \
\r
573 if (ih. name##flg&4) d-> name##flg|=EF_LOOP; \
\r
574 d-> name##susbeg=d-> name##susend=ih. name##sus; \
\r
575 d-> name##beg=ih. name##beg; \
\r
576 d-> name##end=ih. name##end; \
\r
577 d-> name##pts=ih. name##pts; \
\r
579 if ((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \
\r
580 d-> name##flg&=~EF_ON
\r
582 #define IMF_ProcessEnvelope(name) \
\r
583 for (u = 0; u < (IMFENVCNT >> 1); u++) { \
\r
584 d-> name/**/env[u].pos = ih. name/**/env[u << 1]; \
\r
585 d-> name/**/env[u].val = ih. name/**/env[(u << 1)+ 1]; \
\r
587 if (ih. name/**/flg&1) d-> name/**/flg|=EF_ON; \
\r
588 if (ih. name/**/flg&2) d-> name/**/flg|=EF_SUSTAIN; \
\r
589 if (ih. name/**/flg&4) d-> name/**/flg|=EF_LOOP; \
\r
590 d-> name/**/susbeg=d-> name/**/susend=ih. name/**/sus; \
\r
591 d-> name/**/beg=ih. name/**/beg; \
\r
592 d-> name/**/end=ih. name/**/end; \
\r
593 d-> name/**/pts=ih. name/**/pts; \
\r
595 if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \
\r
596 d-> name/**/flg&=~EF_ON
\r
599 IMF_ProcessEnvelope(vol);
\r
600 IMF_ProcessEnvelope(pan);
\r
601 IMF_ProcessEnvelope(pit);
\r
602 #undef IMF_ProcessEnvelope
\r
606 #ifdef MIKMOD_DEBUG
\r
607 fprintf(stderr, "\rFilter envelopes not supported yet\n");
\r
611 /* gather sample information */
\r
612 for(u=0;u<ih.numsmp;u++,s++) {
\r
613 /* allocate more room for sample information if necessary */
\r
614 if(of.numsmp+u==wavcnt) {
\r
615 wavcnt+=IMF_SMPINCR;
\r
616 if(!(nextwav=realloc(nextwav,wavcnt*sizeof(ULONG)))) {
\r
618 _mm_errno=MMERR_OUT_OF_MEMORY;
\r
621 if(!(wh=realloc(wh,wavcnt*sizeof(IMFWAVHEADER)))) {
\r
623 _mm_errno=MMERR_OUT_OF_MEMORY;
\r
626 s=wh+(wavcnt-IMF_SMPINCR);
\r
629 _mm_read_string(s->samplename,13,modreader);
\r
630 _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);
\r
631 s->length =_mm_read_I_ULONG(modreader);
\r
632 s->loopstart =_mm_read_I_ULONG(modreader);
\r
633 s->loopend =_mm_read_I_ULONG(modreader);
\r
634 s->samplerate=_mm_read_I_ULONG(modreader);
\r
635 s->volume =_mm_read_UBYTE(modreader)&0x7f;
\r
636 s->pan =_mm_read_UBYTE(modreader);
\r
637 _mm_fseek(modreader,14,SEEK_CUR);
\r
638 s->flags =_mm_read_UBYTE(modreader);
\r
639 _mm_fseek(modreader,11,SEEK_CUR);
\r
640 _mm_read_UBYTES(id,4,modreader);
\r
641 if(((memcmp(id,"IS10",4))&&(memcmp(id,"IW10",4)))||
\r
642 (_mm_eof(modreader))) {
\r
643 free(nextwav);free(wh);
\r
644 _mm_errno=MMERR_LOADING_SAMPLEINFO;
\r
647 nextwav[of.numsmp+u]=_mm_ftell(modreader);
\r
648 _mm_fseek(modreader,s->length,SEEK_CUR);
\r
651 of.numsmp+=ih.numsmp;
\r
657 if(nextwav) free(nextwav);
\r
659 _mm_errno=MMERR_LOADING_SAMPLEINFO;
\r
664 if(!AllocSamples()) {
\r
665 free(nextwav);free(wh);
\r
668 if(!AllocLinear()) {
\r
669 free(nextwav);free(wh);
\r
674 for(u=0;u<of.numsmp;u++,s++,q++) {
\r
675 q->samplename=DupStr(s->samplename,12,1);
\r
676 q->length =s->length;
\r
677 q->loopstart=s->loopstart;
\r
678 q->loopend =s->loopend;
\r
679 q->volume =s->volume;
\r
680 q->speed =s->samplerate;
\r
681 if(of.flags&UF_LINEAR)
\r
682 q->speed=speed_to_finetune(s->samplerate<<1,u);
\r
683 q->panning =s->pan;
\r
684 q->seekpos =nextwav[u];
\r
686 q->flags|=SF_SIGNED;
\r
687 if(s->flags&0x1) q->flags|=SF_LOOP;
\r
688 if(s->flags&0x2) q->flags|=SF_BIDI;
\r
689 if(s->flags&0x8) q->flags|=SF_OWNPAN;
\r
691 q->flags|=SF_16BITS;
\r
700 for(u=0;u<of.numins;u++,d++) {
\r
701 for(t=0;t<IMFNOTECNT;t++) {
\r
702 if(d->samplenumber[t]>=of.numsmp)
\r
703 d->samplenote[t]=255;
\r
704 else if (of.flags&UF_LINEAR) {
\r
705 int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]];
\r
706 d->samplenote[u]=(note<0)?0:(note>255?255:note);
\r
708 d->samplenote[t]=t;
\r
712 free(wh);free(nextwav);
\r
716 CHAR *IMF_LoadTitle(void)
\r
720 _mm_fseek(modreader,0,SEEK_SET);
\r
721 if(!_mm_read_UBYTES(s,31,modreader)) return NULL;
\r
723 return(DupStr(s,31,1));
\r
726 /*========== Loader information */
\r
728 MIKMODAPI MLOADER load_imf={
\r
731 "IMF (Imago Orpheus)",
\r