Mercurial > hg > aimc
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(¶meter_kind, sizeof(parameter_kind), 1, file_handle_); | 134 fwrite(¶meter_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; |