Mercurial > hg > aimc
changeset 411:a908972d234e
- Added support for movies!
line wrap: on
line diff
--- a/trunk/SConstruct Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/SConstruct Thu Oct 21 01:46:39 2010 +0000 @@ -137,7 +137,7 @@ elif compiler == 'gcc': env['STRIP'] = 'strip' env.AppendUnique(CPPFLAGS = ['-Wall']) - env.AppendUnique(CPPFLAGS = ['-O2',])# '-fomit-frame-pointer']) + env.AppendUnique(CPPFLAGS = ['-O1',])# '-fomit-frame-pointer']) if env['symbols']: env.AppendUnique(CPPFLAGS = ['-g']) if env['mingw']:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/Configurations/SAI_movie.aimcconfig Thu Oct 21 01:46:39 2010 +0000 @@ -0,0 +1,31 @@ +module1.name = FileInput +module1.id = file_input +module1.child1 = PZFCFilterbank + +module2.name = PZFCFilterbank +module2.id = pzfc +module2.child1 = NAP + +module3.name = NAP +module3.id = hcl +module3.child1 = Strobes + +module4.name = Strobes +module4.id = local_max +module4.parameters = <<<ENDPARAMS +ENDPARAMS +module4.child1 = SAI + +module5.name = SAI +module5.id = weighted_sai +module5.child1 = SAIMovie + +module6.name = SAIMovie +module6.id = graphics_time +module6.parameters = <<<ENDPARAMS +graph.y.min=0 +graph.y.max=0.5 +graph.freq.label=Cochlear Channel +graph.x.label=Time Interval +graph.type=line +ENDPARAMS
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/Configurations/SSI_movie.aimcconfig Thu Oct 21 01:46:39 2010 +0000 @@ -0,0 +1,40 @@ +module1.name = FileInput +module1.id = file_input +module1.child1 = PZFCFilterbank + +module2.name = PZFCFilterbank +module2.id = pzfc +module2.child1 = NAP + +module3.name = NAP +module3.id = hcl +module3.child1 = Strobes + +module4.name = Strobes +module4.id = local_max +module4.parameters = <<<ENDPARAMS +ENDPARAMS +module4.child1 = SAI + +module5.name = SAI +module5.id = weighted_sai +module5.child1 = SSI + +module6.name = SSI +module6.id = ssi +module6.parameters = <<<ENDPARAMS +ssi.pitch_cutoff=true +ssi.do_smooth_offset=true +ss.smooth_offset_cycles=3.0 +ENDPARAMS +module6.child1 = SSIMovie + +module7.name = SSIMovie +module7.id = graphics_time +module7.parameters = <<<ENDPARAMS +graph.y.min=0 +graph.y.max=1 +graph.freq.label=Cochlear Channel +graph.x.label=Cycles of the impulse response +graph.type=colormap +ENDPARAMS
--- a/trunk/src/Main/AIMCopy.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Main/AIMCopy.cc Thu Oct 21 01:46:39 2010 +0000 @@ -111,6 +111,7 @@ LOG_ERROR(_T("Failed to initialize tree.")); return false; } + tree_.Reset(); } else { LOG_ERROR(_T("No input files in script.")); return false; @@ -167,8 +168,8 @@ aimc::LOG_INFO(_T("%s -> %s"), script_[i].first.c_str(), script_[i].second.c_str()); + tree_.Process(); tree_.Reset(); - tree_.Process(); } return true; }
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevice.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevice.cc Thu Oct 21 01:46:39 2010 +0000 @@ -20,8 +20,8 @@ namespace aimc { -GraphicsOutputDevice::GraphicsOutputDevice(Parameters *pParam) { - m_pParam = pParam; +GraphicsOutputDevice::GraphicsOutputDevice(Parameters *parameters) { + parameters_ = parameters; } void GraphicsOutputDevice::gVertex3f(float x, @@ -49,8 +49,8 @@ void GraphicsOutputDevice::gText2f(float x, float y, - const char *sStr, - bool bRotated) { - gText3f(x, y, 0, sStr, bRotated); + const char *text_string, + bool rotated) { + gText3f(x, y, 0, text_string, rotated); } } // namespace aimc
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevice.h Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevice.h Thu Oct 21 01:46:39 2010 +0000 @@ -1,4 +1,4 @@ -// Copyright 2006, Willem van Engen +// Copyright 2006-2010, Willem van Engen, Thomas Walters // // AIM-C: A C++ implementation of the Auditory Image Model // http://www.acousticscale.org/AIMC @@ -81,12 +81,15 @@ * * \sa Module::Initialize() */ - virtual bool Initialize(unsigned int iVerticesMax) { return true; }; + /*! \overload * This function reloads the parameters; make sure to have at least the * function with maximum parameters called once. */ - virtual bool Initialize() { return true; }; + virtual bool Initialize(Parameters *global_parameters) { + global_parameters_ = global_parameters; + return true; + }; /*! \brief Create a new drawing * Run this before any other drawing command. @@ -184,7 +187,8 @@ //! \brief True when animation is running bool m_bRunning; //! \brief Parameter store - Parameters *m_pParam; + Parameters *parameters_; + Parameters *global_parameters_; //! \brief Pixel Formats enum PixelFormat {AIM_PIX_FMT_RGB24_32, AIM_PIX_FMT_RGB24_24};
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.cc Thu Oct 21 01:46:39 2010 +0000 @@ -1,4 +1,4 @@ -// Copyright 2007, Thomas Walters +// Copyright 2007-2010, Thomas Walters, Willem van Engen // // AIM-C: A C++ implementation of the Auditory Image Model // http://www.acousticscale.org/AIMC @@ -32,6 +32,8 @@ #include <stdio.h> #include <math.h> +#include "cairo-quartz.h" + #include "Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.h" namespace aimc { @@ -42,47 +44,58 @@ m_iFileNumber = 0; m_iVertexType = VertexTypeNone; m_bUseMemoryBuffer=false; - m_pParam->DefaultString("output.img.format", ".png"); + parameters_->DefaultString("output.img.format", ".png"); } -bool GraphicsOutputDeviceCairo::Initialize(const char *sDir) { - Init(); - - //! \todo Output to file if sDir is a file, to directory with - //! multiple images if it's a directory. - strncpy(m_sDir, sDir, sizeof(m_sDir)/sizeof(m_sDir[0])); +bool GraphicsOutputDeviceCairo::Initialize(string directory) { + directory_ = directory; + InititalzeInternal(); /* Try to open an image to see if everything is allright. We want to avoid * errors in the main Process()ing loop. */ - if ( !OpenFile(0) ) { + /*if (!OpenFile(0)) { //! \todo Better error message that is more specific about the cause. LOG_ERROR(_T("Could not open output directory '%s' using graphics format '%s'."), - m_sDir, m_pParam->DefaultString("output.img.format", ".png") ); + directory_.c_str(), parameters_->DefaultString("output.img.format", "png")); return false; } - CloseFile(); + CloseFile();*/ return true; } -bool GraphicsOutputDeviceCairo::Initialize() { +/*bool GraphicsOutputDeviceCairo::Initialize() { Init(); m_bUseMemoryBuffer = true; return(true); -} +}*/ -void GraphicsOutputDeviceCairo::Init() { - AIM_ASSERT(m_pParam); - /* - * Set parameters - */ - m_pParam->GetString("output.img.color.background"); +void GraphicsOutputDeviceCairo::InititalzeInternal() { + AIM_ASSERT(parameters_); - m_bInvertColors = m_pParam->GetBool("output.img.color.invert"); + parameters_->DefaultString("output.img.color.background", "black"); - // Output size! - m_iWidth = m_pParam->GetUInt("output.img.width"); - m_iHeight = m_pParam->GetUInt("output.img.height"); + m_bInvertColors = parameters_->DefaultBool("output.img.color.invert", "false"); + + // Output size. + m_iWidth = parameters_->DefaultInt("output.img.width", 800); + m_iHeight = parameters_->DefaultInt("output.img.height", 600); + + // Cairo's RGB24 format has 32-bit pixels with the upper 8 bits unused. + // This is not the same as the plotutils PNG format. This information is transferred by the + // function GetPixelFormat. The pixel format is dealt with by the reciever. + m_cSurface = cairo_quartz_surface_create(CAIRO_FORMAT_RGB24, + m_iWidth, + m_iHeight); + m_cCr = cairo_create(m_cSurface); + cairo_scale(m_cCr, (float)m_iWidth, (float)m_iHeight); + // Now setup things for this plotter. + cairo_select_font_face(m_cCr, + parameters_->DefaultString("output.img.fontname", + "HersheySans"), + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size (m_cCr, 0.02); } unsigned char* GraphicsOutputDeviceCairo::GetBuffer() { @@ -93,25 +106,27 @@ } bool GraphicsOutputDeviceCairo::OpenFile(unsigned int index) { - const char *strPlottype = m_pParam->GetString("output.img.format"); + const char *strPlottype = parameters_->GetString("output.img.format"); if (!m_bUseMemoryBuffer) { struct stat fileinfo; // Get filename without trailing slash - strncpy(m_sFilename, m_sDir, sizeof(m_sFilename)/sizeof(m_sFilename[0])); + char filename[PATH_MAX]; + strncpy(filename, directory_.c_str(), sizeof(filename)/sizeof(filename[0])); #ifdef _WINDOWS - if (m_sFilename[strlen(m_sFilename)-1]=='\\') { - m_sFilename[strlen(m_sFilename)-1]='\0'; + if (filename[strlen(filename)-1]=='\\') { + filename[strlen(filename)-1]='\0'; } #else - if (m_sFilename[strlen(m_sFilename)-1]=='/') { - m_sFilename[strlen(m_sFilename)-1]='\0'; + if (filename[strlen(filename)-1]=='/') { + filename[strlen(filename)-1]='\0'; } #endif // Enumerate files it m_sDir is a directory. - if (stat(m_sFilename, &fileinfo) == 0 && (fileinfo.st_mode & S_IFDIR)) { + if (stat(filename, &fileinfo) == 0 && (fileinfo.st_mode & S_IFDIR)) { // We have a directory: enumerate with index - snprintf(m_sFilename, sizeof(m_sFilename)/sizeof(m_sFilename[0]),"%s%06d.%s", - m_sDir, + snprintf(filename, sizeof(filename) / sizeof(filename[0]), + "%s%06d.%s", + directory_.c_str(), index, strPlottype); // If type is 'auto', fallback to 'png' @@ -119,46 +134,34 @@ strPlottype = "png"; } else { // We have a (probably non-existant) file. Auto-detect type by extension if requested - strncpy(m_sFilename, m_sDir, sizeof(m_sFilename)/sizeof(m_sFilename[0])); - char *pDot = strrchr(m_sFilename, '.'); + strncpy(filename, + directory_.c_str(), + sizeof(filename)/sizeof(filename[0])); + char *pDot = strrchr(filename, '.'); if (!pDot) { LOG_ERROR(_T("Please supply extension on filename when using 'auto' format: '%s'"), - m_sFilename); + filename); return false; } strPlottype = &pDot[1]; } + image_filename_ = filename; m_bOutputFile= true; //! \todo Should check that it's possible to write to the file } - // Cairo's RGB24 format has 32-bit pixels with the upper 8 bits unused. - // This is not the same as the plotutils PNG format. This information is transferred by the - // function GetPixelFormat. The pixel format is dealt with by the reciever. - m_cSurface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, - m_iWidth, - m_iHeight); - m_cCr = cairo_create (m_cSurface); - cairo_scale(m_cCr, (float)m_iWidth, (float)m_iHeight); - // Now setup things for this plotter. - cairo_select_font_face(m_cCr, - m_pParam->GetString("output.img.fontname"), - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size (m_cCr, 0.015); + return true; } void GraphicsOutputDeviceCairo::CloseFile() { - // Plotting library - if (m_iPlotHandle>0) { - cairo_destroy(m_cCr); - m_iPlotHandle = 0; - } // And the output file if (m_bOutputFile) { - cairo_surface_write_to_png(m_cSurface, m_sFilename); + cairo_surface_write_to_png(m_cSurface, image_filename_.c_str()); m_bOutputFile = false; } - cairo_surface_destroy(m_cSurface); + cairo_set_source_rgb (m_cCr, 0.0, 0.0, 0.0); + cairo_paint (m_cCr); + //cairo_destroy(m_cCr); + //cairo_surface_destroy(m_cSurface); } GraphicsOutputDeviceCairo::~GraphicsOutputDeviceCairo() { @@ -198,9 +201,9 @@ void GraphicsOutputDeviceCairo::gColor3f(float r, float g, float b) { if (m_bInvertColors) { - r = 1-r; - g = 1-g; - b = 1-b; + r = 1.0 - r; + g = 1.0 - g; + b = 1.0 - b; } cairo_set_source_rgb (m_cCr, r, g, b); } @@ -211,14 +214,14 @@ if (m_bIsFirstVertex) { m_bIsFirstVertex = false; //pl_fmove(x, y); - cairo_move_to(m_cCr, x, 1-y); + cairo_move_to(m_cCr, x, 1.0 - y); } else { //pl_fcont(x, y); - cairo_line_to(m_cCr, x, 1-y); + cairo_line_to(m_cCr, x, 1.0 - y); } break; case VertexTypeQuad: - /* Store vertices until we got four in a row. + /* Store vertices until we have four in a row. * The order of vertices when processing quads is: * 1-----3-----5 * | | | @@ -226,11 +229,17 @@ */ if (m_iPrevVertexCount >= 3) { // Plot this quad - cairo_move_to(m_cCr, m_aPrevX[0], 1-m_aPrevY[0]); - cairo_line_to(m_cCr, m_aPrevX[1], 1-m_aPrevY[1]); + //cairo_set_source_rgb(m_cCr, 0.2, 1 - m_aPrevY[0], m_aPrevX[0]); + cairo_rectangle (m_cCr, m_aPrevX[2], + 1 - m_aPrevY[2], m_aPrevX[2] - m_aPrevX[0], + y - m_aPrevY[2]); + cairo_fill (m_cCr); + + /*cairo_move_to(m_cCr, , ); + cairo_line_to(m_cCr, , 1 - m_aPrevY[1]); cairo_line_to(m_cCr, x, y); - cairo_line_to(m_cCr, m_aPrevX[2], 1-m_aPrevY[2]); - cairo_close_path (m_cCr); + cairo_line_to(m_cCr, m_aPrevX[2], 1 - m_aPrevY[2]);*/ + // Last vertices of this quad are the first of the next m_aPrevX[0] = m_aPrevX[2]; @@ -267,7 +276,7 @@ //cairo_text_extents_t te; if (bRotated) { cairo_rotate(m_cCr, M_PI/2); - cairo_move_to(m_cCr, x ,1-y); + //cairo_move_to(m_cCr, x ,1-y); cairo_show_text(m_cCr, sStr); //cairo_identity_matrix(m_cCr); cairo_rotate(m_cCr, -M_PI/2);
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.h Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.h Thu Oct 21 01:46:39 2010 +0000 @@ -47,12 +47,12 @@ */ class GraphicsOutputDeviceCairo : public GraphicsOutputDevice { public: - GraphicsOutputDeviceCairo(Parameters *pParam); + GraphicsOutputDeviceCairo(Parameters *parameters); virtual ~GraphicsOutputDeviceCairo(); /*! \brief Initializes this output device, prepares plotting tools. * \param sDir Directory or filename where to put images, max length is - * _MAX_PATH. Must end with slash!!! + * _MAX_PATH. Must end with slash. * \return true on success, false on failure. * * sDir can be either a filename, in which case the output will be @@ -63,8 +63,7 @@ * As usual, make sure to call this function before any other. If this * Initialize() failed, you shouldn't try the other functions either. */ - bool Initialize(const char *sDir); - bool Initialize(); + bool Initialize(string directory); void gGrab(); void gBeginLineStrip(); void gBeginQuadStrip(); @@ -80,7 +79,7 @@ /*! \brief Internal initialisation * */ - void Init(); + void InititalzeInternal(); /*! \brief Open the file with given index for output * \param index File number to open @@ -95,10 +94,8 @@ //! \brief Set to true if the input file can be written to bool m_bOutputFile; - //! \brief The Cairo plotter - int m_iPlotHandle; //! \brief Output directory - char m_sDir[FILENAME_MAX]; + string directory_; //! \brief Current file number unsigned int m_iFileNumber; //! \brief true if this is the first vertex after gBegin() @@ -126,7 +123,7 @@ cairo_t *m_cCr; //! \brief Internal store for the input filename - char m_sFilename[FILENAME_MAX]; + string image_filename_; unsigned int m_iWidth; unsigned int m_iHeight;
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.cc Thu Oct 21 01:46:39 2010 +0000 @@ -50,84 +50,90 @@ namespace aimc { -GraphicsOutputDeviceMovie::GraphicsOutputDeviceMovie(Parameters *pParam) - : GraphicsOutputDeviceCairo(pParam) { // or GraphicsOutputDevicePlotutils - m_sMovieFile[0] = '\0'; - m_sSoundFile[0] = '\0'; +GraphicsOutputDeviceMovie::GraphicsOutputDeviceMovie(Parameters *parameters) + : GraphicsOutputDeviceCairo(parameters) { + sound_filename_.clear(); + movie_filename_.clear(); } -bool GraphicsOutputDeviceMovie::Initialize(const char *sSoundFile, - const char *sMovieFile) { +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; - AIM_ASSERT(sSoundFile); - AIM_ASSERT(sMovieFile); // Check sound file exists - if ((f = fopen(sSoundFile, "r")) == NULL) { + if ((f = fopen(sound_filename_.c_str(), "r")) == NULL) { LOG_ERROR(_T("Couldn't open sound file '%s' for movie creation."), - sSoundFile); + sound_filename_.c_str()); + sound_filename_.clear(); return false; } fclose(f); - strcpy(m_sSoundFile, sSoundFile); // Check movie output file can be made - if ( (f=fopen(sMovieFile, "w"))==NULL ) { + if ((f = fopen(movie_filename_.c_str(), "w")) == NULL) { LOG_ERROR(_T("Couldn't open movie file '%s' to write to."), - sMovieFile); + movie_filename_.c_str()); + movie_filename_.clear(); return false; } fclose(f); - strcpy(m_sMovieFile, sMovieFile); // 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. - char *sTmpDir = NULL; #ifdef _WINDOWS - if ((sTmpDir = _tempnam(NULL, AIM_NAME)) - && _mkdir(sTmpDir) >= 0) { - strcpy(m_sDir, sTmpDir); - strcat(m_sDir, "\\"); // Make sure to end with trailing slash - } else -#else - strcpy(m_sDir, "/tmp/"AIM_NAME"-movie.XXXXXX"); - if (mkdtemp(m_sDir)) { - strcat(m_sDir, "/"); // Make sure to end with trailing slash - } else -#endif - { + 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 (sTmpDir) free(sTmpDir); + if (temp_dir) { + free(temp_dir); + } return false; } - if (sTmpDir) { - free(sTmpDir); + if (temp_dir) { + free(temp_dir); } - - // We want png for movie conversion - //! \bug This may change the user preference in GUI, hmm what to do? See TODO.txt - m_pParam->SetString("output.img.format", "png"); - //if ( !GraphicsOutputDevicePlotutils::Initialize(m_sDir) ) { - if ( !GraphicsOutputDeviceCairo::Initialize(m_sDir) ) { +#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() { - //GraphicsOutputDevicePlotutils::Start(); GraphicsOutputDeviceCairo::Start(); - // Just output a single frame to get audio/video in sync, put params in there + // Output a couple of frames to get audio/video in sync, put params in there. + gGrab(); + PlotParameterScreen(); + gRelease(); gGrab(); PlotParameterScreen(); gRelease(); } void GraphicsOutputDeviceMovie::Stop() { - // Make sure Plotutils is really done writing. - //GraphicsOutputDevicePlotutils::Stop(); GraphicsOutputDeviceCairo::Stop(); CloseFile(); @@ -136,33 +142,28 @@ #else printf("Generating movie ... \n"); #endif - AIM_ASSERT(m_pParam); - // Convert images and sound file to a movie - //! \warning Movie files are overwritten without warning - //! \bug ffmpeg only works with colour images, not with bw. So make sure to not use bw only in drawing.. - // Always convert to audio stream of 44.1kHz or problems may occur in playing or conversio. - float fFps = 1000.0 / m_pParam->GetFloat("output.frameperiod"); + AIM_ASSERT(parameters_); + // Convert images and sound file to a movie. + //! \warning Movie files are overwritten without warning. char sffmpegPath[1024]; - if (!m_pParam->IsSet("output.ffmpeg_path")) { + if (!parameters_->IsSet("output.ffmpeg_path")) { strcpy(sffmpegPath,"ffmpeg"); } else { - strcpy(sffmpegPath, m_pParam->GetString("output.ffmpeg_path")); + strcpy(sffmpegPath, parameters_->GetString("output.ffmpeg_path")); } char sCodecOptions[1024]; - if (!m_pParam->IsSet("output.ffmpeg_codec_options")) { + if (!parameters_->IsSet("output.ffmpeg_codec_options")) { strcpy(sCodecOptions,""); } else { - strcpy(sCodecOptions, m_pParam->GetString("output.ffmpeg_codec_options")); + 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\" " - "-title \"%s\" -comment \"Generated by "AIM_NAME" "AIM_VERSION_STRING"\" " "-sameq -r %.2f -ar 44100 -acodec pcm_s16le %s \"%s\"", - sffmpegPath, fFps, m_sSoundFile, m_sDir, - m_pParam->GetString("output.movie.title"), - fFps, sCodecOptions, m_sMovieFile); + sffmpegPath, frame_rate, sound_filename_.c_str(), directory_.c_str(), + frame_rate, sCodecOptions, movie_filename_.c_str()); printf(sCmdLine); printf("\n"); if (system(sCmdLine)) { @@ -199,7 +200,7 @@ #else DIR *dir; struct dirent *dirent; - if (!(dir = opendir(m_sDir))) { + if (!(dir = opendir(directory_.c_str()))) { LOG_ERROR(_T("Couldn't remove files in temporary directory.")); return; } @@ -207,22 +208,22 @@ snprintf(sCmdLine, sizeof(sCmdLine)/sizeof(sCmdLine[0]), "%s%s", - m_sDir, + directory_.c_str(), dirent->d_name); unlink(sCmdLine); } closedir(dir); - rmdir(m_sDir); + rmdir(directory_.c_str()); #endif } void GraphicsOutputDeviceMovie::PlotParameterScreen() { - AIM_ASSERT(m_pParam); + AIM_ASSERT(parameters_); char sStr[50]; int lineno = 1; - float fMarL = m_pParam->GetFloat(_S("graph.margin.left")); - float fMarT = m_pParam->GetFloat(_S("graph.margin.top")); + 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++), @@ -249,7 +250,7 @@ snprintf(sStr, sizeof(sStr)/sizeof(sStr[0]), _S("%s=%s"), pPlotParams[i], - m_pParam->GetString(pPlotParams[i])); + parameters_->GetString(pPlotParams[i])); gText2f(fMarL, 1-(fMarT+fTextHeight*lineno++), sStr);
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.h Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.h Thu Oct 21 01:46:39 2010 +0000 @@ -27,7 +27,7 @@ #ifndef __GRAPHICS_OUTPUT_DEVICE_MOVIE_H__ #define __GRAPHICS_OUTPUT_DEVICE_MOVIE_H__ -//#include "Modules/Output/Graphics/Devices/GraphicsOutputDevicePlotutils.h" +#include <string> #include "Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.h" namespace aimc { @@ -39,7 +39,7 @@ // GraphicsOutputDevicePlotutils is also possible here class GraphicsOutputDeviceMovie : public GraphicsOutputDeviceCairo { public: - GraphicsOutputDeviceMovie(Parameters *pParam); + GraphicsOutputDeviceMovie(Parameters *parameters); virtual ~GraphicsOutputDeviceMovie() { }; /*! \brief Initializes this output device, prepares plotting tools. @@ -50,7 +50,7 @@ * As usual, make sure to call this function before any other. If this * Initialize() failed, you shouldn't try the other functions either. */ - bool Initialize(const char *sSoundFile, const char *sMovieFile); + bool Initialize(Parameters *global_parameters); void Start(); //! \brief This function now also generates the output movie. @@ -68,9 +68,9 @@ void PlotParameterScreen(); //! \brief Name of the sound file to be merged with the video - char m_sSoundFile[PATH_MAX]; + string sound_filename_; //! \brief Name of the movie file to produce - char m_sMovieFile[PATH_MAX]; + string movie_filename_; }; } // namespace aimc #endif /* __GRAPHICS_OUTPUT_DEVICE_MOVIE_H__ */
--- a/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.cc Thu Oct 21 01:46:39 2010 +0000 @@ -269,7 +269,7 @@ } else if (strstr(extensions, "GL_EXT_compiled_vertex_array")) { m_glLockArraysEXT = (LOCAL_PFNGLLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glLockArraysEXT"); m_glUnlockArraysEXT = (LOCAL_PFNGLUNLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glUnlockArraysEXT"); - if(!m_glLockArraysEXT || !m_glUnlockArraysEXT) + if (!m_glLockArraysEXT || !m_glUnlockArraysEXT) AIM_ERROR(_T("OpenGL error on GL_EXT_compiled_vertex_array")); else m_bVertexArrayLock = true;
--- a/trunk/src/Modules/Output/Graphics/GraphAxisSpec.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/GraphAxisSpec.cc Thu Oct 21 01:46:39 2010 +0000 @@ -70,23 +70,20 @@ snprintf(sParamName, sizeof(sParamName)/sizeof(sParamName[0]), "%s.min", sPrefix); - if (parameters->IsSet(sParamName)) { - if (strcmp(parameters->GetString(sParamName), "auto") == 0) - m_fMin = fMin; - else - m_fMin = parameters->GetFloat(sParamName); - } + if (strcmp(parameters->DefaultString(sParamName, "auto"), "auto") == 0) + m_fMin = fMin; + else + m_fMin = parameters->GetFloat(sParamName); + //! - \c "<prefix>.max", the maximum value; a float or \c 'auto' snprintf(sParamName, sizeof(sParamName)/sizeof(sParamName[0]), "%s.max", sPrefix); - if (parameters->IsSet(sParamName)) { - if (strcmp(parameters->GetString(sParamName), "auto")==0) - m_fMax = fMax; - else - m_fMax = parameters->GetFloat(sParamName); - } + if (strcmp(parameters->DefaultString(sParamName, "auto"), "auto")==0) + m_fMax = fMax; + else + m_fMax = parameters->GetFloat(sParamName); // Make sure ranges are updated properly SetDisplayRange(m_fMin, m_fMax); @@ -96,33 +93,31 @@ snprintf(sParamName, sizeof(sParamName)/sizeof(sParamName[0]), "%s.scale", sPrefix); - if (parameters->IsSet(sParamName)) { - // Scale change, we updated min/max values already so no need to - Scale::ScaleType iThisScale; - const char *sVal = parameters->GetString(sParamName); - if (strcmp(sVal, "auto")==0) - iThisScale = iScale; - else if (strcmp(sVal, "linear")==0) - iThisScale = Scale::SCALE_LINEAR; - else if (strcmp(sVal, "erb")==0) - iThisScale = Scale::SCALE_ERB; - else if (strcmp(sVal, "log")==0) - iThisScale = Scale::SCALE_LOG; - else { - LOG_ERROR(_T("Unrecognized scale type in parameter '%s': '%s'"), - sParamName, - sVal); - return false; - } - SetDisplayScale(iThisScale); + // Scale change, we updated min/max values already so no need to + Scale::ScaleType iThisScale; + const char *sVal = parameters->DefaultString(sParamName, "auto"); + if (strcmp(sVal, "auto")==0) + iThisScale = iScale; + else if (strcmp(sVal, "linear")==0) + iThisScale = Scale::SCALE_LINEAR; + else if (strcmp(sVal, "erb")==0) + iThisScale = Scale::SCALE_ERB; + else if (strcmp(sVal, "log")==0) + iThisScale = Scale::SCALE_LOG; + else { + LOG_ERROR(_T("Unrecognized scale type in parameter '%s': '%s'"), + sParamName, + sVal); + return false; } + SetDisplayScale(iThisScale); + //! - \c "<prefix>.label", the label; a string snprintf(sParamName, sizeof(sParamName)/sizeof(sParamName[0]), "%s.label", sPrefix); - if (parameters->IsSet(sParamName)) - m_sLabel = parameters->GetString(sParamName); // Assumes strings remains valid + m_sLabel = parameters->DefaultString(sParamName, ""); // Assumes strings remains valid return true; }
--- a/trunk/src/Modules/Output/Graphics/GraphicsView.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/GraphicsView.cc Thu Oct 21 01:46:39 2010 +0000 @@ -21,6 +21,7 @@ #include "Modules/Output/Graphics/GraphicsView.h" #include "Modules/Output/Graphics/Devices/GraphicsOutputDevice.h" +#include "Modules/Output/Graphics/Devices/GraphicsOutputDeviceMovie.h" namespace aimc { @@ -30,7 +31,7 @@ module_type_ = "output"; module_version_ = "$Id: $"; - m_pDev = new GraphicsOutputDeviceCairo(); + m_pDev = new GraphicsOutputDeviceMovie(parameters); m_bPlotLabels = false; m_pAxisX = new GraphAxisSpec(); AIM_ASSERT(m_pAxisX); @@ -48,13 +49,13 @@ LOG_ERROR("Axis initialization failed"); initialized_ = false; } - m_fMarginLeft = parameters_->GetFloat(_S("graph.margin.left")); - m_fMarginRight = parameters_->GetFloat(_S("graph.margin.right")); - m_fMarginTop = parameters_->GetFloat(_S("graph.margin.top")); - m_fMarginBottom = parameters_->GetFloat(_S("graph.margin.bottom")); - m_bPlotLabels = parameters_->GetBool(_S("graph.plotlabels")); + m_fMarginLeft = parameters_->DefaultFloat(_S("graph.margin.left"), 0.05); + m_fMarginRight = parameters_->DefaultFloat(_S("graph.margin.right"), 0.005); + m_fMarginTop = parameters_->DefaultFloat(_S("graph.margin.top"), 0.005); + m_fMarginBottom = parameters_->DefaultFloat(_S("graph.margin.bottom"), 0.05); + m_bPlotLabels = parameters_->DefaultBool(_S("graph.plotlabels"), true); - const char *sGraphType = parameters_->GetString(_S("graph.type")); + const char *sGraphType = parameters_->DefaultString(_S("graph.type"), "line"); if (strcmp(sGraphType, _S("line"))==0) m_iGraphType = GraphTypeLine; else if (strcmp(sGraphType, _S("colormap"))==0) @@ -66,7 +67,7 @@ initialized_ = false; } - if (strcmp(parameters_->GetString(_S("graph.mindistance")),"auto") == 0) + if (strcmp(parameters_->DefaultString(_S("graph.mindistance"), "auto"),"auto") == 0) // -1 means detect later, based on type and Fire() argument m_fMinPlotDistance = -1; else @@ -80,6 +81,9 @@ } void GraphicsView::ResetInternal() { + if (m_pDev != NULL) { + m_pDev->Stop(); + } } bool GraphicsView::InitializeInternal(const SignalBank &bank) { @@ -95,7 +99,7 @@ y_min, y_max, Scale::SCALE_ERB)) { - LOG_ERROR(""); + LOG_ERROR("Frequency axis init failed."); return false; } @@ -106,17 +110,21 @@ x_min, x_max, Scale::SCALE_LINEAR)) { - LOG_ERROR(""); + LOG_ERROR("Time axis init failed."); return false; } /* Inform graphics output of maximum number of vertices between * gBegin*() and gEnd(), for any type of plot. Colormap needs most. */ - if (!m_pDev->Initialize(std::max<int>(10, bank.buffer_length() * 2 + 2))) { - LOG_ERROR(""); + LOG_INFO("Initializing graphics output device."); + + if (!m_pDev->Initialize(global_parameters_)) { + LOG_ERROR("Graphics output device init failed."); return false; } + m_pDev->Start(); + previous_start_time_ = 0; return true; } @@ -145,6 +153,11 @@ PlotData(bank[i], bank.sample_rate(), yOffs, heightMinMargin, xScaling); } m_pDev->gRelease(); + + frame_rate_ = bank.sample_rate() + / (bank.start_time() - previous_start_time_); + previous_start_time_ = bank.start_time(); + global_parameters_->SetFloat("frame_rate", frame_rate_); } void GraphicsView::SetAxisScale(Scale::ScaleType iHori,
--- a/trunk/src/Modules/Output/Graphics/GraphicsView.h Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/GraphicsView.h Thu Oct 21 01:46:39 2010 +0000 @@ -163,6 +163,8 @@ float m_fPrevVal, m_fPrevX, m_fPrevY, m_fPrevHeight; //! \brief Number of times m_fValPrev was within range m_fMinPlotDistance int m_iPrevValEqual; + float frame_rate_; + int previous_start_time_; bool initialized_; };
--- a/trunk/src/Modules/Output/Graphics/GraphicsViewTime.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/GraphicsViewTime.cc Thu Oct 21 01:46:39 2010 +0000 @@ -43,7 +43,7 @@ } GraphicsViewTime *GraphicsViewTime::Clone(GraphicsOutputDevice *pDev) { - GraphicsViewTime *pView = new GraphicsViewTime(m_pParam); + GraphicsViewTime *pView = new GraphicsViewTime(parameters_); // Copy everything pView->m_pAxisX->SetDisplayRange(m_pAxisX->m_fMax, m_pAxisX->m_fMin); pView->m_pAxisX->SetDisplayScale(m_pAxisX->m_pScale->getType()); @@ -67,8 +67,8 @@ m_pDev->gVertex2f(1.0f-m_fMarginRight, m_fMarginBottom); m_pDev->gEnd(); - if (!m_bPlotLabels) - return; + //if (!m_bPlotLabels) + // return; // Labels char sTxt[80]; @@ -88,9 +88,9 @@ m_pDev->gText2f(m_fMarginLeft, 0.0025f, sTxt, false); // Frame time - //snprintf(sTxt, sizeof(sTxt)/sizeof(sTxt[0]), _S("t=%.0f ms"), - // pBank->getSampleTime(0)); - //m_pDev->gText2f(0.8f, 0.0025f, sTxt, false); + snprintf(sTxt, sizeof(sTxt)/sizeof(sTxt[0]), _S("t=%.0f ms"), + 1000.0 * bank.start_time() / bank.sample_rate()); + m_pDev->gText2f(0.8f, 0.0025f, sTxt, false); } void GraphicsViewTime::PlotData(const vector<float> &signal,
--- a/trunk/src/Modules/Output/Graphics/GraphicsViewTime.h Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/Output/Graphics/GraphicsViewTime.h Thu Oct 21 01:46:39 2010 +0000 @@ -35,10 +35,10 @@ private: void PlotData(const vector<float> &signal, - float sample_rate, - float yOffset, - float height, - float xScale = 1.0); + float sample_rate, + float yOffset, + float height, + float xScale = 1.0); void PlotAxes(const vector<float> &signal); void PlotAxes(const SignalBank &pBank); };
--- a/trunk/src/Modules/SSI/ModuleSSI.cc Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/src/Modules/SSI/ModuleSSI.cc Thu Oct 21 01:46:39 2010 +0000 @@ -57,7 +57,7 @@ // Time from the zero-lag line of the SAI from which to start searching // for a maximum in the input SAI's temporal profile. pitch_search_start_ms_ = parameters_->DefaultFloat( - "ssi.pitch_search_start_ms", 2.0f); + "ssi.pitch_search_start_ms", 2.0f); // Total width in cycles of the whole SSI ssi_width_cycles_ = parameters_->DefaultFloat("ssi.width_cycles", 10.0f); @@ -99,6 +99,10 @@ ssi_width_samples_, cycles); ssi_width_cycles_ = cycles; } + for (int i = 0; i < input.channel_count(); ++i) { + output_.set_centre_frequency(i, input.centre_frequency(i)); + } + output_.Initialize(channel_count_, ssi_width_samples_, sample_rate_); return true; } @@ -159,6 +163,7 @@ for (int ch = 0; ch < channel_count_; ++ch) { float centre_frequency = input.centre_frequency(ch); + float cycle_samples = sample_rate_ / centre_frequency; float channel_weight = 1.0f; int cutoff_index = buffer_length_ - 1; @@ -166,31 +171,22 @@ if (pitch_index < cutoff_index) { if (weight_by_cutoff_) { channel_weight = static_cast<float>(buffer_length_) - / static_cast<float>(pitch_index); + / static_cast<float>(pitch_index); } cutoff_index = pitch_index; } } // tanh(3) is about 0.995. Seems reasonable. - float smooth_pitch_constant = smooth_offset_cycles_ * 3.0f; + float smooth_pitch_constant = 3.0f / smooth_offset_cycles_; float pitch_h = 0.0f; if (do_smooth_offset_) { - if (log_cycles_axis_) { - float gamma = gamma_min + (gamma_max - gamma_min) - * static_cast<float>(pitch_index) - / static_cast<float>(ssi_width_samples_); - pitch_h = pow(2.0f, gamma); - } else { - pitch_h = static_cast<float>(pitch_index) * ssi_width_cycles_ - / static_cast<float>(ssi_width_samples_); - } + pitch_h = static_cast<float>(pitch_index) / cycle_samples; } - // Copy the buffer from input to output, addressing by h-value + // Copy the buffer from input to output, addressing by h-value. for (int i = 0; i < ssi_width_samples_; ++i) { float h; - float cycle_samples = sample_rate_ / centre_frequency; if (log_cycles_axis_) { float gamma = gamma_min + (gamma_max - gamma_min) * static_cast<float>(i) @@ -213,7 +209,10 @@ if (do_smooth_offset_ && do_pitch_cutoff_) { // Smoothing around the pitch cutoff line. - weight *= (1.0f + tanh(smooth_pitch_constant * (pitch_h - h))) / 2.0f; + float pitch_weight = (1.0f + tanh((pitch_h - h) + * smooth_pitch_constant)) / 2.0f; + weight *= pitch_weight; + //LOG_INFO("Channel %d, Sample %d. Pitch weight: %f", ch, i, pitch_weight); } if (weight_by_scaling_) {
--- a/trunk/swig/aim_modules.i Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/swig/aim_modules.i Thu Oct 21 01:46:39 2010 +0000 @@ -38,6 +38,7 @@ #include "Modules/SSI/ModuleSSI.h" #include "Modules/Profile/ModuleSlice.h" #include "Modules/Profile/ModuleScaler.h" +#include "Modules/Features/ModuleGaussians.h" %} %include "Support/Parameters.h" @@ -77,3 +78,4 @@ %include "Modules/SSI/ModuleSSI.h" %include "Modules/Profile/ModuleSlice.h" %include "Modules/Profile/ModuleScaler.h" +%include "Modules/Features/ModuleGaussians.h"
--- a/trunk/swig/example.py Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/swig/example.py Thu Oct 21 01:46:39 2010 +0000 @@ -17,10 +17,11 @@ # limitations under the License. import aimc -params = aimc.Parameters() +module_params = aimc.Parameters() +global_params = aimc.Parameters() mod_gauss = aimc.ModuleGaussians(params) sig = aimc.SignalBank() sig.Initialize(115, 1, 44100) -mod_gauss.Initialize(sig) +mod_gauss.Initialize(sig, global_params) mod_gauss.Process(sig)
--- a/trunk/swig/setup.py Tue Oct 19 19:48:37 2010 +0000 +++ b/trunk/swig/setup.py Thu Oct 21 01:46:39 2010 +0000 @@ -29,6 +29,7 @@ '../src/Support/SignalBank.cc', '../src/Support/Module.cc', '../src/Modules/BMM/ModuleGammatone.cc', + '../src/Modules/Features/ModuleGaussians.cc', '../src/Modules/BMM/ModulePZFC.cc', '../src/Modules/NAP/ModuleHCL.cc', '../src/Modules/Strobes/ModuleParabola.cc',