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_uni.c,v 1.2 2004/02/06 19:29:03 raph Exp $
\r
25 UNIMOD (libmikmod's and APlayer's internal module format) 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
51 typedef struct UNIHEADER {
\r
67 UBYTE positions[256];
\r
71 typedef struct UNISMP05 {
\r
87 /*========== Loader variables */
\r
89 static UWORD universion;
\r
90 static UNIHEADER mh;
\r
92 #define UNI_SMPINCR 64
\r
93 static UNISMP05 *wh=NULL,*s=NULL;
\r
95 /*========== Loader code */
\r
97 static char* readstring(void)
\r
102 len=_mm_read_I_UWORD(modreader);
\r
104 s=_mm_malloc(len+1);
\r
105 _mm_read_UBYTES(s,len,modreader);
\r
111 BOOL UNI_Test(void)
\r
115 if(!_mm_read_UBYTES(id,6,modreader)) return 0;
\r
117 /* UNIMod created by MikCvt */
\r
118 if(!(memcmp(id,"UN0",3))) {
\r
119 if((id[3]>='4')&&(id[3]<='6')) return 1;
\r
121 /* UNIMod created by APlayer */
\r
122 if(!(memcmp(id,"APUN\01",5))) {
\r
123 if((id[5]>=1)&&(id[5]<=6)) return 1;
\r
128 BOOL UNI_Init(void)
\r
133 void UNI_Cleanup(void)
\r
139 static UBYTE* readtrack(void)
\r
146 len=_mm_read_M_UWORD(modreader);
\r
148 len=_mm_read_I_UWORD(modreader);
\r
150 if(!len) return NULL;
\r
151 if(!(t=_mm_malloc(len))) return NULL;
\r
152 _mm_read_UBYTES(t,len,modreader);
\r
154 /* Check if the track is correct */
\r
158 chunk=(chunk&0x1f)-1;
\r
168 /* Remap opcodes */
\r
169 if (universion <= 5) {
\r
175 /* UNI_NOTE .. UNI_S3MEFFECTQ are the same */
\r
177 opcode = UNI_S3MEFFECTT;
\r
180 opcode = UNI_XMEFFECTA;
\r
183 opcode = UNI_XMEFFECTG;
\r
186 opcode = UNI_XMEFFECTH;
\r
189 opcode = UNI_XMEFFECTP;
\r
193 /* APlayer < 1.05 does not have XMEFFECT6 */
\r
194 if (opcode >= UNI_XMEFFECT6 && universion < 0x105)
\r
196 /* APlayer < 1.03 does not have ITEFFECTT */
\r
197 if (opcode >= UNI_ITEFFECTT && universion < 0x103)
\r
199 /* APlayer < 1.02 does not have ITEFFECTZ */
\r
200 if (opcode >= UNI_ITEFFECTZ && universion < 0x102)
\r
204 if((!opcode)||(opcode>=UNI_LAST)) {
\r
209 oplen=unioperands[opcode]+1;
\r
213 if((chunk<0)||(cur>=len)) {
\r
221 static BOOL loadsmp6(void)
\r
227 for(t=0;t<of.numsmp;t++,s++) {
\r
230 flags = _mm_read_M_UWORD(modreader);
\r
232 if(flags&0x0004) s->flags|=SF_STEREO;
\r
233 if(flags&0x0002) s->flags|=SF_SIGNED;
\r
234 if(flags&0x0001) s->flags|=SF_16BITS;
\r
235 /* convert flags */
\r
236 if(universion>=0x104) {
\r
237 if(flags&0x2000) s->flags|=SF_UST_LOOP;
\r
238 if(flags&0x1000) s->flags|=SF_OWNPAN;
\r
239 if(flags&0x0800) s->flags|=SF_SUSTAIN;
\r
240 if(flags&0x0400) s->flags|=SF_REVERSE;
\r
241 if(flags&0x0200) s->flags|=SF_BIDI;
\r
242 if(flags&0x0100) s->flags|=SF_LOOP;
\r
243 if(flags&0x0020) s->flags|=SF_ITPACKED;
\r
244 if(flags&0x0010) s->flags|=SF_DELTA;
\r
245 if(flags&0x0008) s->flags|=SF_BIG_ENDIAN;
\r
246 } else if(universion>=0x102) {
\r
247 if(flags&0x0800) s->flags|=SF_UST_LOOP;
\r
248 if(flags&0x0400) s->flags|=SF_OWNPAN;
\r
249 if(flags&0x0200) s->flags|=SF_SUSTAIN;
\r
250 if(flags&0x0100) s->flags|=SF_REVERSE;
\r
251 if(flags&0x0080) s->flags|=SF_BIDI;
\r
252 if(flags&0x0040) s->flags|=SF_LOOP;
\r
253 if(flags&0x0020) s->flags|=SF_ITPACKED;
\r
254 if(flags&0x0010) s->flags|=SF_DELTA;
\r
255 if(flags&0x0008) s->flags|=SF_BIG_ENDIAN;
\r
257 if(flags&0x400) s->flags|=SF_UST_LOOP;
\r
258 if(flags&0x200) s->flags|=SF_OWNPAN;
\r
259 if(flags&0x100) s->flags|=SF_REVERSE;
\r
260 if(flags&0x080) s->flags|=SF_SUSTAIN;
\r
261 if(flags&0x040) s->flags|=SF_BIDI;
\r
262 if(flags&0x020) s->flags|=SF_LOOP;
\r
263 if(flags&0x010) s->flags|=SF_BIG_ENDIAN;
\r
264 if(flags&0x008) s->flags|=SF_DELTA;
\r
267 s->speed = _mm_read_M_ULONG(modreader);
\r
268 s->volume = _mm_read_UBYTE(modreader);
\r
269 s->panning = _mm_read_M_UWORD(modreader);
\r
270 s->length = _mm_read_M_ULONG(modreader);
\r
271 s->loopstart = _mm_read_M_ULONG(modreader);
\r
272 s->loopend = _mm_read_M_ULONG(modreader);
\r
273 s->susbegin = _mm_read_M_ULONG(modreader);
\r
274 s->susend = _mm_read_M_ULONG(modreader);
\r
275 s->globvol = _mm_read_UBYTE(modreader);
\r
276 s->vibflags = _mm_read_UBYTE(modreader);
\r
277 s->vibtype = _mm_read_UBYTE(modreader);
\r
278 s->vibsweep = _mm_read_UBYTE(modreader);
\r
279 s->vibdepth = _mm_read_UBYTE(modreader);
\r
280 s->vibrate = _mm_read_UBYTE(modreader);
\r
282 s->samplename=readstring();
\r
284 if(_mm_eof(modreader)) {
\r
285 _mm_errno = MMERR_LOADING_SAMPLEINFO;
\r
292 static BOOL loadinstr6(void)
\r
298 for(t=0;t<of.numins;t++,i++) {
\r
299 i->flags = _mm_read_UBYTE(modreader);
\r
300 i->nnatype = _mm_read_UBYTE(modreader);
\r
301 i->dca = _mm_read_UBYTE(modreader);
\r
302 i->dct = _mm_read_UBYTE(modreader);
\r
303 i->globvol = _mm_read_UBYTE(modreader);
\r
304 i->panning = _mm_read_M_UWORD(modreader);
\r
305 i->pitpansep = _mm_read_UBYTE(modreader);
\r
306 i->pitpancenter = _mm_read_UBYTE(modreader);
\r
307 i->rvolvar = _mm_read_UBYTE(modreader);
\r
308 i->rpanvar = _mm_read_UBYTE(modreader);
\r
309 i->volfade = _mm_read_M_UWORD(modreader);
\r
311 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
\r
312 #define UNI_LoadEnvelope6(name) \
\r
313 i-> name##flg=_mm_read_UBYTE(modreader); \
\r
314 i-> name##pts=_mm_read_UBYTE(modreader); \
\r
315 i-> name##susbeg=_mm_read_UBYTE(modreader); \
\r
316 i-> name##susend=_mm_read_UBYTE(modreader); \
\r
317 i-> name##beg=_mm_read_UBYTE(modreader); \
\r
318 i-> name##end=_mm_read_UBYTE(modreader); \
\r
319 for(w=0;w<(universion>=0x100?32:i-> name##pts);w++) { \
\r
320 i-> name##env[w].pos=_mm_read_M_SWORD(modreader); \
\r
321 i-> name##env[w].val=_mm_read_M_SWORD(modreader); \
\r
324 #define UNI_LoadEnvelope6(name) \
\r
325 i-> name/**/flg=_mm_read_UBYTE(modreader); \
\r
326 i-> name/**/pts=_mm_read_UBYTE(modreader); \
\r
327 i-> name/**/susbeg=_mm_read_UBYTE(modreader); \
\r
328 i-> name/**/susend=_mm_read_UBYTE(modreader); \
\r
329 i-> name/**/beg=_mm_read_UBYTE(modreader); \
\r
330 i-> name/**/end=_mm_read_UBYTE(modreader); \
\r
331 for (w=0;w<(universion>=0x100?32:i-> name/**/pts);w++) { \
\r
332 i-> name/**/env[w].pos=_mm_read_M_SWORD(modreader); \
\r
333 i-> name/**/env[w].val=_mm_read_M_SWORD(modreader); \
\r
337 UNI_LoadEnvelope6(vol);
\r
338 UNI_LoadEnvelope6(pan);
\r
339 UNI_LoadEnvelope6(pit);
\r
340 #undef UNI_LoadEnvelope6
\r
342 if(universion>=0x103)
\r
343 _mm_read_M_UWORDS(i->samplenumber,120,modreader);
\r
346 i->samplenumber[w]=_mm_read_UBYTE(modreader);
\r
347 _mm_read_UBYTES(i->samplenote,120,modreader);
\r
349 i->insname=readstring();
\r
351 if(_mm_eof(modreader)) {
\r
352 _mm_errno = MMERR_LOADING_SAMPLEINFO;
\r
359 static BOOL loadinstr5(void)
\r
364 UBYTE vibtype,vibsweep,vibdepth,vibrate;
\r
367 for(of.numsmp=t=0;t<of.numins;t++,i++) {
\r
370 numsmp=_mm_read_UBYTE(modreader);
\r
372 memset(i->samplenumber,0xff,INSTNOTES*sizeof(UWORD));
\r
374 i->samplenumber[u]=of.numsmp+_mm_read_UBYTE(modreader);
\r
376 #if defined __STDC__ || defined _MSC_VER || defined MPW_C
\r
377 #define UNI_LoadEnvelope5(name) \
\r
378 i-> name##flg=_mm_read_UBYTE(modreader); \
\r
379 i-> name##pts=_mm_read_UBYTE(modreader); \
\r
380 i-> name##susbeg=_mm_read_UBYTE(modreader); \
\r
381 i-> name##susend=i-> name##susbeg; \
\r
382 i-> name##beg=_mm_read_UBYTE(modreader); \
\r
383 i-> name##end=_mm_read_UBYTE(modreader); \
\r
384 for(u=0;u<12;u++) { \
\r
385 i-> name##env[u].pos=_mm_read_I_SWORD(modreader); \
\r
386 i-> name##env[u].val=_mm_read_I_SWORD(modreader); \
\r
389 #define UNI_LoadEnvelope5(name) \
\r
390 i-> name/**/flg=_mm_read_UBYTE(modreader); \
\r
391 i-> name/**/pts=_mm_read_UBYTE(modreader); \
\r
392 i-> name/**/susbeg=_mm_read_UBYTE(modreader); \
\r
393 i-> name/**/susend=i-> name/**/susbeg; \
\r
394 i-> name/**/beg=_mm_read_UBYTE(modreader); \
\r
395 i-> name/**/end=_mm_read_UBYTE(modreader); \
\r
396 for(u=0;u<12;u++) { \
\r
397 i-> name/**/env[u].pos=_mm_read_I_SWORD(modreader); \
\r
398 i-> name/**/env[u].val=_mm_read_I_SWORD(modreader); \
\r
402 UNI_LoadEnvelope5(vol);
\r
403 UNI_LoadEnvelope5(pan);
\r
404 #undef UNI_LoadEnvelope5
\r
406 vibtype =_mm_read_UBYTE(modreader);
\r
407 vibsweep =_mm_read_UBYTE(modreader);
\r
408 vibdepth =_mm_read_UBYTE(modreader);
\r
409 vibrate =_mm_read_UBYTE(modreader);
\r
411 i->volfade=_mm_read_I_UWORD(modreader);
\r
412 i->insname=readstring();
\r
414 for(u=0;u<numsmp;u++,s++,of.numsmp++) {
\r
415 /* Allocate more room for sample information if necessary */
\r
416 if(of.numsmp+u==wavcnt) {
\r
417 wavcnt+=UNI_SMPINCR;
\r
418 if(!(wh=realloc(wh,wavcnt*sizeof(UNISMP05)))) {
\r
419 _mm_errno=MMERR_OUT_OF_MEMORY;
\r
422 s=wh+(wavcnt-UNI_SMPINCR);
\r
425 s->c2spd =_mm_read_I_UWORD(modreader);
\r
426 s->transpose=_mm_read_SBYTE(modreader);
\r
427 s->volume =_mm_read_UBYTE(modreader);
\r
428 s->panning =_mm_read_UBYTE(modreader);
\r
429 s->length =_mm_read_I_ULONG(modreader);
\r
430 s->loopstart=_mm_read_I_ULONG(modreader);
\r
431 s->loopend =_mm_read_I_ULONG(modreader);
\r
432 s->flags =_mm_read_I_UWORD(modreader);
\r
433 s->samplename=readstring();
\r
435 s->vibtype =vibtype;
\r
436 s->vibsweep=vibsweep;
\r
437 s->vibdepth=vibdepth;
\r
438 s->vibrate =vibrate;
\r
440 if(_mm_eof(modreader)) {
\r
442 _mm_errno=MMERR_LOADING_SAMPLEINFO;
\r
450 if(wh) { free(wh);wh=NULL; }
\r
451 _mm_errno=MMERR_LOADING_SAMPLEINFO;
\r
457 static BOOL loadsmp5(void)
\r
464 for(u=0;u<of.numsmp;u++,q++,s++) {
\r
465 q->samplename=s->samplename;
\r
467 q->length =s->length;
\r
468 q->loopstart=s->loopstart;
\r
469 q->loopend =s->loopend;
\r
470 q->volume =s->volume;
\r
471 q->speed =s->c2spd;
\r
472 q->panning =s->panning;
\r
473 q->vibtype =s->vibtype;
\r
474 q->vibsweep =s->vibsweep;
\r
475 q->vibdepth =s->vibdepth;
\r
476 q->vibrate =s->vibrate;
\r
478 /* convert flags */
\r
480 if(s->flags&128) q->flags|=SF_REVERSE;
\r
481 if(s->flags& 64) q->flags|=SF_SUSTAIN;
\r
482 if(s->flags& 32) q->flags|=SF_BIDI;
\r
483 if(s->flags& 16) q->flags|=SF_LOOP;
\r
484 if(s->flags& 8) q->flags|=SF_BIG_ENDIAN;
\r
485 if(s->flags& 4) q->flags|=SF_DELTA;
\r
486 if(s->flags& 2) q->flags|=SF_SIGNED;
\r
487 if(s->flags& 1) q->flags|=SF_16BITS;
\r
490 d=of.instruments;s=wh;
\r
491 for(u=0;u<of.numins;u++,d++)
\r
492 for(t=0;t<INSTNOTES;t++)
\r
493 d->samplenote[t]=(d->samplenumber[t]>=of.numsmp)?
\r
494 255:(t+s[d->samplenumber[t]].transpose);
\r
501 BOOL UNI_Load(BOOL curious)
\r
504 char *modtype,*oldtype=NULL;
\r
509 /* read module header */
\r
510 _mm_read_UBYTES(mh.id,4,modreader);
\r
512 universion=mh.id[3]-'0';
\r
516 if(universion>=6) {
\r
518 _mm_read_UBYTE(modreader);
\r
520 universion=_mm_read_M_UWORD(modreader);
\r
522 mh.flags =_mm_read_M_UWORD(modreader);
\r
523 mh.numchn =_mm_read_UBYTE(modreader);
\r
524 mh.numvoices =_mm_read_UBYTE(modreader);
\r
525 mh.numpos =_mm_read_M_UWORD(modreader);
\r
526 mh.numpat =_mm_read_M_UWORD(modreader);
\r
527 mh.numtrk =_mm_read_M_UWORD(modreader);
\r
528 mh.numins =_mm_read_M_UWORD(modreader);
\r
529 mh.numsmp =_mm_read_M_UWORD(modreader);
\r
530 mh.reppos =_mm_read_M_UWORD(modreader);
\r
531 mh.initspeed =_mm_read_UBYTE(modreader);
\r
532 mh.inittempo =_mm_read_UBYTE(modreader);
\r
533 mh.initvolume=_mm_read_UBYTE(modreader);
\r
534 /* I expect this to show up soon in APlayer 1.06 format */
\r
535 if (universion >= 0x106)
\r
536 mh.bpmlimit=_mm_read_M_UWORD(modreader);
\r
540 mh.flags &= UF_XMPERIODS | UF_LINEAR | UF_INST | UF_NNA;
\r
541 mh.flags |= UF_PANNING;
\r
543 mh.numchn =_mm_read_UBYTE(modreader);
\r
544 mh.numpos =_mm_read_I_UWORD(modreader);
\r
545 mh.reppos =(universion==5)?_mm_read_I_UWORD(modreader):0;
\r
546 mh.numpat =_mm_read_I_UWORD(modreader);
\r
547 mh.numtrk =_mm_read_I_UWORD(modreader);
\r
548 mh.numins =_mm_read_I_UWORD(modreader);
\r
549 mh.initspeed =_mm_read_UBYTE(modreader);
\r
550 mh.inittempo =_mm_read_UBYTE(modreader);
\r
551 _mm_read_UBYTES(mh.positions,256,modreader);
\r
552 _mm_read_UBYTES(mh.panning,32,modreader);
\r
553 mh.flags =_mm_read_UBYTE(modreader);
\r
556 mh.flags &= UF_XMPERIODS | UF_LINEAR;
\r
557 mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING;
\r
560 /* set module parameters */
\r
561 of.flags =mh.flags;
\r
562 of.numchn =mh.numchn;
\r
563 of.numpos =mh.numpos;
\r
564 of.numpat =mh.numpat;
\r
565 of.numtrk =mh.numtrk;
\r
566 of.numins =mh.numins;
\r
567 of.reppos =mh.reppos;
\r
568 of.initspeed =mh.initspeed;
\r
569 of.inittempo =mh.inittempo;
\r
571 of.bpmlimit=mh.bpmlimit;
\r
573 /* be bug-compatible with older releases */
\r
576 of.songname=readstring();
\r
577 if(universion<0x102)
\r
578 oldtype=readstring();
\r
580 int len=strlen(oldtype)+20;
\r
581 if(!(modtype=_mm_malloc(len))) return 0;
\r
582 #ifdef HAVE_SNPRINTF
\r
583 snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
\r
585 sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype);
\r
588 if(!(modtype=_mm_malloc(10))) return 0;
\r
589 #ifdef HAVE_SNPRINTF
\r
590 snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
\r
592 sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3");
\r
595 of.modtype=strdup(modtype);
\r
596 free(modtype);free(oldtype);
\r
597 of.comment=readstring();
\r
599 if(universion>=6) {
\r
600 of.numvoices=mh.numvoices;
\r
601 of.initvolume=mh.initvolume;
\r
604 if(_mm_eof(modreader)) {
\r
605 _mm_errno=MMERR_LOADING_HEADER;
\r
610 if(!AllocPositions(of.numpos)) return 0;
\r
611 if(universion>=6) {
\r
612 if(universion>=0x100)
\r
613 _mm_read_M_UWORDS(of.positions,of.numpos,modreader);
\r
615 for(t=0;t<of.numpos;t++) of.positions[t]=_mm_read_UBYTE(modreader);
\r
616 _mm_read_M_UWORDS(of.panning,of.numchn,modreader);
\r
617 _mm_read_UBYTES(of.chanvol,of.numchn,modreader);
\r
619 if((mh.numpos>256)||(mh.numchn>32)) {
\r
620 _mm_errno=MMERR_LOADING_HEADER;
\r
623 for(t=0;t<of.numpos;t++) of.positions[t]=mh.positions[t];
\r
624 for(t=0;t<of.numchn;t++) of.panning[t]=mh.panning[t];
\r
626 /* convert the ``end of song'' pattern code if necessary */
\r
627 if(universion<0x106)
\r
628 for(t=0;t<of.numpos;t++)
\r
629 if(of.positions[t]==255) of.positions[t]=LAST_PATTERN;
\r
631 /* instruments and samples */
\r
632 if(universion>=6) {
\r
633 of.numsmp=mh.numsmp;
\r
634 if(!AllocSamples()) return 0;
\r
635 if(!loadsmp6()) return 0;
\r
637 if(of.flags&UF_INST) {
\r
638 if(!AllocInstruments()) return 0;
\r
639 if(!loadinstr6()) return 0;
\r
642 if(!AllocInstruments()) return 0;
\r
643 if(!loadinstr5()) return 0;
\r
644 if(!AllocSamples()) {
\r
645 if(wh) { free(wh);wh=NULL; }
\r
648 if(!loadsmp5()) return 0;
\r
650 /* check if the original file had no instruments */
\r
651 if(of.numsmp==of.numins) {
\r
652 for(t=0,d=of.instruments;t<of.numins;t++,d++) {
\r
655 if((d->volpts)||(d->panpts)||(d->globvol!=64)) break;
\r
657 if((d->samplenumber[u]!=t)||(d->samplenote[u]!=u)) break;
\r
661 of.flags&=~UF_INST;
\r
662 of.flags&=~UF_NOWRAP;
\r
663 for(t=0,d=of.instruments,q=of.samples;t<of.numins;t++,d++,q++) {
\r
664 q->samplename=d->insname;
\r
672 if(!AllocPatterns()) return 0;
\r
673 if(universion>=6) {
\r
674 _mm_read_M_UWORDS(of.pattrows,of.numpat,modreader);
\r
675 _mm_read_M_UWORDS(of.patterns,of.numpat*of.numchn,modreader);
\r
677 _mm_read_I_UWORDS(of.pattrows,of.numpat,modreader);
\r
678 _mm_read_I_UWORDS(of.patterns,of.numpat*of.numchn,modreader);
\r
682 if(!AllocTracks()) return 0;
\r
683 for(t=0;t<of.numtrk;t++)
\r
684 if(!(of.tracks[t]=readtrack())) {
\r
685 _mm_errno=MMERR_LOADING_TRACK;
\r
692 CHAR *UNI_LoadTitle(void)
\r
695 int posit[3]={304,306,26};
\r
697 _mm_fseek(modreader,3,SEEK_SET);
\r
698 ver=_mm_read_UBYTE(modreader);
\r
699 if(ver=='N') ver='6';
\r
701 _mm_fseek(modreader,posit[ver-'4'],SEEK_SET);
\r
702 return readstring();
\r
705 /*========== Loader information */
\r
707 MIKMODAPI MLOADER load_uni={
\r
710 "APUN (APlayer) and UNI (MikMod)",
\r