// file: $isip/class/mmedia/AudioFile/adf_13.cc // version: $Id: adf_13.cc 9286 2003-08-05 19:46:21Z parihar $ // //note: // AH (08/05/2010): In readSphereHeader and writeSphereHeader, I have changed // some variables from int32 to long and also I add (long) for // calling sp_h_set_field and sp_h_get_field to eliminate a // segmentation fault error on 64-bit systems. // isip include files // #include "AudioFile.h" // method: readSphereData // // arguments: // Vector& data: (output) the audio data // int32 ctag: (input) the channel to read // int32 start_samp: (input) the start sample of the audio data // int32 num_samp: (input) the number of samples to read // // return: the number of samples read // // this method gets data from the sphere format audiofile and puts each // channel data into a VectorFloat // int32 AudioFile::readSphereData(Vector& data_a, int32 ctag_a, int32 start_samp_a, int32 num_samp_a) { #ifdef HAVE_SPHERE // format: SPHERE // if (file_format_d != SPHERE) { Error::handle(name(), L"readSphereData", ERR_TYPE, __FILE__, __LINE__); return -1; } // take care of the partial frame condition // int32 total_samples = getNumSamples() * num_channels_d; if ((num_samp_a == ALL_SAMPLES) || ((start_samp_a + num_samp_a) > total_samples)) { // set the number of samples to be all samples remaining // num_samp_a = total_samples - start_samp_a; if (debug_level_d >= Integral::DETAILED) { String output; output.assign(num_samp_a); output.insert(L"readSphereData: clipping num_samp_a to ", 0); Console::put(output); } } data_a.setLength(num_channels_d); for (int32 i = 0; i < num_channels_d; i++) { data_a(i).setLength(num_samp_a / num_channels_d); } // seek to the right place // if (sp_seek(sp_file_d, start_samp_a, (int32)0) > (int32)0) { return Error::handle(name(), L"readSphereData", Error::IO, __FILE__, __LINE__, Error::WARNING); } // temporary holder for all the data // int32 num_read = num_samp_a * num_channels_d; if (sample_num_bytes_d == (Long)sizeof(byte8)) { byte8* samples = (byte8*)io_buf_d; if (sp_read_data(samples, num_read, sp_file_d) != num_read) { return Error::handle(name(), L"readSphereData", Error::READ, __FILE__, __LINE__, Error::WARNING); } interleaved_d.assign(num_read, samples); } else if (sample_num_bytes_d == (Long)sizeof(int16)) { int16* samples = (int16*) io_buf_d; int32 temp = 0; temp = sp_read_data(samples, num_read, sp_file_d); if (temp != num_read) { return Error::handle(name(), L"readSphereData", Error::READ, __FILE__, __LINE__, Error::WARNING); } interleaved_d.assign(num_read, samples); } else { Error::handle(name(), L"readSphereData", Error::ENUM, __FILE__, __LINE__); return -1; } // now do interleave // for (int32 i = 0; i < num_channels_d; i++) { data_a(i).setLength(num_samp_a); for (int32 j = 0; j < num_samp_a; j++) { // pull the sample out of the single buffer // data_a(i)(j) = (float32)interleaved_d(j * num_channels_d + i); // scale the sample // data_a(i)(j) /= max_sample_val_d; } } // exit gracefully // return num_samp_a; #else // error if Nist's Sphere library is not available // Error::handle(name(), L"readSphereData", Error::NOT_IMPLEM, __FILE__, __LINE__); return -1; #endif } // method: writeSphereData // // arguments: // Vector& data: (input) the audio data to write // int32 ctag: (input) channel tag // // return: the number of elements written // // this method writes the audio data to a sphere audio file // int32 AudioFile::writeSphereData(Vector& data_a, int32 ctag_a) { #ifdef HAVE_SPHERE // format: SPHERE // if (file_format_d != SPHERE) { return Error::handle(name(), L"writeSphereData", ERR, __FILE__, __LINE__); } // combine the multi-channel data to a single Vector // VectorLong whole_data; revertData(whole_data, data_a, ctag_a); int32 num_write = whole_data.length(); if (sample_num_bytes_d == (Long)sizeof(byte8)) { byte8 buffer[num_write]; for (int32 i = 0; i < num_write; i++) { buffer[i] = (byte8)whole_data(i); } // call the sphere library write method // if (sp_write_data(buffer, num_write, sp_file_d) != num_write) { return Error::handle(name(), L"writeSphereData", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } else if (sample_num_bytes_d == (Long)sizeof(int16)) { int16 buffer[num_write]; for (int32 i = 0; i < num_write; i++) { buffer[i] = (int16)whole_data(i); } // call the sphere library write method // if (sp_write_data(buffer, num_write, sp_file_d) != num_write) { return Error::handle(name(), L"writeSphereData", Error::WRITE, __FILE__, __LINE__, Error::WARNING); } } else { Error::handle(name(), L"writeSphereData", Error::ENUM, __FILE__, __LINE__); return -1; } // exit gracefully // return true; #else // error if Nist's Sphere library is not available // Error::handle(name(), L"writeSphereData", Error::NOT_IMPLEM, __FILE__, __LINE__); return -1; #endif } // method: readSphereHeader // // arguments: none // // return: a bool8 value indicating status // // this method read the sphere header // bool8 AudioFile::readSphereHeader() { #ifdef HAVE_SPHERE // format: SPHERE // if (file_format_d != SPHERE) { return Error::handle(name(), L"readSphereHeader", ERR, __FILE__, __LINE__); } // make sure the object is allocated // if (sp_file_d == (SP_FILE*)NULL) { return Error::handle(name(), L"readSphereHeader", Error::MEM, __FILE__, __LINE__); } // read the parameters from the sphere header that are absolutely // needed to correctly read the samples // // number of channels ///* amir long num_channels = (long)1; if (sp_h_get_field(sp_file_d, "channel_count", T_INTEGER, (void**)&num_channels) > (int32)99) { return Error::handle(name(), L"readSphereHeader", Error::READ, __FILE__, __LINE__); } if(!setNumChannels(num_channels)) { return Error::handle(name(), L"readSphereHeader", Error::READ, __FILE__, __LINE__); } // sampling frequency ///* long sample_rate = (long)0; if (sp_h_get_field(sp_file_d, "sample_rate", T_INTEGER, (void**)&sample_rate) > (int32)99) { return Error::handle(name(), L"readSphereHeader", Error::READ, __FILE__, __LINE__); } // number of bytes per sample ///* amir if (sp_h_get_field(sp_file_d, "sample_n_bytes", T_INTEGER, (void**)(long)&sample_num_bytes_d) > (int32)99) { return Error::handle(name(), L"readSphereHeader", Error::READ, __FILE__, __LINE__); } /* // read the parameters from the sphere header that are not necessary // to correctly read the samples. these parameters are only set to // return a right type if called from outside this class // // compression type // char* sample_coding = new char[99]; if (sp_h_get_field(sp_file_d, "sample_coding", T_STRING, (void**)&sample_coding) > (int32)99) { return Error::handle(name(), L"readSphereHeader", Error::READ, __FILE__, __LINE__); } // now set the compression type // // PCM // if (strcmp(sample_coding, "pcm") == (int32)0) { compression_type_d = PCM; } // ALAW // else if (strcmp(sample_coding, "alaw") == (int32)0) { // compression_type_d = ALAW; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // ULAW // else if (strcmp(sample_coding, "ulaw") == (int32)0) { // compression_type_d = ULAW; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // PCM_SHORTEN1 // else if (strcmp(sample_coding, "pcm,embedded-shorten-v1.0") == (int32)0) { compression_type_d = PCM_SHORTEN1; } // PCM_SHORTEN2 // else if (strcmp(sample_coding, "pcm,embedded-shorten-v2.00") == (int32)0) { compression_type_d = PCM_SHORTEN2; } // ULAW_SHORTEN1 // else if (strcmp(sample_coding, "ulaw,embedded-shorten-v1.0") == (int32)0) { compression_type_d = ULAW_SHORTEN1; } // ULAW_SHORTEN2 // else if (strcmp(sample_coding, "ulaw,embedded-shorten-v2.00") == (int32)0) { compression_type_d = ULAW_SHORTEN2; } // PCM_WAVPACK1 // else if (strcmp(sample_coding, "pcm,embedded-wavpack-v1.0") == (int32)0) { compression_type_d = PCM_WAVPACK1; } // ULAW_WAVPACK1 // else if (strcmp(sample_coding, "ulaw,embedded-wavpack-v1.0") == (int32)0) { compression_type_d = ULAW_WAVPACK1; } // PCM_SHORTPACK0 // else if (strcmp(sample_coding, "pcm,embedded-shortpack-v0") == (int32)0) { compression_type_d = PCM_SHORTPACK0; } // else error // else { return Error::handle(name(), L"readSphereHeader", Error::READ, __FILE__, __LINE__); } // sample bytes format // char* sample_byte_format = new char[99]; if (sp_h_get_field(sp_file_d, "sample_byte_format", T_STRING, (void**)&sample_byte_format) > (int32)99) { // return Error::handle(name(), L"readSphereHeader", Error::READ, // __FILE__, __LINE__); } // now set the sample byte format // // little-endian // if (strcmp(sample_byte_format, "01") == (int32)0) { byte_mode_d = LITTLE_ENDIAN; } // big-endian // else if (strcmp(sample_byte_format, "10") == (int32)0) { byte_mode_d = BIG_ENDIAN; } // native // else if (strcmp(sample_byte_format, "1") == (int32)0) { byte_mode_d = NATIVE; } // support the non-standard field as done by sphere. See // sphere-2.6a/doc/sphere.doc in the sphere documentation for // further details // else if (strcmp(sample_byte_format, "shortpack-v0") == (int32)0) { compression_type_d = PCM_SHORTPACK0; } // else error // else { return Error::handle(name(), L"readSphereHeader", Error::READ, __FILE__, __LINE__); } // free the memory // if (sample_coding != (char*)NULL) { // delete [] sample_coding; // sample_coding = (char*)NULL; } if (sample_byte_format != (char*)NULL) { // delete [] sample_byte_format; // sample_byte_format = (char*)NULL; } */ // exit gracefully // return true; #else // error if Nist's Sphere library is not available // Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); return -1; #endif } // method: writeSphereHeader // // arguments: none // // return: a bool8 value indicating status // // this method writes the sphere header // bool8 AudioFile::writeSphereHeader() const { // write to sphere file // if (file_format_d != SPHERE) { return Error::handle(name(), L"writeSphereHeader", ERR, __FILE__, __LINE__); } #ifdef HAVE_SPHERE // make sure the object is allocated // if (sp_file_d == (SP_FILE*)NULL) { return Error::handle(name(), L"writeSphereHeader", Error::MEM, __FILE__, __LINE__); } // number of channels //* amir long num_channels_d_temp=num_channels_d; if (sp_h_set_field(sp_file_d, "channel_count", T_INTEGER, (void*)&num_channels_d_temp) > (int32)99) { return Error::handle(name(), L"writeSphereHeader", Error::WRITE, __FILE__, __LINE__); } //num_channels_d=1; // sampling frequency // int32 sample_rate = sample_freq_d; if (sp_h_set_field(sp_file_d, "sample_rate", T_INTEGER, (void*)(long)&sample_rate) > (int32)99) { return Error::handle(name(), L"writeSphereHeader", Error::WRITE, __FILE__, __LINE__); } // number of bytes per sample ///* if (sp_h_set_field(sp_file_d, "sample_n_bytes", T_INTEGER, (void*)(long)&sample_num_bytes_d) > (int32)99) { return Error::handle(name(), L"writeSphereHeader", Error::WRITE, __FILE__, __LINE__); } // no need to set number of samples, it is set automatically while // writing the data to the sphere file // // compression type // char* sample_coding = new char[99]; // PCM // if (compression_type_d == PCM) { sample_coding = "pcm"; } // ALAW // else if (compression_type_d == ALAW) { // sample_coding = "alaw"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // ULAW // else if (compression_type_d == ULAW) { // sample_coding = "ulaw"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // PCM_SHORTEN1 // else if (compression_type_d == PCM_SHORTEN1) { // sample_coding = "pcm,embedded-shorten-v1.0"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // PCM_SHORTEN2 // else if (compression_type_d == PCM_SHORTEN2) { // sample_coding = "pcm,embedded-shorten-v2.00"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // ULAW_SHORTEN1 // else if (compression_type_d == ULAW_SHORTEN1) { // sample_coding = "ulaw,embedded-shorten-v1.0"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // ULAW_SHORTEN2 // else if (compression_type_d == ULAW_SHORTEN2) { // sample_coding = "ulaw,embedded-shorten-v2.00"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // PCM_WAVPACK1 // else if (compression_type_d == PCM_WAVPACK1) { // sample_coding = "pcm,embedded-wavpack-v1.0"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // ULAW_WAVPACK1 // else if (compression_type_d == ULAW_WAVPACK1) { // sample_coding = "ulaw,embedded-wavpack-v1.0"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // PCM_SHORTPACK0 // else if (compression_type_d == PCM_SHORTPACK0) { // sample_coding = "pcm,embedded-shortpack-v0"; return Error::handle(name(), L"readSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // else error // else { return Error::handle(name(), L"writeSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); } // now set compression type // if (sp_h_set_field(sp_file_d, "sample_coding", T_STRING, (void*)sample_coding) > (int32)99) { return Error::handle(name(), L"writeSphereHeader", Error::WRITE, __FILE__, __LINE__); } // sample bytes format // char* sample_byte_format = new char[99]; // little-endian // if (byte_mode_d == LITTLE_ENDIAN) { sample_byte_format = "01"; } // big-endian // else if (byte_mode_d == BIG_ENDIAN) { sample_byte_format = "10"; } // native // else if (byte_mode_d == NATIVE) { sample_byte_format = "1"; } // else error // else { return Error::handle(name(), L"writeSphereHeader", Error::WRITE, __FILE__, __LINE__); } // now set the sample byte format // sp_h_set_field(sp_file_d, "sample_byte_format", T_STRING, (void*)sample_byte_format); //* if (sp_h_set_field(sp_file_d, "sample_byte_format", T_STRING, //* (void*)sample_byte_format) > (int32)99) { //* return Error::handle(name(), L"writeSphereHeader", Error::WRITE, //* __FILE__, __LINE__); //* } // free the memory // if (sample_coding != (char*)NULL) { // delete [] sample_coding; // sample_coding = (char*)NULL; } if (sample_byte_format != (char*)NULL) { // delete [] sample_byte_format; // sample_byte_format = (char*)NULL; } // exit gracefully // return true; #else // not implemented // return Error::handle(name(), L"writeSphereHeader", Error::NOT_IMPLEM, __FILE__, __LINE__); #endif }