name: AudioFile public: File
synopsis:

>     g++ [flags ...] file ... -l /isip/tools/lib/$ISIP_BINARY/lib_mmedia.a

>     #include <AudioFile.h>

>     AudioFile();
>     long getData(Vector& data,
>     	     double start_time = DEF_START_TIME,
>     	     double duration = DEF_DURATION);
>     long getData(VectorFloat& data, long channel_tag,
>     	     double start_time = DEF_START_TIME,
>     	     double duration = DEF_DURATION);
>     long getRange(Vector& data, double start_time, double end_time);
>     boolean setFileType(FILE_TYPE file_type);

quick start:

>     AudioFile src;
>     src.open(L"/tmp/input.raw");

>     Vector <VectorFloat> data(1);
>     src.getData(data(0), 0, 50, 50l);

>     Filename output(L"/tmp/output.raw");

>     AudioFile dst;
>     dst.open(output, File::WRITE_ONLY);
>     dst.writeAudioData(data, 0);

description:
The AudioFile class provides a transparent interface to many different types of file formats including Sof, raw, and Microsoft WAV files. Manipulation of these files is hidden from the user. Standard C++ file-handling functions such as open and close are provided. In read-only mode, the type of a file is sensed automatically. Write modes allow a user to control the file type, compression format, storage precision, etc.
AudioFile inherits the File class from the System library. Therefore, its basic file system interactions are implemented in that class. Support for the NIST Speech File Manipulation Software (SPHERE) is provided using the NIST Sphere 2.6a library. Support for Microsoft WAV files, and a variety of other types, is provided using SGI's Audio File Library.
dependencies:

- Sphere 2.6a: Speech File Manipulation Software (NIST)
- Audiofile 0.2.2: Audio File Library (SGI)
- File
- Filename
- Long
- Double
- NameMap
- CircularBuffer
- Vector
- VectorFloat
- VectorLong

public constants:

- define the class name:

      static const String CLASS_NAME = L"AudioFile";

- define the supported file types, compression modes and channel tags:

      enum FILE_TYPE { TEXT = 0, BINARY, DEF_FILE_TYPE = TEXT };

      enum FILE_FORMAT { SOF = 0, RAW, SPHERE, AIFF, AIFFC, AU, BICSF, WAV, DEF_FILE_FORMAT = SOF };

      enum COMP_TYPE { LINEAR = 0, ULAW, ALAW, DEF_COMP_TYPE = LINEAR };

      enum SAMPLE_PRECISION { NONE = 0, USE_SIZE, EIGHT_BITS, TWELVE_BITS, SIXTEEN_BITS, TWENTY_BITS, TWENTY_FOUR_BITS, THIRTY_TWO_BITS, DEF_SAMPLE_PRECISION = NONE };

- define the names for each of the enumerated values:

      static NameMap FILE_TYPE_MAP;

      static NameMap FILE_FORMAT_MAP;

      static NameMap COMP_TYPE_MAP;

      static NameMap SAMPLE_PRECISION_MAP;

- define additional name maps for the type of data (e.g., features) and the byte mode (e.g., little endian)

      static NameMap DATA_TYPE_MAP;

      static NameMap BMODE_MAP;

- define the channel related constants:

      static const long CHANNEL_TAG_RIGHT = 1;

      static const long CHANNEL_TAG_LEFT = 0;

      static const long CHANNEL_TAG_ALL = -2;

      static const long DEF_CHANNEL_TAG = CHANNEL_TAG_ALL;

- code to read all samples:

      static const long ALL_SAMPLES = -2;

- i/o related constants:

      static const String PARAM_BYTE_ORDER = L"byte_order";

      static const String PARAM_FILE_TYPE = L"file_type";

      static const String PARAM_FILE_FORMAT = L"file_format";

      static const String PARAM_DATA_TYPE = L"data_type";

      static const String PARAM_COMP_TYPE = L"comp_type";

      static const String PARAM_RANGE = L"amplitude_range";

      static const String PARAM_DATA = L"data";

      static const String PARAM_TAG = L"tag";

      static const String PARAM_SAMPLE_FREQUENCY = L"sample_frequency";

      static const String PARAM_SAMPLE_NUM_BYTES = L"sample_num_bytes";

      static const String PARAM_SAMPLE_PRECISON = L"sample_precision";

      static const String PARAM_NUM_CHANNELS = L"num_channels";

      static const String PARAM_BLOCK_SIZE = L"block_size";

      static const String PARAM_BUF_SIZE = L"buf_size";

      static const String PARAM_ID = L"id";

      static const String PARAM_MA_COEFF = L"ma_coeff";

      static const String PARAM_AR_COEFF = L"ar_coeff";

- define the default values:

      static const double DEF_AMPLITUDE_RANGE = 1.0;

      static const double DEF_SAMPLE_FREQ = 8000.0;

      static const long DEF_SAMPLE_NUM_BYTES = 2;

      static const long DEF_NUM_CHANNELS = 1;

- a buffer contains DEF_BUF_SIZE * DEF_BLOCK_SIZE elements:

      static const long DEF_BLOCK_SIZE = 8192;

      static const long DEF_BUF_SIZE = 4;

- coefficients of the built-in filter:

      static VectorFloat DEF_MA_COEFF(L"1.0");

      static VectorFloat DEF_AR_COEFF(L"1.0");

- define the default arguments to methods:

      static const double DEF_START_TIME = 0.0;

      static const double DEF_CENTER_TIME = 0.25;

      static const double DEF_DURATION = 0.5;

      static const long DEF_START_SAMP = 0;

      static const long DEF_NUM_SAMP = 4000;

      static const long DEF_TAG = 0;

error codes:

- error code indicating AudioFile class general error:

      static const long ERR = 50000;

- error code indicating the wrong data type:

      static const long ERR_TYPE = 50001;

- error code indicating a bad ar coefficient:

      static const long ERR_ARCOEF = 50002;

- error code indicating an attempt to pipe a non-raw file:

      static const long ERR_PTYPE = 50003;

- error code indicating an attempt to pipe a non-raw file:

      static const long ERR_PMODE = 50004;

- error code indicating an attempt to open non-raw file:

      static const long ERR_PRECFG = 50005;

protected data:

- buffer of audio data:

      Vector<CircularBuffer<Float> > buffers_d;

      Vector<Long> buf_end_samp_d;

- parameters of the audio file:

      FILE_TYPE file_type_d;                // file type

      FILE_FORMAT file_format_d;            // file format

      COMP_TYPE compression_type_d;         // compression type

      Double range_threshold_d;             // range threshold for compression

      Double sample_freq_d;                 // sample frequency

      Long sample_num_bytes_d;              // number of bytes per sample

      SAMPLE_PRECISION sample_precision_d;  // sample precision in bits

      Long num_channels_d;                  // number of channels

- maximum sample value: computed from sample_precision_d and sample_num_bytes_d

      double sample_max_val_d;

- parameters for reading data: we read a block of bytes from the file with each read operation (for efficiency):

      Long block_size_d;

      Long buf_size_d;

- parameter for file identification

      String id_d;

- parameters of the IIR filter:

      VectorFloat ma_coeff_d;

      VectorFloat ar_coeff_d;

      Vector< CircularBuffer<Float> > ma_mem_d;

      Vector< CircularBuffer<Float> > ar_mem_d;

- internal buffers for reading and writing from the file:

      byte* io_buf_d;

      VectorFloat interleaved_d;

- old configuration: if we open a file that has its own configuration we should store the user's configuration wishes in case we later encounter a file without parameters. for example, the user sets the byte order to native, reads in a Sof file that is rev4, then later encounters a raw file.

      AudioFile* backup_config_d;

- since the AudioFile class can either hold configuration information for auxiliary file formats (RAW, SPHERE, WAV, etc) or the actual signal data, this flag lets the class keep track of whether data is actually present in the file or not:

      boolean no_data_d;

- have we reached the end of file?

      boolean end_of_file_d;

- buffer to store the whole data when AudioFile object is read at one time instead of reading frame by frame or piece by piece:

      Vector < VectorFloat > sampled_data_d;

- variables for Sof file formats:

      Sof* sof_d;

      Long tag_d;

- if we are writing to an Sof file we need to keep track of where we write the AudioFile object's size and the vector's length:

      long sof_length_pos_d;

      long samples_written_d;

- debug level: this debug_level_d is not inherited because the AudioFile needs to have its own debug level.

      static Integral::DEBUG debug_level_d;

- a static memory manager for AudioFile objects:

      static MemoryManager mgr_d;

- a static memory manager for the byte* scratch space:

      static MemoryManager scratch_mgr_d;

- this section contains data for specific file formats
  - file format: NIST Sphere
    - define a Sphere file object

          #ifdef HAVE_SPHERE

          SP_FILE* sp_file_d;

          #endif

  - file format: any type supported by SGI Audio File (e.g., WAV and AIFF)
    - define an Audio File object

          #ifdef HAVE_AUDIOFILE

          AFfilehandle af_file_d;

          #endif

required public methods:

- static methods:

      inline static const String& name();

      static boolean diagnose(Integral::DEBUG debug_level);

- debug methods:

      boolean debug(const unichar* message) const;

      inline boolean setDebug(Integral::DEBUG debug_level);

- destructor/constructor(s):

      ~AudioFile();

      AudioFile(FILE_TYPE ftype = DEF_FILE_TYPE, FILE_FORMAT fformat = DEF_FILE_FORMAT, DATA_TYPE dtype = DEF_DATA_TYPE);

      AudioFile(const AudioFile& copy_audio_file);

- assign methods:

      boolean assign(const AudioFile& copy_adf);

- operator= methods:

      inline AudioFile& operator= (const AudioFile& arg);

- i/o methods: these methods are the standard IFC I/O methods that interface to Sof files. Note that the read method reads the entire file, while the write method writes to disk only the amount of the file that has been read into memory.

      long sofSize() const;

      boolean read(Sof& sof, long tag, const String& name);

      boolean write(Sof& sof, long tag, const String& name) const;

      boolean readData(Sof& sof, const String& pname = String::getEmptyString(), long size = SofParser::FULL_OBJECT, boolean param = true, boolean nested = false);

      boolean writeData(Sof& sof, const String& pname = String::getEmptyString()) const;

- equality methods:

      boolean eq(const AudioFile& arg) const;

- memory management methods:

      static void* operator new(size_t size);

      static void* operator new[](size_t size);

      static void operator delete(void* ptr);

      static void operator delete[](void* ptr);

      static boolean setGrowSize(long grow_size);

      boolean clear();

class-specific public methods:

- constructor(s):

      AudioFile(FILE_TYPE ftype = DEF_FILE_TYPE, FILE_FORMAT fformat = DEF_FILE_FORMAT, DATA_TYPE dtype = DEF_DATA_TYPE, double sample_frequency, long sample_num_bytes, long num_channels););

- open and close methods:

      boolean open(const Filename& filename, MODE mode = READ_ONLY);

      boolean open(const unichar* filename, MODE mode = READ_ONLY);

      boolean isOpen() const;

      boolean close();

- get data methods: these are the primary interface for getting sampled audio data from a file.

      long getData(Vector<VectorFloat>& data, double start_time = DEF_START_TIME, double duration = DEF_DURATION);

      long getData(VectorFloat& data, long channel_tag, double start_time = DEF_START_TIME, double duration = DEF_DURATION);

      long getData(Vector<VectorFloat>& data, long start_samp, long num_samp);

      long getData(VectorFloat& data, long channel_tag, long start_samp, long num_samp);

      long getWindow(Vector<VectorFloat>& data, double center_time, double duration = DEF_DURATION);

      long getWindow(VectorFloat& data, long channel_tag, double center_time, double duration = DEF_DURATION);

      long getRange(Vector<VectorFloat>& data,double start_time, double end_time);

      long getRange(VectorFloat& data, long channel_tag, double start_time, double end_time);

      long readAudioData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG, long start_samp = DEF_START_SAMP, long num_samp = DEF_NUM_SAMP);

      long writeAudioData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG);

- methods to get auxillary information

      double getAmplitudeRange() const;

      COMP_TYPE getCompType() const;

      FILE_FORMAT getFileFormat() const;

      FILE_TYPE getFileType() const;

      const String& getID() const;

      long getNumChannels() const;

      long getNumSamples() const;

      double getSampleFrequency() const;

      long getSampleNumBytes() const;

      SAMPLE_PRECISION getSamplePrecision() const;

- methods to set auxillary information

      boolean setAmplitudeRange(double range_threshold);

      boolean setBlockSize(long nbytes);

      boolean setBufferSize(long nblocks);

      boolean setCompType(COMP_TYPE comp_type);

      boolean setFileFormat(FILE_FORMAT file_format);

      boolean setFileType(FILE_TYPE file_type);

      boolean setID(const String& id);

      boolean setNumChannels(long num_channels);

      boolean setSampleFrequency(double sample_freq);

      boolean setSampleNumBytes(long sample_num_bytes);

      boolean setSamplePrecision(SAMPLE_PRECISION sample_precision);

- methods to manipulate the internal filter:

      const VectorFloat& getMaCoeff() const;

      const VectorFloat& getArCoeff() const;

      boolean setMaCoeff(VectorFloat& ma_coeff);

      boolean setArCoeff(VectorFloat& ar_coeff);

- methods that perform units conversions:

      long timeToSample(double time) const;

      double sampleToTime(long index) const;

- methods that specifically deal with Sof files:

      boolean readSofData(Sof& sof);

      boolean writeSofData(Sof& sof) const;

      boolean readSofStart(Sof& sof, long tag, const String& name);

      boolean writeSofStart(Sof& sof, long tag, const String& name) const;

      boolean readSofStartData(Sof& sof, const String& pname = String::getEmptyString(), long size = SofParser::FULL_OBJECT, boolean param = true, boolean nested = false);

      boolean writeSofStartData(Sof& sof, const String& pname = String::getEmptyString()) const;

      boolean readSofConfig(Sof& sof, SofParser& parser);

      boolean writeSofConfig(Sof& sof) const;

private methods:

- get the starting and ending time points of the internal buffer:

      long getStartSamp(long channel_tag = DEF_CHANNEL_TAG) const;

      long getEndSamp(long channel_tag = DEF_CHANNEL_TAG) const;

- methods to read the next block of data:

      boolean appendData();

- convert the Vector<VectorFloat> to bytes for writing:

      boolean revertData(VectorLong& whole_data, Vector<VectorFloat>& data, long channel_tag) const;

- round methods:

      long blockFloor(long samp_num) const;

      long blockCeil(long samp_num) const;

- reset methods:

      boolean resetBuffer(long channel_tag);

      boolean resetFilter(long channel_tag);

- file-type specific methods: for each type supported, implementations must be supplied for six functions.
  Format: Signal Object File (Sof)

      boolean openSofStream(const Filename& filename, MODE mode = READ_ONLY);

      boolean openSof(const Filename& filename, MODE mode = READ_ONLY);

      boolean readSofHeader();

      boolean writeSofHeader();

      long readSofData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG, long start_samp = DEF_START_SAMP, long num_samp = DEF_NUM_SAMP);

      long writeSofData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG);

  Format: Unformatted data (RAW)

      boolean openRawStream(const Filename& filename, MODE mode = READ_ONLY);

      boolean openRaw(const Filename& filename, MODE mode = READ_ONLY);

      boolean readRawHeader();

      boolean writeRawHeader();

      long readRawData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG, long start_samp = DEF_START_SAMP, long num_samp = DEF_NUM_SAMP);

      long writeRawData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG);

  Format: NIST Speech File Manipulation Software (SPHERE)

      boolean openSphereStream(const Filename& filename, MODE mode = READ_ONLY);

      boolean openSphere(const Filename& filename, MODE mode = READ_ONLY);

      boolean readSphereHeader();

      boolean writeSphereHeader();

      long readSphereData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG, long start_samp = DEF_START_SAMP, long num_samp = DEF_NUM_SAMP);

      long writeSphereData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG);

  Format: SGI Audio File (WAV, AIFF, etc.)

      boolean openAFStream(const Filename& filename, MODE mode = READ_ONLY);

      boolean openAF(const Filename& filename, MODE mode = READ_ONLY);

      boolean readAFHeader();

      boolean writeAFHeader();

      long readAFData(Vector<VectorFloat>& data, long channel_tag = DEF_CHANNEL_TAG, long start_samp = DEF_START_SAMP, long num_samp = DEF_NUM_SAMP);

      long writeAFData(Vector<VectorFloat>& data, long channel_tag  = DEF_CHANNEL_TAG);

examples:

- This example shows how to use read/write AuidoFile and get data from AudioFile

      // isip include files
      //
      #include <AudioFile.h>

      // main program starts here
      //
      int main() {

        // declare AudioFile objects for read
        //
        AudioFile src;

        src.setFileFormat(AudioFile::RAW);  // set file format
        src.setFileType(AudioFile::BINARY);  // set file type

        // open file, default is read only
        //
        src.open(L"$ISIP_DEVEL/doc/examples/data/audio/bg_119oo39a.raw");

        long N = 80; // defined the sample number for one process
        Long len;  // define local variable

        len = src.getNumSamples(); // get number of samples in this file
        len = (long)len / N;      // get how many frames we need to process

        // loop through N samples at a time
        //
        for (long i = 0; i < len; i++) {

          // define local variable to hold data
          //
          Vector<VectorFloat> data(1);

          // get sample data
          //
          src.getData(data(0), 0, i * N, N);

          // write these N samples to the output
          //
          data.debug(L"data");
        }

        // close file
        //
        src.close();

        // exit gracefully
        //
        Integral::exit();

      }

notes:

- AudioFile currently supports RAW and Sof audio files using internal code. It also supports other formats using two external libraries described above.