annotate src/Modules/Input/ModuleFileInput.cc @ 232:af531fc3f280

- Massive refactoring to make module tree stuff work. In theory we now support configuration files again. The graphics stuff is untested as yet.
author tomwalters
date Mon, 18 Oct 2010 04:42:28 +0000
parents 9fcf55c040fe
children 0a3342606855
rev   line source
tomwalters@3 1 // Copyright 2006-2010, Willem van Engen, Thomas Walters
tomwalters@3 2 //
tomwalters@3 3 // AIM-C: A C++ implementation of the Auditory Image Model
tomwalters@3 4 // http://www.acousticscale.org/AIMC
tomwalters@3 5 //
tomwalters@45 6 // Licensed under the Apache License, Version 2.0 (the "License");
tomwalters@45 7 // you may not use this file except in compliance with the License.
tomwalters@45 8 // You may obtain a copy of the License at
tomwalters@3 9 //
tomwalters@45 10 // http://www.apache.org/licenses/LICENSE-2.0
tomwalters@3 11 //
tomwalters@45 12 // Unless required by applicable law or agreed to in writing, software
tomwalters@45 13 // distributed under the License is distributed on an "AS IS" BASIS,
tomwalters@45 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
tomwalters@45 15 // See the License for the specific language governing permissions and
tomwalters@45 16 // limitations under the License.
tomwalters@3 17
tomwalters@3 18 /*! \file
tomwalters@3 19 * \brief Audio file input
tomwalters@3 20 *
tomwalters@3 21 * \author Willem van Engen <cnbh@willem.engen.nl>
tomwalters@3 22 * \author Thomas Walters <tom@acousticscale.org>
tomwalters@3 23 * \date created 2006/09/21
tomwalters@3 24 * \version \$Id$
tomwalters@3 25 */
tomwalters@3 26
tomwalters@3 27 #include <vector>
tomwalters@3 28
tomwalters@3 29 #include "Modules/Input/ModuleFileInput.h"
tomwalters@3 30
tomwalters@3 31 namespace aimc {
tomwalters@3 32 ModuleFileInput::ModuleFileInput(Parameters *params) : Module(params) {
tomwalters@6 33 module_description_ = "File input using libsndfile";
tomwalters@6 34 module_identifier_ = "file_input";
tomwalters@6 35 module_type_ = "input";
tomwalters@6 36 module_version_ = "$Id$";
tomwalters@6 37
tomwalters@7 38 file_handle_ = NULL;
tomwalters@7 39 buffer_length_ = parameters_->DefaultInt("input.buffersize", 1024);
tomwalters@3 40
tomwalters@3 41 file_position_samples_ = 0;
tomwalters@3 42 file_loaded_ = false;
tomwalters@3 43 audio_channels_ = 0;
tomwalters@3 44 sample_rate_ = 0.0f;
tomwalters@3 45 }
tomwalters@3 46
tomwalters@3 47 ModuleFileInput::~ModuleFileInput() {
tomwalters@20 48 if (file_handle_ != NULL) {
tomwalters@7 49 sf_close(file_handle_);
tomwalters@20 50 file_handle_ = NULL;
tomwalters@20 51 }
tomwalters@3 52 }
tomwalters@3 53
tomwalters@3 54 void ModuleFileInput::ResetInternal() {
tomwalters@232 55 // If there's a file open, rewind to the beginning.
tomwalters@232 56 if (file_handle_ != NULL) {
tomwalters@232 57 sf_seek(file_handle_, 0, SEEK_SET);
tomwalters@232 58 file_position_samples_ = 0;
tomwalters@232 59 }
tomwalters@162 60 }
tomwalters@162 61
tomwalters@232 62 bool ModuleFileInput::InitializeInternal(const SignalBank& input) {
tomwalters@20 63 // If there's a file open. Close it.
tomwalters@20 64 if (file_handle_ != NULL) {
tomwalters@20 65 sf_close(file_handle_);
tomwalters@20 66 file_handle_ = NULL;
tomwalters@20 67 }
tomwalters@162 68 // Open the file
tomwalters@7 69 SF_INFO sfinfo;
tomwalters@8 70 memset(reinterpret_cast<void*>(&sfinfo), 0, sizeof(SF_INFO));
tomwalters@20 71
tomwalters@232 72 file_loaded_ = false;
tomwalters@232 73 file_handle_ = sf_open(global_parameters_->GetString("input_filename"),
tomwalters@232 74 SFM_READ,
tomwalters@232 75 &sfinfo);
tomwalters@3 76
tomwalters@7 77 if (file_handle_ == NULL) {
tomwalters@8 78 /*! \todo Also display error reason
tomwalters@8 79 */
tomwalters@232 80 LOG_ERROR(_T("Couldn't read audio file '%s'"),
tomwalters@232 81 global_parameters_->GetString("input_filename"));
tomwalters@162 82 return false;
tomwalters@7 83 }
tomwalters@232 84
tomwalters@3 85 file_loaded_ = true;
tomwalters@232 86 done_ = false;
tomwalters@3 87 audio_channels_ = sfinfo.channels;
tomwalters@3 88 sample_rate_ = sfinfo.samplerate;
tomwalters@7 89 file_position_samples_ = 0;
tomwalters@3 90
tomwalters@232 91 if (audio_channels_ < 1 || buffer_length_ < 1 || sample_rate_ < 0.0f) {
tomwalters@232 92 LOG_ERROR(_T("Problem with file: audio_channels = %d, buffer_length_ = %d, sample_rate = %f"), audio_channels_, buffer_length_, sample_rate_);
tomwalters@232 93 return false;
tomwalters@232 94 }
tomwalters@3 95
tomwalters@232 96 output_.Initialize(audio_channels_, buffer_length_, sample_rate_);
tomwalters@232 97 output_.set_start_time(0);
tomwalters@232 98
tomwalters@232 99 return true;
tomwalters@162 100 }
tomwalters@162 101
tomwalters@162 102 void ModuleFileInput::Process(const SignalBank& input) {
tomwalters@6 103 if (!file_loaded_)
tomwalters@6 104 return;
tomwalters@7 105 sf_count_t read;
tomwalters@3 106 vector<float> buffer;
tomwalters@3 107 buffer.resize(buffer_length_ * audio_channels_);
tomwalters@3 108
tomwalters@232 109 // Read buffersize bytes into buffer
tomwalters@232 110 read = sf_readf_float(file_handle_, &buffer[0], buffer_length_);
tomwalters@232 111
tomwalters@232 112 // Place the contents of the buffer into the signal bank
tomwalters@232 113 int counter = 0;
tomwalters@232 114 for (int c = 0; c < audio_channels_; ++c) {
tomwalters@232 115 for (int i = 0; i < read; ++i) {
tomwalters@232 116 output_.set_sample(c, i, buffer[counter]);
tomwalters@232 117 ++counter;
tomwalters@232 118 }
tomwalters@232 119 }
tomwalters@3 120
tomwalters@232 121 // If the number of saples read is less than the buffer length, the end
tomwalters@232 122 // of the file has been reached.
tomwalters@232 123 if (read < buffer_length_) {
tomwalters@232 124 // Zero samples at end
tomwalters@162 125 for (int c = 0; c < audio_channels_; ++c) {
tomwalters@232 126 for (int i = read; i < buffer_length_; ++i) {
tomwalters@232 127 output_.set_sample(c, i, 0.0f);
tomwalters@3 128 }
tomwalters@3 129 }
tomwalters@232 130 // When we're past the end of the buffer, set the
tomwalters@232 131 // module state to 'done' and exit.
tomwalters@232 132 if (read == 0)
tomwalters@232 133 done_ = true;
tomwalters@232 134 return;
tomwalters@232 135 }
tomwalters@162 136
tomwalters@232 137 // Update time.
tomwalters@232 138 output_.set_start_time(file_position_samples_);
tomwalters@232 139 file_position_samples_ += read;
tomwalters@232 140 PushOutput();
tomwalters@3 141 }
tomwalters@3 142 } // namespace aimc