Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

/root/src/subsynth/syn/Stream/WavAudioIStream.cpp

Go to the documentation of this file.
00001 
00002 /****************** <SYN heading BEGIN do not edit this line> *****************
00003  *
00004  * subsynth - modular audio synthesizer
00005  * subsynth is (C) Copyright 2001-2002 by Kevin Meinert
00006  *
00007  * Original Author: Kevin Meinert
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Library General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Library General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public
00020  * License along with this library; if not, write to the
00021  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00022  * Boston, MA 02111-1307, USA.
00023  *
00024  * -----------------------------------------------------------------
00025  * File:          $RCSfile: WavAudioIStream.cpp,v $
00026  * Date modified: $Date: 2002/02/16 19:24:16 $
00027  * Version:       $Revision: 1.10 $
00028  * -----------------------------------------------------------------
00029  *
00030  ****************** <SYN heading END do not edit this line> ******************/
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    // filter the data to the correct host byte ordering...
00076    //syn::byteReverse( syn::LITTLE, *((int*)wave.riff) );
00077    syn::byteReverse( syn::LITTLE, wave.riffSize );
00078    //syn::byteReverse( syn::LITTLE, *((int*)wave.wave) );
00079    //syn::byteReverse( syn::LITTLE, *((int*)wave.fmt) );
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    //syn::byteReverse( syn::LITTLE, *((int*)wave.data) );
00088    syn::byteReverse( syn::LITTLE, wave.dataSize );
00089 
00090    // make sure the format is one that we can read...
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    // save the streampos at the beginning of the data...
00107    mDataPosition = mFile.tellp();
00108 
00109    // save the important data read from the header...
00110    mSourceFormat.channels = wave.Channels;
00111    mSourceFormat.samplingRateHz = wave.SamplesPerSec;
00112    int bytes_per_sample = wave.BitsPerSample / 8;
00113    //std::cout<<"bytes per sample: "<<bytes_per_sample<<"\n"<<std::flush;
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    // make sure everything is sane, then return.
00128    assert( mFile.bad() == false ); // to record a loss of integrity of the stream buffer
00129    assert( mFile.fail() == false ); // to record a failure to extract a valid field from a stream 
00130    assert( mFile.eof() == false ); // to record end-of-file while extracting from a stream 
00131    assert( mFile.good() == true ); // no bits set
00132    assert( mFile.is_open() == true ); // we didn't accidentally close it.
00133    return true;
00134 }
00135 
00141 void WavAudioIStream::read( void* data, unsigned int samples )
00142 {
00143    // handle the case where dest channels is different than src channels.
00144    // if we are converting to more channles, then we only need to read half as much
00145    // if we are converting to less channles, then we need to read twice as many samples...
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    // get the actual number read...
00154    int actual_bytes_read = mFile.gcount();
00155    actual_samples_read = actual_bytes_read / mSourceFormat.sampsize();
00156 
00157    // convert the data to host byte order...
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       // get the data in floats...
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       // get the data in the requested format
00183       syn::audio_convert( fmt, mDestFormat,
00184                           (char*)&float_data[0], actual_samples_read, data, actual_samples_read );
00185    }
00186    else
00187    {
00188       // get the data in the requested format
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 };

Generated at Mon Apr 15 09:26:08 2002 for subsynth by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001