00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "syn/Stream/WavAudioIStream.h"
00033
00034 namespace syn
00035 {
00036
00037 WavAudioIStream::WavAudioIStream() : mFilename( "filename_not_set.wav" ), mAmplitude( 1.0f ), mDcOffset( 0.0f )
00038 {
00039 }
00040
00044 void WavAudioIStream::setName( const std::string& filename )
00045 {
00046 mFilename = filename;
00047 }
00048
00054 bool WavAudioIStream::open( const syn::AudioFormat& fmt, syn::AudioIStream::Operation op )
00055 {
00056 syn::WavHeader wave;
00057
00058 mFile.open( mFilename.c_str(), std::ios::in | std::ios::binary );
00059
00060 if (mFile.bad())
00061 {
00062 std::cout<<"Failed to open "<<mFilename<<"\n"<<std::flush;
00063 mFile.close();
00064 return false;
00065 }
00066
00067 mFile.read( (char*)&wave, sizeof(syn::WavHeader) );
00068 if (mFile.eof() == true || mFile.bad() == true)
00069 {
00070 std::cout<<"Invalid wave file\n"<<std::flush;
00071 mFile.close();
00072 return false;
00073 }
00074
00075
00076
00077 syn::byteReverse( syn::LITTLE, wave.riffSize );
00078
00079
00080 syn::byteReverse( syn::LITTLE, wave.fmtSize );
00081 syn::byteReverse( syn::LITTLE, wave.Format );
00082 syn::byteReverse( syn::LITTLE, wave.Channels );
00083 syn::byteReverse( syn::LITTLE, wave.SamplesPerSec );
00084 syn::byteReverse( syn::LITTLE, wave.BytesPerSec );
00085 syn::byteReverse( syn::LITTLE, wave.BlockAlign );
00086 syn::byteReverse( syn::LITTLE, wave.BitsPerSample );
00087
00088 syn::byteReverse( syn::LITTLE, wave.dataSize );
00089
00090
00091 std::string r, w, f, d;
00092 r.assign( (char*)wave.riff, 4 );
00093 w.assign( (char*)wave.wave, 4 );
00094 f.assign( (char*)wave.fmt, 4 );
00095 d.assign( (char*)wave.data, 4 );
00096
00097 if (std::string( "RIFF" ) != r || std::string( "WAVE" ) != w ||
00098 std::string( "fmt " ) != f || std::string( "data" ) != d )
00099 {
00100 std::cout<<"unsupported wave file format\n"<<std::flush;
00101 std::cout<<r<<" "<<w<<" "<<f<<" "<<d<<"\n"<<std::flush;
00102 mFile.close();
00103 return false;
00104 }
00105
00106
00107 mDataPosition = mFile.tellp();
00108
00109
00110 mSourceFormat.channels = wave.Channels;
00111 mSourceFormat.samplingRateHz = wave.SamplesPerSec;
00112 int bytes_per_sample = wave.BitsPerSample / 8;
00113
00114 switch (bytes_per_sample)
00115 {
00116 case 1: mSourceFormat.datatype = syn::AudioFormat::SIGNED8; break;
00117 case 2: mSourceFormat.datatype = syn::AudioFormat::SIGNED16; break;
00118 default:
00119 std::cout<<"unsuported bit depth\n"<<std::flush;
00120 assert( false && "unsupported" );
00121 mFile.close();
00122 return false;
00123 }
00124 mDestFormat = fmt;
00125 mNumBytes = wave.dataSize;
00126
00127
00128 assert( mFile.bad() == false );
00129 assert( mFile.fail() == false );
00130 assert( mFile.eof() == false );
00131 assert( mFile.good() == true );
00132 assert( mFile.is_open() == true );
00133 return true;
00134 }
00135
00141 void WavAudioIStream::read( void* data, unsigned int samples )
00142 {
00143
00144
00145
00146 samples = (unsigned int)((float)samples * (float)mSourceFormat.channels / (float)mDestFormat.channels);
00147
00148 actual_data.resize( samples * mSourceFormat.sampsize() );
00149 assert( actual_data.size() == samples * mSourceFormat.sampsize() && "couldn't resize" );
00150
00151 mFile.read( (char*)&actual_data.front(), actual_data.size() );
00152
00153
00154 int actual_bytes_read = mFile.gcount();
00155 actual_samples_read = actual_bytes_read / mSourceFormat.sampsize();
00156
00157
00158 if (mSourceFormat.sampsize() == 2 && syn::isBig() == true)
00159 {
00160 short* temp = (short*)&actual_data.front();
00161 for (int x = 0; x < actual_samples_read; ++x)
00162 {
00163 syn::byteReverse( temp[x] );
00164 }
00165 }
00166
00167 if (mAmplitude != 1.0f || mDcOffset != 0.0f)
00168 {
00169 float_data.resize( actual_samples_read );
00170
00171
00172 AudioFormat fmt = mSourceFormat;
00173 fmt.datatype = AudioFormat::FLOAT32;
00174 syn::audio_convert( mSourceFormat, fmt,
00175 (char*)&actual_data[0], actual_samples_read, (char*)&float_data[0], actual_samples_read );
00176
00177 for (int x = 0; x < actual_samples_read; ++x)
00178 {
00179 float_data[x] = audio_clamp<float>( float_data[x] * mAmplitude + mDcOffset );
00180 }
00181
00182
00183 syn::audio_convert( fmt, mDestFormat,
00184 (char*)&float_data[0], actual_samples_read, data, actual_samples_read );
00185 }
00186 else
00187 {
00188
00189 syn::audio_convert( mSourceFormat, mDestFormat,
00190 (char*)&actual_data[0], actual_samples_read, data, actual_samples_read );
00191 }
00192 }
00193
00194
00195
00196
00200 bool WavAudioIStream::close()
00201 {
00202 mFile.close();
00203 return true;
00204 }
00205
00211 int WavAudioIStream::numsamps()
00212 {
00213 return mNumBytes / mSourceFormat.sampsize();
00214 }
00215
00216
00217 bool WavAudioIStream::good() const
00218 {
00219 return mFile.good();
00220 }
00221
00222 bool WavAudioIStream::bad() const
00223 {
00224 return mFile.bad();
00225 }
00226
00227 bool WavAudioIStream::eof() const
00228 {
00229 return mFile.eof();
00230 }
00231
00232 bool WavAudioIStream::isOpen() const
00233 {
00234 return mFile.is_open();
00235 }
00236
00237 int WavAudioIStream::gcount() const
00238 {
00239 return actual_samples_read;
00240 }
00241
00245 void WavAudioIStream::seek( int sampleNum )
00246 {
00247 if (mFile.is_open())
00248 {
00249 mFile.clear();
00250 this->seek_data( sampleNum * mSourceFormat.sampsize() );
00251 }
00252 }
00253
00257 int WavAudioIStream::numbytes()
00258 {
00259 return mNumBytes;
00260 }
00261
00265 void WavAudioIStream::seek_data( int numBytes )
00266 {
00267 mFile.seekg( mDataPosition );
00268 mFile.seekg( numBytes, std::ios::cur );
00269 }
00270
00271
00272 };