annotate src/Modules/Output/FileOutputAIMC.cc @ 121:3cdaa81c3aca

- Massive refactoring to make module tree stuff work. In theory we now support configuration files again. The graphics stuff is untested as yet.
author tomwalters
date Mon, 18 Oct 2010 04:42:28 +0000
parents c5ac2f0c7fc5
children f03d4455b262
rev   line source
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>
tomwalters@46 39
tomwalters@46 40 #include "Modules/Output/FileOutputAIMC.h"
tomwalters@46 41
tomwalters@46 42 namespace aimc {
tomwalters@46 43 FileOutputAIMC::FileOutputAIMC(Parameters *params) : Module(params) {
tomwalters@46 44 module_description_ = "File output in AIMC format";
tomwalters@121 45 module_identifier_ = "aimc_out";
tomwalters@46 46 module_type_ = "output";
tomwalters@46 47 module_version_ = "$Id: FileOutputAIMC.cc 51 2010-03-30 22:06:24Z tomwalters $";
tomwalters@46 48
tomwalters@46 49 file_handle_ = NULL;
tomwalters@46 50 header_written_ = false;
tomwalters@46 51 frame_period_ms_ = 0.0f;
tomwalters@46 52 }
tomwalters@46 53
tomwalters@46 54 FileOutputAIMC::~FileOutputAIMC() {
tomwalters@46 55 if (file_handle_ != NULL)
tomwalters@46 56 CloseFile();
tomwalters@46 57 }
tomwalters@46 58
tomwalters@46 59 bool FileOutputAIMC::OpenFile(const char* filename, float frame_period_ms) {
tomwalters@46 60 if (file_handle_ != NULL) {
tomwalters@46 61 LOG_ERROR(_T("Couldn't open output file. A file is already open."));
tomwalters@46 62 return false;
tomwalters@46 63 }
tomwalters@46 64
tomwalters@46 65 // Check that the output file exists and is writeable
tomwalters@46 66 if ((file_handle_ = fopen(filename, "wb")) == NULL) {
tomwalters@46 67 LOG_ERROR(_T("Couldn't open output file '%s' for writing."), filename);
tomwalters@46 68 return false;
tomwalters@46 69 }
tomwalters@48 70 frame_count_ = 0;
tomwalters@46 71 frame_period_ms_ = frame_period_ms;
tomwalters@46 72 header_written_ = false;
tomwalters@46 73 if (initialized_) {
tomwalters@46 74 WriteHeader();
tomwalters@46 75 }
tomwalters@46 76 return true;
tomwalters@46 77 }
tomwalters@46 78
tomwalters@46 79 bool FileOutputAIMC::InitializeInternal(const SignalBank &input) {
tomwalters@46 80 if (file_handle_ == NULL) {
tomwalters@46 81 LOG_ERROR(_T("Couldn't initialize file output. "
tomwalters@46 82 "Please call FileOutputAIMC::OpenFile first"));
tomwalters@46 83 return false;
tomwalters@46 84 }
tomwalters@46 85 if (header_written_) {
tomwalters@46 86 LOG_ERROR(_T("A header has already been written on the output file. "
tomwalters@46 87 "Please call FileOutputAIMC::CloseFile to close that file, "
tomwalters@46 88 "and FileOutputAIMC::OpenFile to open an new one before "
tomwalters@46 89 "calling FileOutputAIMC::Initialize again."));
tomwalters@46 90 return false;
tomwalters@46 91 }
tomwalters@46 92 channel_count_ = input.channel_count();
tomwalters@117 93 buffer_length_ = input.buffer_length();
tomwalters@117 94 sample_rate_ = input.sample_rate();
tomwalters@46 95 WriteHeader();
tomwalters@46 96 return true;
tomwalters@46 97 }
tomwalters@46 98
tomwalters@46 99 void FileOutputAIMC::ResetInternal() {
tomwalters@46 100 if (file_handle_ != NULL && !header_written_) {
tomwalters@46 101 WriteHeader();
tomwalters@46 102 }
tomwalters@46 103 if (file_handle_ != NULL)
tomwalters@46 104 CloseFile();
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@48 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@48 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@48 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@48 171 uint32_t frame_count = frame_count_;
tomwalters@48 172 fwrite(&frame_count, sizeof(frame_count), 1, file_handle_);
tomwalters@46 173
tomwalters@46 174 // And close the file
tomwalters@46 175 fclose(file_handle_);
tomwalters@46 176 file_handle_ = NULL;
tomwalters@46 177 header_written_ = false;
tomwalters@46 178 return true;
tomwalters@46 179 }
tomwalters@46 180 } // namespace aimc
tomwalters@46 181