1 /*--------------------------------------------------------------------------*
2 Project: Revolution SOUNDFILE dynamic link library
3 File: Wavfile.c
4
5 Copyright (C)2001-2006 Nintendo All Rights Reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: Wavfile.c,v $
14 Revision 1.2 02/09/2006 06:51:39 aka
15 Changed copyright.
16
17
18 *--------------------------------------------------------------------------*/
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include "Wavfile.h"
22
23 u32 * str_riff = (u32 *)"RIFF";
24 u32 * str_wave = (u32 *)"WAVE";
25 u32 * str_fmt = (u32 *)"fmt ";
26 u32 * str_data = (u32 *)"data";
27
28
29 /*--------------------------------------------------------------------------*/
wavCreateHeader(WAVECHUNK * wc,int numOfSamples,int channel,int bitsPerSample,int frequency)30 void wavCreateHeader
31 (
32 WAVECHUNK *wc,
33 int numOfSamples,
34 int channel,
35 int bitsPerSample,
36 int frequency
37 )
38 {
39 u32 datasize, riffchunksize;
40 u16 blocksize;
41
42
43 *((u32*)(wc->chunkId)) = *str_riff;
44 *((u32*)(wc->formType)) = *str_wave;
45 *((u32*)(wc->fmt.chunkId)) = *str_fmt;
46 *((u32*)(wc->data.chunkId)) = *str_data;
47
48 blocksize = channel * ( bitsPerSample / 8 );
49 datasize = blocksize * numOfSamples;
50 riffchunksize = datasize + 36;
51
52 wc->chunkSize = riffchunksize;
53
54 wc->fmt.chunkSize = 16;
55 wc->fmt.waveFormatType = 1;
56 wc->fmt.channel = channel;
57 wc->fmt.samplesPerSec = frequency;
58 wc->fmt.bytesPerSec = frequency * blocksize;
59 wc->fmt.blockSize = blocksize;
60 wc->fmt.bitsPerSample = bitsPerSample;
61
62 wc->data.chunkSize = datasize;
63
64 return;
65 }
66
67
68 /*--------------------------------------------------------------------------*/
wavWriteHeader(WAVECHUNK * wc,FILE * outfile)69 void wavWriteHeader
70 (
71 WAVECHUNK *wc,
72 FILE *outfile
73 )
74 {
75 fwrite(wc, 1, sizeof(WAVECHUNK), outfile);
76 return;
77 }
78
79
80 /*--------------------------------------------------------------------------*/
wavReadHeader(WAVECHUNK * wc,FILE * infile)81 int wavReadHeader
82 (
83 WAVECHUNK *wc,
84 FILE *infile
85 )
86 {
87 u32 d, riffchunksize, size;
88 int state;
89
90 state = FALSE;
91
92 if (0 != fseek(infile, 0, SEEK_SET))
93 return FALSE;
94
95 fread(&d, 1, sizeof(u32), infile);
96
97 if (d != *str_riff)
98 return FALSE;
99
100 *(u32*)(wc->chunkId) = d;
101
102 fread(&riffchunksize, 1, sizeof(u32), infile);
103 wc->chunkSize = riffchunksize;
104
105 fread(&d, 1, sizeof(u32), infile);
106
107 if (d != *str_wave)
108 return FALSE;
109
110 *(u32*)(wc->formType) = d;
111
112 riffchunksize -= 4;
113
114 while (riffchunksize > 8)
115 {
116 fread(&d, 1, sizeof(u32), infile);
117 fread(&size, 1, sizeof(u32), infile);
118
119 if (d == *str_fmt)
120 {
121 int remaining;
122
123 *(u32*)(wc->fmt.chunkId) = d;
124 wc->fmt.chunkSize = size;
125
126 fread(&wc->fmt.waveFormatType, 1, sizeof(FMTCHUNK)-8, infile);
127
128 remaining = size - (sizeof(FMTCHUNK) - 8);
129
130 if (remaining)
131 fseek(infile, remaining, SEEK_CUR);
132
133 riffchunksize -= (2 * sizeof(int)) + size;
134 }
135 else if (d == *str_data)
136 {
137 *(u32*)(wc->data.chunkId) = d;
138 wc->data.chunkSize = size;
139
140 state = TRUE;
141 riffchunksize -= sizeof(DATACHUNK);
142
143 break;
144 }
145 else
146 {
147 fseek(infile, size, SEEK_CUR);
148
149 riffchunksize = riffchunksize - size - 8;
150 }
151 }
152
153 return state;
154 }
155
156
157 /*--------------------------------------------------------------------------*/
wavGetSamples(WAVECHUNK * wc)158 u32 wavGetSamples(WAVECHUNK *wc)
159 {
160 u32 a, bps;
161
162 bps = wc->fmt.channel * wc->fmt.bitsPerSample / 8;
163 a = wc->data.chunkSize / bps;
164
165 return a;
166 }
167
168
169 /*--------------------------------------------------------------------------*/
wavGetChannels(WAVECHUNK * wc)170 u32 wavGetChannels(WAVECHUNK *wc)
171 {
172 return (u32)wc->fmt.channel;
173 }
174
175
176 /*--------------------------------------------------------------------------*/
wavGetBitsPerSample(WAVECHUNK * wc)177 u32 wavGetBitsPerSample(WAVECHUNK *wc)
178 {
179 return (u32)wc->fmt.bitsPerSample;
180 }
181
182
183 /*--------------------------------------------------------------------------*/
wavGetSampleRate(WAVECHUNK * wc)184 u32 wavGetSampleRate(WAVECHUNK *wc)
185 {
186 return (u32)wc->fmt.samplesPerSec;
187 }
188