* #27819: audiofile: merge RawFile and WaveFile into AudioFile

This commit is contained in:
Tristan Matthews
2013-08-09 14:46:37 -04:00
parent c8ddbdcf77
commit a1f2a6f2ee
4 changed files with 36 additions and 103 deletions

View File

@ -109,16 +109,6 @@ class AudioRecord {
protected:
/**
* Set the header for raw files
*/
bool setRawFile();
/**
* Set the header for wave files
*/
bool setWavFile();
/**
* Open an existing raw file, used when the call is set on hold
*/

View File

@ -50,6 +50,7 @@ AudioFile::onBufferFinish()
{
// We want to send values in milisecond
const int divisor = buffer_->getSampleRate() / 1000;
if (divisor == 0) {
ERROR("Error cannot update playback slider, sampling rate is 0");
return;
@ -63,96 +64,58 @@ AudioFile::onBufferFinish()
updatePlaybackScale_++;
}
RawFile::RawFile(const std::string& name, unsigned int sampleRate)
: AudioFile(name, sampleRate)
AudioFile::AudioFile(const std::string &fileName, unsigned int sampleRate) :
AudioLoop(sampleRate), filepath_(fileName), updatePlaybackScale_(0)
{
bool hasHeader = false;
const unsigned fileSampleRate = 8000;
int format = SF_FORMAT_RAW | SF_FORMAT_ULAW;
int format;
bool hasHeader = true;
if (filepath_.find(".al") != std::string::npos)
if (filepath_.find(".wav") != std::string::npos) {
format = SF_FORMAT_WAV;
} else if (filepath_.find(".ul") != std::string::npos) {
format = SF_FORMAT_RAW | SF_FORMAT_ULAW;
hasHeader = false;
} else if (filepath_.find(".al") != std::string::npos) {
format = SF_FORMAT_RAW | SF_FORMAT_ALAW;
else if (filepath_.find(".au") != std::string::npos) {
hasHeader = false;
} else if (filepath_.find(".au") != std::string::npos) {
format = SF_FORMAT_AU;
hasHeader = true;
} else {
WARN("No file extension, guessing WAV");
format = SF_FORMAT_WAV;
}
SndfileHandle fileHandle(filepath_.c_str(), SFM_READ, format, hasHeader ? 0 : 1, hasHeader ? 0 : 8000);
SndfileHandle fileHandle(fileName.c_str(), SFM_READ, format, hasHeader ? 0 : 1,
hasHeader ? 0 : 8000);
if (!fileHandle)
throw AudioFileException("Unable to open audio file");
throw AudioFileException("File " + fileName + " doesn't exist");
switch (fileHandle.channels()) {
case 1:
case 2:
break;
default:
throw AudioFileException("Unsupported number of channels");
}
// get # of bytes in file
const size_t fileSize = fileHandle.seek(0, SEEK_END);
fileHandle.seek(0, SEEK_SET);
const size_t nbFrames = hasHeader ? fileHandle.frames() : fileSize * fileHandle.channels();
std::vector<SFLAudioSample> temp(nbFrames);
fileHandle.read(&*temp.begin(), nbFrames);
const sf_count_t nbFrames = hasHeader ? fileHandle.frames() : fileSize / fileHandle.channels();
AudioBuffer * buffer = new AudioBuffer(nbFrames, fileHandle.channels(), fileSampleRate);
buffer->deinterleave(&*temp.begin(), nbFrames, fileHandle.channels());
SFLAudioSample * deinterleaved = new SFLAudioSample[nbFrames * fileHandle.channels()];
if (sampleRate == fileHandle.samplerate()) {
delete buffer_;
buffer_ = buffer;
} else {
double factord = (double) sampleRate / fileHandle.samplerate();
size_t samples = buffer->samples();
size_t size = fileHandle.channels() * samples;
float* floatBufferIn = new float[size];
buffer->interleaveFloat(floatBufferIn);
int samplesOut = ceil(factord * samples);
int sizeOut = samplesOut * fileHandle.channels();
SRC_DATA src_data;
src_data.data_in = floatBufferIn;
src_data.input_frames = samples;
src_data.output_frames = samplesOut;
src_data.src_ratio = factord;
float* floatBufferOut = new float[sizeOut];
src_data.data_out = floatBufferOut;
src_simple(&src_data, SRC_SINC_BEST_QUALITY, fileHandle.channels());
samplesOut = src_data.output_frames_gen;
sizeOut = samplesOut * fileHandle.channels();
SFLAudioSample *scratch = new SFLAudioSample[sizeOut];
src_float_to_short_array(floatBufferOut, scratch, src_data.output_frames_gen);
buffer->deinterleave(scratch, samplesOut, fileHandle.channels());
delete buffer_;
buffer_ = buffer;
delete [] floatBufferOut;
delete [] floatBufferIn;
delete [] scratch;
}
}
WaveFile::WaveFile(const std::string &fileName, unsigned int sampleRate) : AudioFile(fileName, sampleRate)
{
SndfileHandle fileHandle(fileName.c_str(), SFM_READ);
if (!fileHandle)
throw AudioFileException("File " + fileName + " doesn't exist");
if (fileHandle.channels() > 2)
throw AudioFileException("Unsupported number of channels");
const sf_count_t nbFrames = fileHandle.frames();
SFLAudioSample * tempBuffer = new SFLAudioSample[nbFrames * fileHandle.channels()];
fileHandle.read(tempBuffer, nbFrames);
fileHandle.read(deinterleaved, nbFrames);
AudioBuffer * buffer = new AudioBuffer(nbFrames, fileHandle.channels(), fileHandle.samplerate());
buffer->deinterleave(tempBuffer, nbFrames, fileHandle.channels());
buffer->deinterleave(deinterleaved, nbFrames, fileHandle.channels());
const int rate = static_cast<int32_t>(sampleRate);
if (fileHandle.samplerate() != rate) {
SamplerateConverter converter(std::max(fileHandle.samplerate(), rate), fileHandle.channels());
AudioBuffer * resampled = new AudioBuffer(nbFrames, fileHandle.channels(), rate);
@ -165,5 +128,5 @@ WaveFile::WaveFile(const std::string &fileName, unsigned int sampleRate) : Audio
buffer_ = buffer;
}
delete [] tempBuffer;
delete [] deinterleaved;
}

View File

@ -48,8 +48,7 @@ class AudioFileException : public std::runtime_error {
*/
class AudioFile : public AudioLoop {
public:
AudioFile(const std::string &filepath, unsigned int sampleRate) : AudioLoop(sampleRate), filepath_(filepath), updatePlaybackScale_(0)
{}
AudioFile(const std::string &filepath, unsigned int sampleRate);
std::string getFilePath() const {
return filepath_;
@ -65,19 +64,4 @@ class AudioFile : public AudioLoop {
unsigned updatePlaybackScale_;
};
class RawFile : public AudioFile {
public:
RawFile(const std::string& name, unsigned int sampleRate = 8000);
};
class WaveFile : public AudioFile {
public:
/**
* Load a sound file in memory
* @param filename The absolute path to the file
* @param sampleRate The sample rate to read it
*/
WaveFile(const std::string&, unsigned int sampleRate);
};
#endif // __AUDIOFILE_H__

View File

@ -1866,11 +1866,7 @@ void
ManagerImpl::updateAudioFile(const std::string &file, int sampleRate)
{
try {
if (file.find(".wav") != std::string::npos) {
audiofile_.reset(new WaveFile(file, sampleRate));
} else {
audiofile_.reset(new RawFile(file, sampleRate));
}
audiofile_.reset(new AudioFile(file, sampleRate));
} catch (const AudioFileException &e) {
ERROR("Exception: %s", e.what());
}