protected function execute($arguments = array(), $options = array())
 {
     // initialize default context
     sfContext::createInstance(sfProjectConfiguration::getApplicationConfiguration('smint', 'dev', true));
     // initialize the database connection
     $databaseManager = new sfDatabaseManager($this->configuration);
     $connection = $databaseManager->getDatabase($options['connection'])->getConnection();
     // add your code here
     $tmpFilePath = smintUploadFileHelper::getUploadPath();
     $tmpfname = tempnam($tmpFilePath, "uploadscript.tmp");
     copy($options['filename'], $tmpfname);
     $newFile = new sfValidatedFile($options['filename'], "audio/mpeg", $tmpfname, null, $tmpFilePath);
     $fileInfo = smintUploadFileHelper::saveFile($newFile);
     //print_r($fileInfo);
     echo "originalFilename=" . urlencode($fileInfo["originalFilename"]) . "&existingUploadedFile=" . urlencode($fileInfo["filename"]) . "\n";
     unlink($tmpfname);
 }
示例#2
0
    /** Action that is called if file has been uploaded (metadata may have been entered)
     *
     */
    public function executeRelated(sfWebRequest $request)
    {
        try {
            // Load helpers
            $this->getContext()->getConfiguration()->loadHelpers('Asset');
            $this->getContext()->getConfiguration()->loadHelpers('Url');
            // get config
            $configFeaturevectortypeid = sfConfig::get('app_defaults_featurevectortypeid', 0);
            // get request params
            $reqparamtracknr = $request->getParameter('tracknr');
            $filename = $request->getParameter('uploadedFilename');
            $originalFilename = $request->getParameter('originalFilename');
            $metadataquery = $request->getParameter('metadataquery');
            // 2 possibilities: either tracknr is given or uploadedFilename
            if (isset($reqparamtracknr) && $reqparamtracknr != '' && $reqparamtracknr != 'undefined') {
                //get file via external key
                $tracknr = $reqparamtracknr;
                $fileForSearchSimilar = FilePeer::getFileByExternalKey($tracknr);
                //only if the file was found in the smafestore db
                if ($fileForSearchSimilar) {
                    $originalFilename = $fileForSearchSimilar->getUri();
                    $filesavepath = $fileForSearchSimilar->getUri();
                } else {
                    throw new Exception("Could not find file in database with external_key: {$tracknr}");
                }
                $bUploadedFile = false;
            } else {
                $originalFilename = $request->getParameter('originalFilename');
                $filesavepath = smintUploadFileHelper::getUploadPath() . $filename;
                $bUploadedFile = true;
            }
            // variables about segment selection
            //$reqparamStartSegment = '10000';
            // Start of segment in ms MOCKUP   10 to 20 seconds
            //$reqparamEndSegment = '20000';
            // end of segment in ms   MOCKUP
            $reqparamStartSegment = $request->getParameter('segmentStart');
            // Start of segment in ms
            $reqparamEndSegment = $request->getParameter('segmentEnd');
            $reqparamDuration = $request->getParameter('duration');
            // end of segment in ms
            $aSegmSearch = array('enabled' => false, 'startSegment' => 0, 'endSegment' => 0);
            //$bSegmSearch =			FALSE;										// boolean: is this segmented search? To be set later.
            //$startSegment;														// int value, to be set later
            //$endSegment; 															// int value, to be set later
            $empty_livequery = false;
            $empty_metadatafilteredquery = false;
            $omit_empty_metadataquery = $request->getParameter('omit_empty_metadataquery', false);
            ///// check validity of parameters
            if (isset($reqparamStartSegment)) {
                $aSegmSearch['startSegment'] = intval($reqparamStartSegment);
            }
            if (isset($reqparamEndSegment)) {
                $aSegmSearch['endSegment'] = intval($reqparamEndSegment);
            }
            if (isset($reqparamDuration)) {
                $aSegmSearch['duration'] = intval($reqparamDuration);
            }
            if (isset($reqparamStartSegment) && isset($reqparamEndSegment)) {
                mysfLog::log($this, "DEBUG: " . intval($reqparamStartSegment) . ", {$reqparamEndSegment}     " . $aSegmSearch['startSegment']);
            }
            // for selection, both start and end must be given and of type int and greater or equal 0
            // Note that the start and end times are set "inline"
            if (isset($reqparamStartSegment) && $aSegmSearch['startSegment'] > 0 || isset($reqparamEndSegment) && $aSegmSearch['endSegment'] > 0) {
                mysfLog::log($this, "DEBUG: Using segmented search with start-end in ms:" . $aSegmSearch['startSegment'] . " - " . $aSegmSearch['endSegment']);
                $aSegmSearch['enabled'] = TRUE;
            } else {
                mysfLog::log($this, "DEBUG: NOT using segmented search");
                $aSegmSearch['enabled'] = false;
            }
            $this->exec_result = smintSmafeHelper::queryFile($filesavepath, $aSegmSearch);
            $results = smintSmafeHelper::getResultsOnly($this->exec_result["output"]);
            //			$results = smintSmafeHelper::getResultsWithUri($this -> exec_result["output"]);
            // If we are here in a "search similar" scenario (track is in db, so it will be returned as result again)
            // we have to filter out the seed song
            if (!$bUploadedFile) {
                // do filtering
                $track_id_seed = $fileForSearchSimilar->getTrackId();
                $results_no_seed = array();
                foreach ($results as $key => $result) {
                    if ($result[0] != $track_id_seed) {
                        $results_no_seed[$key] = $result;
                    }
                }
                $results = $results_no_seed;
            }
            if (count($results) == 0) {
                $empty_livequery = true;
            }
            // filter with metadata
            // select external_key,genre from file left join filedesc on file.external_key = filedesc.tracknr where filedesc.genre ilike '%metadata%' and track_id IN ('31469', '31465') limit 10
            if (is_string($metadataquery) && strlen($metadataquery) > 0) {
                $bMDsearch = true;
                $filtered_results = $this->metadataFilter($results, $metadataquery);
                // omit metadata query if empty
                if ($omit_empty_metadataquery) {
                    if (count($filtered_results) > 0) {
                        // set results to filtered results if the metadata filter returns results
                        $results = $filtered_results;
                    } else {
                        $empty_metadatafilteredquery = true;
                    }
                } else {
                    $results = $filtered_results;
                }
            } else {
                $bMDsearch = false;
            }
            // reduce to maxresults
            $this->limit = $this->getContext()->getConfiguration()->getSmintMaxQueryResults();
            $this->results = array_slice($results, 0, $this->limit);
            //$this -> results = array_slice($results, 0, 50);
            ////// If this is segmented search, we perform re-ordering
            if ($aSegmSearch['enabled']) {
                // First, we get the length of the segments in samples
                mysfLog::log($this, "res " . print_r($this->results, true));
                $aResultsEnhanced = array();
                foreach ($this->results as $key => $value) {
                    // check for negative segmentnr (indicates non-segment server)
                    if ($value[1] < 0) {
                        //throw new Exception("Negative value for segment nr. Probably the smafe server is not configured for segmented search?");
                        // Set dummy segments (whole track)
                        array_push($aResultsEnhanced, array('track_id' => intval($value[0]), 'segmnr' => 0, 'dist' => doubleval($value[2]), 'start' => 0, 'end' => 0));
                    } else {
                        $fvsegm = FeaturevectorsegmentPeer::getInformationOnSegment($value[0], $value[1], $configFeaturevectortypeid);
                        $iSamplef = $fvsegm->getFile()->getSamplef();
                        array_push($aResultsEnhanced, array('track_id' => $fvsegm->getTrackId(), 'segmnr' => $fvsegm->getSegmentnr(), 'dist' => doubleval($value[2]), 'start' => intval($fvsegm->getStartsample() * 1000 / $iSamplef), 'end' => intval(($fvsegm->getStartsample() + $fvsegm->getLength()) * 1000 / $iSamplef)));
                        //$value[3] = $value[1] * 262144; 	// this is correct for 44100 Hz samples audio
                        //$value[4] = 262144; 						// this is correct for 44100 Hz samples audio
                    }
                }
                //mysfLog::log($this, "DEBUG: " . print_r($aResultsEnhanced, true));
                $aSegmSearch['resultsegments'] = array();
                // Structure of $aSegmSearch['resultsegments']:
                // first dim:
                //		each element corresponds to element at same position in $this -> results (and later: ->files)
                // second dim:
                //		list of result segments for given track
                // third dim:
                // 		assoc array with start and end time for this result segment
                // INPUT for the aggregation algo:
                // - $aResultsEnhanced
                // - $this->results
                // OUTPUT
                // - $this -> results					array of array[0]...track id , [1] segm nr, [2] distance
                // - $aSegmSearch['resultsegments']		(see above)
                switch (sfConfig::get('app_defaults_segm_search_aggregation_algo', 0)) {
                    case 0:
                        foreach ($aResultsEnhanced as $key => $value) {
                            // new segment
                            // conversion done from sample number to ms
                            array_push($aSegmSearch['resultsegments'], array(array('start' => $value['start'], 'end' => $value['end'], 'dist' => $value['dist'])));
                        }
                        break;
                    case 1:
                        // extract 1st column (track ids)
                        // do the actual work
                        //						$column = 0;
                        //					$result_trackids = array_map('array_slice', $this->results, array_fill(0, count( $this->results), $column), array_fill(0, count( $this->results), 1));
                        $result_trackids = array();
                        foreach ($this->results as $key => $value) {
                            array_push($result_trackids, $value[0]);
                        }
                        mysfLog::log($this, "DEBUG: " . print_r($result_trackids, true));
                        $unique = array();
                        foreach ($result_trackids as $key => $value) {
                            if (!in_array($value, $unique)) {
                                array_push($unique, $value);
                            }
                        }
                        //						$unique = array_unique($result_trackids);
                        //mysfLog::log($this, "DEBUG: " . print_r($unique, true));
                        foreach ($unique as $ukey => $uvalue) {
                            // segments for $value
                            $tmparray = array();
                            foreach ($aResultsEnhanced as $key => $value) {
                                if ($uvalue == $value['track_id']) {
                                    array_push($tmparray, array('start' => $value['start'], 'end' => $value['end'], 'dist' => $value['dist']));
                                }
                            }
                            // Sort result segments ascending in start time
                            $fCmpSegments = create_function('$a, $b', '
							
							if ($a[\'start\'] == $b[\'start\']) {
									return 0;
								} else if ($a[\'start\'] < $b[\'start\']) {
									return -1;
								} else {
									return 1;
								}
						
							');
                            usort($tmparray, $fCmpSegments);
                            // push segments to master array
                            array_push($aSegmSearch['resultsegments'], $tmparray);
                        }
                        //mysfLog::log($this, "DEBUG: " . print_r($aSegmSearch['resultsegments'], true));
                        $this->results = $unique;
                        break;
                    default:
                        throw new Exception("Bad value for app_defaults_segm_search_aggregation_algo: " . sfConfig::get('app_defaults_segm_search_aggregation_algo', 0));
                        break;
                }
            } else {
                // segmented search enabled
                // nothing to do, normal search
            }
            // segmented search enabled
            // not used in _result.php
            //			$this -> distances = smintSmafeHelper::getDistances($this -> results);
            $this->files = $this->queryMetadataDatabase($this->results);
            //mysfLog::log($this, "DEBUG: " . print_r($this -> files, true));
            // depending on whether it is an upload or not
            if ($bUploadedFile) {
                //tracknr is before underscore in filename
                $fileNameParts = explode("_", $filename);
                $tracknr = $fileNameParts[0];
                $uploadedFileURL = _compute_public_path($filename, 'uploads/mp3uploads', 'mp3', false);
                //url_for("getAudioFile/download") . "?uploaded=" . rawurlencode($filename);
                // the url for getting the file via PHP, but incomplete. Format parameter is missing and will be
                // appended in mp3 helper class
                $uploadedFilePHPUrl_incomplete = url_for("getAudioFile/download", true) . "?uploaded=" . rawurlencode(basename($filename));
                if ($aSegmSearch['enabled']) {
                    $seedLabel = intval(($aSegmSearch['endSegment'] - $aSegmSearch['startSegment']) / 1000) . " seconds from {$originalFilename}";
                    if ($bMDsearch) {
                        $seedlabel_topleft = "Seed track, results filtered by " . $metadataquery;
                    } else {
                        $seedlabel_topleft = "Seed track";
                    }
                } else {
                    $seedLabel = $originalFilename;
                    if ($bMDsearch) {
                        $seedlabel_topleft = "Seed track, results filtered by " . $metadataquery;
                    } else {
                        $seedlabel_topleft = "Seed track";
                    }
                }
            } else {
                $queryFileMetadata = FiledescPeer::retrieveByPk($tracknr);
                $fileInfoName = $queryFileMetadata->getTitle() . " - " . $queryFileMetadata->getPerformers();
                $uploadedFilePHPUrl_incomplete = url_for("getAudioFile/download", true) . "?tracknr=" . rawurlencode($tracknr);
                $uploadedFileURL = smintUploadFileHelper::getDirectFileUrl($fileForSearchSimilar->getUri());
                $seedLabel = $fileInfoName;
                if ($bMDsearch) {
                    $seedlabel_topleft = "Acoustic similarity, filtered by " . $metadataquery;
                } else {
                    $seedlabel_topleft = "Acoustic similarity";
                }
            }
            return $this->renderPartial('search/result', array('render' => 'related', 'id_prefix' => "id_prefix", 'tracknr' => $tracknr, 'uploadedFilePHPUrl_incomplete' => $uploadedFilePHPUrl_incomplete, 'uploadedFileURL' => $uploadedFileURL, 'files' => $this->files, 'queryTrackIsUploaded' => true, 'seedLabel' => $seedLabel, 'limit' => $this->limit, 'metadataquery' => $metadataquery, 'empty_livequery' => $empty_livequery, 'empty_metadatafilteredquery' => $empty_metadatafilteredquery, 'aSegmSearch' => $aSegmSearch, 'seedlabel_topleft' => $seedlabel_topleft));
        } catch (Exception $e) {
            // an error occoured while trying to query the file
            mysfLog::log($this, "STARTING the QUERY failed: " . $e->getMessage());
            return $this->renderPartial('search/error', array('error_message' => $e->getMessage()));
        }
    }
示例#3
0
 /** provides the file as download/streaming
  * Request params:
  * - tracknr
  * - fileid
  * - uploaded
  * 		( either tracknr or fileid or uploaded is required)
  * - format		optional. One of: mp3, ogg. If format is given, the file is converted to the given format, using command line invocations that are configured in app.yml
  *
  *
  */
 public function executeDownload(sfWebRequest $request)
 {
     // write session, so it won't lock other requests
     session_write_close();
     $reqparamUploaded = $this->getRequestParameter('uploaded');
     if ($reqparamUploaded) {
         $filename = smintUploadFileHelper::getUploadPath() . $reqparamUploaded;
     } else {
         $tracknr = $this->getRequestParameter('tracknr');
         if ($tracknr) {
             $file = FilePeer::getFileByExternalKey($tracknr);
             $filekey = $tracknr;
         } else {
             # check if file.id is given
             $fileid = $this->getRequestParameter('fileid');
             $file = FilePeer::retrieveByPK($fileid);
             $filekey = $fileid;
         }
         //check if a file was found matching tracknr, else exit with 404
         if ($file) {
             $filename = $file->getUri();
         } else {
             $this->forward404("file not found in database.");
         }
     }
     //check if a tracknr is given, otherwise exit with 404
     if (!$filename) {
         $this->forward404("Invalid query! Provide tracknr, fileid or uploaded to get a file.");
     }
     if (file_exists($filename)) {
         //check if file is inside the folder configured in smint/config/app.yml
         // or inside the upload folder
         $mp3Path = dirname(sfConfig::get('app_files_mp3path') . "/file");
         if (strpos($filename, $mp3Path) === false && strpos($filename, smintUploadFileHelper::getUploadPath()) === false) {
             $this->forward404("file: {$filename} is outside of the configured path (app.yml): {$mp3Path}. Accessing files outside the path is not allowed. Check app.yml and URI in file table.");
         }
         // -----------------------------------------------
         // -------------- check for format --------------
         // if no format is given,
         $reqparamFormat = $this->getRequestParameter('format');
         if ($reqparamFormat) {
             if (substr($filename, -3) === $reqparamFormat) {
                 mysfLog::log($this, "INFO: format parameter equals original audio file suffix. No conversion.");
                 if ($reqparamFormat === "mp3") {
                     $contenttype = "audio/mpeg";
                 } else {
                     $contenttype = "audio/{$reqparamFormat}";
                 }
             } else {
                 // conversion
                 if ($reqparamFormat === "ogg") {
                     $filename = smintFileserverHelper::doFileConversion($filename, $reqparamFormat);
                     $contenttype = "audio/ogg";
                 } else {
                     if ($reqparamFormat === "mp3") {
                         $filename = smintFileserverHelper::doFileConversion($filename, $reqparamFormat);
                         $contenttype = "audio/mpeg";
                     } else {
                         if ($reqparamFormat === "waveform") {
                             $filename = smintFileserverHelper::doFileConversion($filename, $reqparamFormat);
                             $contenttype = "application/txt";
                         } else {
                             if ($reqparamFormat === "png") {
                                 $waveformfilename = smintFileserverHelper::doFileConversion($filename, "waveform");
                                 $wfdata = split(", ", file_get_contents($waveformfilename));
                                 //mysfLog::log($this, print_r($wfdata, true));
                                 // how much detail we want. Larger number means less detail
                                 // (basically, how many bytes/frames to skip processing)
                                 // the lower the number means longer processing time
                                 // EP: in SMINT we do not chagne this. To change the detail, edit your waveform_resolution
                                 // config param in app.yml!
                                 define("DETAIL", 1);
                                 // get user vars from form
                                 $width = $this->getRequestParameter('width') ? rawurldecode($this->getRequestParameter('width')) : 640;
                                 $height = $this->getRequestParameter('height') ? rawurldecode($this->getRequestParameter('height')) : 100;
                                 $foreground = $this->getRequestParameter('fg') ? rawurldecode($this->getRequestParameter('fg')) : "#4D4D4D";
                                 $background = $this->getRequestParameter('bg') ? rawurldecode($this->getRequestParameter('bg')) : "#ffffff";
                                 $maxval = 0;
                                 $factor = sfConfig::get('app_defaults_waveform_factor', 0.8);
                                 // create original image width based on amount of detail
                                 $img = imagecreatetruecolor(sizeof($wfdata) / DETAIL, $height);
                                 // apply factor to the data
                                 //$wfdata_factor = array_map("this->pow_func", $wfdata);
                                 for ($i = 0; $i < sizeof($wfdata); $i += DETAIL) {
                                     $wfdata[$i] = pow(abs($wfdata[$i]), $factor);
                                 }
                                 $datamaxval = max(array_map("abs", $wfdata));
                                 $normconstant = doubleval($height) / doubleval($datamaxval);
                                 for ($i = 0; $i < sizeof($wfdata); $i += DETAIL) {
                                     $wfdata[$i] = $wfdata[$i] * $normconstant;
                                 }
                                 /*
                                 						for ($i = 0; $i < sizeof($wfdata); $i += DETAIL) {
                                 
                                 							if (abs($wfdata[$i]) > $maxval) {
                                 								$maxval = $wfdata[$i];
                                 							}
                                 						}
                                 						if ($maxval < 40) {
                                 							for ($i = 0; $i < sizeof($wfdata); $i += DETAIL) {
                                 								$wfdata[$i] = pow(abs($wfdata[$i]), 1.4);
                                 							}
                                 						}
                                  * */
                                 // fill background of image
                                 if ($background == "") {
                                     imagesavealpha($img, true);
                                     $transparentColor = imagecolorallocatealpha($img, 0, 0, 0, 127);
                                     imagefill($img, 0, 0, $transparentColor);
                                 } else {
                                     list($r, $g, $b) = smintTools::html2rgb($background);
                                     imagefilledrectangle($img, 0, 0, sizeof($wfdata) / DETAIL, $height, imagecolorallocate($img, $r, $g, $b));
                                 }
                                 // generate foreground color
                                 list($r, $g, $b) = smintTools::html2rgb($foreground);
                                 // loop through frames/bytes of wav data as genearted above
                                 for ($d = 0; $d < sizeof($wfdata); $d += DETAIL) {
                                     // relative value based on height of image being generated
                                     // data values can range between -127 and 128
                                     $v = $wfdata[$d];
                                     //$v = pow($v, sfConfig::get('app_defaults_waveform_factor', 0.8));
                                     // draw the line on the image using the $v value and centering it vertically on the canvas
                                     imageline($img, $d / DETAIL, ($height - $v) / 2, $d / DETAIL, ($height + $v) / 2, imagecolorallocate($img, $r, $g, $b));
                                 }
                                 // want it resized?
                                 if ($width != imagesx($img)) {
                                     // resample the image to the proportions defined in the form
                                     $rimg = imagecreatetruecolor($width, $height);
                                     // save alpha from original image
                                     imagesavealpha($rimg, true);
                                     imagealphablending($rimg, false);
                                     // copy to resized
                                     imagecopyresampled($rimg, $img, 0, 0, 0, 0, $width, $height, sizeof($wfdata) / DETAIL, $height);
                                     $img = $rimg;
                                 }
                                 $contenttype = "image/png";
                                 header("Content-type: {$contenttype}");
                                 imagepng($img);
                                 imagedestroy($img);
                                 // dont render view
                                 return sfView::NONE;
                             } else {
                                 $error_message = "ERROR: Format {$reqparamFormat} not valid";
                                 mysfLog::log($this, $error_message);
                                 throw new Exception($error_message);
                             }
                         }
                     }
                 }
             }
         } else {
             mysfLog::log($this, "INFO: format parameter not given, sending the original file ");
             // assuming file ending as content type. Just an approximation
             $contenttype = "audio/" . substr($filename, -3);
         }
         // do a redirect to file to have apache handle it
         $this->redirect(smintUploadFileHelper::getDirectFileUrl_for_uploads($filename));
         /* alternate version of redirect (not using symf framework)
         			 * does not work better :-(
         			 *
         			 $url = smintUploadFileHelper::getDirectFileUrl_for_uploads($filename);
         			 $statusCode = 302;
         			 // redirect
         			 $response = $this->context->getResponse();
         			 $response->clearHttpHeaders();
         			 $response->setStatusCode($statusCode);
         			 $response->setHttpHeader('Location', $url);
         			 $response->send();
         
         			 throw new sfStopException();
         			 // we do not reach this part b/o the redirect!
         			 *
         			 */
         // ------------ delegate to helper for download
         // serves file, obeying the range header
         smintFileserverHelper::serve_file_resumable($this->getResponse(), $filename, $contenttype);
         // dont render view
         return sfView::NONE;
         //return sfView::HEADER_ONLY;
     } else {
         $missingfile = $filename ? $filename : "No filename found!";
         $this->forward404("file for tracknr:  not found: " . $missingfile);
     }
 }
示例#4
0
 public function configure()
 {
     $this->setWidgets(array('mp3' => new sfWidgetFormInputFile(array(), array('size' => 30)), 'metadataquery' => new sfWidgetFormInputText()));
     $this->setValidators(array('metadataquery' => new sfValidatorString(array('required' => false)), 'mp3' => new sfValidatorFile(array('required' => true, 'max_size' => '30000000', 'path' => smintUploadFileHelper::getUploadPath()))));
     $this->widgetSchema->setNameFormat('fileupload[%s]');
 }
示例#5
0
 /**
  * Performs the file conversion, ie, calls external tool, checks if it worked correctly, and returns the filename of the output file
  * Note that the output files can be deleted safely. On the other hand this function also checks if the file has already been converted.
  * If so, it will not be converted a second time.
  * @param filename the filename including path (local)
  * @param formatcode Currently these codes are supported:
  * 				- ogg
  * 				- mp3
  * 				- waveform
  *				- waveformpng 					
  *
  *
  * 			To add another type:
  * 				- Add command_XXX in app.yml. The command must follow the same conventions as command_mp3 and _ogg ($INfile, ...)
  * 				- XXX is also used as the file suffix for the output file
  */
 public static function doFileConversion($filename, $formatcode = "ogg")
 {
     $exec_output = array();
     $exec_err = array();
     $current_date = date("_Ymd_His_");
     // get command as configured in app.yml
     $exec_cmd_raw = mysfConfig::get('app_conversion_setting_command_' . $formatcode, "");
     // replace placeholder with real file name, infile
     $exec_cmd = str_replace('$INfile', escapeshellcmd($filename), $exec_cmd_raw);
     // replace outfile placeholder. outfile is : upload dir, basename of infile, and ogg suffix
     if ($formatcode === 'waveform') {
         // extra file ending for waveform, since waveform is not recognized by apache
         $outfile = smintUploadFileHelper::getUploadPath() . basename($filename) . "." . $formatcode . ".txt";
     } else {
         $outfile = smintUploadFileHelper::getUploadPath() . basename($filename) . "." . $formatcode;
     }
     $exec_cmd = str_replace('$OUTfile', escapeshellcmd($outfile), $exec_cmd);
     // check for pixels per second variable. If found, replace it with config param
     if (substr_count($exec_cmd, '$PIXELSPERSECOND') > 0) {
         $pixelspersecond = sfConfig::get('app_defaults_waveform_resolution');
         $exec_cmd = str_replace('$PIXELSPERSECOND', escapeshellcmd($pixelspersecond), $exec_cmd);
     }
     $exec_cmd_escaped = $exec_cmd;
     // before conversion check if file exists already
     if (file_exists($outfile)) {
         mysfLog::log(self::$context, "INFO: file {$outfile} exists, using it.");
     } else {
         mysfLog::log(self::$context, "INFO: starting conversion. Command = {$exec_cmd_escaped}");
         // executing, redirecting stderr to stdout
         exec($exec_cmd_escaped . " 2>&1", $exec_err, $exec_result);
         if ($exec_result != 0 || !file_exists($outfile)) {
             $result_array = array("command" => $exec_cmd_escaped, "result" => $exec_result, "error" => $exec_err);
             $error_message = "ERROR during conversion. " . print_r($result_array, true);
             mysfLog::log(self::$context, $error_message);
             throw new Exception($error_message);
         }
         mysfLog::log(self::$context, "INFO: conversion done");
     }
     return $outfile;
 }