1 /* MikMod sound library
\r
2 (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS
\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: mwav.c,v 1.1.1.1 2004/01/21 01:36:35 raph Exp $
\r
27 ==============================================================================*/
\r
30 FIXME: Stereo .WAV files are not yet supported as samples.
\r
33 #ifdef HAVE_CONFIG_H
\r
37 #ifdef HAVE_UNISTD_H
\r
43 #include "mikmod_internals.h"
\r
46 extern int fprintf(FILE *, const char *, ...);
\r
49 typedef struct WAV {
\r
57 ULONG nSamplesPerSec;
\r
58 ULONG nAvgBytesPerSec;
\r
60 UWORD nFormatSpecific;
\r
63 SAMPLE* Sample_LoadGeneric_internal(MREADER* reader)
\r
69 /* read wav header */
\r
70 _mm_read_string(wh.rID,4,reader);
\r
71 wh.rLen = _mm_read_I_ULONG(reader);
\r
72 _mm_read_string(wh.wID,4,reader);
\r
74 /* check for correct header */
\r
75 if(_mm_eof(reader)|| memcmp(wh.rID,"RIFF",4) || memcmp(wh.wID,"WAVE",4)) {
\r
76 _mm_errno = MMERR_UNKNOWN_WAVE_TYPE;
\r
80 /* scan all RIFF blocks until we find the sample data */
\r
85 _mm_read_string(dID,4,reader);
\r
86 len = _mm_read_I_ULONG(reader);
\r
87 /* truncated file ? */
\r
88 if (_mm_eof(reader)) {
\r
89 _mm_errno=MMERR_UNKNOWN_WAVE_TYPE;
\r
92 start = _mm_ftell(reader);
\r
94 /* sample format block
\r
95 should be present only once and before a data block */
\r
96 if(!memcmp(dID,"fmt ",4)) {
\r
97 wh.wFormatTag = _mm_read_I_UWORD(reader);
\r
98 wh.nChannels = _mm_read_I_UWORD(reader);
\r
99 wh.nSamplesPerSec = _mm_read_I_ULONG(reader);
\r
100 wh.nAvgBytesPerSec = _mm_read_I_ULONG(reader);
\r
101 wh.nBlockAlign = _mm_read_I_UWORD(reader);
\r
102 wh.nFormatSpecific = _mm_read_I_UWORD(reader);
\r
104 #ifdef MIKMOD_DEBUG
\r
105 fprintf(stderr,"\rwavloader : wFormatTag=%04x blockalign=%04x nFormatSpc=%04x\n",
\r
106 wh.wFormatTag,wh.nBlockAlign,wh.nFormatSpecific);
\r
109 if((have_fmt)||(wh.nChannels>1)) {
\r
110 _mm_errno=MMERR_UNKNOWN_WAVE_TYPE;
\r
115 /* sample data block
\r
116 should be present only once and after a format block */
\r
117 if(!memcmp(dID,"data",4)) {
\r
119 _mm_errno=MMERR_UNKNOWN_WAVE_TYPE;
\r
122 if(!(si=(SAMPLE*)_mm_malloc(sizeof(SAMPLE)))) return NULL;
\r
123 si->speed = wh.nSamplesPerSec/wh.nChannels;
\r
126 if(wh.nBlockAlign == 2) {
\r
127 si->flags = SF_16BITS | SF_SIGNED;
\r
130 si->inflags = si->flags;
\r
131 SL_RegisterSample(si,MD_SNDFX,reader);
\r
134 /* skip any other remaining blocks - so in case of repeated sample
\r
135 fragments, we'll return the first anyway instead of an error */
\r
138 /* onto next block */
\r
139 _mm_fseek(reader,start+len,SEEK_SET);
\r
140 if (_mm_eof(reader))
\r
147 MIKMODAPI SAMPLE* Sample_LoadGeneric(MREADER* reader)
\r
152 result=Sample_LoadGeneric_internal(reader);
\r
153 MUTEX_UNLOCK(vars);
\r
158 MIKMODAPI SAMPLE* Sample_LoadFP(int fp)
\r
160 SAMPLE* result=NULL;
\r
163 if((reader=_mm_new_file_reader(fp))) {
\r
164 result=Sample_LoadGeneric(reader);
\r
165 _mm_delete_file_reader(reader);
\r
170 MIKMODAPI SAMPLE* Sample_Load(CHAR* filename)
\r
175 if(!(md_mode & DMODE_SOFT_SNDFX)) return NULL;
\r
176 if((fp=_mm_fopen(filename,O_RDONLY))) {
\r
177 si = Sample_LoadFP(fp);
\r
183 MIKMODAPI void Sample_Free(SAMPLE* si)
\r
186 MD_SampleUnload(si->handle);
\r
191 void Sample_Free_internal(SAMPLE *si)
\r
195 MUTEX_UNLOCK(vars);
\r