annotate src/Modules/Input/ModuleFileInput.cc @ 246:0a3342606855

- Allow processing without re-initialization.
author tom@acousticscale.org
date Tue, 26 Oct 2010 04:48:56 +0000
parents af531fc3f280
children b953e295b49e
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@20 55 // If there's a file open. Close it.
tomwalters@20 56 if (file_handle_ != NULL) {
tomwalters@20 57 sf_close(file_handle_);
tomwalters@20 58 file_handle_ = NULL;
tomwalters@20 59 }
tom@246 60 // Open a file
tomwalters@7 61 SF_INFO sfinfo;
tomwalters@8 62 memset(reinterpret_cast<void*>(&sfinfo), 0, sizeof(SF_INFO));
tomwalters@20 63
tomwalters@232 64 file_loaded_ = false;
tomwalters@232 65 file_handle_ = sf_open(global_parameters_->GetString("input_filename"),
tomwalters@232 66 SFM_READ,
tomwalters@232 67 &sfinfo);
tomwalters@3 68
tomwalters@7 69 if (file_handle_ == NULL) {
tomwalters@8 70 /*! \todo Also display error reason
tomwalters@8 71 */
tomwalters@232 72 LOG_ERROR(_T("Couldn't read audio file '%s'"),
tomwalters@232 73 global_parameters_->GetString("input_filename"));
tom@246 74 return;
tomwalters@7 75 }
tomwalters@232 76
tomwalters@3 77 file_loaded_ = true;
tomwalters@232 78 done_ = false;
tomwalters@3 79 audio_channels_ = sfinfo.channels;
tomwalters@3 80 sample_rate_ = sfinfo.samplerate;
tomwalters@7 81 file_position_samples_ = 0;
tomwalters@3 82
tomwalters@232 83 if (audio_channels_ < 1 || buffer_length_ < 1 || sample_rate_ < 0.0f) {
tomwalters@232 84 LOG_ERROR(_T("Problem with file: audio_channels = %d, buffer_length_ = %d, sample_rate = %f"), audio_channels_, buffer_length_, sample_rate_);
tom@246 85 return;
tomwalters@232 86 }
tomwalters@3 87
tomwalters@232 88 output_.Initialize(audio_channels_, buffer_length_, sample_rate_);
tomwalters@232 89 output_.set_start_time(0);
tom@246 90 }
tom@246 91
tom@246 92 bool ModuleFileInput::InitializeInternal(const SignalBank& input) {
tom@246 93 ResetInternal();
tomwalters@232 94 return true;
tomwalters@162 95 }
tomwalters@162 96
tomwalters@162 97 void ModuleFileInput::Process(const SignalBank& input) {
tomwalters@6 98 if (!file_loaded_)
tomwalters@6 99 return;
tomwalters@7 100 sf_count_t read;
tomwalters@3 101 vector<float> buffer;
tomwalters@3 102 buffer.resize(buffer_length_ * audio_channels_);
tomwalters@3 103
tomwalters@232 104 // Read buffersize bytes into buffer
tomwalters@232 105 read = sf_readf_float(file_handle_, &buffer[0], buffer_length_);
tomwalters@232 106
tomwalters@232 107 // Place the contents of the buffer into the signal bank
tomwalters@232 108 int counter = 0;
tomwalters@232 109 for (int c = 0; c < audio_channels_; ++c) {
tomwalters@232 110 for (int i = 0; i < read; ++i) {
tomwalters@232 111 output_.set_sample(c, i, buffer[counter]);
tomwalters@232 112 ++counter;
tomwalters@232 113 }
tomwalters@232 114 }
tomwalters@3 115
tomwalters@232 116 // If the number of saples read is less than the buffer length, the end
tomwalters@232 117 // of the file has been reached.
tomwalters@232 118 if (read < buffer_length_) {
tomwalters@232 119 // Zero samples at end
tomwalters@162 120 for (int c = 0; c < audio_channels_; ++c) {
tomwalters@232 121 for (int i = read; i < buffer_length_; ++i) {
tomwalters@232 122 output_.set_sample(c, i, 0.0f);
tomwalters@3 123 }
tomwalters@3 124 }
tomwalters@232 125 // When we're past the end of the buffer, set the
tomwalters@232 126 // module state to 'done' and exit.
tomwalters@232 127 if (read == 0)
tomwalters@232 128 done_ = true;
tomwalters@232 129 return;
tomwalters@232 130 }
tomwalters@162 131
tomwalters@232 132 // Update time.
tomwalters@232 133 output_.set_start_time(file_position_samples_);
tomwalters@232 134 file_position_samples_ += read;
tomwalters@232 135 PushOutput();
tomwalters@3 136 }
tomwalters@3 137 } // namespace aimc