tomwalters@320
|
1 // Copyright 2006-2010, Thomas Walters
|
tomwalters@320
|
2 //
|
tomwalters@320
|
3 // AIM-C: A C++ implementation of the Auditory Image Model
|
tomwalters@320
|
4 // http://www.acousticscale.org/AIMC
|
tomwalters@320
|
5 //
|
tomwalters@320
|
6 // Licensed under the Apache License, Version 2.0 (the "License");
|
tomwalters@320
|
7 // you may not use this file except in compliance with the License.
|
tomwalters@320
|
8 // You may obtain a copy of the License at
|
tomwalters@320
|
9 //
|
tomwalters@320
|
10 // http://www.apache.org/licenses/LICENSE-2.0
|
tomwalters@320
|
11 //
|
tomwalters@320
|
12 // Unless required by applicable law or agreed to in writing, software
|
tomwalters@320
|
13 // distributed under the License is distributed on an "AS IS" BASIS,
|
tomwalters@320
|
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
tomwalters@320
|
15 // See the License for the specific language governing permissions and
|
tomwalters@320
|
16 // limitations under the License.
|
tomwalters@320
|
17
|
tomwalters@320
|
18 /*!
|
tomwalters@320
|
19 * \file
|
tomwalters@320
|
20 * \brief File output in the HTK format.
|
tomwalters@320
|
21 *
|
tomwalters@320
|
22 * \author Tom Walters <tom@acousticscale.org>
|
tomwalters@320
|
23 * \author Willem van Engen <cnbh@willem.engen.nl>
|
tomwalters@320
|
24 * \date created 2007/01/26
|
tomwalters@320
|
25 * \version \$Id: $
|
tomwalters@320
|
26 */
|
tomwalters@320
|
27
|
tomwalters@614
|
28 #include "Modules/Output/FileOutputAIMC.h"
|
tomwalters@614
|
29
|
tomwalters@320
|
30 #ifdef _WINDOWS
|
tomwalters@320
|
31 # include <direct.h> // for _mkdir & _rmdir
|
tomwalters@320
|
32 #else
|
tomwalters@320
|
33 # include <sys/types.h>
|
tomwalters@320
|
34 # include <dirent.h> // for opendir & friends
|
tomwalters@320
|
35 #endif
|
tomwalters@320
|
36
|
tomwalters@320
|
37 #include <stdint.h>
|
tomwalters@320
|
38 #include <stdio.h>
|
tomwalters@320
|
39 #include <string.h>
|
tomwalters@320
|
40 #include <cmath>
|
tom@440
|
41 #include <string>
|
tomwalters@320
|
42
|
tomwalters@320
|
43 namespace aimc {
|
tomwalters@320
|
44 FileOutputAIMC::FileOutputAIMC(Parameters *params) : Module(params) {
|
tomwalters@320
|
45 module_description_ = "File output in AIMC format";
|
tomwalters@402
|
46 module_identifier_ = "aimc_out";
|
tomwalters@320
|
47 module_type_ = "output";
|
tomwalters@320
|
48 module_version_ = "$Id: FileOutputAIMC.cc 51 2010-03-30 22:06:24Z tomwalters $";
|
tom@440
|
49 file_suffix_ = parameters_->DefaultString("file_suffix", ".aimc");
|
tomwalters@614
|
50 dump_strobes_ = parameters_->DefaultBool("dump_strobes", false);
|
tomwalters@614
|
51 strobes_file_suffix_ = parameters_->DefaultString("strobes_file_suffix", ".strobes");
|
tomwalters@320
|
52
|
tomwalters@320
|
53 file_handle_ = NULL;
|
tomwalters@614
|
54 strobes_file_handle_ = NULL;
|
tomwalters@320
|
55 header_written_ = false;
|
tomwalters@320
|
56 frame_period_ms_ = 0.0f;
|
tomwalters@320
|
57 }
|
tomwalters@320
|
58
|
tomwalters@320
|
59 FileOutputAIMC::~FileOutputAIMC() {
|
tomwalters@320
|
60 if (file_handle_ != NULL)
|
tomwalters@320
|
61 CloseFile();
|
tomwalters@614
|
62 if (strobes_file_handle_ != NULL)
|
tomwalters@614
|
63 CloseStrobesFile();
|
tomwalters@614
|
64 }
|
tomwalters@614
|
65
|
tomwalters@614
|
66 bool FileOutputAIMC::OpenStrobesFile(string &filename) {
|
tomwalters@614
|
67 if (strobes_file_handle_ != NULL) {
|
tomwalters@614
|
68 LOG_ERROR(_T("Couldn't open strobes output file. A file is already open."));
|
tomwalters@614
|
69 return false;
|
tomwalters@614
|
70 }
|
tomwalters@614
|
71 // Check that the output file exists and is writeable
|
tomwalters@614
|
72 if ((strobes_file_handle_ = fopen(filename.c_str(), "wb")) == NULL) {
|
tomwalters@614
|
73 LOG_ERROR(_T("Couldn't open output file '%s' for writing."), filename.c_str());
|
tomwalters@614
|
74 return false;
|
tomwalters@614
|
75 }
|
tomwalters@614
|
76 return true;
|
tomwalters@320
|
77 }
|
tomwalters@320
|
78
|
tom@440
|
79 bool FileOutputAIMC::OpenFile(string &filename) {
|
tomwalters@320
|
80 if (file_handle_ != NULL) {
|
tomwalters@320
|
81 LOG_ERROR(_T("Couldn't open output file. A file is already open."));
|
tomwalters@320
|
82 return false;
|
tomwalters@320
|
83 }
|
tomwalters@320
|
84
|
tomwalters@320
|
85 // Check that the output file exists and is writeable
|
tom@440
|
86 if ((file_handle_ = fopen(filename.c_str(), "wb")) == NULL) {
|
tom@440
|
87 LOG_ERROR(_T("Couldn't open output file '%s' for writing."), filename.c_str());
|
tomwalters@320
|
88 return false;
|
tomwalters@320
|
89 }
|
tom@440
|
90 // Write temporary values for the frame count and frame period.
|
tomwalters@322
|
91 frame_count_ = 0;
|
tom@440
|
92 frame_period_ms_ = 0.0;
|
tomwalters@320
|
93 header_written_ = false;
|
tomwalters@320
|
94 if (initialized_) {
|
tomwalters@320
|
95 WriteHeader();
|
tomwalters@320
|
96 }
|
tomwalters@614
|
97
|
tomwalters@320
|
98 return true;
|
tomwalters@320
|
99 }
|
tomwalters@320
|
100
|
tomwalters@320
|
101 bool FileOutputAIMC::InitializeInternal(const SignalBank &input) {
|
tom@440
|
102 channel_count_ = input.channel_count();
|
tom@440
|
103 buffer_length_ = input.buffer_length();
|
tom@440
|
104 sample_rate_ = input.sample_rate();
|
tom@440
|
105 ResetInternal();
|
tomwalters@320
|
106 if (file_handle_ == NULL) {
|
tom@440
|
107 LOG_ERROR(_T("Couldn't initialize file output."));
|
tomwalters@320
|
108 return false;
|
tomwalters@320
|
109 }
|
tomwalters@320
|
110 return true;
|
tomwalters@320
|
111 }
|
tomwalters@320
|
112
|
tomwalters@320
|
113 void FileOutputAIMC::ResetInternal() {
|
tomwalters@320
|
114 if (file_handle_ != NULL && !header_written_) {
|
tomwalters@320
|
115 WriteHeader();
|
tomwalters@320
|
116 }
|
tomwalters@320
|
117 if (file_handle_ != NULL)
|
tomwalters@320
|
118 CloseFile();
|
tom@440
|
119
|
tom@440
|
120 string out_filename;
|
tom@440
|
121 out_filename = global_parameters_->GetString("output_filename_base") + file_suffix_;
|
tom@440
|
122 OpenFile(out_filename);
|
tomwalters@614
|
123 if (dump_strobes_) {
|
tomwalters@614
|
124 if (strobes_file_handle_ != NULL) {
|
tomwalters@614
|
125 CloseStrobesFile();
|
tomwalters@614
|
126 }
|
tomwalters@614
|
127 string strobes_filename =
|
tomwalters@614
|
128 global_parameters_->GetString("output_filename_base")
|
tomwalters@614
|
129 + strobes_file_suffix_;
|
tomwalters@614
|
130 OpenStrobesFile(strobes_filename);
|
tomwalters@614
|
131 }
|
tomwalters@320
|
132 }
|
tomwalters@320
|
133
|
tomwalters@320
|
134 void FileOutputAIMC::WriteHeader() {
|
tomwalters@320
|
135 if (header_written_)
|
tomwalters@320
|
136 return;
|
tomwalters@320
|
137
|
tomwalters@320
|
138 /* File format:
|
tomwalters@320
|
139 * Header: Number of frames (uint32),
|
tomwalters@320
|
140 * Frame period in milliseconds (float32),
|
tomwalters@320
|
141 * Number of channels per frame (uint32),
|
tomwalters@320
|
142 * Number of samples per channel of each frame (uint32)
|
tomwalters@320
|
143 * Sample rate (float32)
|
tomwalters@320
|
144 *
|
tomwalters@320
|
145 * Data: Series of floats, by time, then channel, then frame
|
tomwalters@320
|
146 * f1c1t1,f1c1t2,f1c1t3...
|
tomwalters@320
|
147 */
|
tomwalters@320
|
148
|
tomwalters@322
|
149 uint32_t frame_count_out = frame_count_;
|
tomwalters@320
|
150 float sample_period_out = frame_period_ms_;
|
tomwalters@320
|
151 uint32_t channels_out = channel_count_;
|
tomwalters@320
|
152 uint32_t samples_out = buffer_length_;
|
tomwalters@320
|
153 float sample_rate = sample_rate_;
|
tomwalters@320
|
154
|
tomwalters@322
|
155 fwrite(&frame_count_out, sizeof(frame_count_out), 1, file_handle_);
|
tomwalters@320
|
156 fwrite(&sample_period_out, sizeof(sample_period_out), 1, file_handle_);
|
tomwalters@320
|
157 fwrite(&channels_out, sizeof(channels_out), 1, file_handle_);
|
tomwalters@320
|
158 fwrite(&samples_out, sizeof(samples_out), 1, file_handle_);
|
tomwalters@320
|
159 fwrite(&sample_rate, sizeof(sample_rate), 1, file_handle_);
|
tomwalters@320
|
160 fflush(file_handle_);
|
tomwalters@320
|
161
|
tomwalters@320
|
162 header_written_ = true;
|
tomwalters@320
|
163 }
|
tomwalters@320
|
164
|
tomwalters@320
|
165 void FileOutputAIMC::Process(const SignalBank &input) {
|
tomwalters@320
|
166 if (file_handle_ == NULL) {
|
tomwalters@320
|
167 LOG_ERROR(_T("Couldn't process file output. No file is open."
|
tomwalters@320
|
168 "Please call FileOutputAIMC::OpenFile first"));
|
tomwalters@320
|
169 return;
|
tomwalters@320
|
170 }
|
tomwalters@320
|
171
|
tomwalters@320
|
172 if (!header_written_) {
|
tomwalters@320
|
173 LOG_ERROR(_T("No header has been written on the output file yet. Please "
|
tomwalters@320
|
174 "call FileOutputAIMC::Initialize() before calling "
|
tomwalters@320
|
175 "FileOutputAIMC::Process()"));
|
tomwalters@320
|
176 return;
|
tomwalters@320
|
177 }
|
tomwalters@320
|
178 float s;
|
tomwalters@320
|
179
|
tomwalters@320
|
180 for (int ch = 0; ch < input.channel_count(); ch++) {
|
tomwalters@320
|
181 for (int i = 0; i < input.buffer_length(); i++) {
|
tomwalters@320
|
182 s = input.sample(ch, i);
|
tomwalters@320
|
183 fwrite(&s, sizeof(s), 1, file_handle_);
|
tomwalters@320
|
184 }
|
tomwalters@320
|
185 }
|
tomwalters@322
|
186 frame_count_++;
|
tomwalters@614
|
187
|
tomwalters@614
|
188 if (dump_strobes_) {
|
tomwalters@614
|
189 if (strobes_file_handle_ == NULL) {
|
tomwalters@614
|
190 LOG_ERROR(_T("Couldn't process file output for strobes. No srobes file is open."
|
tomwalters@614
|
191 "Please call FileOutputAIMC::OpenStrobesFile first"));
|
tomwalters@614
|
192 return;
|
tomwalters@614
|
193 }
|
tomwalters@614
|
194 int strobe;
|
tomwalters@614
|
195 for (int ch = 0; ch < input.channel_count(); ch++) {
|
tomwalters@614
|
196 const int kStartOfStrobeRow = -65535;
|
tomwalters@614
|
197 strobe = kStartOfStrobeRow;
|
tomwalters@614
|
198 fwrite(&strobe, sizeof(strobe), 1, strobes_file_handle_);
|
tomwalters@614
|
199 for (int i = 0; i < static_cast<int>(input.get_strobes(ch).size());
|
tomwalters@614
|
200 i++) {
|
tomwalters@614
|
201 strobe = input.get_strobes(ch)[i];
|
tomwalters@614
|
202 fwrite(&strobe, sizeof(strobe), 1, strobes_file_handle_);
|
tomwalters@614
|
203 }
|
tomwalters@614
|
204 }
|
tomwalters@614
|
205 }
|
tomwalters@614
|
206
|
tomwalters@614
|
207 }
|
tomwalters@614
|
208
|
tomwalters@614
|
209 bool FileOutputAIMC::CloseStrobesFile() {
|
tomwalters@614
|
210 if (strobes_file_handle_ == NULL)
|
tomwalters@614
|
211 return false;
|
tomwalters@614
|
212
|
tomwalters@614
|
213 // And close the file
|
tomwalters@614
|
214 fclose(strobes_file_handle_);
|
tomwalters@614
|
215 strobes_file_handle_ = NULL;
|
tomwalters@614
|
216 return true;
|
tomwalters@320
|
217 }
|
tomwalters@320
|
218
|
tomwalters@320
|
219 bool FileOutputAIMC::CloseFile() {
|
tomwalters@320
|
220 if (file_handle_ == NULL)
|
tomwalters@320
|
221 return false;
|
tomwalters@320
|
222
|
tomwalters@320
|
223 // Write the first 4 bytes of the file
|
tomwalters@320
|
224 // with how many samples there are in the file
|
tomwalters@320
|
225 fflush(file_handle_);
|
tomwalters@320
|
226 rewind(file_handle_);
|
tomwalters@320
|
227 fflush(file_handle_);
|
tomwalters@322
|
228 uint32_t frame_count = frame_count_;
|
tom@440
|
229 float sample_period_out = frame_period_ms_;
|
tomwalters@322
|
230 fwrite(&frame_count, sizeof(frame_count), 1, file_handle_);
|
tom@440
|
231 fwrite(&sample_period_out, sizeof(sample_period_out), 1, file_handle_);
|
tomwalters@320
|
232
|
tomwalters@320
|
233 // And close the file
|
tomwalters@320
|
234 fclose(file_handle_);
|
tomwalters@320
|
235 file_handle_ = NULL;
|
tomwalters@320
|
236 header_written_ = false;
|
tomwalters@320
|
237 return true;
|
tomwalters@320
|
238 }
|
tomwalters@320
|
239 } // namespace aimc
|
tomwalters@320
|
240
|