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(&params);
   aimc::ModuleGammatone bmm(&params);
-  // aimc::ModulePZFC bmm(&params);
   aimc::ModuleHCL nap(&params);
-  // aimc::ModuleParabola strobes(&params);
-  // aimc::ModuleSAI sai(&params);
-  // aimc::ModuleSSI ssi(&params);
-  aimc::ModuleSlice profile(&params);
-  aimc::ModuleScaler scaler(&params);
-  aimc::ModuleGaussians features(&params);
-  aimc::FileOutputHTK output(&params);
+  aimc::ModuleLocalMax strobes(&params);
+  aimc::ModuleSAI sai(&params);
+  aimc::FileOutputAIMC output(&params);
 
   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."