changeset 252:de2b483654ee

Windows build fixes.
author tomwalters
date Tue, 02 Nov 2010 23:46:56 +0000
parents 612ef7b70936
children 988c8b6f7946
files SConstruct src/Modules/Features/ModuleGaussians.cc src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc src/Support/Common.h src/Support/Module.h src/Support/ModuleFactory.cc
diffstat 6 files changed, 286 insertions(+), 274 deletions(-) [+]
line wrap: on
line diff
--- a/SConstruct	Mon Nov 01 01:36:44 2010 +0000
+++ b/SConstruct	Tue Nov 02 23:46:56 2010 +0000
@@ -28,8 +28,9 @@
 import os
 import shutil
 
-# Location of libsndfile on Windows
+# Location of libraries / headers on Windows
 windows_libsndfile_location = "C:\\Program Files\\Mega-Nerd\\libsndfile\\"
+windows_cairo_location = "C:\\Program Files\\cairo\\"
 
 # Sources common to every version
 common_sources = ['Support/Common.cc',
@@ -197,6 +198,11 @@
       # Replace 'sndfile' with 'sndfile-1'
       deplibs.remove('sndfile')
       deplibs.append('libsndfile-1')
+  if 'cairo' in deplibs:
+    shutil.copyfile(windows_cairo_location + '/bin/libcairo-2.dll',
+                    build_dir+'/libcairo-2.dll')
+    env.Append(CPPPATH = [windows_cairo_location + '/include/cairo/'])
+    env.AppendUnique(LIBPATH = [windows_cairo_location + '/lib/'])
 env.AppendUnique(LIBS = deplibs)
 
 
--- a/src/Modules/Features/ModuleGaussians.cc	Mon Nov 01 01:36:44 2010 +0000
+++ b/src/Modules/Features/ModuleGaussians.cc	Tue Nov 02 23:46:56 2010 +0000
@@ -27,6 +27,10 @@
 
 #include <math.h>
 
+#ifdef _MSC_VER
+#include <float.h>
+#endif
+
 #include "Modules/Features/ModuleGaussians.h"
 #include "Support/Common.h"
 
@@ -120,7 +124,7 @@
   }
 
   for (int ch = 0; ch < input.channel_count(); ++ch) {
-    m_pSpectralProfile[ch] = pow(m_pSpectralProfile[ch], 0.8);
+    m_pSpectralProfile[ch] = pow(m_pSpectralProfile[ch], 0.8f);
   }
 
   RubberGMMCore(2, true);
--- a/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc	Mon Nov 01 01:36:44 2010 +0000
+++ b/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc	Tue Nov 02 23:46:56 2010 +0000
@@ -1,264 +1,264 @@
-// Copyright 2006, 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 Output device for output to a movie
- *
- * \author Willem van Engen <cnbh@willem.engen.nl>
- * \date created 2006/10/16
- * \version \$Id: GraphicsOutputDeviceMovie.cpp 633 2008-09-11 04:20:16Z tom $
- */
-
-/*! \todo
- *  A recent experiment showed that the video was about an audioframe
- *  (something like 30 ms) behind the audio in rdct.wav. It seems odd
- *  to me, since I already output a frame at the beginning to compensate
- *  for the missed buffer.
- *  A solution that would solve this and be a broader improvement, is to
- *  include the source's time when Fire()ing. The outputdevice can then
- *  do audio/video synchronization. In the case of the movie, the very
- *  first gGrab() looks at the time and emits as much empty output frames
- *  as needed until the correct signal time is reached.
- */
-#include "Support/Common.h"
-
-#ifdef _WINDOWS
-#  include <direct.h> // for _mkdir&_rmdir
-#else
-#  include <sys/types.h>
-#  include <dirent.h> // for opendir&friends
-#endif
-#include <stdio.h>
-#include <string.h>
-
-#include "Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.h"
-
-namespace aimc {
-
-GraphicsOutputDeviceMovie::GraphicsOutputDeviceMovie(Parameters *parameters)
-  : GraphicsOutputDeviceCairo(parameters) {
-  sound_filename_.clear();
-  movie_filename_.clear();
-}
-
-bool GraphicsOutputDeviceMovie::Initialize(Parameters *global_parameters) {
-  global_parameters_ = global_parameters;
-  sound_filename_ = global_parameters->GetString("input_filename");
-  string file_suffix = parameters_->DefaultString("filename_suffix", ".mov");
-  movie_filename_ = global_parameters->GetString("output_filename_base")
-                    + file_suffix;
-  
-  FILE *f;
-
-  // Check sound file exists
-  if ((f = fopen(sound_filename_.c_str(), "r")) == NULL) {
-    LOG_ERROR(_T("Couldn't open sound file '%s' for movie creation."),
-             sound_filename_.c_str());
-    sound_filename_.clear();
-    return false;
-  }
-  fclose(f);
-
-  // Check movie output file can be made
-  if ((f = fopen(movie_filename_.c_str(), "w")) == NULL) {
-    LOG_ERROR(_T("Couldn't open movie file '%s' to write to."),
-             movie_filename_.c_str());
-    movie_filename_.clear();
-    return false;
-  }
-  fclose(f);
-
-  // Get a temporary image output directory
-  //! \warning Not really safe ... but windows has no mkdtemp()
-  //! \todo Make build system check for mkdtemp() to use it when available. See TODO.txt.
-#ifdef _WINDOWS
-  char *temp_dir = NULL;
-  if ((temp_dir = _tempnam(NULL, AIM_NAME))
-      && _mkdir(temp_dir) >= 0) {
-    directory_ = temp_dir;
-    directory_ += "\\"; // Make sure to end with trailing slash
-  } else  {
-    LOG_ERROR(_T("Couldn't create a temporary directory for movie output."));
-    if (temp_dir) {
-      free(temp_dir);
-    }
-    return false;
-  }
-  if (temp_dir) {
-    free(temp_dir);
-  }
-#else
-  char temp_dir[PATH_MAX];
-  strcpy(temp_dir, "/tmp/"AIM_NAME"-movie.XXXXXX");
-  if (mkdtemp(temp_dir)) {
-    directory_ = temp_dir;
-    directory_ += "/"; // Make sure to end with trailing slash    
-  } else {
-    LOG_ERROR(_T("Couldn't create a temporary directory for movie output."));
-    return false;
-  }
-#endif
-  
-  // We want png for movie conversion
-  parameters_->SetString("output.img.format", "png");
-  if ( !GraphicsOutputDeviceCairo::Initialize(directory_) ) {
-    return false;
-  }
-  return true;
-}
-
-void GraphicsOutputDeviceMovie::Start() {
-  GraphicsOutputDeviceCairo::Start();
-  // Output a couple of frames to get audio/video in sync, put params in there.
-  gGrab();
-  PlotParameterScreen();
-  gRelease();
-  gGrab();
-  PlotParameterScreen();
-  gRelease();
-}
-
-void GraphicsOutputDeviceMovie::Reset(Parameters* global_parameters) {
-  Stop();
-  Initialize(global_parameters);
-}
-
-void GraphicsOutputDeviceMovie::Stop() {
-  GraphicsOutputDeviceCairo::Stop();
-  CloseFile();
-
-#ifdef __WX__
-  // GUI only: popup dialog
-#else
-  printf("Generating movie ... \n");
-#endif
-  AIM_ASSERT(parameters_);
-  // Convert images and sound file to a movie.
-  //! \warning Movie files are overwritten without warning.
-  char sffmpegPath[1024];
-  if (!parameters_->IsSet("output.ffmpeg_path")) {
-  strcpy(sffmpegPath,"ffmpeg");
-  } else {
-    strcpy(sffmpegPath, parameters_->GetString("output.ffmpeg_path"));
-  }
-  char sCodecOptions[1024];
-  if (!parameters_->IsSet("output.ffmpeg_codec_options")) {
-    strcpy(sCodecOptions,"");
-  } else {
-    strcpy(sCodecOptions, parameters_->GetString("output.ffmpeg_codec_options"));
-  }
-  float frame_rate = global_parameters_->DefaultFloat("frame_rate", -1.0);
-  char sCmdLine[1024]; //!\todo check that snprintf does not want a larger buffer
-  snprintf(sCmdLine, sizeof(sCmdLine)/sizeof(sCmdLine[0]),
-    "%s -r %.2f -y -i \"%s\" -i \"%s%%06d.png\" "
-    "-sameq -r %.2f -ar 44100 -acodec pcm_s16le %s \"%s\"",
-    sffmpegPath, frame_rate, sound_filename_.c_str(), directory_.c_str(),
-    frame_rate, sCodecOptions, movie_filename_.c_str());
-    printf(sCmdLine);
-    printf("\n");
-  if (system(sCmdLine)) {
-    LOG_ERROR(_T("Couldn't create movie output."));
-  }
-
-#ifdef __WX__
-  // GUI only: close dialog again
-#endif
-  // Remove files in temporary directory and the dir itself
-  //! \todo make portable function, possibly decided on by build system
-#ifdef _WINDOWS
-  HANDLE hList;
-  WIN32_FIND_DATA FileData;
-  snprintf(sCmdLine, sizeof(sCmdLine)/sizeof(sCmdLine[0]), "%s/*.*", m_sDir);
-  if ((hList = FindFirstFile(sCmdLine, &FileData)) == INVALID_HANDLE_VALUE) {
-    LOG_ERROR(_T("Couldn't remove files from temporary directory."));
-    return;
-  }
-  bool bRMfinished = false;
-  while (!bRMfinished) {
-    snprintf(sCmdLine,
-             sizeof(sCmdLine)/sizeof(sCmdLine[0]),
-             "%s%s",
-             m_sDir,
-             FileData.cFileName);
-    remove(sCmdLine);
-    if (!FindNextFile(hList, &FileData) && GetLastError() == ERROR_NO_MORE_FILES) {
-      bRMfinished = true;
-    }
-  }
-  FindClose(hList);
-  _rmdir(m_sDir);
-#else
-  DIR *dir;
-  struct dirent *dirent;
-  if (!(dir = opendir(directory_.c_str()))) {
-    LOG_ERROR(_T("Couldn't remove files in temporary directory."));
-    return;
-  }
-  while ((dirent = readdir(dir))) {
-    snprintf(sCmdLine,
-             sizeof(sCmdLine)/sizeof(sCmdLine[0]),
-             "%s%s",
-             directory_.c_str(),
-             dirent->d_name);
-    unlink(sCmdLine);
-  }
-  closedir(dir);
-  rmdir(directory_.c_str());
-#endif
-}
-
-void GraphicsOutputDeviceMovie::PlotParameterScreen() {
-  AIM_ASSERT(parameters_);
-  char sStr[50];
-  int lineno = 1;
-
-  float fMarL = parameters_->GetFloat(_S("graph.margin.left"));
-  float fMarT = parameters_->GetFloat(_S("graph.margin.top"));
-  float fTextHeight = 1.0f / 50.0f * 1.2; // change this when fontsizing is there!
-
-  gText2f(fMarL, 1-(fMarT+fTextHeight*lineno++),
-          _S("AIM-C"));
-  gText2f(fMarL,
-          1-(fMarT+fTextHeight*lineno++),
-          _S("(c) 2006-2010, Thomas Walters, Willem van Engen"));
-  gText2f(fMarL,
-          1-(fMarT+fTextHeight*lineno++),
-          _S("http://aimc.acousticscale.org/"));
-  lineno++;
-
-  static const char *pPlotParams[] = {
-    _S("input.buffersize"),
-    _S("input.samplerate"),
-    _S("bmm.freqstart"),
-    _S("bmm.freqend"),
-    _S("bmm.numchannels"),
-    _S("preset.name"),
-    _S("preset.title"),
-    NULL
-  };
-  for (int i = 0; pPlotParams[i]; i++) {
-    snprintf(sStr,
-             sizeof(sStr)/sizeof(sStr[0]), _S("%s=%s"),
-             pPlotParams[i],
-             parameters_->GetString(pPlotParams[i]));
-    gText2f(fMarL,
-            1-(fMarT+fTextHeight*lineno++),
-            sStr);
-  }
-}
-}  // namespace aimc
+// Copyright 2006, 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 Output device for output to a movie
+ *
+ * \author Willem van Engen <cnbh@willem.engen.nl>
+ * \date created 2006/10/16
+ * \version \$Id: GraphicsOutputDeviceMovie.cpp 633 2008-09-11 04:20:16Z tom $
+ */
+
+/*! \todo
+ *  A recent experiment showed that the video was about an audioframe
+ *  (something like 30 ms) behind the audio in rdct.wav. It seems odd
+ *  to me, since I already output a frame at the beginning to compensate
+ *  for the missed buffer.
+ *  A solution that would solve this and be a broader improvement, is to
+ *  include the source's time when Fire()ing. The outputdevice can then
+ *  do audio/video synchronization. In the case of the movie, the very
+ *  first gGrab() looks at the time and emits as much empty output frames
+ *  as needed until the correct signal time is reached.
+ */
+#include "Support/Common.h"
+
+#ifdef _WINDOWS
+#  include <direct.h> // for _mkdir&_rmdir
+#else
+#  include <sys/types.h>
+#  include <dirent.h> // for opendir&friends
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include "Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.h"
+
+namespace aimc {
+
+GraphicsOutputDeviceMovie::GraphicsOutputDeviceMovie(Parameters *parameters)
+  : GraphicsOutputDeviceCairo(parameters) {
+  sound_filename_.clear();
+  movie_filename_.clear();
+}
+
+bool GraphicsOutputDeviceMovie::Initialize(Parameters *global_parameters) {
+  global_parameters_ = global_parameters;
+  sound_filename_ = global_parameters->GetString("input_filename");
+  string file_suffix = parameters_->DefaultString("filename_suffix", ".mov");
+  movie_filename_ = global_parameters->GetString("output_filename_base")
+                    + file_suffix;
+  
+  FILE *f;
+
+  // Check sound file exists
+  if ((f = fopen(sound_filename_.c_str(), "r")) == NULL) {
+    LOG_ERROR(_T("Couldn't open sound file '%s' for movie creation."),
+             sound_filename_.c_str());
+    sound_filename_.clear();
+    return false;
+  }
+  fclose(f);
+
+  // Check movie output file can be made
+  if ((f = fopen(movie_filename_.c_str(), "w")) == NULL) {
+    LOG_ERROR(_T("Couldn't open movie file '%s' to write to."),
+             movie_filename_.c_str());
+    movie_filename_.clear();
+    return false;
+  }
+  fclose(f);
+
+  // Get a temporary image output directory
+  //! \warning Not really safe ... but windows has no mkdtemp()
+  //! \todo Make build system check for mkdtemp() to use it when available. See TODO.txt.
+#ifdef _WINDOWS
+  char *temp_dir = NULL;
+  if ((temp_dir = _tempnam(NULL, AIM_NAME))
+      && _mkdir(temp_dir) >= 0) {
+    directory_ = temp_dir;
+    directory_ += "\\"; // Make sure to end with trailing slash
+  } else  {
+    LOG_ERROR(_T("Couldn't create a temporary directory for movie output."));
+    if (temp_dir) {
+      free(temp_dir);
+    }
+    return false;
+  }
+  if (temp_dir) {
+    free(temp_dir);
+  }
+#else
+  char temp_dir[PATH_MAX];
+  strcpy(temp_dir, "/tmp/"AIM_NAME"-movie.XXXXXX");
+  if (mkdtemp(temp_dir)) {
+    directory_ = temp_dir;
+    directory_ += "/"; // Make sure to end with trailing slash    
+  } else {
+    LOG_ERROR(_T("Couldn't create a temporary directory for movie output."));
+    return false;
+  }
+#endif
+  
+  // We want png for movie conversion
+  parameters_->SetString("output.img.format", "png");
+  if ( !GraphicsOutputDeviceCairo::Initialize(directory_) ) {
+    return false;
+  }
+  return true;
+}
+
+void GraphicsOutputDeviceMovie::Start() {
+  GraphicsOutputDeviceCairo::Start();
+  // Output a couple of frames to get audio/video in sync, put params in there.
+  gGrab();
+  PlotParameterScreen();
+  gRelease();
+  gGrab();
+  PlotParameterScreen();
+  gRelease();
+}
+
+void GraphicsOutputDeviceMovie::Reset(Parameters* global_parameters) {
+  Stop();
+  Initialize(global_parameters);
+}
+
+void GraphicsOutputDeviceMovie::Stop() {
+  GraphicsOutputDeviceCairo::Stop();
+  CloseFile();
+
+#ifdef __WX__
+  // GUI only: popup dialog
+#else
+  printf("Generating movie ... \n");
+#endif
+  AIM_ASSERT(parameters_);
+  // Convert images and sound file to a movie.
+  //! \warning Movie files are overwritten without warning.
+  char sffmpegPath[1024];
+  if (!parameters_->IsSet("output.ffmpeg_path")) {
+  strcpy(sffmpegPath,"ffmpeg");
+  } else {
+    strcpy(sffmpegPath, parameters_->GetString("output.ffmpeg_path"));
+  }
+  char sCodecOptions[1024];
+  if (!parameters_->IsSet("output.ffmpeg_codec_options")) {
+    strcpy(sCodecOptions,"");
+  } else {
+    strcpy(sCodecOptions, parameters_->GetString("output.ffmpeg_codec_options"));
+  }
+  float frame_rate = global_parameters_->DefaultFloat("frame_rate", -1.0);
+  char sCmdLine[1024]; //!\todo check that snprintf does not want a larger buffer
+  snprintf(sCmdLine, sizeof(sCmdLine)/sizeof(sCmdLine[0]),
+    "%s -r %.2f -y -i \"%s\" -i \"%s%%06d.png\" "
+    "-sameq -r %.2f -ar 44100 -acodec pcm_s16le %s \"%s\"",
+    sffmpegPath, frame_rate, sound_filename_.c_str(), directory_.c_str(),
+    frame_rate, sCodecOptions, movie_filename_.c_str());
+    printf(sCmdLine);
+    printf("\n");
+  if (system(sCmdLine)) {
+    LOG_ERROR(_T("Couldn't create movie output."));
+  }
+
+#ifdef __WX__
+  // GUI only: close dialog again
+#endif
+  // Remove files in temporary directory and the dir itself
+  //! \todo make portable function, possibly decided on by build system
+#ifdef _WINDOWS
+  HANDLE hList;
+  WIN32_FIND_DATA FileData;
+  snprintf(sCmdLine, sizeof(sCmdLine)/sizeof(sCmdLine[0]), "%s/*.*", directory_.c_str());
+  if ((hList = FindFirstFile(sCmdLine, &FileData)) == INVALID_HANDLE_VALUE) {
+    LOG_ERROR(_T("Couldn't remove files from temporary directory."));
+    return;
+  }
+  bool bRMfinished = false;
+  while (!bRMfinished) {
+    snprintf(sCmdLine,
+             sizeof(sCmdLine)/sizeof(sCmdLine[0]),
+             "%s%s",
+             directory_.c_str(),
+             FileData.cFileName);
+    remove(sCmdLine);
+    if (!FindNextFile(hList, &FileData) && GetLastError() == ERROR_NO_MORE_FILES) {
+      bRMfinished = true;
+    }
+  }
+  FindClose(hList);
+  _rmdir(directory_.c_str());
+#else
+  DIR *dir;
+  struct dirent *dirent;
+  if (!(dir = opendir(directory_.c_str()))) {
+    LOG_ERROR(_T("Couldn't remove files in temporary directory."));
+    return;
+  }
+  while ((dirent = readdir(dir))) {
+    snprintf(sCmdLine,
+             sizeof(sCmdLine)/sizeof(sCmdLine[0]),
+             "%s%s",
+             directory_.c_str(),
+             dirent->d_name);
+    unlink(sCmdLine);
+  }
+  closedir(dir);
+  rmdir(directory_.c_str());
+#endif
+}
+
+void GraphicsOutputDeviceMovie::PlotParameterScreen() {
+  AIM_ASSERT(parameters_);
+  char sStr[50];
+  int lineno = 1;
+
+  float fMarL = parameters_->GetFloat(_S("graph.margin.left"));
+  float fMarT = parameters_->GetFloat(_S("graph.margin.top"));
+  float fTextHeight = 1.0f / 50.0f * 1.2; // change this when fontsizing is there!
+
+  gText2f(fMarL, 1-(fMarT+fTextHeight*lineno++),
+          _S("AIM-C"));
+  gText2f(fMarL,
+          1-(fMarT+fTextHeight*lineno++),
+          _S("(c) 2006-2010, Thomas Walters, Willem van Engen"));
+  gText2f(fMarL,
+          1-(fMarT+fTextHeight*lineno++),
+          _S("http://aimc.acousticscale.org/"));
+  lineno++;
+
+  static const char *pPlotParams[] = {
+    _S("input.buffersize"),
+    _S("input.samplerate"),
+    _S("bmm.freqstart"),
+    _S("bmm.freqend"),
+    _S("bmm.numchannels"),
+    _S("preset.name"),
+    _S("preset.title"),
+    NULL
+  };
+  for (int i = 0; pPlotParams[i]; i++) {
+    snprintf(sStr,
+             sizeof(sStr)/sizeof(sStr[0]), _S("%s=%s"),
+             pPlotParams[i],
+             parameters_->GetString(pPlotParams[i]));
+    gText2f(fMarL,
+            1-(fMarT+fTextHeight*lineno++),
+            sStr);
+  }
+}
+}  // namespace aimc
--- a/src/Support/Common.h	Mon Nov 01 01:36:44 2010 +0000
+++ b/src/Support/Common.h	Tue Nov 02 23:46:56 2010 +0000
@@ -32,6 +32,15 @@
 #include <stdio.h>
 #include <stdarg.h>
 
+// Defines for windows
+#ifdef _WINDOWS
+#define M_PI 3.14159265359
+#define isnan _isnan
+#define isinf(x) (!_finite(x))
+#define snprintf _snprintf
+#define PATH_MAX _MAX_PATH
+#endif
+
 #define AIM_NAME "AIM-C"
 #define AIM_VERSION_STRING "version_number"
 
--- a/src/Support/Module.h	Mon Nov 01 01:36:44 2010 +0000
+++ b/src/Support/Module.h	Tue Nov 02 23:46:56 2010 +0000
@@ -27,13 +27,6 @@
 #ifndef AIMC_SUPPORT_MODULE_H_
 #define AIMC_SUPPORT_MODULE_H_
 
-// Several modules expect the M_PI macro and isnan() to be defined
-#ifdef _MSC_VER
-#define M_PI 3.14159265359
-#define isnan _isnan
-#define isinf _isinf
-#endif
-
 #include <iostream>
 #include <set>
 #include <string>
--- a/src/Support/ModuleFactory.cc	Mon Nov 01 01:36:44 2010 +0000
+++ b/src/Support/ModuleFactory.cc	Tue Nov 02 23:46:56 2010 +0000
@@ -28,7 +28,7 @@
 #include "Modules/Profile/ModuleScaler.h"
 #include "Modules/SAI/ModuleSAI.h"
 #include "Modules/SSI/ModuleSSI.h"
-#include "Modules/SNR/ModuleNoise.h"
+//#include "Modules/SNR/ModuleNoise.h"
 #include "Modules/Strobes/ModuleParabola.h"
 #include "Modules/Strobes/ModuleLocalMax.h"