Mercurial > hg > aimc
comparison trunk/src/Modules/Output/FileOutputAIMC.cc @ 320:c74acd46121b
- Added support for a very basic AIM-C file format
author | tomwalters@google.com |
---|---|
date | Thu, 27 May 2010 07:25:03 +0000 |
parents | |
children | 1c0723041971 |
comparison
equal
deleted
inserted
replaced
319:566a8543a6f1 | 320:c74acd46121b |
---|---|
1 // Copyright 2006-2010, Thomas Walters | |
2 // | |
3 // AIM-C: A C++ implementation of the Auditory Image Model | |
4 // http://www.acousticscale.org/AIMC | |
5 // | |
6 // Licensed under the Apache License, Version 2.0 (the "License"); | |
7 // you may not use this file except in compliance with the License. | |
8 // You may obtain a copy of the License at | |
9 // | |
10 // http://www.apache.org/licenses/LICENSE-2.0 | |
11 // | |
12 // Unless required by applicable law or agreed to in writing, software | |
13 // distributed under the License is distributed on an "AS IS" BASIS, | |
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 // See the License for the specific language governing permissions and | |
16 // limitations under the License. | |
17 | |
18 /*! | |
19 * \file | |
20 * \brief File output in the HTK format. | |
21 * | |
22 * \author Tom Walters <tom@acousticscale.org> | |
23 * \author Willem van Engen <cnbh@willem.engen.nl> | |
24 * \date created 2007/01/26 | |
25 * \version \$Id: $ | |
26 */ | |
27 | |
28 #ifdef _WINDOWS | |
29 # include <direct.h> // for _mkdir & _rmdir | |
30 #else | |
31 # include <sys/types.h> | |
32 # include <dirent.h> // for opendir & friends | |
33 #endif | |
34 | |
35 #include <stdint.h> | |
36 #include <stdio.h> | |
37 #include <string.h> | |
38 #include <cmath> | |
39 | |
40 #include "Modules/Output/FileOutputAIMC.h" | |
41 | |
42 namespace aimc { | |
43 FileOutputAIMC::FileOutputAIMC(Parameters *params) : Module(params) { | |
44 module_description_ = "File output in AIMC format"; | |
45 module_identifier_ = "htk_out"; | |
46 module_type_ = "output"; | |
47 module_version_ = "$Id: FileOutputAIMC.cc 51 2010-03-30 22:06:24Z tomwalters $"; | |
48 | |
49 file_handle_ = NULL; | |
50 header_written_ = false; | |
51 frame_period_ms_ = 0.0f; | |
52 } | |
53 | |
54 FileOutputAIMC::~FileOutputAIMC() { | |
55 if (file_handle_ != NULL) | |
56 CloseFile(); | |
57 } | |
58 | |
59 bool FileOutputAIMC::OpenFile(const char* filename, float frame_period_ms) { | |
60 if (file_handle_ != NULL) { | |
61 LOG_ERROR(_T("Couldn't open output file. A file is already open.")); | |
62 return false; | |
63 } | |
64 | |
65 // Check that the output file exists and is writeable | |
66 if ((file_handle_ = fopen(filename, "wb")) == NULL) { | |
67 LOG_ERROR(_T("Couldn't open output file '%s' for writing."), filename); | |
68 return false; | |
69 } | |
70 sample_count_ = 0; | |
71 frame_period_ms_ = frame_period_ms; | |
72 header_written_ = false; | |
73 if (initialized_) { | |
74 WriteHeader(); | |
75 } | |
76 return true; | |
77 } | |
78 | |
79 bool FileOutputAIMC::InitializeInternal(const SignalBank &input) { | |
80 if (file_handle_ == NULL) { | |
81 LOG_ERROR(_T("Couldn't initialize file output. " | |
82 "Please call FileOutputAIMC::OpenFile first")); | |
83 return false; | |
84 } | |
85 if (header_written_) { | |
86 LOG_ERROR(_T("A header has already been written on the output file. " | |
87 "Please call FileOutputAIMC::CloseFile to close that file, " | |
88 "and FileOutputAIMC::OpenFile to open an new one before " | |
89 "calling FileOutputAIMC::Initialize again.")); | |
90 return false; | |
91 } | |
92 channel_count_ = input.channel_count(); | |
93 buffer_length_ = input.buffer_length(); | |
94 sample_rate_ = input.sample_rate(); | |
95 WriteHeader(); | |
96 return true; | |
97 } | |
98 | |
99 void FileOutputAIMC::ResetInternal() { | |
100 if (file_handle_ != NULL && !header_written_) { | |
101 WriteHeader(); | |
102 } | |
103 if (file_handle_ != NULL) | |
104 CloseFile(); | |
105 } | |
106 | |
107 void FileOutputAIMC::WriteHeader() { | |
108 if (header_written_) | |
109 return; | |
110 | |
111 /* File format: | |
112 * Header: Number of frames (uint32), | |
113 * Frame period in milliseconds (float32), | |
114 * Number of channels per frame (uint32), | |
115 * Number of samples per channel of each frame (uint32) | |
116 * Sample rate (float32) | |
117 * | |
118 * Data: Series of floats, by time, then channel, then frame | |
119 * f1c1t1,f1c1t2,f1c1t3... | |
120 */ | |
121 | |
122 uint32_t sample_count_out = sample_count_; | |
123 float sample_period_out = frame_period_ms_; | |
124 uint32_t channels_out = channel_count_; | |
125 uint32_t samples_out = buffer_length_; | |
126 float sample_rate = sample_rate_; | |
127 | |
128 fwrite(&sample_count_out, sizeof(sample_count_out), 1, file_handle_); | |
129 fwrite(&sample_period_out, sizeof(sample_period_out), 1, file_handle_); | |
130 fwrite(&channels_out, sizeof(channels_out), 1, file_handle_); | |
131 fwrite(&samples_out, sizeof(samples_out), 1, file_handle_); | |
132 fwrite(&sample_rate, sizeof(sample_rate), 1, file_handle_); | |
133 fflush(file_handle_); | |
134 | |
135 header_written_ = true; | |
136 } | |
137 | |
138 void FileOutputAIMC::Process(const SignalBank &input) { | |
139 if (file_handle_ == NULL) { | |
140 LOG_ERROR(_T("Couldn't process file output. No file is open." | |
141 "Please call FileOutputAIMC::OpenFile first")); | |
142 return; | |
143 } | |
144 | |
145 if (!header_written_) { | |
146 LOG_ERROR(_T("No header has been written on the output file yet. Please " | |
147 "call FileOutputAIMC::Initialize() before calling " | |
148 "FileOutputAIMC::Process()")); | |
149 return; | |
150 } | |
151 float s; | |
152 | |
153 for (int ch = 0; ch < input.channel_count(); ch++) { | |
154 for (int i = 0; i < input.buffer_length(); i++) { | |
155 s = input.sample(ch, i); | |
156 fwrite(&s, sizeof(s), 1, file_handle_); | |
157 } | |
158 } | |
159 sample_count_++; | |
160 } | |
161 | |
162 bool FileOutputAIMC::CloseFile() { | |
163 if (file_handle_ == NULL) | |
164 return false; | |
165 | |
166 // Write the first 4 bytes of the file | |
167 // with how many samples there are in the file | |
168 fflush(file_handle_); | |
169 rewind(file_handle_); | |
170 fflush(file_handle_); | |
171 uint32_t samples = sample_count_; | |
172 fwrite(&samples, sizeof(samples), 1, file_handle_); | |
173 | |
174 // And close the file | |
175 fclose(file_handle_); | |
176 file_handle_ = NULL; | |
177 header_written_ = false; | |
178 return true; | |
179 } | |
180 } // namespace aimc | |
181 |