comparison trunk/src/Modules/Output/FileOutputHTK.cc @ 279:f469d936337f

- Replacing tabs with spaces for indentation
author tomwalters
date Thu, 18 Feb 2010 20:04:04 +0000
parents 5b8b9ea1218a
children e55d0c225a57
comparison
equal deleted inserted replaced
278:5b8b9ea1218a 279:f469d936337f
16 // You should have received a copy of the GNU General Public License 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/>. 17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 /*! 19 /*!
20 * \file 20 * \file
21 * \brief File output in the HTK format. 21 * \brief File output in the HTK format.
22 * 22 *
23 * \author Tom Walters <tom@acousticscale.org> 23 * \author Tom Walters <tom@acousticscale.org>
24 * \author Willem van Engen <cnbh@willem.engen.nl> 24 * \author Willem van Engen <cnbh@willem.engen.nl>
25 * \date created 2006/10/30 25 * \date created 2006/10/30
26 * \version \$Id$ 26 * \version \$Id$
27 */ 27 */
28 28
29 #ifdef _WINDOWS 29 #ifdef _WINDOWS
30 # include <direct.h> // for _mkdir&_rmdir 30 # include <direct.h> // for _mkdir&_rmdir
31 #else 31 #else
32 # include <sys/types.h> 32 # include <sys/types.h>
33 # include <dirent.h> // for opendir&friends 33 # include <dirent.h> // for opendir&friends
34 #endif 34 #endif
35 #include <stdio.h> 35 #include <stdio.h>
36 #include <string.h> 36 #include <string.h>
37 #include <cmath> 37 #include <cmath>
38 38
43 module_description_ = "File output in HTK format"; 43 module_description_ = "File output in HTK format";
44 module_identifier_ = "htk_out"; 44 module_identifier_ = "htk_out";
45 module_type_ = "output"; 45 module_type_ = "output";
46 module_version_ = "$Id$"; 46 module_version_ = "$Id$";
47 47
48 file_handle_ = NULL; 48 file_handle_ = NULL;
49 header_written_ = false; 49 header_written_ = false;
50 filename_[0] = '\0'; 50 filename_[0] = '\0';
51 frame_period_ms_ = 0.0f; 51 frame_period_ms_ = 0.0f;
52 } 52 }
53 53
54 FileOutputHTK::~FileOutputHTK() { 54 FileOutputHTK::~FileOutputHTK() {
55 if (file_handle_ != NULL) 55 if (file_handle_ != NULL)
56 CloseFile(); 56 CloseFile();
57 } 57 }
58 58
59 bool FileOutputHTK::OpenFile(const char* filename, float frame_period_ms) { 59 bool FileOutputHTK::OpenFile(const char* filename, float frame_period_ms) {
60 if (file_handle_ != NULL) { 60 if (file_handle_ != NULL) {
61 LOG_ERROR(_T("Couldn't open output file. A file is already open.")); 61 LOG_ERROR(_T("Couldn't open output file. A file is already open."));
62 return false; 62 return false;
63 } 63 }
64 64
65 // Check that the output file exists and is writeable 65 // Check that the output file exists and is writeable
66 if ((file_handle_ = fopen(filename, "wb"))==NULL ) { 66 if ((file_handle_ = fopen(filename, "wb"))==NULL ) {
67 LOG_ERROR(_T("Couldn't open output file '%s' for writing."), filename); 67 LOG_ERROR(_T("Couldn't open output file '%s' for writing."), filename);
68 return false; 68 return false;
69 } 69 }
70 strcpy(filename_, filename); 70 strcpy(filename_, filename);
71 sample_count_ = 0; 71 sample_count_ = 0;
72 frame_period_ms_ = frame_period_ms; 72 frame_period_ms_ = frame_period_ms;
73 header_written_ = false; 73 header_written_ = false;
74 return true; 74 return true;
75 } 75 }
76 76
77 bool FileOutputHTK::InitializeInternal(const SignalBank &input) { 77 bool FileOutputHTK::InitializeInternal(const SignalBank &input) {
78 if (file_handle_ == NULL) { 78 if (file_handle_ == NULL) {
79 LOG_ERROR(_T("Couldn't initialize file output. " 79 LOG_ERROR(_T("Couldn't initialize file output. "
80 "Please call FileOutputHTK::OpenFile first")); 80 "Please call FileOutputHTK::OpenFile first"));
81 return false; 81 return false;
82 } 82 }
83 if (header_written_) { 83 if (header_written_) {
84 LOG_ERROR(_T("A header has already been written on the output file." 84 LOG_ERROR(_T("A header has already been written on the output file."
85 "Please call FileOutputHTK::CloseFile to close that file, " 85 "Please call FileOutputHTK::CloseFile to close that file, "
86 "and FileOutputHTK::OpenFile to open an new one before " 86 "and FileOutputHTK::OpenFile to open an new one before "
87 "calling FileOutputHTK::Initialize again.")); 87 "calling FileOutputHTK::Initialize again."));
88 return false; 88 return false;
89 } 89 }
90 channel_count_ = input.channel_count(); 90 channel_count_ = input.channel_count();
91 buffer_length_ = input.buffer_length(); 91 buffer_length_ = input.buffer_length();
92 WriteHeader(channel_count_ * buffer_length_, frame_period_ms_); 92 WriteHeader(channel_count_ * buffer_length_, frame_period_ms_);
93 return true; 93 return true;
98 WriteHeader(channel_count_ * buffer_length_, frame_period_ms_); 98 WriteHeader(channel_count_ * buffer_length_, frame_period_ms_);
99 } 99 }
100 } 100 }
101 101
102 void FileOutputHTK::WriteHeader(int num_elements, float period_ms) { 102 void FileOutputHTK::WriteHeader(int num_elements, float period_ms) {
103 if (header_written_) 103 if (header_written_)
104 return; 104 return;
105 105
106 /* HTK format file: (taken from the HTK book - section 5.10.1) 106 /* HTK format file: (taken from the HTK book - section 5.10.1)
107 * Header: 12 bytes in total, contains: 107 * Header: 12 bytes in total, contains:
108 * sample_count - number of samples in file (4-byte integer)(long) 108 * sample_count - number of samples in file (4-byte integer)(long)
109 * sample_period - sample period in 100ns units (4-byte integer)(long) 109 * sample_period - sample period in 100ns units (4-byte integer)(long)
110 * sample_size - number of bytes per sample (2-byte integer)(short) 110 * sample_size - number of bytes per sample (2-byte integer)(short)
111 * parameter_kind - a code indicating the sample kind (2-byte integer)(short) 111 * parameter_kind - a code indicating the sample kind (2-byte integer)(short)
112 */ 112 */
113 113
114 // To be filled in when the file is done 114 // To be filled in when the file is done
115 int32_t sample_count = 0; 115 int32_t sample_count = 0;
116 116
117 int32_t sample_period = floor(1e4 * period_ms); 117 int32_t sample_period = floor(1e4 * period_ms);
118 int16_t sample_size = num_elements * sizeof(float); 118 int16_t sample_size = num_elements * sizeof(float);
119 119
120 // User-defined coefficients with energy term 120 // User-defined coefficients with energy term
121 int16_t parameter_kind = H_USER + H_E; 121 int16_t parameter_kind = H_USER + H_E;
122 122
123 // Fix endianness 123 // Fix endianness
124 sample_count = ByteSwap32(sample_count); 124 sample_count = ByteSwap32(sample_count);
125 sample_period = ByteSwap32(sample_period); 125 sample_period = ByteSwap32(sample_period);
126 sample_size = ByteSwap16(sample_size); 126 sample_size = ByteSwap16(sample_size);
127 parameter_kind = ByteSwap16(parameter_kind); 127 parameter_kind = ByteSwap16(parameter_kind);
128 128
129 // Enter header values. sample_count is a dummy value which is filled in on 129 // Enter header values. sample_count is a dummy value which is filled in on
130 // file close 130 // file close
131 fwrite(&sample_count, sizeof(sample_count), 1, file_handle_); 131 fwrite(&sample_count, sizeof(sample_count), 1, file_handle_);
132 fwrite(&sample_period, sizeof(sample_period), 1, file_handle_); 132 fwrite(&sample_period, sizeof(sample_period), 1, file_handle_);
133 fwrite(&sample_size, sizeof(sample_size), 1, file_handle_); 133 fwrite(&sample_size, sizeof(sample_size), 1, file_handle_);
134 fwrite(&parameter_kind, sizeof(parameter_kind), 1, file_handle_); 134 fwrite(&parameter_kind, sizeof(parameter_kind), 1, file_handle_);
135 fflush(file_handle_); 135 fflush(file_handle_);
136 136
137 header_written_ = true; 137 header_written_ = true;
138 } 138 }
139 139
140 140
141 void FileOutputHTK::Process(const SignalBank &input) { 141 void FileOutputHTK::Process(const SignalBank &input) {
142 if (file_handle_ == NULL) { 142 if (file_handle_ == NULL) {
143 LOG_ERROR(_T("Couldn't process file output. No file is open." 143 LOG_ERROR(_T("Couldn't process file output. No file is open."
144 "Please call FileOutputHTK::OpenFile first")); 144 "Please call FileOutputHTK::OpenFile first"));
145 return; 145 return;
146 } 146 }
147 147
148 if (!header_written_) { 148 if (!header_written_) {
149 LOG_ERROR(_T("No header has been written on the output file yet. Please" 149 LOG_ERROR(_T("No header has been written on the output file yet. Please"
150 "call FileOutputHTK::Initialize() before calling " 150 "call FileOutputHTK::Initialize() before calling "
151 "FileOutputHTK::Process()")); 151 "FileOutputHTK::Process()"));
152 return; 152 return;
153 } 153 }
154 float s; 154 float s;
155 155
156 for (int ch = 0; ch < input.channel_count(); ch++) { 156 for (int ch = 0; ch < input.channel_count(); ch++) {
157 for (int i = 0; i < input.buffer_length(); i++) { 157 for (int i = 0; i < input.buffer_length(); i++) {
158 s = input.sample(ch, i); 158 s = input.sample(ch, i);
159 s = ByteSwapFloat(s); 159 s = ByteSwapFloat(s);
160 fwrite(&s, sizeof(float), 1, file_handle_); 160 fwrite(&s, sizeof(float), 1, file_handle_);
161 } 161 }
162 } 162 }
163 sample_count_++; 163 sample_count_++;
164 } 164 }
165 165
166 bool FileOutputHTK::CloseFile() { 166 bool FileOutputHTK::CloseFile() {
167 if (file_handle_ == NULL) 167 if (file_handle_ == NULL)
168 return false; 168 return false;
169 169
170 // Write the first 4 bytes of the file 170 // Write the first 4 bytes of the file
171 // with how many samples there are in the file 171 // with how many samples there are in the file
172 fflush(file_handle_); 172 fflush(file_handle_);
173 rewind(file_handle_); 173 rewind(file_handle_);
174 fflush(file_handle_); 174 fflush(file_handle_);
175 int32_t samples = sample_count_; 175 int32_t samples = sample_count_;
176 samples = ByteSwap32(samples); 176 samples = ByteSwap32(samples);
177 fwrite(&samples, sizeof(samples), 1, file_handle_); 177 fwrite(&samples, sizeof(samples), 1, file_handle_);
178 178
179 // And close the file 179 // And close the file
180 fclose(file_handle_); 180 fclose(file_handle_);
181 file_handle_ = NULL; 181 file_handle_ = NULL;
182 return true; 182 return true;
183 } 183 }
184 184
185 float FileOutputHTK::ByteSwapFloat(float d) { 185 float FileOutputHTK::ByteSwapFloat(float d) {
186 // Endianness fix 186 // Endianness fix
187 float a; 187 float a;