2 * FryingPan - Amiga CD/DVD Recording Software (User Interface and supporting Libraries only)
3 * Copyright (C) 2001-2011 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "rWAVAudio.h"
21 #include <libclass/dos.h>
22 #include <libclass/exec.h>
23 #include <libclass/utility.h>
24 #include <exec/lists.h>
25 #include <Generic/HookT.h>
27 #define FLIP16(a) ((((a)&0xff00)>>8) | (((a)&0xff)<<8))
29 #define MKID(a,b,c,d) (((a&255)<<24)|((b&255)<<16)|((c&255)<<8)|(d&255))
30 #define ID_RIFF MKID('R','I','F','F')
31 #define ID_WAVE MKID('W','A','V','E')
32 #define ID_fmt MKID('f','m','t',' ')
33 #define ID_data MKID('d','a','t','a')
37 unsigned short format
;
38 unsigned short channels
;
39 unsigned long frequency
;
40 unsigned long bytesPerSecond
;
41 unsigned short bytesPerSample
;
42 unsigned short resolution
;
45 IFileReader
*rWAVAudio::openRead(const char* sFile
, EDtError
&rc
)
48 if (true == rWAVAudio::checkFile(sFile
, rc
))
50 pSkel
= new rWAVAudio(sFile
, rc
);
55 rWAVAudio::rWAVAudio(const char *sName
, EDtError
&rc
)
56 : FileReader(sName
, rc
)
63 setLittleEndian(true);
67 const char *rWAVAudio::static_getName()
69 return "WAV Audio Track";
72 bool rWAVAudio::static_isAudio()
77 bool rWAVAudio::static_isData()
82 bool rWAVAudio::static_isSession()
87 bool rWAVAudio::isAudio()
89 return static_isAudio();
92 bool rWAVAudio::isData()
94 return static_isData();
97 const char *rWAVAudio::getName()
99 return static_getName();
102 void rWAVAudio::readHeaders()
107 _D(Lvl_Info
, "%s: Reading headers", (int)__PRETTY_FUNCTION__
);
108 DOS
->Seek(getFile(), 0, OFFSET_BEGINNING
);
110 if (DOS
->Read(getFile(), &buff
, 4)!=4)
112 _D(Lvl_Info
, "%s: File seems to be too small.. reading failed.", (int)__PRETTY_FUNCTION__
);
118 _D(Lvl_Info
, "%s: RIFF Wave file header not present (got: %08lx)", (int)__PRETTY_FUNCTION__
, buff
);
122 DOS
->Seek(getFile(), 4, OFFSET_CURRENT
);
124 if (DOS
->Read(getFile(), &buff
, 4)!=4)
126 _D(Lvl_Info
, "%s: File truncated..?", (int)__PRETTY_FUNCTION__
);
132 _D(Lvl_Info
, "%s: This RIFF is not Wave... (%08lx)", (int)__PRETTY_FUNCTION__
, buff
);
138 if (DOS
->Read(getFile(), &buff
, 4)!=4)
140 _D(Lvl_Info
, "%s: File truncated...", (int)__PRETTY_FUNCTION__
);
144 _D(Lvl_Info
, "%s: Read tag: %08lx", (int)__PRETTY_FUNCTION__
, buff
);
150 _D(Lvl_Info
, "%s: format tag located.", (int)__PRETTY_FUNCTION__
);
153 else if (buff
== ID_data
)
155 _D(Lvl_Info
, "%s: data tag located.", (int)__PRETTY_FUNCTION__
);
157 if (DOS
->Read(getFile(), &buff
, 4)!=4)
159 _D(Lvl_Info
, "%s: file truncated.", (int)__PRETTY_FUNCTION__
);
163 setDataOffset(DOS
->Seek(getFile(), 0, OFFSET_CURRENT
));
166 DOS
->Seek(getFile(), -4, OFFSET_CURRENT
);
168 if (DOS
->Read(getFile(), &buff
, 4)!=4)
170 _D(Lvl_Info
, "%s: Failed to read chunk size. File truncated.", (int)__PRETTY_FUNCTION__
);
174 _D(Lvl_Info
,"%s: chunk size = %ld bytes.", (int)__PRETTY_FUNCTION__
, buff
);
175 DOS
->Seek(getFile(), buff
, OFFSET_CURRENT
);
181 bool rWAVAudio::checkHeader(WaveHdr
* pHdr
, EDtError
&rc
)
183 if (W2LE(1) != pHdr
->format
)
185 rc
= DT_FileFormatNotSupported
;
188 if (W2LE(2) != pHdr
->channels
)
190 rc
= DT_WrongChannelCount
;
193 if (L2LE(44100) != pHdr
->frequency
)
195 rc
= DT_WrongFrequency
;
198 if (W2LE(16) != pHdr
->resolution
)
200 rc
= DT_WrongResolution
;
207 bool rWAVAudio::checkFile(const char* sFileName
, EDtError
&rc
)
213 rc
= DT_UnableToOpenFile
;
215 fh
= DOS
->Open(const_cast<char*>(sFileName
), MODE_OLDFILE
);
219 DOS
->Seek(fh
, 0, OFFSET_BEGINNING
);
221 if (DOS
->Read(fh
, &buff
, 4)!=4)
224 rc
= DT_FileMalformed
;
231 rc
= DT_InvalidFormat
;
235 DOS
->Seek(fh
, 4, OFFSET_CURRENT
);
237 if (DOS
->Read(fh
, &buff
, 4)!=4)
240 rc
= DT_FileMalformed
;
247 rc
= DT_InvalidFormat
;
253 if (DOS
->Read(fh
, &buff
, 4)!=4)
255 rc
= DT_FileMalformed
;
263 WaveHdr
*wave_hdr
= 0;
264 bool bCorrect
= false;
267 DOS
->Read(fh
, &buff
, 4);
269 wave_hdr
= (WaveHdr
*)new char[len
];
271 if ((NULL
!= wave_hdr
) && (len
== DOS
->Read(fh
, wave_hdr
, len
)))
273 bCorrect
= checkHeader(wave_hdr
, rc
);
274 delete [] ((char*)wave_hdr
);
278 if (false == bCorrect
)
285 else if (buff
== ID_data
)
290 if (DOS
->Read(fh
, &buff
, 4)!=4)
292 rc
= DT_FileMalformed
;
298 DOS
->Seek(fh
, buff
, OFFSET_CURRENT
);