AudioWavFile.C

Go to the documentation of this file.
00001 /*!@file Audio/AudioWavFile.C File I/O on audio .wav files */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file:
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Audio/AudioWavFile.C $
00035 // $Id: AudioWavFile.C 8648 2007-07-30 19:41:42Z abondada $
00036 //
00037 
00038 #ifndef AUDIO_AUDIOWAVFILE_C_DEFINED
00039 #define AUDIO_AUDIOWAVFILE_C_DEFINED
00040 
00041 #include "Audio/AudioWavFile.H"
00042 #include "Util/log.H"
00043 #include <cstdio>
00044 
00045 // ######################################################################
00046 template <class T>
00047 void writeAudioWavFile(const std::string& fname,
00048                        const AudioBuffer<T>& buf)
00049 {
00050   std::vector<AudioBuffer<T> > vbuf;
00051   vbuf.push_back(buf);
00052   writeAudioWavFile(fname, vbuf);
00053 }
00054 
00055 // ######################################################################
00056 template <class T>
00057 void writeAudioWavFile(const std::string& fname,
00058                        const std::vector<AudioBuffer<T> >& buf)
00059 {
00060   FILE *fil = fopen(fname.c_str(), "wb");
00061   if (fil == NULL) PLFATAL("Cannot write %s", fname.c_str());
00062 
00063   // Write a .wav file. Format was gleaned from
00064   // http://www.borg.com/~jglatt/tech/wave.htm and from
00065   // http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
00066   uint bufsiz = 0;
00067   for (uint i = 0; i < buf.size(); ++ i) bufsiz += buf[i].sizeBytes();
00068 
00069   const uint fsiz = bufsiz + 36;
00070   const uint freq = uint(buf[0].freq());
00071   const uint brate = freq * sizeof(T) * buf[0].nchans(); // byte rate
00072   const byte bps = byte(sizeof(T) * 8);
00073   const uint blockalign = buf[0].nchans() * sizeof(T);
00074 
00075   LDEBUG("buffer: freq=%u, brate=%u, bps=%d",
00076          freq, brate, int(bps));
00077 
00078   const byte header[44] =
00079     {
00080       /* 0-3    */ 'R', 'I', 'F', 'F',
00081 
00082       /* 4-5    */ byte(fsiz & 0xFF), byte((fsiz >> 8) & 0xFF),
00083       /* 6-7    */ byte((fsiz >> 16) & 0xFF), byte((fsiz >> 24) & 0xFF),
00084 
00085       /* 8-21   */ 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ', 0x10, 0, 0, 0, 1, 0,
00086       /* 22-23  */ byte(buf[0].nchans()), 0,
00087 
00088       /* 24-25  */ byte(freq & 0xFF), byte((freq >> 8) & 0xFF),
00089       /* 26-27  */ byte((freq >> 16) & 0xFF), byte((freq >> 24) & 0xFF),
00090 
00091       /* 28-29  */ byte(brate & 0xFF), byte((brate >> 8) & 0xFF),
00092       /* 30-31  */ byte((brate >> 16) & 0xFF), byte((brate >> 24) & 0xFF),
00093 
00094       /* 32-39  */ byte(blockalign & 0xFF), byte((blockalign >> 8) & 0xFF),
00095       /* 34-39  */ bps, 0, 'd', 'a', 't', 'a',
00096 
00097       /* 40-41  */ byte(bufsiz & 0xFF), byte((bufsiz >> 8) & 0xFF),
00098       /* 42-43  */ byte((bufsiz >> 16) & 0xFF), byte((bufsiz >> 24) & 0xFF)
00099     };
00100 
00101   if (fwrite(header, 44, 1, fil) != 1)
00102     PLFATAL("Error writing header to %s", fname.c_str());
00103 
00104   for (uint i = 0; i < buf.size(); ++ i)
00105     if (fwrite(buf[i].getDataPtr(), buf[i].sizeBytes(), 1, fil) != 1)
00106       PLFATAL("Error writing data chunk %u to %s", i, fname.c_str());
00107 
00108   fclose(fil);
00109 
00110   LINFO("%d bytes written to %s", bufsiz, fname.c_str());
00111 }
00112 
00113 // ######################################################################
00114 template <class T>
00115 void readAudioWavFile(const std::string& fname, AudioBuffer<T>& buf)
00116 {
00117   FILE *fil = fopen(fname.c_str(), "rb");
00118   if (fil == NULL) PLFATAL("Cannot read %s", fname.c_str());
00119 
00120   // Read a .wav file. Format was gleaned from
00121   // http://www.borg.com/~jglatt/tech/wave.htm and from
00122   // http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
00123   byte header[44];
00124   if (fread(header, 44, 1, fil) != 1)
00125     PLFATAL("Error reading header from %s", fname.c_str());
00126 
00127   // decode header:
00128   if (header[0]!='R' || header[1]!='I' || header[2]!='F' || header[3]!='F')
00129     LFATAL("Wrong magic - %s is not a .wav file", fname.c_str());
00130 
00131   const uint nchan = header[22];
00132   const uint freq = header[24] | (header[25]<<8) |
00133     (header[26]<<16) | (header[27]<<24);
00134   const uint blockalign = header[32] + (header[33]<<8);
00135   const uint bps = header[34];
00136   const uint bufsiz =
00137     header[40] | (header[41]<<8) | (header[42]<<16) | (header[43]<<24);
00138 
00139   LDEBUG("%s: nchan=%u, freq=%u, blockalign=%u, bps=%u, bufsiz=%u",
00140          fname.c_str(), nchan, freq, blockalign, bps, bufsiz);
00141 
00142   if (bps != sizeof(T) * 8)
00143     LFATAL("Wrong bps: file=%u, buffer=%u", bps, uint(sizeof(T)));
00144 
00145   // initialize the AudioBuffer:
00146   AudioBuffer<T> b(bufsiz / (nchan * (bps / 8)), nchan, float(freq), NO_INIT);
00147 
00148   // read the audio data:
00149   if (fread(b.getDataPtr(), bufsiz, 1, fil) != 1)
00150     PLFATAL("Error reading data from %s", fname.c_str());
00151 
00152   // return buffer:
00153   fclose(fil);
00154   buf = b;
00155 }
00156 
00157 // template instantiations:
00158 template void writeAudioWavFile(const std::string& fname,
00159                                 const std::vector<AudioBuffer<byte> >& buf);
00160 template void writeAudioWavFile(const std::string& fname,
00161                                 const std::vector<AudioBuffer<uint16> >& buf);
00162 template void writeAudioWavFile(const std::string& fname,
00163                                 const std::vector<AudioBuffer<int16> >& buf);
00164 
00165 template void writeAudioWavFile(const std::string& fname,
00166                                 const AudioBuffer<byte>& buf);
00167 template void writeAudioWavFile(const std::string& fname,
00168                                 const AudioBuffer<uint16>& buf);
00169 template void writeAudioWavFile(const std::string& fname,
00170                                 const AudioBuffer<int16>& buf);
00171 
00172 template void readAudioWavFile(const std::string& fname,
00173                                AudioBuffer<byte>& buf);
00174 template void readAudioWavFile(const std::string& fname,
00175                                AudioBuffer<uint16>& buf);
00176 template void readAudioWavFile(const std::string& fname,
00177                                AudioBuffer<int16>& buf);
00178 
00179 // ######################################################################
00180 /* So things look consistent in everyone's emacs... */
00181 /* Local Variables: */
00182 /* mode: c++ */
00183 /* indent-tabs-mode: nil */
00184 /* End: */
00185 
00186 #endif // DEVICES_AUDIOWAVFILE_C_DEFINED
Generated on Sun May 8 08:04:24 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3