Mercurial > hg > aimc
comparison trunk/src/Modules/Input/ModuleFileInput.cc @ 275:ce2bab04f155
- Imported file input using libsndfile from old AIM-C and updated to the new API
- Modified the Module base class to propogate Reset() calls down the module chain.
- This required changing all Reset() functions in subclasses to ResetInternal()
- Removed some unneeded imports from the Gaussians test
author | tomwalters |
---|---|
date | Tue, 16 Feb 2010 18:00:16 +0000 |
parents | |
children | 5b8b9ea1218a |
comparison
equal
deleted
inserted
replaced
274:3640d25b65ab | 275:ce2bab04f155 |
---|---|
1 // Copyright 2006-2010, Willem van Engen, Thomas Walters | |
2 // | |
3 // AIM-C: A C++ implementation of the Auditory Image Model | |
4 // http://www.acousticscale.org/AIMC | |
5 // | |
6 // This program is free software: you can redistribute it and/or modify | |
7 // it under the terms of the GNU General Public License as published by | |
8 // the Free Software Foundation, either version 3 of the License, or | |
9 // (at your option) any later version. | |
10 // | |
11 // This program is distributed in the hope that it will be useful, | |
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 // GNU General Public License for more details. | |
15 // | |
16 // You should have received a copy of the GNU General Public License | |
17 // along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 /*! \file | |
20 * \brief Audio file input | |
21 * | |
22 * \author Willem van Engen <cnbh@willem.engen.nl> | |
23 * \author Thomas Walters <tom@acousticscale.org> | |
24 * \date created 2006/09/21 | |
25 * \version \$Id$ | |
26 */ | |
27 | |
28 #include <vector> | |
29 | |
30 #include "Modules/Input/ModuleFileInput.h" | |
31 | |
32 namespace aimc { | |
33 ModuleFileInput::ModuleFileInput(Parameters *params) : Module(params) { | |
34 file_handle_ = NULL; | |
35 buffer_length_ = parameters_->DefaultInt("input.buffersize", 1024); | |
36 | |
37 file_position_samples_ = 0; | |
38 file_loaded_ = false; | |
39 audio_channels_ = 0; | |
40 buffer_length_ = 0; | |
41 sample_rate_ = 0.0f; | |
42 } | |
43 | |
44 ModuleFileInput::~ModuleFileInput() { | |
45 if (file_handle_) | |
46 sf_close(file_handle_); | |
47 } | |
48 | |
49 void ModuleFileInput::ResetInternal() { | |
50 output_.Initialize(audio_channels_, buffer_length_, sample_rate_); | |
51 output_.set_start_time(0); | |
52 } | |
53 | |
54 bool ModuleFileInput::LoadFile(const char* filename) { | |
55 // Open the file | |
56 SF_INFO sfinfo; | |
57 memset((void*)&sfinfo, 0, sizeof(SF_INFO)); | |
58 file_handle_ = sf_open(filename, SFM_READ, &sfinfo); | |
59 | |
60 if (file_handle_ == NULL) { | |
61 //! \todo Also display error reason | |
62 LOG_ERROR(_T("Couldn't read audio file '%s'"), filename); | |
63 return false; | |
64 } | |
65 | |
66 file_loaded_ = true; | |
67 audio_channels_ = sfinfo.channels; | |
68 sample_rate_ = sfinfo.samplerate; | |
69 file_position_samples_ = 0; | |
70 | |
71 // A dummy signal bank to be passed to the Initialize() function. | |
72 SignalBank s; | |
73 s.Initialize(1, 1, 1); | |
74 | |
75 // Self-initialize by calling Module::Initialize() explicitly. | |
76 // The Initialize() call in this subclass is overloaded to prevent it from | |
77 // being called drectly. | |
78 return Module::Initialize(s); | |
79 } | |
80 | |
81 bool ModuleFileInput::Initialize(const SignalBank& input) { | |
82 LOG_ERROR(_T("Do not call Initialize() on ModuleFileInput directly " | |
83 "instead call LoadFile() with a filename to load. " | |
84 "This will automatically initialize the module.")); | |
85 return false; | |
86 } | |
87 | |
88 void ModuleFileInput::Process(const SignalBank& input) { | |
89 LOG_ERROR(_T("Call Process() on ModuleFileInput instead of passing in " | |
90 "a SignalBank")); | |
91 } | |
92 | |
93 bool ModuleFileInput::InitializeInternal(const SignalBank& input) { | |
94 if (!file_loaded_) | |
95 return false; | |
96 ResetInternal(); | |
97 return true; | |
98 } | |
99 | |
100 void ModuleFileInput::Process() { | |
101 sf_count_t read; | |
102 vector<float> buffer; | |
103 buffer.resize(buffer_length_ * audio_channels_); | |
104 | |
105 while (true) { | |
106 // Read buffersize bytes into buffer | |
107 read = sf_readf_float(file_handle_, &buffer[0], buffer_length_); | |
108 | |
109 // Place the contents of the buffer into the signal bank | |
110 int counter = 0; | |
111 for (int c = 0; c < audio_channels_; ++c) { | |
112 for (int i = 0; i < read; ++i) { | |
113 output_.set_sample(c, i, buffer[counter]); | |
114 ++counter; | |
115 } | |
116 } | |
117 | |
118 // If the number of saples read is less than the buffer length, the end | |
119 // of the file has been reached. | |
120 if (read < buffer_length_) { | |
121 // Zero samples at end | |
122 for (int c = 0; c < audio_channels_; ++c) { | |
123 for (int i = read; i < buffer_length_; ++i) { | |
124 output_.set_sample(c, i, 0.0f); | |
125 } | |
126 } | |
127 // When we're past the end of the buffer, stop looping. | |
128 if (read == 0) | |
129 break; | |
130 } | |
131 | |
132 // Update time | |
133 output_.set_start_time(file_position_samples_); | |
134 file_position_samples_ += read; | |
135 | |
136 PushOutput(); | |
137 } | |
138 } | |
139 } // namespace aimc |