annotate src/Modules/Input/ModuleFileInput.cc @ 121:3cdaa81c3aca

- 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 c5f5e9569863
children 0c492eada814
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@121 55 // If there's a file open, rewind to the beginning.
tomwalters@121 56 if (file_handle_ != NULL) {
tomwalters@121 57 sf_seek(file_handle_, 0, SEEK_SET);
tomwalters@121 58 file_position_samples_ = 0;
tomwalters@121 59 }
tomwalters@3 60 }
tomwalters@3 61
tomwalters@121 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@7 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@121 72 file_loaded_ = false;
tomwalters@121 73 file_handle_ = sf_open(global_parameters_->GetString("input_filename"),
tomwalters@121 74 SFM_READ,
tomwalters@121 75 &sfinfo);
tomwalters@3 76
tomwalters@7 77 if (file_handle_ == NULL) {
tomwalters@8 78 /*! \todo Also display error reason
tomwalters@8 79 */
tomwalters@121 80 LOG_ERROR(_T("Couldn't read audio file '%s'"),
tomwalters@121 81 global_parameters_->GetString("input_filename"));
tomwalters@7 82 return false;
tomwalters@7 83 }
tomwalters@121 84
tomwalters@3 85 file_loaded_ = true;
tomwalters@121 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@121 91 if (audio_channels_ < 1 || buffer_length_ < 1 || sample_rate_ < 0.0f) {
tomwalters@121 92 LOG_ERROR(_T("Problem with file: audio_channels = %d, buffer_length_ = %d, sample_rate = %f"), audio_channels_, buffer_length_, sample_rate_);
tomwalters@121 93 return false;
tomwalters@121 94 }
tomwalters@3 95
tomwalters@121 96 output_.Initialize(audio_channels_, buffer_length_, sample_rate_);
tomwalters@121 97 output_.set_start_time(0);
tomwalters@121 98
tomwalters@121 99 return true;
tomwalters@3 100 }
tomwalters@3 101
tomwalters@3 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@121 109 // Read buffersize bytes into buffer
tomwalters@121 110 read = sf_readf_float(file_handle_, &buffer[0], buffer_length_);
tomwalters@121 111
tomwalters@121 112 // Place the contents of the buffer into the signal bank
tomwalters@121 113 int counter = 0;
tomwalters@121 114 for (int c = 0; c < audio_channels_; ++c) {
tomwalters@121 115 for (int i = 0; i < read; ++i) {
tomwalters@121 116 output_.set_sample(c, i, buffer[counter]);
tomwalters@121 117 ++counter;
tomwalters@121 118 }
tomwalters@121 119 }
tomwalters@3 120
tomwalters@121 121 // If the number of saples read is less than the buffer length, the end
tomwalters@121 122 // of the file has been reached.
tomwalters@121 123 if (read < buffer_length_) {
tomwalters@121 124 // Zero samples at end
tomwalters@3 125 for (int c = 0; c < audio_channels_; ++c) {
tomwalters@121 126 for (int i = read; i < buffer_length_; ++i) {
tomwalters@121 127 output_.set_sample(c, i, 0.0f);
tomwalters@3 128 }
tomwalters@3 129 }
tomwalters@121 130 // When we're past the end of the buffer, set the
tomwalters@121 131 // module state to 'done' and exit.
tomwalters@121 132 if (read == 0)
tomwalters@121 133 done_ = true;
tomwalters@121 134 return;
tomwalters@121 135 }
tomwalters@3 136
tomwalters@121 137 // Update time.
tomwalters@121 138 output_.set_start_time(file_position_samples_);
tomwalters@121 139 file_position_samples_ += read;
tomwalters@121 140 PushOutput();
tomwalters@3 141 }
tomwalters@3 142 } // namespace aimc