Mercurial > hg > aimc
view src/Modules/Input/ModuleFileInput.cc @ 94:cbe78255b12c
- AWS
author | tomwalters |
---|---|
date | Fri, 13 Aug 2010 10:28:14 +0000 |
parents | c5f5e9569863 |
children | 3cdaa81c3aca |
line wrap: on
line source
// Copyright 2006-2010, Willem van Engen, Thomas Walters // // AIM-C: A C++ implementation of the Auditory Image Model // http://www.acousticscale.org/AIMC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /*! \file * \brief Audio file input * * \author Willem van Engen <cnbh@willem.engen.nl> * \author Thomas Walters <tom@acousticscale.org> * \date created 2006/09/21 * \version \$Id$ */ #include <vector> #include "Modules/Input/ModuleFileInput.h" namespace aimc { ModuleFileInput::ModuleFileInput(Parameters *params) : Module(params) { module_description_ = "File input using libsndfile"; module_identifier_ = "file_input"; module_type_ = "input"; module_version_ = "$Id$"; file_handle_ = NULL; buffer_length_ = parameters_->DefaultInt("input.buffersize", 1024); file_position_samples_ = 0; file_loaded_ = false; audio_channels_ = 0; sample_rate_ = 0.0f; } ModuleFileInput::~ModuleFileInput() { if (file_handle_ != NULL) { sf_close(file_handle_); file_handle_ = NULL; } } void ModuleFileInput::ResetInternal() { output_.Initialize(audio_channels_, buffer_length_, sample_rate_); output_.set_start_time(0); } bool ModuleFileInput::LoadFile(const char* filename) { // If there's a file open. Close it. if (file_handle_ != NULL) { sf_close(file_handle_); file_handle_ = NULL; } // Open the file SF_INFO sfinfo; memset(reinterpret_cast<void*>(&sfinfo), 0, sizeof(SF_INFO)); file_handle_ = sf_open(filename, SFM_READ, &sfinfo); if (file_handle_ == NULL) { /*! \todo Also display error reason */ LOG_ERROR(_T("Couldn't read audio file '%s'"), filename); return false; } file_loaded_ = true; audio_channels_ = sfinfo.channels; sample_rate_ = sfinfo.samplerate; file_position_samples_ = 0; // A dummy signal bank to be passed to the Initialize() function. SignalBank s; s.Initialize(1, 1, 1); // Self-initialize by calling Module::Initialize() explicitly. // The Initialize() call in this subclass is overloaded to prevent it from // being called drectly. return Module::Initialize(s); } /* Do not call Initialize() on ModuleFileInput directly * instead call LoadFile() with a filename to load. * This will automatically initialize the module. */ bool ModuleFileInput::Initialize(const SignalBank& input) { LOG_ERROR(_T("Do not call Initialize() on ModuleFileInput directly " "instead call LoadFile() with a filename to load. " "This will automatically initialize the module.")); return false; } void ModuleFileInput::Process(const SignalBank& input) { LOG_ERROR(_T("Call Process() on ModuleFileInput instead of passing in " "a SignalBank")); } bool ModuleFileInput::InitializeInternal(const SignalBank& input) { if (!file_loaded_) { LOG_ERROR(_T("No file loaded in FileOutputHTK")); return false; } if (audio_channels_ < 1 || buffer_length_ < 1 || sample_rate_ < 0.0f) { LOG_ERROR(_T("audio_channels, buffer_length_ or sample_rate too small")); return false; } ResetInternal(); return true; } void ModuleFileInput::Process() { if (!file_loaded_) return; sf_count_t read; vector<float> buffer; buffer.resize(buffer_length_ * audio_channels_); while (true) { // Read buffersize bytes into buffer read = sf_readf_float(file_handle_, &buffer[0], buffer_length_); // Place the contents of the buffer into the signal bank int counter = 0; for (int c = 0; c < audio_channels_; ++c) { for (int i = 0; i < read; ++i) { output_.set_sample(c, i, buffer[counter]); ++counter; } } // If the number of saples read is less than the buffer length, the end // of the file has been reached. if (read < buffer_length_) { // Zero samples at end for (int c = 0; c < audio_channels_; ++c) { for (int i = read; i < buffer_length_; ++i) { output_.set_sample(c, i, 0.0f); } } // When we're past the end of the buffer, stop looping. if (read == 0) break; } // Update time output_.set_start_time(file_position_samples_); file_position_samples_ += read; PushOutput(); } } } // namespace aimc