annotate trunk/src/Modules/Input/ModuleFileInput.cc @ 402:69466da9745e

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