cWavDecoder.cpp
00001
00002
00003
00004
00005 #include "../Headers/cWavDecoder.h"
00006 #include <string.h>
00007
00008 #ifdef CAUDIO_COMPILE_WITH_WAV_DECODER
00009
00010 namespace cAudio
00011 {
00012 cWavDecoder::cWavDecoder(IDataSource* stream) : IAudioDecoder(stream), Valid(false)
00013 {
00014 const char* RIFFTAG = "RIFF";
00015 const char* WAVETAG = "WAVE";
00016 const char* FORMATTAG = "fmt ";
00017 const char* DATATAG = "data";
00018
00019 char ident[4];
00020 int tempint32 = 0;
00021 short tempint16 = 0;
00022 char tempint8 = 0;
00023
00024 unsigned int startOffset = 0;
00025
00026
00027 Stream->seek(0, false);
00028 Stream->read(ident, 4);
00029
00030 if(strncmp(ident, RIFFTAG, 4) == 0)
00031 {
00032 Stream->read(&tempint32, 4);
00033
00034 if(tempint32 >= 44)
00035 {
00036 Stream->read(ident, 4);
00037
00038 if(strncmp(ident, WAVETAG, 4) == 0)
00039 {
00040
00041 startOffset = Stream->getCurrentPos();
00042
00043
00044 do
00045 {
00046 Stream->read(ident, 4);
00047 }
00048 while((strncmp(ident, FORMATTAG, 4) != 0) && (Stream->getCurrentPos() < Stream->getSize()));
00049
00050
00051 if(Stream->getCurrentPos() < (Stream->getSize() - 16))
00052 {
00053
00054 Stream->read(&tempint32, 4);
00055 if(tempint32 >= 16)
00056 {
00057
00058 Stream->read(&tempint16, 2);
00059 if(tempint16 == 1)
00060 {
00061 Stream->read(&tempint16, 2);
00062 Channels = tempint16;
00063
00064 if(Channels == 1 || Channels == 2)
00065 {
00066 Stream->read(&tempint32, 4);
00067 SampleRate = tempint32;
00068 Stream->read(&tempint32, 4);
00069 ByteRate = tempint32;
00070 Stream->read(&tempint16, 2);
00071 BlockAlign = tempint16;
00072 Stream->read(&tempint16, 2);
00073 BitsPerSample = tempint16;
00074
00075
00076 if(BitsPerSample == 8 || BitsPerSample == 16)
00077 {
00078
00079 Stream->seek(startOffset, false);
00080
00081 do
00082 {
00083 Stream->read(ident, 4);
00084 }
00085 while((strncmp(ident, DATATAG, 4) != 0) && (Stream->getCurrentPos() < Stream->getSize()));
00086
00087
00088 if(Stream->getCurrentPos() < Stream->getSize())
00089 {
00090
00091 Stream->read(&tempint32, 4);
00092 DataSize = tempint32;
00093 DataOffset = Stream->getCurrentPos();
00094
00095 Valid = true;
00096 }
00097 }
00098 }
00099 }
00100 }
00101 }
00102 }
00103 }
00104 }
00105 }
00106
00107 cWavDecoder::~cWavDecoder()
00108 {
00109 Channels = 0;
00110 SampleRate = 0;
00111 ByteRate = 0;
00112 BlockAlign = 0;
00113 BitsPerSample = 0;
00114 DataSize = 0;
00115 DataOffset = 0;
00116 Valid = false;
00117 }
00118
00119 AudioFormats cWavDecoder::getFormat()
00120 {
00121 if(Channels == 1 && BitsPerSample == 8)
00122 return EAF_8BIT_MONO;
00123 else if(Channels == 1 && BitsPerSample == 16)
00124 return EAF_16BIT_MONO;
00125 else if(Channels == 2 && BitsPerSample == 8)
00126 return EAF_8BIT_STEREO;
00127 else
00128 return EAF_16BIT_STEREO;
00129 }
00130
00131 int cWavDecoder::getFrequency()
00132 {
00133 return SampleRate;
00134 }
00135
00136 bool cWavDecoder::isSeekingSupported()
00137 {
00138 return true;
00139 }
00140
00141 bool cWavDecoder::isValid()
00142 {
00143 return Valid;
00144 }
00145
00146 int cWavDecoder::readAudioData(void* output, int amount)
00147 {
00148 int currentPos = Stream->getCurrentPos();
00149 int startPos = DataOffset;
00150 int endPos = DataOffset + DataSize;
00151 int amountToRead = amount;
00152
00153
00154 if(currentPos > endPos)
00155 return 0;
00156
00157 if(currentPos < startPos)
00158 {
00159 Stream->seek(startPos, false);
00160 currentPos = Stream->getCurrentPos();
00161 }
00162
00163 if((currentPos + amountToRead) > endPos)
00164 amountToRead = endPos - currentPos;
00165
00166 if(amountToRead < 0)
00167 amountToRead = 0;
00168
00169 return Stream->read(output,amountToRead);
00170
00171 }
00172
00173 bool cWavDecoder::setPosition(int position, bool relative)
00174 {
00175 int currentPos = Stream->getCurrentPos();
00176 int startPos = DataOffset;
00177 int endPos = DataOffset + DataSize;
00178
00179
00180 if(!relative && position < startPos)
00181 position = startPos;
00182 if(!relative && position > endPos)
00183 position = endPos;
00184 if(relative && currentPos + position < startPos)
00185 position = startPos - currentPos;
00186 if(relative && currentPos + position > startPos)
00187 position = endPos - currentPos;
00188
00189 Stream->seek(position,relative);
00190 return true;
00191 }
00192
00193 bool cWavDecoder::seek(float seconds,bool relative)
00194 {
00195 int amountToSeek = seconds * (float)SampleRate * (float)Channels * (float)(BitsPerSample/8);
00196 return setPosition(amountToSeek, relative);
00197 }
00198
00199 float cWavDecoder::getTotalTime()
00200 {
00201 return (float)Stream->getSize() / ((float)SampleRate * (float)Channels * (float)(BitsPerSample/8));
00202 }
00203
00204 int cWavDecoder::getTotalSize()
00205 {
00206 return Stream->getSize();
00207 }
00208
00209 int cWavDecoder::getCompressedSize()
00210 {
00211 return Stream->getSize();
00212 }
00213
00214 float cWavDecoder::getCurrentTime()
00215 {
00216 return (float)Stream->getCurrentPos() / ((float)SampleRate * (float)Channels * (float)(BitsPerSample/8));
00217 }
00218
00219 int cWavDecoder::getCurrentPosition()
00220 {
00221 return Stream->getCurrentPos();
00222 }
00223
00224 int cWavDecoder::getCurrentCompressedPosition()
00225 {
00226 return Stream->getCurrentPos();
00227 }
00228 };
00229
00230 #endif
00231
00232