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