6
|
1 /*
|
|
2
|
|
3 Name: MWAV.C
|
|
4
|
|
5 Description:
|
|
6 WAV sample loader
|
|
7 Stereo .WAV files are not yet supported as samples.
|
|
8
|
|
9 Portability:
|
|
10 All compilers -- All systems (hopefully)
|
|
11
|
|
12 */
|
|
13
|
|
14 #include <string.h>
|
|
15 #include "mikmod.h"
|
|
16
|
|
17
|
|
18 typedef struct WAV
|
|
19 { CHAR rID[4];
|
|
20 ULONG rLen;
|
|
21 CHAR wID[4];
|
|
22 CHAR fID[4];
|
|
23 ULONG fLen;
|
|
24 UWORD wFormatTag;
|
|
25 UWORD nChannels;
|
|
26 ULONG nSamplesPerSec;
|
|
27 ULONG nAvgBytesPerSec;
|
|
28 UWORD nBlockAlign;
|
|
29 UWORD nFormatSpecific;
|
|
30 } WAV;
|
|
31
|
|
32
|
|
33 SAMPLE *WAV_LoadFP(FILE *fp)
|
|
34 {
|
|
35 SAMPLE *si;
|
|
36 static WAV wh;
|
|
37 static CHAR dID[4];
|
|
38
|
|
39 // read wav header
|
|
40
|
|
41 _mm_read_string(wh.rID,4,fp);
|
|
42 wh.rLen = _mm_read_I_ULONG(fp);
|
|
43 _mm_read_string(wh.wID,4,fp);
|
|
44
|
|
45 while(1)
|
|
46 { _mm_read_string(wh.fID,4,fp);
|
|
47 wh.fLen = _mm_read_I_ULONG(fp);
|
|
48 if(memcmp(wh.fID,"fmt ",4) == 0) break;
|
|
49 _mm_fseek(fp,wh.fLen,SEEK_CUR);
|
|
50 }
|
|
51
|
|
52 if( feof(fp) ||
|
|
53 memcmp(wh.rID,"RIFF",4) ||
|
|
54 memcmp(wh.wID,"WAVE",4))
|
|
55 {
|
|
56 _mm_errno = MMERR_UNKNOWN_WAVE_TYPE;
|
|
57 return NULL;
|
|
58 }
|
|
59
|
|
60 wh.wFormatTag = _mm_read_I_UWORD(fp);
|
|
61 wh.nChannels = _mm_read_I_UWORD(fp);
|
|
62 wh.nSamplesPerSec = _mm_read_I_ULONG(fp);
|
|
63 wh.nAvgBytesPerSec = _mm_read_I_ULONG(fp);
|
|
64 wh.nBlockAlign = _mm_read_I_UWORD(fp);
|
|
65 wh.nFormatSpecific = _mm_read_I_UWORD(fp);
|
|
66
|
|
67 // check it
|
|
68
|
|
69 if(feof(fp))
|
|
70 { _mm_errno = MMERR_UNKNOWN_WAVE_TYPE;
|
|
71 return NULL;
|
|
72 }
|
|
73
|
|
74 // skip other crap
|
|
75
|
|
76 _mm_fseek(fp,wh.fLen-16,SEEK_CUR);
|
|
77 _mm_read_string(dID,4,fp);
|
|
78
|
|
79 if(memcmp(dID,"data",4))
|
|
80 { _mm_errno = MMERR_UNKNOWN_WAVE_TYPE;
|
|
81 return NULL;
|
|
82 }
|
|
83
|
|
84 if(wh.nChannels > 1)
|
|
85 { _mm_errno = MMERR_UNKNOWN_WAVE_TYPE;
|
|
86 return NULL;
|
|
87 }
|
|
88
|
|
89 // printf("wFormatTag: %x\n",wh.wFormatTag);
|
|
90 // printf("blockalign: %x\n",wh.nBlockAlign);
|
|
91 // prinff("nFormatSpc: %x\n",wh.nFormatSpecific);
|
|
92
|
|
93 if((si=(SAMPLE *)_mm_calloc(1,sizeof(SAMPLE)))==NULL) return NULL;
|
|
94
|
|
95 si->speed = wh.nSamplesPerSec;
|
|
96 si->volume = 64;
|
|
97 si->length = _mm_read_I_ULONG(fp);
|
|
98
|
|
99 if(wh.nBlockAlign == 2)
|
|
100 { si->flags = SF_16BITS | SF_SIGNED;
|
|
101 si->length >>= 1;
|
|
102 }
|
|
103
|
|
104 SL_RegisterSample(si,MD_SNDFX,fp);
|
|
105
|
|
106 return si;
|
|
107 }
|
|
108
|
|
109
|
|
110 SAMPLE *WAV_LoadFN(CHAR *filename)
|
|
111 {
|
|
112 FILE *fp;
|
|
113 SAMPLE *si;
|
|
114
|
|
115 if(!(md_mode & DMODE_SOFT_SNDFX)) return NULL;
|
|
116 if((fp=_mm_fopen(filename,"rb"))==NULL) return NULL;
|
|
117
|
|
118 si = WAV_LoadFP(fp);
|
|
119 SL_LoadSamples();
|
|
120 fclose(fp);
|
|
121
|
|
122 return si;
|
|
123 }
|
|
124
|
|
125
|
|
126 void WAV_Free(SAMPLE *si)
|
|
127 {
|
|
128 if(si!=NULL)
|
|
129 { MD_SampleUnLoad(si->handle);
|
|
130 free(si);
|
|
131 }
|
|
132 }
|
|
133
|