Mercurial > hg > aimc
changeset 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 | 566a8543a6f1 |
children | e7bcaf1e87d5 |
files | trunk/SConstruct trunk/matlab/AIMCread.m trunk/src/Main/aimc.cc trunk/src/Modules/Output/FileOutputAIMC.cc trunk/src/Modules/Output/FileOutputAIMC.h trunk/src/Modules/Output/FileOutputHTK.cc |
diffstat | 6 files changed, 320 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/SConstruct Wed May 19 15:28:10 2010 +0000 +++ b/trunk/SConstruct Thu May 27 07:25:03 2010 +0000 @@ -47,10 +47,12 @@ 'Modules/Profile/ModuleSlice.cc', 'Modules/Profile/ModuleScaler.cc', 'Modules/Features/ModuleGaussians.cc', - 'Modules/Output/FileOutputHTK.cc'] + 'Modules/Output/FileOutputHTK.cc', + 'Modules/Output/FileOutputAIMC.cc'] # File which contains main() -sources = common_sources + ['Main/AIMCopy_SSI_Features_v4_PZFC.cc'] +#sources = common_sources + ['Main/AIMCopy_SSI_Features_v4_PZFC.cc'] +sources = common_sources + ['Main/aimc.cc'] # Test sources test_sources = ['Modules/Profile/ModuleSlice_unittest.cc'] @@ -77,7 +79,7 @@ # Build products location and executable name build_dir = os.path.join('build', target_platform + '-release') -target_executable = 'AIMCopy' +target_executable = 'aimc' test_executable = 'aimc_tests' # Create build products directory if necessary
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/matlab/AIMCread.m Thu May 27 07:25:03 2010 +0000 @@ -0,0 +1,47 @@ +function [data, nFrames, period, nChannels, nSamples, sample_rate] = AIMCread(filename) +%[data, nFrames, period, nChannels, nSamples ] = AIMCread( filename) +% +% data ... matrix (or array) of size [nFrames,nChannels,nSamples] +% in case vertical/horizontal profiles are read, you should use squeeze +% nFrames ... number of frames +% period ... Frame interval in ms +% nChannels ... points on vertical axis of an auditori image +% nSamples ... points on horizontal axis of an auditori image + +fid = fopen(filename); + +debug = 0; + +nFrames = fread( fid, 1, 'int32'); +period = fread( fid, 1, 'float32'); % Frame period in ms +nChannels = fread( fid, 1, 'int32'); % vertical axis of an AI +nSamples = fread( fid, 1, 'int32'); % horizontal axis of an AI +sample_rate = fread(fid, 1, 'float32'); % sample rate of each channel in Hz + +if nChannels == 1 % temporal profiles + data = fread( fid, [nSamples,nFrames], 'float32'); % transposed! + data = data.'; + data = reshape( data, [nFrames,1,nSamples]); % to have the same dimensions + % if a 'squeeze' is used, this line has no effect at all + if debug + disp('seems to be temporal profiles') + end +elseif nSamples == 1 % spectral profiles + data = fread( fid, [nChannels,nFrames], 'float32'); % transposed! + data = data.'; + %data = reshape( data, [nFrames,nChannels,1]); % has no effect + if debug + disp('seems to be spectral profiles') + end +else % auditory 2d images + data = zeros(nFrames,nChannels,nSamples); + for k=1:nFrames % loop since fread cannot return 3d array + Image = fread(fid, [nSamples,nChannels], 'float32'); % transposed! + data(k,:,:) = Image.'; + end + if debug + disp('seems to be 2d images') + end +end + +fclose(fid);
--- a/trunk/src/Main/aimc.cc Wed May 19 15:28:10 2010 +0000 +++ b/trunk/src/Main/aimc.cc Thu May 27 07:25:03 2010 +0000 @@ -23,59 +23,38 @@ #include "Modules/BMM/ModuleGammatone.h" #include "Modules/BMM/ModulePZFC.h" #include "Modules/NAP/ModuleHCL.h" -#include "Modules/Strobes/ModuleParabola.h" +#include "Modules/Strobes/ModuleLocalMax.h" #include "Modules/SAI/ModuleSAI.h" #include "Modules/SSI/ModuleSSI.h" #include "Modules/Profile/ModuleSlice.h" #include "Modules/Profile/ModuleScaler.h" #include "Modules/Features/ModuleGaussians.h" #include "Modules/Output/FileOutputHTK.h" +#include "Modules/Output/FileOutputAIMC.h" int main(int argc, char* argv[]) { aimc::Parameters params; int buffer_length = 480; params.SetInt("input.buffersize", buffer_length); - params.SetBool("slice.normalize", true); - params.SetFloat("nap.lowpass_cutoff", 100.0f); aimc::ModuleFileInput input(¶ms); aimc::ModuleGammatone bmm(¶ms); - // aimc::ModulePZFC bmm(¶ms); aimc::ModuleHCL nap(¶ms); - // aimc::ModuleParabola strobes(¶ms); - // aimc::ModuleSAI sai(¶ms); - // aimc::ModuleSSI ssi(¶ms); - aimc::ModuleSlice profile(¶ms); - aimc::ModuleScaler scaler(¶ms); - aimc::ModuleGaussians features(¶ms); - aimc::FileOutputHTK output(¶ms); + aimc::ModuleLocalMax strobes(¶ms); + aimc::ModuleSAI sai(¶ms); + aimc::FileOutputAIMC output(¶ms); std::string parameters_string = params.WriteString(); printf("%s", parameters_string.c_str()); input.AddTarget(&bmm); bmm.AddTarget(&nap); - nap.AddTarget(&profile); - //strobes.AddTarget(&sai); - //sai.AddTarget(&ssi); - //ssi.AddTarget(&profile); - profile.AddTarget(&scaler); - scaler.AddTarget(&features); - features.AddTarget(&output); + nap.AddTarget(&strobes); + strobes.AddTarget(&sai); + sai.AddTarget(&output); - float frame_period_ms = 1000.0f * buffer_length - / input.GetOutputBank()->sample_rate(); - - output.OpenFile("test_output.htk", frame_period_ms); - if (input.LoadFile("test.wav")) { - input.Process(); - } else { - printf("LoadFile failed"); - } - - input.Reset(); - output.OpenFile("test_output_2.htk", frame_period_ms); + output.OpenFile("test_output.aimc", params.GetFloat("sai.frame_period_ms")); if (input.LoadFile("test.wav")) { input.Process(); } else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/Modules/Output/FileOutputAIMC.cc Thu May 27 07:25:03 2010 +0000 @@ -0,0 +1,181 @@ +// Copyright 2006-2010, Thomas Walters +// +// AIM-C: A C++ implementation of the Auditory Image Model +// http://www.acousticscale.org/AIMC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * \file + * \brief File output in the HTK format. + * + * \author Tom Walters <tom@acousticscale.org> + * \author Willem van Engen <cnbh@willem.engen.nl> + * \date created 2007/01/26 + * \version \$Id: $ + */ + +#ifdef _WINDOWS +# include <direct.h> // for _mkdir & _rmdir +#else +# include <sys/types.h> +# include <dirent.h> // for opendir & friends +#endif + +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <cmath> + +#include "Modules/Output/FileOutputAIMC.h" + +namespace aimc { +FileOutputAIMC::FileOutputAIMC(Parameters *params) : Module(params) { + module_description_ = "File output in AIMC format"; + module_identifier_ = "htk_out"; + module_type_ = "output"; + module_version_ = "$Id: FileOutputAIMC.cc 51 2010-03-30 22:06:24Z tomwalters $"; + + file_handle_ = NULL; + header_written_ = false; + frame_period_ms_ = 0.0f; +} + +FileOutputAIMC::~FileOutputAIMC() { + if (file_handle_ != NULL) + CloseFile(); +} + +bool FileOutputAIMC::OpenFile(const char* filename, float frame_period_ms) { + if (file_handle_ != NULL) { + LOG_ERROR(_T("Couldn't open output file. A file is already open.")); + return false; + } + + // Check that the output file exists and is writeable + if ((file_handle_ = fopen(filename, "wb")) == NULL) { + LOG_ERROR(_T("Couldn't open output file '%s' for writing."), filename); + return false; + } + sample_count_ = 0; + frame_period_ms_ = frame_period_ms; + header_written_ = false; + if (initialized_) { + WriteHeader(); + } + return true; +} + +bool FileOutputAIMC::InitializeInternal(const SignalBank &input) { + if (file_handle_ == NULL) { + LOG_ERROR(_T("Couldn't initialize file output. " + "Please call FileOutputAIMC::OpenFile first")); + return false; + } + if (header_written_) { + LOG_ERROR(_T("A header has already been written on the output file. " + "Please call FileOutputAIMC::CloseFile to close that file, " + "and FileOutputAIMC::OpenFile to open an new one before " + "calling FileOutputAIMC::Initialize again.")); + return false; + } + channel_count_ = input.channel_count(); + buffer_length_ = input.buffer_length(); + sample_rate_ = input.sample_rate(); + WriteHeader(); + return true; +} + +void FileOutputAIMC::ResetInternal() { + if (file_handle_ != NULL && !header_written_) { + WriteHeader(); + } + if (file_handle_ != NULL) + CloseFile(); +} + +void FileOutputAIMC::WriteHeader() { + if (header_written_) + return; + + /* File format: + * Header: Number of frames (uint32), + * Frame period in milliseconds (float32), + * Number of channels per frame (uint32), + * Number of samples per channel of each frame (uint32) + * Sample rate (float32) + * + * Data: Series of floats, by time, then channel, then frame + * f1c1t1,f1c1t2,f1c1t3... + */ + + uint32_t sample_count_out = sample_count_; + float sample_period_out = frame_period_ms_; + uint32_t channels_out = channel_count_; + uint32_t samples_out = buffer_length_; + float sample_rate = sample_rate_; + + fwrite(&sample_count_out, sizeof(sample_count_out), 1, file_handle_); + fwrite(&sample_period_out, sizeof(sample_period_out), 1, file_handle_); + fwrite(&channels_out, sizeof(channels_out), 1, file_handle_); + fwrite(&samples_out, sizeof(samples_out), 1, file_handle_); + fwrite(&sample_rate, sizeof(sample_rate), 1, file_handle_); + fflush(file_handle_); + + header_written_ = true; +} + +void FileOutputAIMC::Process(const SignalBank &input) { + if (file_handle_ == NULL) { + LOG_ERROR(_T("Couldn't process file output. No file is open." + "Please call FileOutputAIMC::OpenFile first")); + return; + } + + if (!header_written_) { + LOG_ERROR(_T("No header has been written on the output file yet. Please " + "call FileOutputAIMC::Initialize() before calling " + "FileOutputAIMC::Process()")); + return; + } + float s; + + for (int ch = 0; ch < input.channel_count(); ch++) { + for (int i = 0; i < input.buffer_length(); i++) { + s = input.sample(ch, i); + fwrite(&s, sizeof(s), 1, file_handle_); + } + } + sample_count_++; +} + +bool FileOutputAIMC::CloseFile() { + if (file_handle_ == NULL) + return false; + + // Write the first 4 bytes of the file + // with how many samples there are in the file + fflush(file_handle_); + rewind(file_handle_); + fflush(file_handle_); + uint32_t samples = sample_count_; + fwrite(&samples, sizeof(samples), 1, file_handle_); + + // And close the file + fclose(file_handle_); + file_handle_ = NULL; + header_written_ = false; + return true; +} +} // namespace aimc +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/Modules/Output/FileOutputAIMC.h Thu May 27 07:25:03 2010 +0000 @@ -0,0 +1,76 @@ +// Copyright 2006-2010, Thomas Walters, Willem van Engen +// +// AIM-C: A C++ implementation of the Auditory Image Model +// http://www.acousticscale.org/AIMC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * \file + * \brief File output to AIMC format + * + * \author Thomas Walters <tom@acousticscale.org> + * \author Willem van Engen <cnbh@willem.engen.nl> + * \date created 2006/10/30 + * \version \$Header$ + */ + +#ifndef AIMC_MODULES_OUTPUT_AIMC_H_ +#define AIMC_MODULES_OUTPUT_AIMC_H_ + +#include "Support/Module.h" +#include "Support/SignalBank.h" + +namespace aimc { +class FileOutputAIMC : public Module { + public: + /*! \brief Create a new file output for an AIMC format file. + */ + explicit FileOutputAIMC(Parameters *pParam); + ~FileOutputAIMC(); + + /*! \brief Initialize the output to AIMC. + * \param *filename Filename of the ouptut file to be created. + * If the file exists it will be overwritten + * \return Returns true on success of initialization. + */ + bool OpenFile(const char *filename, float frame_period_ms); + bool CloseFile(); + virtual void Process(const SignalBank &input); + private: + virtual bool InitializeInternal(const SignalBank &input); + virtual void ResetInternal(); + + void WriteHeader(); + + /*! \brief Whether initialization is done or not + */ + bool header_written_; + + /*! \brief Internal pointer to the output file + */ + FILE *file_handle_; + + /*! \brief Count of the number of samples in the file, written on close + */ + int sample_count_; + + int channel_count_; + int buffer_length_; + float sample_rate_; + float frame_period_ms_; +}; +} // namespace aimc + +#endif // AIMC_MODULES_OUTPUT_AIMC_H_ +
--- a/trunk/src/Modules/Output/FileOutputHTK.cc Wed May 19 15:28:10 2010 +0000 +++ b/trunk/src/Modules/Output/FileOutputHTK.cc Thu May 27 07:25:03 2010 +0000 @@ -26,10 +26,10 @@ */ #ifdef _WINDOWS -# include <direct.h> // for _mkdir&_rmdir +# include <direct.h> // for _mkdir & _rmdir #else # include <sys/types.h> -# include <dirent.h> // for opendir&friends +# include <dirent.h> // for opendir & friends #endif #include <stdint.h> @@ -141,7 +141,6 @@ header_written_ = true; } - void FileOutputHTK::Process(const SignalBank &input) { if (file_handle_ == NULL) { LOG_ERROR(_T("Couldn't process file output. No file is open."