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