// file: $isip/class/mmedia/AudioFile/adf_07.cc // version: $Id: adf_07.cc 9328 2003-10-27 21:43:25Z parihar $ // // isip include files // #include "AudioFile.h" #include #include #include // method: isOpen // // arguments: none // // return: bool8 answer // // this method checks if the audiofile is open // bool8 AudioFile::isOpen() const { // branch on file type // if (file_format_d == RAW) { return File::isOpen(); } else if (file_format_d == SOF) { if (sof_d != (Sof*)NULL) { return sof_d->isOpen(); } } #ifdef HAVE_SPHERE else if (file_format_d == SPHERE) { return sp_file_d != (SP_FILE*)NULL; } #endif #ifdef HAVE_AUDIOFILE else { return af_file_d != (AFfilehandle)NULL; } #endif // must not be open // return false; } // method: open // // arguments: // const unichar* filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the file // bool8 AudioFile::open(const unichar* filename_a, MODE mode_a) { Filename temp(filename_a); // call the master function // return open(temp, mode_a); } // method: open // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the file // bool8 AudioFile::open(const Filename& filename_a, MODE mode_a) { // save the configuration // if (backup_config_d != (AudioFile*)NULL) { return Error::handle(name(), L"open", Error::MEM, __FILE__, __LINE__); } backup_config_d = new AudioFile; backup_config_d->assign(*this); // if the filename is a '-' (streaming input from stdin) // if (filename_a.eq(STREAM_FILE)) { // format: SOF // if (file_format_d == SOF) { if (!openSofStream(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } // format: RAW // else if (file_format_d == RAW) { if (!openRawStream(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } // format: SPHERE // else if (file_format_d == SPHERE) { if (!openSphereStream(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } // format: supported by sgi audiofile library // else { if (!openAFStream(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } } // non-piped file, branch on type // else { // format: SOF // if (file_format_d == SOF) { if (!openSof(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } // format: RAW // else if (file_format_d == RAW) { if (!openRaw(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } // format: SPHERE // else if (file_format_d == SPHERE) { if (!openSphere(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } // format: supported though sgi's audiofile library // else { if (!openAF(filename_a, mode_a)) { return Error::handle(name(), L"open", Error::IO, __FILE__, __LINE__, Error::WARNING); } } } // reset the buffers and filters // resetBuffer(); resetFilter(); // exit gracefully // return true; } // method: openRawStream // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the audiofile as streaming input from stdin // bool8 AudioFile::openRawStream(const Filename& filename_a, MODE mode_a) { // if the filename is a '-', open the pipe // if (filename_a.eq(STREAM_FILE)) { if (file_format_d == RAW) { // a read only pipe pulls data from stdin // if (mode_a == READ_ONLY) { File::open(STREAM_FILE, mode_a); // read the dummy raw header // if (!readRawHeader()) { return Error::handle(name(), L"openRawStream", Error::READ, __FILE__, __LINE__, Error::WARNING); } } // a write only pipe pushes to stdout // else if (mode_a == WRITE_ONLY) { File::open(STREAM_FILE, mode_a); // write the dummy raw header // if (!writeRawHeader()) { return Error::handle(name(), L"openRawStream", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } // no other pipes are supported // else { return Error::handle(name(), L"openRawStream", ERR_PMODE, __FILE__, __LINE__); } } // wrong file type // else { return Error::handle(name(), L"openRawStream", ERR_PTYPE, __FILE__, __LINE__); } } // wrong file type // else { return Error::handle(name(), L"openRawStream", ERR_PTYPE, __FILE__, __LINE__); } // set the id to the stream file symbol // id_d.assign(STREAM_FILE); // exit gracefully // return true; } // method: openRaw // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the file // bool8 AudioFile::openRaw(const Filename& filename_a, MODE mode_a) { // only RAW format // if (file_format_d == RAW) { // non-piped file // if (filename_a.ne(STREAM_FILE)) { if (!exists(filename_a)) { // the file doesn't need to exist if we are in write only mode // if (mode_a == WRITE_ONLY) { if (num_channels_d == (Long)0) { return Error::handle(name(), L"openRaw", ERR, __FILE__, __LINE__); } File::TYPE type = File::BINARY; if (file_type_d == TEXT) { type = File::TEXT; } // call the master function in the File class // if (!File::open(filename_a, mode_a, type)) { return Error::handle(name(), L"openRaw", Error::IO, __FILE__, __LINE__, Error::WARNING); } // write the dummy raw header // if (!writeRawHeader()) { return Error::handle(name(), L"openRaw", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } // file does not exist but should, error // else { return Error::handle(name(), L"openRaw", Error::FILE_NOTFND, __FILE__, __LINE__, Error::WARNING); } } // else read existing file // else { // call the master function in the File class // if (!File::open(filename_a, mode_a)) { return Error::handle(name(), L"openRaw", Error::IO, __FILE__, __LINE__, Error::WARNING); } // read or write dummy raw header // if (mode_a == READ_ONLY) { if (!readRawHeader()) { return Error::handle(name(), L"openRaw", Error::READ, __FILE__, __LINE__, Error::WARNING); } } else if (mode_a == WRITE_ONLY) { if (!writeRawHeader()) { return Error::handle(name(), L"openRaw", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } if (num_channels_d == (Long)0) { return Error::handle(name(), L"openRaw", ERR, __FILE__, __LINE__); } } } // bad streaming type // else { return Error::handle(name(), L"openRaw", ERR_PTYPE, __FILE__, __LINE__); } } // bad enumeration value // else { return Error::handle(name(), L"openRaw", Error::ENUM, __FILE__, __LINE__); } // get the file basename as the id // filename_a.getBase(id_d); // exit gracefully // return true; } // method: openSofStream // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the audiofile as streaming input from stdin // bool8 AudioFile::openSofStream(const Filename& filename_a, MODE mode_a) { // error // Error::handle(name(), L"readSofStream", Error::NOT_IMPLEM, __FILE__, __LINE__); return -1; } // method: openSof // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the audiofile (SOF format) // bool8 AudioFile::openSof(const Filename& filename_a, MODE mode_a) { // only SOF format // if (file_format_d == SOF) { // non-piped file // if (filename_a.ne(STREAM_FILE)) { if (!exists(filename_a)) { // the file doesn't need to exist if we are in write only mode // if (mode_a == WRITE_ONLY) { if (num_channels_d == (Long)0) { return Error::handle(name(), L"openSof", ERR, __FILE__, __LINE__); } if (sof_d != (Sof*)NULL) { return Error::handle(name(), L"openSof", Error::MEM, __FILE__, __LINE__); } sof_d = new Sof; sof_d->fp_d.setBMode(byte_mode_d); File::TYPE type = File::BINARY; if (file_type_d == TEXT) { type = File::TEXT; } if (!sof_d->open(filename_a, mode_a, type)) { return Error::handle(name(), L"openSof", Error::IO, __FILE__, __LINE__, Error::WARNING); } // write the sof header // if (!writeSofHeader()) { return Error::handle(name(), L"openSof", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } // file does not exist but should, error // else { return Error::handle(name(), L"openSof", Error::FILE_NOTFND, __FILE__, __LINE__, Error::WARNING); } } // else read existing file // else { // make sure it is valid // if ((mode_a != WRITE_ONLY) && (!Sof::isSof(filename_a))) { Error::handle(name(), L"openSof", Sof::ERR_NOTSOF, __FILE__, __LINE__, Error::WARNING); } if (sof_d != (Sof*)NULL) { return Error::handle(name(), L"openSof", Error::MEM, __FILE__, __LINE__); } sof_d = new Sof; // if we READ an existing file these commands will be ignored by Sof // sof_d->fp_d.setBMode(byte_mode_d); File::TYPE type = File::BINARY; if (file_type_d == TEXT) { type = File::TEXT; } if (!sof_d->open(filename_a, mode_a, type)) { filename_a.debug(L"file_name"); return Error::handle(name(), L"openSof", Error::IO, __FILE__, __LINE__, Error::WARNING); } // set the byte order from the sof file // byte_mode_d = sof_d->fp_d.getBMode(); // start the partial read or write though the header // if (mode_a == READ_ONLY) { if (!readSofHeader()) { return Error::handle(name(), L"openSof", Error::READ, __FILE__, __LINE__, Error::WARNING); } } else if (mode_a == WRITE_ONLY) { if (!writeSofHeader()) { return Error::handle(name(), L"openSof", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } } } // bad streaming type // else { return Error::handle(name(), L"openSof", ERR_PTYPE, __FILE__, __LINE__); } } // bad enumeration value // else { return Error::handle(name(), L"openSof", Error::ENUM, __FILE__, __LINE__); } // exit gracefully // return true; } // method: openSphereStream // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the SPHERE format as streaming input from stdin // bool8 AudioFile::openSphereStream(const Filename& filename_a, MODE mode_a) { #ifdef HAVE_SPHERE // if the filename is a '-', open the pipe // if (filename_a.eq(STREAM_FILE)) { // format supported by Nist's Sphere library // if (file_format_d == SPHERE) { if (mode_a == READ_ONLY) { // open the sphere file handler with checksum checking enabled // if ((sp_file_d = sp_open((char*)(byte8*)filename_a, "rv")) == (SP_FILE*)NULL) { return Error::handle(name(), L"openSphereStream", Error::IO, __FILE__, __LINE__, Error::WARNING); } // read the Sphere header // if (!readSphereHeader()) { return Error::handle(name(), L"openSphereStream", Error::READ, __FILE__, __LINE__, Error::WARNING); } } // no other modes are supported // else { return Error::handle(name(), L"openSphereStream", ERR_PMODE, __FILE__, __LINE__); } } // wrong file format // else { return Error::handle(name(), L"openSphereStream", ERR_PTYPE, __FILE__, __LINE__); } } // wrong file type // else { return Error::handle(name(), L"openSphereStream", ERR_PTYPE, __FILE__, __LINE__); } // set the id to the stream file symbol // id_d.assign(STREAM_FILE); #else // not supported Error::handle(name(), L"openSphereStream", Error::NOT_IMPLEM, __FILE__, __LINE__); #endif // exit gracefully // return true; } // method: openSphere // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the SPHERE format audiofile // bool8 AudioFile::openSphere(const Filename& filename_a, MODE mode_a) { #ifdef HAVE_SPHERE // Nist's Sphere format // if (file_format_d == SPHERE) { // non-piped file // if (filename_a.ne(STREAM_FILE)) { if (!exists(filename_a)) { // the file doesn't need to exist if we are in write only mode // if (mode_a == WRITE_ONLY) { if (num_channels_d == (Long)0) { return Error::handle(name(), L"openSphere", ERR, __FILE__, __LINE__); } // open the sphere file handler with checksum checking enabled // if ((sp_file_d = sp_open((char*)(byte8*)filename_a, "wv")) == (SP_FILE*)NULL) { return Error::handle(name(), L"openSphere", Error::IO, __FILE__, __LINE__, Error::WARNING); } // write the Sphere header // if (!writeSphereHeader()) { return Error::handle(name(), L"openSphere", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } // file does not exist but should, error // else { return Error::handle(name(), L"openSphere", Error::FILE_NOTFND, __FILE__, __LINE__, Error::WARNING); } } // else read existing file // else { if (mode_a == READ_ONLY) { // open the sphere file as read-only with checksum checking enabled // if ((sp_file_d = sp_open((char*)(byte8*)filename_a, "rv")) == (SP_FILE*)NULL) { return Error::handle(name(), L"openSphere", Error::IO, __FILE__, __LINE__, Error::WARNING); } // read the Sphere header // if (!readSphereHeader()) { return Error::handle(name(), L"openSphere", Error::READ, __FILE__, __LINE__, Error::WARNING); } } else if (mode_a == WRITE_ONLY) { // open the audiofile with checksum checking enabled // if ((sp_file_d = sp_open((char*)(byte8*)filename_a, "wv")) == (SP_FILE*)NULL) { return Error::handle(name(), L"openSphere", Error::IO, __FILE__, __LINE__, Error::WARNING); } // write the Sphere header // if (!writeSphereHeader()) { return Error::handle(name(), L"openSphere", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } // bad enumeration type // else { return Error::handle(name(), L"openSphere", Error::ENUM, __FILE__, __LINE__); } } } // bad streaming type // else { return Error::handle(name(), L"openSphere", ERR_PTYPE, __FILE__, __LINE__); } } // bad enumeration value // else { return Error::handle(name(), L"openSphere", Error::ENUM, __FILE__, __LINE__); } // get the file basename as the id // filename_a.getBase(id_d); #else // not supported // Error::handle(name(), L"openSphere", Error::NOT_IMPLEM, __FILE__, __LINE__); #endif // exit gracefully // return true; } // method: openAFStream // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the sgi's audiofile as streaming input from stdin. only raw // mode is called in the code below // bool8 AudioFile::openAFStream(const Filename& filename_a, MODE mode_a) { #ifdef HAVE_AUDIOFILE // if the filename is a '-', open the pipe // if (filename_a.eq(STREAM_FILE)) { // open a new setup for SGI audiofile // af_setup_d = afNewFileSetup(); // format supported by SGI's audiofile library // if ((file_format_d == AIFF) || (file_format_d == AIFFC) || (file_format_d == AU) || (file_format_d == BICSF) || (file_format_d == WAV)) { if (mode_a == READ_ONLY) { // open the sgi audiofile handler // if ((af_file_d = afOpenFD(0, "r", NULL)) == (AFfilehandle)NULL) { return Error::handle(name(), L"openAFStream", Error::IO, __FILE__, __LINE__, Error::WARNING); } // read the Wav header // if (!readAFHeader()) { return Error::handle(name(), L"openAFStream", Error::READ, __FILE__, __LINE__, Error::WARNING); } } // no other modes are supported // else { return Error::handle(name(), L"openAFStream", ERR_PMODE, __FILE__, __LINE__); } } // wrong file format // else { return Error::handle(name(), L"openAFStream", ERR_PTYPE, __FILE__, __LINE__); } } // wrong file type // else { return Error::handle(name(), L"openAFStream", ERR_PTYPE, __FILE__, __LINE__); } // set the id to the stream file symbol // id_d.assign(STREAM_FILE); #else // not supported // Error::handle(name(), L"openAFStream", Error::NOT_IMPLEM, __FILE__, __LINE__); #endif // exit gracefully // return true; } // method: openAF // // arguments: // const Filename& filename: (input) file to open // MODE mode: (input) open mode // // return: a bool8 value indicating status // // open the audiofile (sgi file handler) // bool8 AudioFile::openAF(const Filename& filename_a, MODE mode_a) { #ifdef HAVE_AUDIOFILE // any format supported by sgi audiofile library // if ((file_format_d == AIFF) || (file_format_d == AIFFC) || (file_format_d == AU) || (file_format_d == BICSF) || (file_format_d == WAV)) { // non-piped file // if (filename_a.ne(STREAM_FILE)) { // open a new setup for SGI audiofile // af_setup_d = afNewFileSetup(); if (!exists(filename_a)) { // the file doesn't need to exist if we are in write only mode // if (mode_a == WRITE_ONLY) { if (num_channels_d == (Long)0) { return Error::handle(name(), L"openAF", ERR, __FILE__, __LINE__); } // set the header information in the setup before opening // the file. note that this is important for writing in the // correct format // if (!writeAFHeader()) { return Error::handle(name(), L"openAF", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } // open a new sgi's audiofile setup // if ((af_file_d = afOpenFile((char*)(byte8*)filename_a, "w", af_setup_d)) == (AFfilehandle)NULL) { return Error::handle(name(), L"openAF", Error::IO, __FILE__, __LINE__, Error::WARNING); } } // file does not exist but should, error // else { return Error::handle(name(), L"openAF", Error::FILE_NOTFND, __FILE__, __LINE__, Error::WARNING); } } // else read existing file // else { if (mode_a == READ_ONLY) { // open the sgi's audiofile as read-only // if ((af_file_d = afOpenFile((char*)(byte8*)filename_a, "r", NULL)) == (AFfilehandle)NULL) { return Error::handle(name(), L"openAF", Error::IO, __FILE__, __LINE__, Error::WARNING); } // read the AF header // if (!readAFHeader()) { return Error::handle(name(), L"openAF", Error::READ, __FILE__, __LINE__, Error::WARNING); } } else if (mode_a == WRITE_ONLY) { // now, open the audiofile // if ((af_file_d = afOpenFile((char*)(byte8*)filename_a, "w", af_setup_d)) == (AFfilehandle)NULL) { return Error::handle(name(), L"openAF", Error::IO, __FILE__, __LINE__, Error::WARNING); } // write the AF header // if (!writeAFHeader()) { return Error::handle(name(), L"openAF", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } // bad enumeration type // else { return Error::handle(name(), L"openAF", Error::ENUM, __FILE__, __LINE__); } } } // bad streaming type // else { return Error::handle(name(), L"openAF", ERR_PTYPE, __FILE__, __LINE__); } } // bad enumeration value // else { return Error::handle(name(), L"openAF", Error::ENUM, __FILE__, __LINE__); } // get the file basename as the id // filename_a.getBase(id_d); #else // not supported // Error::handle(name(), L"openAF", Error::NOT_IMPLEM, __FILE__, __LINE__); #endif // exit gracefully // return true; } // method: close // // arguments: // // return: a bool8 value indicating status // // close the file // bool8 AudioFile::close() { // close the Sof file and delete object // if (sof_d != (Sof*)NULL) { if (sample_num_bytes_d == (Long)sizeof(byte8)) { VectorByte buffer; if (sof_d->getPartialRead()) { // call the partial read terminate method // buffer.readTerminate(*sof_d); } else if (sof_d->getPartialWrite()) { // call the partial write terminate method // buffer.writeTerminate(*sof_d, PARAM_DATA); } } else if (sample_num_bytes_d == (Long)sizeof(int16)) { VectorShort buffer; if (sof_d->getPartialRead()) { // call the partial read terminate method // buffer.readTerminate(*sof_d); } else if (sof_d->getPartialWrite()) { // call the partial write terminate method // buffer.writeTerminate(*sof_d, PARAM_DATA); } } else if (sample_num_bytes_d == (Long)sizeof(int32)) { VectorLong buffer; if (sof_d->getPartialRead()) { // call the partial read terminate method // buffer.readTerminate(*sof_d); } else if (sof_d->getPartialWrite()) { // call the partial write terminate method // buffer.writeTerminate(*sof_d, PARAM_DATA); } } else { return Error::handle(name(), L"unaligned word", ERR, __FILE__, __LINE__); } sof_d->close(); delete sof_d; sof_d = (Sof*)NULL; } // call the master function in the File class // else if (fp_d != NULL) { if (!File::close()) { return Error::handle(name(), L"close", Error::IO, __FILE__, __LINE__, Error::WARNING); } } #ifdef HAVE_SPHERE // format: SPHERE // else if (sp_file_d != (SP_FILE*)NULL) { if (sp_close(sp_file_d) > (int32)0) { return Error::handle(name(), L"close", Error::IO, __FILE__, __LINE__, Error::WARNING); } sp_file_d = (SP_FILE*)NULL; } #endif #ifdef HAVE_AUDIOFILE // if audiofile format is supported by sgi audiofile library // else if (af_file_d != (AFfilehandle)NULL) { if ((int32)afCloseFile(af_file_d) != (int32)0) { return Error::handle(name(), L"close", Error::IO, __FILE__, __LINE__, Error::WARNING); } af_file_d = (AFfilehandle)NULL; // free the file setup // afFreeFileSetup(af_setup_d); } #endif // reset the buffers // resetBuffer(); // if the configuration was saved, restore it and delete object // if (backup_config_d != (AudioFile*)NULL) { assign(*backup_config_d); delete backup_config_d; backup_config_d = (AudioFile*)NULL; } // initialize the id // id_d.clear(); // exit gracefully // return true; }