/*---------------------------------------------------------------------------* * IT++ * *---------------------------------------------------------------------------* * Copyright (c) 1995-2001 by Tony Ottosson, Thomas Eriksson, Pål Frenger, * * Tobias Ringström, and Jonas Samuelsson. * * * * Permission to use, copy, modify, and distribute this software and its * * documentation under the terms of the GNU General Public License is hereby * * granted. No representations are made about the suitability of this * * software for any purpose. It is provided "as is" without expressed or * * implied warranty. See the GNU General Public License for more details. * *---------------------------------------------------------------------------*/ /*! \file \brief Implementation of audio Audio classes and functions. \author Tobias Ringström 1.5 2003/05/22 08:55:20 */ #include "srccode/audiofile.h" #include "base/machdep.h" #include "base/scalfunc.h" #include #include using std::istream; using std::ostream; using std::ifstream; using std::ofstream; using std::ios; namespace itpp { #ifndef DOXYGEN_SHOULD_SKIP_THIS #define SND_MAGIC 0x2e736e64 inline static short double_to_short(double x) { if (x >= 32767.0) return 32767; else if (x <= -32768.0) return -32768; else return round_i(x); } inline static signed char double_to_char(double x) { if (x >= 127.0) return 127; else if (x <= -128.0) return -128; else return round_i(x); } #define MK_RW_FUNS(type,namestub) \ inline static type read_##namestub(istream &s) \ { type v; s.read(reinterpret_cast(&v), sizeof(type)); return v; } \ inline static void write_##namestub(ostream &s, type v) \ { s.write(reinterpret_cast(&v), sizeof(type)); } #endif /* DOXYGEN_SHOULD_SKIP_THIS */ MK_RW_FUNS(signed char,char) MK_RW_FUNS(short,short) MK_RW_FUNS(int,int) MK_RW_FUNS(unsigned,unsigned) MK_RW_FUNS(float,float) MK_RW_FUNS(double,double) bool raw16le_read(const char *fname, vec &v) { ifstream file(fname, ios::in | ios::binary); struct stat st; int n, i; if (stat(fname, &st) == -1) return false; n = st.st_size / 2; // short vs. byte v.set_size(n, false); for (i=0; i= 0, "raw16_read()"); v.set_size(len, false); file.seekg(2 * beg); for (i=0; i= 0, "raw16_read()"); v.set_size(len, false); file.seekg(2 * beg); for (i=0; i(&header.info), SND_INFO_LEN); return f.good(); } ////////////////////////////////////////////////// // // SND_In_File // ////////////////////////////////////////////////// SND_In_File::SND_In_File() { } SND_In_File::SND_In_File(const char *fname) { open(fname); } bool SND_In_File::open(const char *fname) { if (file.is_open()) close(); file.clear(); is_valid = false; file.open(fname, ios::in | ios::binary); if (!file) return false; if (!read_header(file)) { file.close(); return false; } is_valid = true; return true; } void SND_In_File::close() { file.close(); is_valid = false; } bool SND_In_File::seek_read(int pos) { if (pos < 0) file.seekg(0, ios::end); else file.seekg(header.hdr_size + header.channels * sample_size() * pos); return true; } int SND_In_File::tell_read() { if (!good()) return -1; return ( static_cast(file.tellg()) - sizeof(header) ) / ( header.channels * sample_size() ); } bool SND_In_File::read(vec &v) { if (!good()) return false; int i, n; n = samples(); v.set_size(n, false); seek_read(0); switch (header.encoding) { case enc_linear8 : for (i=0; i(file.tellp()) - sizeof(header); write_header(file); file.close(); is_valid = false; } bool SND_Out_File::seek_write(int pos) { if (!good()) return false; if (pos < 0) file.seekp(0, ios::end); else file.seekp(sizeof(header) + header.channels * sample_size() * pos); return true; } int SND_Out_File::tell_write() { if (!good()) return -1; return ( static_cast(file.tellp()) - sizeof(header) ) / ( header.channels * sample_size() ); } bool SND_Out_File::write(const vec &v) { if (!good()) return false; int i; switch (header.encoding) { case enc_linear8 : for (i=0; i