1 /* SpiralSynth
2 * Copyleft (C) 2000 David Griffiths <dave@pawfal.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include <iostream>
20 #include <fstream>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "RiffWav.h"
24 #include "SpiralInfo.h"
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28
29 const int HEADERLEN = (4+24+8);
30
31 #if __BYTE_ORDER == BIG_ENDIAN
32 #define SWAPINT(a) (a)=(((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|\
33 (((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24)
34 #endif
35
HeaderInfo()36 WavFile::HeaderInfo::HeaderInfo() : RiffStr1("RIFF"),RiffStr2("WAVE"),FrmtStr("fmt "),DataStr("data")
37 {
38 RiffSize = HEADERLEN; // needs size of data too?
39
40 Length = 0x10; // length of format, always this
41 Unknown = 0x01; // ?
42 Channels = 0x01; // Mono, stereo=0x02
43 SampleRate = SpiralInfo::SAMPLERATE;
44 BytesPerSec = SpiralInfo::SAMPLERATE*2; // 2 bytes = 16 bits
45 BytesPerSample = 0x02;
46 BitsPerSample = 0x10;
47
48 DataLength = 2055;
49 Zero = 0x00;
50 #if __BYTE_ORDER == BIG_ENDIAN
51 SWAPINT(RiffSize);
52 SWAPINT(SampleRate);
53 SWAPINT(BytesPerSec);
54 SWAPINT(DataLength);
55 #endif
56 }
Open(string FileName,Mode mode)57 int WavFile::Open(string FileName, Mode mode)
58 {
59 if (m_Stream!=NULL)
60 {
61 cerr<<"WavFile: File already open"<<endl;
62 return 0;
63 }
64
65 if (mode==WRITE)
66 {
67 m_Stream = fopen (FileName.c_str(), "wb");
68 }
69 else
70 {
71 m_Stream = fopen (FileName.c_str(), "rb");
72 }
73
74 if (m_Stream == (FILE*)0)
75 {
76 cerr<<"WavFile: File open error"<<endl;
77 return 0;
78 }
79
80 //Write the header
81
82 if (mode==WRITE)
83 {
84 HeaderInfo w;
85
86 // todo: sort this mess out!
87
88 fwrite(w.RiffStr1.c_str(),4,1,m_Stream);
89 fwrite(&w.RiffSize,sizeof(w.RiffSize),1,m_Stream);
90 fwrite(w.RiffStr2.c_str(),4,1,m_Stream);
91
92 fwrite(w.FrmtStr.c_str(),4,1,m_Stream);
93
94 fwrite(&w.Length,sizeof(w.Length),1,m_Stream);
95
96 fwrite(&w.Zero,sizeof(w.Zero),1,m_Stream);
97 fwrite(&w.Zero,sizeof(w.Zero),1,m_Stream);
98 fwrite(&w.Zero,sizeof(w.Zero),1,m_Stream);
99 fwrite(&w.Unknown,sizeof(w.Unknown),1,m_Stream);
100
101 fwrite(&w.Zero,sizeof(w.Zero),1,m_Stream);
102 fwrite(&w.Channels,sizeof(w.Channels),1,m_Stream);
103
104 fwrite(&w.Zero,sizeof(w.Zero),1,m_Stream);
105 fwrite(&w.SampleRate,sizeof(w.SampleRate),1,m_Stream);
106
107 fwrite(&w.BytesPerSec,sizeof(w.BytesPerSec),1,m_Stream);
108
109 fwrite(&w.BytesPerSample,sizeof(w.BytesPerSample),1,m_Stream);
110
111 fwrite(&w.Zero,sizeof(w.Zero),1,m_Stream);
112 fwrite(&w.BitsPerSample,sizeof(w.BitsPerSample),1,m_Stream);
113
114 fwrite(&w.Zero,sizeof(w.Zero),1,m_Stream);
115
116 fwrite(w.DataStr.c_str(),4,1,m_Stream);
117 fwrite(&w.DataLength,sizeof(w.DataLength),1,m_Stream);
118
119 return 1;
120 }
121 else
122 if (mode==READ)
123 {
124 // check we have a wav file here
125 char Check[4];
126 fread(Check,4,1,m_Stream);
127 if (Check[0]=='R' && Check[1]=='I' && Check[2]=='F' && Check[3]=='F')
128 {
129 // todo: check, and implement other formats
130
131 // see if it's saved in stereo
132 char temp=0;
133 fseek(m_Stream, 19, SEEK_SET);
134 fread(&temp,4,1,m_Stream);
135 if (temp==0x02)
136 {
137 m_Stereo=true;
138 }
139
140 // get the total size
141 fseek(m_Stream, 40, SEEK_SET);
142 fread(&m_TotalLength,4,1,m_Stream);
143 m_TotalLength/=2;
144
145 // leave the filepointer on the first sample
146 return 1;
147 }
148 else
149 {
150 fclose(m_Stream);
151 cerr<<"WavFile: File open error, wrong format"<<endl;
152 return 0;
153 }
154
155 }
156 }
157
Close()158 int WavFile::Close()
159 {
160 if (m_Stream==NULL)
161 {
162 //cerr<<"WavFile: File already closed"<<endl;
163 return 0;
164 }
165
166 // write the total length in
167 fseek(m_Stream, 40, SEEK_SET);
168 m_TotalLength*=2;
169 fwrite(&m_TotalLength,sizeof(m_TotalLength),1,m_Stream);
170
171 fclose(m_Stream);
172
173 m_Stream=NULL;
174 m_TotalLength=0;
175
176 return 1;
177 }
178
Save(int Length,short * data)179 int WavFile::Save(int Length, short *data)
180 {
181 if (m_Stream==NULL)
182 {
183 cerr<<"WavFile: No stream open"<<endl;
184 return 0;
185 }
186
187 if (!data) return 0;
188
189 m_TotalLength+=Length;
190
191 fwrite(data,sizeof(data),Length/2,m_Stream);
192
193 return 1;
194 }
195
GetSize()196 int WavFile::GetSize()
197 {
198 return m_TotalLength;
199 }
200
Load(short * data)201 int WavFile::Load(short *data)
202 {
203 if (m_TotalLength==(int)fread(data,2,m_TotalLength,m_Stream))
204 {
205 return 1;
206 }
207
208 cerr<<"WavFile: Read error"<<endl;
209 return 0;
210 }
211