1 /****************************************************************************
3 * ____ ___ ____ __ ______ ___ ____ ____/ / *
4 * / __ `__ \/ __ `/ |/ / __ `__ \/ __ \/ __ / *
5 * / / / / / / /_/ /> </ / / / / / /_/ / /_/ / *
6 * /_/ /_/ /_/\__,_/_/|_/_/ /_/ /_/\____/\__,_/ *
8 * Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org) *
10 * Permission to use, copy, modify, and/or distribute this software for any *
11 * purpose with or without fee is hereby granted, provided that the above *
12 * copyright notice and this permission notice appear in all copies. *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF *
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR *
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES *
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN *
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
21 ****************************************************************************/
32 #include "samplefix.h"
34 int Load_WAV( Sample* samp, bool verbose, bool fix )
36 unsigned int file_size;
37 unsigned int bit_depth = 8;
38 unsigned int hasformat = 0;
39 unsigned int hasdata = 0;
40 unsigned int chunk_code;
41 unsigned int chunk_size;
42 unsigned int num_channels = 0;
45 printf( "Loading WAV file...\n" );
48 memset( samp, 0, sizeof( Sample ) );
50 file_size = file_tell_size();
53 read32(); // filesize-8
58 // break on end of file
59 if( file_tell_read() >= file_size ) break;
61 // read chunk code and length
62 chunk_code = read32();
63 chunk_size = read32();
68 //---------------------------------------------------------------------
69 case ' tmf': // format chunk
70 //---------------------------------------------------------------------
72 // check compression code (1 = PCM)
76 printf( "Unsupported WAV format.\n" );
77 return LOADWAV_UNKNOWN_COMP;
81 num_channels = read16();
83 // read sampling frequency
84 samp->frequency = read32();
86 // skip average something, wBlockAlign
90 // get bit depth, catch unsupported values
92 if( bit_depth != 8 && bit_depth != 16 )
95 printf( "Unsupported bit-depth.\n" );
96 return LOADWAV_UNSUPPORTED_BD;
100 samp->format |= SAMPF_16BIT;
102 // print verbose data
105 printf( "Sample Rate...%i\n", samp->frequency );
106 printf( "Bit Depth.....%i-bit\n", bit_depth );
109 // skip the rest of the chunk (if any)
110 if( (chunk_size - 0x10) > 0 )
111 skip8( (chunk_size - 0x10) );
116 //---------------------------------------------------------------------
117 case 'atad': // data chunk
118 //---------------------------------------------------------------------
124 return LOADWAV_CORRUPT;
128 printf( "Loading Sample Data...\n" );
130 // clip chunk size against end of file (for some borked wavs...)
132 int br = file_size - file_tell_read();
133 chunk_size = chunk_size > br ? br : chunk_size;
136 samp->sample_length = chunk_size / (bit_depth/8) / num_channels;
137 samp->data = malloc( chunk_size );
140 for( t = 0; t < samp->sample_length; t++ )
144 // for multi-channel samples, get average value
145 for( c = 0; c < num_channels; c++ )
147 dat += bit_depth == 8 ? ((int)read8()) - 128 : ((short)read16());
153 ((u8*)samp->data)[t] = dat + 128;
157 ((u16*)samp->data)[t] = dat + 32768;
165 //------------------------------------------------------------------------------
166 case 'lpms': // sampler chunk
167 //------------------------------------------------------------------------------
170 skip8( 4 // manufacturer
173 +4 // midi unity note
174 +4 // midi pitch fraction
178 int num_sample_loops = read32();
180 read32(); // sample data
184 // check for sample looping data
185 if( num_sample_loops )
187 read32(); // cue point ID
188 int loop_type = read32();
196 samp->loop_type = loop_type + 1;
197 samp->loop_start = read32();
198 samp->loop_end = read32();
200 // clip loop start against sample length
201 if( samp->loop_end > samp->sample_length ) {
202 samp->loop_end = samp->sample_length;
206 // catch invalid loop
207 if( (samp->loop_start > samp->sample_length) ||
208 (samp->loop_end - samp->loop_start < 16) ) {
211 samp->loop_start = 0;
221 skip8( chunk_size - pos );
229 if( hasformat && hasdata )
231 if( fix ) FixSample( samp );
236 return LOADWAV_CORRUPT;