//-------------------------------------------------------------- bool ofxSoundFile::save(string path, const ofSoundBuffer &buff){ // check that we're writing a wav and complain if the file extension is wrong. ofFile f(path); if(ofToLower(f.getExtension())!="wav") { path += ".wav"; ofLogWarning() << "Can only write wav files - will save file as " << path; } fstream file(ofToDataPath(path).c_str(), ios::out | ios::binary); if(!file.is_open()) { ofLogError() << "Error opening sound file '" << path << "' for writing"; return false; } // write a wav header short myFormat = 1; // for pcm int mySubChunk1Size = 16; int bitsPerSample = 16; // assume 16 bit pcm int myByteRate = buff.getSampleRate() * buff.getNumChannels() * bitsPerSample/8; short myBlockAlign = buff.getNumChannels() * bitsPerSample/8; int myChunkSize = 36 + buff.size()*bitsPerSample/8; int myDataSize = buff.size()*bitsPerSample/8; int channels = buff.getNumChannels(); int samplerate = buff.getSampleRate(); file.seekp (0, ios::beg); file.write ("RIFF", 4); file.write ((char*) &myChunkSize, 4); file.write ("WAVE", 4); file.write ("fmt ", 4); file.write ((char*) &mySubChunk1Size, 4); file.write ((char*) &myFormat, 2); // should be 1 for PCM file.write ((char*) &channels, 2); // # channels (1 or 2) file.write ((char*) &samplerate, 4); // 44100 file.write ((char*) &myByteRate, 4); // file.write ((char*) &myBlockAlign, 2); file.write ((char*) &bitsPerSample, 2); //16 file.write ("data", 4); file.write ((char*) &myDataSize, 4); // write the wav file per the wav file format, 4096 bytes of data at a time. #define WRITE_BUFF_SIZE 4096 short writeBuff[WRITE_BUFF_SIZE]; int pos = 0; while(pos<buff.size()) { int len = MIN(WRITE_BUFF_SIZE, buff.size()-pos); for(int i = 0; i < len; i++) { writeBuff[i] = (int)(buff[pos]*32767.f); pos++; } file.write((char*)writeBuff, len*bitsPerSample/8); } file.close(); return true; }
bool ofxSoundFile::sfReadFile(ofSoundBuffer & buffer){ samples_read = sf_read_float (sndFile, &buffer[0], buffer.size()); /*if(samples_read<(int)buffer.size()){ ofLogError() << "ofxSoundFile: couldnt read " << path; return false; }*/ if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE){ for (int i = 0 ; i < int(buffer.size()) ; i++){ buffer[i] *= scale ; } } return true; }
//------------------------------------------------------------ bool ofxSoundFile::mpg123ReadFile(ofSoundBuffer & buffer){ size_t done=0; size_t block_size = mpg123_outblock( mp3File ); int err; if(buffer.size()==0){ buffer.resize(block_size); do{ err = mpg123_read(mp3File,(unsigned char*)&buffer[buffer.size()-block_size],block_size*4,&done); buffer.resize(buffer.size()+block_size); }while(err==MPG123_OK); buffer.resize(buffer.size()-(block_size-done/4)); if(err != MPG123_DONE){ ofLogError() << "Warning: Decoding ended prematurely because: " << (err == MPG123_ERR ? mpg123_strerror(mp3File) : mpg123_plain_strerror(err)); return false; } duration = float(buffer.size())/float(channels) / float(samplerate); }else{ err = mpg123_read(mp3File,(unsigned char*)&buffer[0],buffer.size()*sizeof(float),&done); if(err != MPG123_OK){ ofLogError() << "Warning: Error decoding mp3: " << (err == MPG123_ERR ? mpg123_strerror(mp3File) : mpg123_plain_strerror(err)); return false; } } return true; }
bool ofxSoundFile::ladReadFile(ofSoundBuffer &buffer){ int samplesRead = audioDecoder->read( buffer.size(), &buffer[0] ); return samplesRead; }