annotate trunk/src/Modules/Input/ModuleFileInput.cc @ 414:03954c09e5d0

- Cairo dependency
author tomwalters
date Sun, 24 Oct 2010 23:53:36 +0000
parents 69466da9745e
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