annotate trunk/src/Modules/Output/FileOutputAIMC.cc @ 706:f8e90b5d85fd tip

Delete CARFAC code from this repository. It has been moved to https://github.com/google/carfac Please email me with your github username to get access. I've also created a new mailing list to discuss CARFAC development: https://groups.google.com/forum/#!forum/carfac-dev
author ronw@google.com
date Thu, 18 Jul 2013 20:56:51 +0000
parents b5dca605c3d5
children
rev   line source
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