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