tomwalters@3: // Copyright 2006-2010, Willem van Engen, Thomas Walters tomwalters@3: // tomwalters@3: // AIM-C: A C++ implementation of the Auditory Image Model tomwalters@3: // http://www.acousticscale.org/AIMC tomwalters@3: // tomwalters@45: // Licensed under the Apache License, Version 2.0 (the "License"); tomwalters@45: // you may not use this file except in compliance with the License. tomwalters@45: // You may obtain a copy of the License at tomwalters@3: // tomwalters@45: // http://www.apache.org/licenses/LICENSE-2.0 tomwalters@3: // tomwalters@45: // Unless required by applicable law or agreed to in writing, software tomwalters@45: // distributed under the License is distributed on an "AS IS" BASIS, tomwalters@45: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. tomwalters@45: // See the License for the specific language governing permissions and tomwalters@45: // limitations under the License. tomwalters@3: tomwalters@3: /*! \file tomwalters@3: * \brief Audio file input tomwalters@3: * tomwalters@3: * \author Willem van Engen tomwalters@3: * \author Thomas Walters tomwalters@3: * \date created 2006/09/21 tomwalters@3: * \version \$Id$ tomwalters@3: */ tomwalters@3: tomwalters@3: #include tomwalters@3: tomwalters@3: #include "Modules/Input/ModuleFileInput.h" tomwalters@3: tomwalters@3: namespace aimc { tomwalters@3: ModuleFileInput::ModuleFileInput(Parameters *params) : Module(params) { tomwalters@6: module_description_ = "File input using libsndfile"; tomwalters@6: module_identifier_ = "file_input"; tomwalters@6: module_type_ = "input"; tomwalters@6: module_version_ = "$Id$"; tomwalters@6: tomwalters@7: file_handle_ = NULL; tomwalters@7: buffer_length_ = parameters_->DefaultInt("input.buffersize", 1024); tomwalters@3: tomwalters@3: file_position_samples_ = 0; tomwalters@3: file_loaded_ = false; tomwalters@3: audio_channels_ = 0; tomwalters@3: sample_rate_ = 0.0f; tomwalters@3: } tomwalters@3: tomwalters@3: ModuleFileInput::~ModuleFileInput() { tomwalters@20: if (file_handle_ != NULL) { tomwalters@7: sf_close(file_handle_); tomwalters@20: file_handle_ = NULL; tomwalters@20: } tomwalters@3: } tomwalters@3: tomwalters@3: void ModuleFileInput::ResetInternal() { tomwalters@20: // If there's a file open. Close it. tomwalters@20: if (file_handle_ != NULL) { tomwalters@20: sf_close(file_handle_); tomwalters@20: file_handle_ = NULL; tomwalters@20: } tom@246: // Open a file tomwalters@7: SF_INFO sfinfo; tomwalters@8: memset(reinterpret_cast(&sfinfo), 0, sizeof(SF_INFO)); tomwalters@20: tomwalters@232: file_loaded_ = false; tomwalters@232: file_handle_ = sf_open(global_parameters_->GetString("input_filename"), tomwalters@232: SFM_READ, tomwalters@232: &sfinfo); tomwalters@3: tomwalters@7: if (file_handle_ == NULL) { tomwalters@8: /*! \todo Also display error reason tomwalters@8: */ tomwalters@232: LOG_ERROR(_T("Couldn't read audio file '%s'"), tomwalters@232: global_parameters_->GetString("input_filename")); tom@246: return; tomwalters@7: } tomwalters@232: tomwalters@3: file_loaded_ = true; tomwalters@232: done_ = false; tomwalters@3: audio_channels_ = sfinfo.channels; tomwalters@3: sample_rate_ = sfinfo.samplerate; tomwalters@7: file_position_samples_ = 0; tomwalters@3: tomwalters@232: if (audio_channels_ < 1 || buffer_length_ < 1 || sample_rate_ < 0.0f) { tomwalters@232: LOG_ERROR(_T("Problem with file: audio_channels = %d, buffer_length_ = %d, sample_rate = %f"), audio_channels_, buffer_length_, sample_rate_); tom@246: return; tomwalters@232: } tomwalters@3: tomwalters@232: output_.Initialize(audio_channels_, buffer_length_, sample_rate_); tomwalters@232: output_.set_start_time(0); tom@246: } tom@246: tom@246: bool ModuleFileInput::InitializeInternal(const SignalBank& input) { tom@246: ResetInternal(); tomwalters@232: return true; tomwalters@162: } tomwalters@162: tomwalters@162: void ModuleFileInput::Process(const SignalBank& input) { tomwalters@6: if (!file_loaded_) tomwalters@6: return; tomwalters@7: sf_count_t read; tomwalters@3: vector buffer; tomwalters@3: buffer.resize(buffer_length_ * audio_channels_); tomwalters@3: tomwalters@232: // Read buffersize bytes into buffer tomwalters@232: read = sf_readf_float(file_handle_, &buffer[0], buffer_length_); hamel@262: tomwalters@232: // Place the contents of the buffer into the signal bank tomwalters@232: int counter = 0; hamel@261: for (int i = 0; i < read; ++i) { hamel@261: for (int c = 0; c < audio_channels_; ++c) { tomwalters@232: output_.set_sample(c, i, buffer[counter]); tomwalters@232: ++counter; tomwalters@232: } tomwalters@232: } tomwalters@3: tom@255: // If the number of samples read is less than the buffer length, the end tomwalters@232: // of the file has been reached. tomwalters@232: if (read < buffer_length_) { tomwalters@232: // Zero samples at end hamel@261: for (int i = read; i < buffer_length_; ++i) { hamel@261: for (int c = 0; c < audio_channels_; ++c) { tomwalters@232: output_.set_sample(c, i, 0.0f); tomwalters@3: } tomwalters@3: } tomwalters@232: // When we're past the end of the buffer, set the tomwalters@232: // module state to 'done' and exit. tomwalters@232: if (read == 0) tomwalters@232: done_ = true; tomwalters@232: return; tomwalters@232: } tomwalters@162: tomwalters@232: // Update time. tomwalters@232: output_.set_start_time(file_position_samples_); tomwalters@232: file_position_samples_ += read; tomwalters@232: PushOutput(); tomwalters@3: } tomwalters@3: } // namespace aimc