Mercurial > hg > aimc
comparison 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 |
comparison
equal
deleted
inserted
replaced
401:b71ec2cbe55b | 402:69466da9745e |
---|---|
50 file_handle_ = NULL; | 50 file_handle_ = NULL; |
51 } | 51 } |
52 } | 52 } |
53 | 53 |
54 void ModuleFileInput::ResetInternal() { | 54 void ModuleFileInput::ResetInternal() { |
55 output_.Initialize(audio_channels_, buffer_length_, sample_rate_); | 55 // If there's a file open, rewind to the beginning. |
56 output_.set_start_time(0); | 56 if (file_handle_ != NULL) { |
57 sf_seek(file_handle_, 0, SEEK_SET); | |
58 file_position_samples_ = 0; | |
59 } | |
57 } | 60 } |
58 | 61 |
59 bool ModuleFileInput::LoadFile(const char* filename) { | 62 bool ModuleFileInput::InitializeInternal(const SignalBank& input) { |
60 // If there's a file open. Close it. | 63 // If there's a file open. Close it. |
61 if (file_handle_ != NULL) { | 64 if (file_handle_ != NULL) { |
62 sf_close(file_handle_); | 65 sf_close(file_handle_); |
63 file_handle_ = NULL; | 66 file_handle_ = NULL; |
64 } | 67 } |
65 // Open the file | 68 // Open the file |
66 SF_INFO sfinfo; | 69 SF_INFO sfinfo; |
67 memset(reinterpret_cast<void*>(&sfinfo), 0, sizeof(SF_INFO)); | 70 memset(reinterpret_cast<void*>(&sfinfo), 0, sizeof(SF_INFO)); |
68 | 71 |
69 file_handle_ = sf_open(filename, SFM_READ, &sfinfo); | 72 file_loaded_ = false; |
73 file_handle_ = sf_open(global_parameters_->GetString("input_filename"), | |
74 SFM_READ, | |
75 &sfinfo); | |
70 | 76 |
71 if (file_handle_ == NULL) { | 77 if (file_handle_ == NULL) { |
72 /*! \todo Also display error reason | 78 /*! \todo Also display error reason |
73 */ | 79 */ |
74 LOG_ERROR(_T("Couldn't read audio file '%s'"), filename); | 80 LOG_ERROR(_T("Couldn't read audio file '%s'"), |
81 global_parameters_->GetString("input_filename")); | |
75 return false; | 82 return false; |
76 } | 83 } |
77 | 84 |
78 file_loaded_ = true; | 85 file_loaded_ = true; |
86 done_ = false; | |
79 audio_channels_ = sfinfo.channels; | 87 audio_channels_ = sfinfo.channels; |
80 sample_rate_ = sfinfo.samplerate; | 88 sample_rate_ = sfinfo.samplerate; |
81 file_position_samples_ = 0; | 89 file_position_samples_ = 0; |
82 | 90 |
83 // A dummy signal bank to be passed to the Initialize() function. | 91 if (audio_channels_ < 1 || buffer_length_ < 1 || sample_rate_ < 0.0f) { |
84 SignalBank s; | 92 LOG_ERROR(_T("Problem with file: audio_channels = %d, buffer_length_ = %d, sample_rate = %f"), audio_channels_, buffer_length_, sample_rate_); |
85 s.Initialize(1, 1, 1); | 93 return false; |
94 } | |
86 | 95 |
87 // Self-initialize by calling Module::Initialize() explicitly. | 96 output_.Initialize(audio_channels_, buffer_length_, sample_rate_); |
88 // The Initialize() call in this subclass is overloaded to prevent it from | 97 output_.set_start_time(0); |
89 // being called drectly. | 98 |
90 return Module::Initialize(s); | 99 return true; |
91 } | |
92 | |
93 | |
94 /* Do not call Initialize() on ModuleFileInput directly | |
95 * instead call LoadFile() with a filename to load. | |
96 * This will automatically initialize the module. | |
97 */ | |
98 bool ModuleFileInput::Initialize(const SignalBank& input) { | |
99 LOG_ERROR(_T("Do not call Initialize() on ModuleFileInput directly " | |
100 "instead call LoadFile() with a filename to load. " | |
101 "This will automatically initialize the module.")); | |
102 return false; | |
103 } | 100 } |
104 | 101 |
105 void ModuleFileInput::Process(const SignalBank& input) { | 102 void ModuleFileInput::Process(const SignalBank& input) { |
106 LOG_ERROR(_T("Call Process() on ModuleFileInput instead of passing in " | |
107 "a SignalBank")); | |
108 } | |
109 | |
110 bool ModuleFileInput::InitializeInternal(const SignalBank& input) { | |
111 if (!file_loaded_) { | |
112 LOG_ERROR(_T("No file loaded in FileOutputHTK")); | |
113 return false; | |
114 } | |
115 if (audio_channels_ < 1 || buffer_length_ < 1 || sample_rate_ < 0.0f) { | |
116 LOG_ERROR(_T("audio_channels, buffer_length_ or sample_rate too small")); | |
117 return false; | |
118 } | |
119 ResetInternal(); | |
120 return true; | |
121 } | |
122 | |
123 void ModuleFileInput::Process() { | |
124 if (!file_loaded_) | 103 if (!file_loaded_) |
125 return; | 104 return; |
126 sf_count_t read; | 105 sf_count_t read; |
127 vector<float> buffer; | 106 vector<float> buffer; |
128 buffer.resize(buffer_length_ * audio_channels_); | 107 buffer.resize(buffer_length_ * audio_channels_); |
129 | 108 |
130 while (true) { | 109 // Read buffersize bytes into buffer |
131 // Read buffersize bytes into buffer | 110 read = sf_readf_float(file_handle_, &buffer[0], buffer_length_); |
132 read = sf_readf_float(file_handle_, &buffer[0], buffer_length_); | 111 |
112 // Place the contents of the buffer into the signal bank | |
113 int counter = 0; | |
114 for (int c = 0; c < audio_channels_; ++c) { | |
115 for (int i = 0; i < read; ++i) { | |
116 output_.set_sample(c, i, buffer[counter]); | |
117 ++counter; | |
118 } | |
119 } | |
133 | 120 |
134 // Place the contents of the buffer into the signal bank | 121 // If the number of saples read is less than the buffer length, the end |
135 int counter = 0; | 122 // of the file has been reached. |
123 if (read < buffer_length_) { | |
124 // Zero samples at end | |
136 for (int c = 0; c < audio_channels_; ++c) { | 125 for (int c = 0; c < audio_channels_; ++c) { |
137 for (int i = 0; i < read; ++i) { | 126 for (int i = read; i < buffer_length_; ++i) { |
138 output_.set_sample(c, i, buffer[counter]); | 127 output_.set_sample(c, i, 0.0f); |
139 ++counter; | |
140 } | 128 } |
141 } | 129 } |
130 // When we're past the end of the buffer, set the | |
131 // module state to 'done' and exit. | |
132 if (read == 0) | |
133 done_ = true; | |
134 return; | |
135 } | |
142 | 136 |
143 // If the number of saples read is less than the buffer length, the end | 137 // Update time. |
144 // of the file has been reached. | 138 output_.set_start_time(file_position_samples_); |
145 if (read < buffer_length_) { | 139 file_position_samples_ += read; |
146 // Zero samples at end | 140 PushOutput(); |
147 for (int c = 0; c < audio_channels_; ++c) { | |
148 for (int i = read; i < buffer_length_; ++i) { | |
149 output_.set_sample(c, i, 0.0f); | |
150 } | |
151 } | |
152 // When we're past the end of the buffer, stop looping. | |
153 if (read == 0) | |
154 break; | |
155 } | |
156 | |
157 // Update time | |
158 output_.set_start_time(file_position_samples_); | |
159 file_position_samples_ += read; | |
160 PushOutput(); | |
161 } | |
162 } | 141 } |
163 } // namespace aimc | 142 } // namespace aimc |