/**************************************************************************** | Digital Audio Processor | ======================= | | Filename : DPTich_macros.cc | | Object : None | | Description : Macro handler code file | | (c) Richard Kent 1997 | | $Id: DPTich_macros.cc,v 1.3 2003/09/10 00:30:40 rk Exp $ | ****************************************************************************/ static char DPTich_macros_cc [] = "$Id: DPTich_macros.cc,v 1.3 2003/09/10 00:30:40 rk Exp $"; #include "DPTich_macros.h" #include "libaudiofile/audiofile.h" int localMacrosUsed = FALSE; int numberMacros = 0; int currentMacro = -1; macroType macro [MAXMACROS]; #define ENDAIFFMACRO \ { \ delete [] reloadFilename; \ delete [] tempOutputFilename; \ delete [] filename; \ return 0; \ } #define REMOVETEMPFILES \ { \ if (macro [macroNumber].output == MACRODIALOGOUTPUT) \ if (remove (tempOutputFilename) == -1) \ fl_show_alert ("Warning", \ "Unable to remove temporary output file", \ tempOutputFilename,TRUE); \ if (reloadUsed) \ if (remove (reloadFilename) == -1) \ fl_show_alert ("Warning", \ "Unable to remove temporary reload file", \ reloadFilename,TRUE); \ if (macro [macroNumber].processMode == MACROTEMPAIFFMODE) \ if (remove (filename) == -1) \ fl_show_alert ("Warning", \ "Unable to remove temporary save file", \ filename,TRUE); \ } /*--------------------------------------------------------------------------- | FUNCTION loadMacros ---------------------------------------------------------------------------*/ int loadMacros () { char *directory = 0; char *filename = 0; FILE *file = 0; int macrosFound; macrosFound = FALSE; directory = getenv ("HOME"); if (!localMacrosUsed && directory) { filename = new char [strlen (directory) + strlen (MACROSNAME) + 2]; strcpy (filename,directory); if (strlen (filename) > 0 && filename [strlen (filename) - 1] != '/') strcat (filename,"/"); strcat (filename,MACROSNAME); file = fopen (filename,"r"); if (file) macrosFound = TRUE; else delete [] filename; } if (!macrosFound) { directory = "."; filename = new char [strlen (directory) + strlen (MACROSNAME) + 2]; strcpy (filename,directory); if (strlen (filename) > 0 && filename [strlen (filename) - 1] != '/') strcat (filename,"/"); strcat (filename,MACROSNAME); file = fopen (filename,"r"); if (file) { macrosFound = TRUE; localMacrosUsed = TRUE; } else delete [] filename; } if (!macrosFound) return FALSE; // Read in macros const int tempStringLen = 128; const char delimiters [] = " \t\n"; const char textDelimiters [] = "\n"; char tempString [tempStringLen]; char *token; int i; i = numberMacros; if (i == MAXMACROS) fl_show_alert ("Warning","Cannot load macro", "Maximum number of macros reached",TRUE); while (i < MAXMACROS && readLine (file,tempString,tempStringLen)) { if (!strlen (tempString)) continue; token = strtok (tempString,delimiters); if (!token) continue; if (!strcasecmp (token,"Name:")) { token = strtok (NULL,textDelimiters); if (token) { int firstNonSpace = findNonSpace (token); strncpy (macro [i].name,token + firstNonSpace,MACRONAMELENGTH); } } else if (!strcasecmp (token,"BufferMode:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"CurrentBuffer")) macro [i].bufferMode = MACROCURRENTBUFFER; else if (!strcasecmp (token,"AllBuffers")) macro [i].bufferMode = MACROALLBUFFERS; } } else if (!strcasecmp (token,"ProcessMode:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"Raw")) macro [i].processMode = MACRORAWMODE; else if (!strcasecmp (token,"Text")) macro [i].processMode = MACROTEXTMODE; else if (!strcasecmp (token,"TempAiff")) macro [i].processMode = MACROTEMPAIFFMODE; else if (!strcasecmp (token,"SaveLoadAiff")) macro [i].processMode = MACROSAVEAIFFMODE; } } else if (!strcasecmp (token,"ChannelMode:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"Interleaved")) macro [i].channelMode = MACROINTERLEAVED; else if (!strcasecmp (token,"Separated")) macro [i].channelMode = MACROSEPARATED; } } else if (!strcasecmp (token,"Input:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"Buffer")) macro [i].input = MACROBUFFERINPUT; else if (!strcasecmp (token,"Range")) macro [i].input = MACRORANGEINPUT; else if (!strcasecmp (token,"EitherBufferOrRange")) macro [i].input = MACROEITHERINPUT; else if (!strcasecmp (token,"None")) macro [i].input = MACRONONEINPUT; } } else if (!strcasecmp (token,"Output:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"Buffer")) macro [i].output = MACROBUFFEROUTPUT; else if (!strcasecmp (token,"Dialog")) macro [i].output = MACRODIALOGOUTPUT; else if (!strcasecmp (token,"None")) macro [i].output = MACRONONEOUTPUT; } } else if (!strcasecmp (token,"DataFormat:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"Byte")) macro [i].dataFormat = MACROBYTEFORMAT; else if (!strcasecmp (token,"Short")) macro [i].dataFormat = MACROSHORTFORMAT; else if (!strcasecmp (token,"Long24")) macro [i].dataFormat = MACROLONG24FORMAT; else if (!strcasecmp (token,"Long32")) macro [i].dataFormat = MACROLONG32FORMAT; else if (!strcasecmp (token,"Float")) macro [i].dataFormat = MACROFLOATFORMAT; else if (!strcasecmp (token,"Double")) macro [i].dataFormat = MACRODOUBLEFORMAT; } } else if (!strcasecmp (token,"DataSigned:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"Signed")) macro [i].dataSigned = MACROSIGNED; else if (!strcasecmp (token,"Unsigned")) macro [i].dataSigned = MACROUNSIGNED; } } else if (!strcasecmp (token,"Endian:")) { token = strtok (NULL,delimiters); if (token) { if (!strcasecmp (token,"Big")) macro [i].endian = MACROBIGENDIAN; else if (!strcasecmp (token,"Little")) macro [i].endian = MACROLITTLEENDIAN; else if (!strcasecmp (token,"Default")) macro [i].endian = MACRODEFENDIAN; } } else if (!strcasecmp (token,"Command:")) { token = strtok (NULL,textDelimiters); if (token) { int firstNonSpace = findNonSpace (token); strncpy (macro [i].command,token + firstNonSpace,MACROCOMMANDLENGTH); } } else if (!strcasecmp (token,"EndMacro")) { fl_addto_browser (macroForm->browser,macro [i].name); fl_addto_browser (macroexecForm->browser,macro [i].name); numberMacros++; i++; } } fclose (file); delete [] filename; updateMacroForm (); macrosChanged = FALSE; return TRUE; } /*--------------------------------------------------------------------------- | FUNCTION saveMacros ---------------------------------------------------------------------------*/ int saveMacros () { char *directory = 0; char *filename = 0; FILE *file = 0; int macrosFound; macrosFound = FALSE; directory = getenv ("HOME"); if (!localMacrosUsed && directory) { filename = new char [strlen (directory) + strlen (MACROSNAME) + 2]; strcpy (filename,directory); if (strlen (filename) > 0 && filename [strlen (filename) - 1] != '/') strcat (filename,"/"); strcat (filename,MACROSNAME); file = fopen (filename,"w"); if (file) macrosFound = TRUE; else delete [] filename; } if (!macrosFound) { directory = ""; filename = new char [strlen (directory) + strlen (MACROSNAME) + 2]; strcpy (filename,directory); if (strlen (filename) > 0 && filename [strlen (filename) - 1] != '/') strcat (filename,"/"); strcat (filename,MACROSNAME); file = fopen (filename,"w"); if (file) { macrosFound = TRUE; localMacrosUsed = TRUE; } else delete [] filename; } if (!macrosFound) return FALSE; // Write out macros int i; for (i=0; ibrowser); fl_clear_browser (macroexecForm->browser); macrosChanged = FALSE; fl_call_object_callback (macroForm->newButton); } /*--------------------------------------------------------------------------- | CALLBACK macroName_cb ---------------------------------------------------------------------------*/ void macroName_cb (FL_OBJECT *,long) { int i; const char *name = fl_safe_get_input (macroForm->name); if ((i = findMacro (name)) >= 0) { fl_select_browser_line (macroForm->browser,i + 1); fl_call_object_callback (macroForm->browser); } else { fl_deselect_browser (macroForm->browser); fl_call_object_callback (macroForm->storeButton); } } /*--------------------------------------------------------------------------- | CALLBACK macroCommand_cb ---------------------------------------------------------------------------*/ void macroCommand_cb (FL_OBJECT *,long) { const char *name = fl_safe_get_input (macroForm->name); if (findMacro (name) >= 0) fl_call_object_callback (macroForm->storeButton); else updateMacroForm (); } /*--------------------------------------------------------------------------- | CALLBACK macroButton_cb ---------------------------------------------------------------------------*/ void macroButton_cb (FL_OBJECT *,long) { const char *name = fl_safe_get_input (macroForm->name); if (findMacro (name) >= 0) fl_call_object_callback (macroForm->storeButton); else updateMacroForm (); } /*--------------------------------------------------------------------------- | CALLBACK macroBrowser_cb ---------------------------------------------------------------------------*/ void macroBrowser_cb (FL_OBJECT *,long) { int current = fl_get_browser (macroForm->browser) - 1; if (current >= 0 && current < numberMacros) { currentMacro = current; updateMacroForm (); } else { fl_deselect_browser (macroForm->browser); } } /*--------------------------------------------------------------------------- | CALLBACK macroNewButton_cb ---------------------------------------------------------------------------*/ void macroNewButton_cb (FL_OBJECT *,long) { currentMacro = -1; fl_set_input (macroForm->name,"Untitled"); fl_set_input (macroForm->command,""); fl_set_button (macroForm->currentBuffer,1); fl_set_button (macroForm->pipeRaw,1); fl_set_button (macroForm->interleavedButton,1); fl_set_button (macroForm->byteButton,1); fl_set_button (macroForm->signedButton,1); fl_set_button (macroForm->noneInput,1); fl_set_button (macroForm->noneOutput,1); fl_deselect_browser (macroForm->browser); updateMacroForm (); } /*--------------------------------------------------------------------------- | CALLBACK macroExecuteButton_cb ---------------------------------------------------------------------------*/ void macroExecuteButton_cb (FL_OBJECT *,long) { DPSample *sample = fl_get_sample (mainForm->sample); const char *name = fl_safe_get_input (macroForm->name); char *errorMessage; int macroNumber; if ((macroNumber = findMacro (name)) >= 0 && macro [macroNumber].output == MACROBUFFEROUTPUT) updateBuffers ("Undo macro"); waitCursorOn (); errorMessage = executeMacro (name); waitCursorOff (); if (errorMessage) fl_show_alert ("Warning","Cannot execute macro",errorMessage,TRUE); updateSample (sample); } /*--------------------------------------------------------------------------- | CALLBACK macroStoreButton_cb ---------------------------------------------------------------------------*/ void macroStoreButton_cb (FL_OBJECT *,long) { int i; const char *name = fl_safe_get_input (macroForm->name); const char *cmd; // Check for inconsistencies and sort them out if (fl_get_button (macroForm->aiffTemp)) { if (fl_get_button (macroForm->noneInput)) fl_set_button (macroForm->eitherInput,1); } else if (fl_get_button (macroForm->aiffSave)) { if (!fl_get_button (macroForm->bufferInput)) fl_set_button (macroForm->bufferInput,1); } if ((i = findMacro (name)) < 0) { if (numberMacros == MAXMACROS) { fl_show_alert ("Warning","Maximum number of macros stored", "Please remove a macro before storing a new one",TRUE); return; } if (strlen (name) < 1) return; i = numberMacros; numberMacros++; strncpy (macro [i].name,name,MACRONAMELENGTH); fl_addto_browser (macroForm->browser,macro [i].name); fl_addto_browser (macroexecForm->browser,macro [i].name); } if (fl_get_button (macroForm->currentBuffer)) macro [i].bufferMode = MACROCURRENTBUFFER; else macro [i].bufferMode = MACROALLBUFFERS; if (fl_get_button (macroForm->pipeRaw)) macro [i].processMode = MACRORAWMODE; else if (fl_get_button (macroForm->pipeText)) macro [i].processMode = MACROTEXTMODE; else if (fl_get_button (macroForm->aiffTemp)) macro [i].processMode = MACROTEMPAIFFMODE; else macro [i].processMode = MACROSAVEAIFFMODE; if (fl_get_button (macroForm->interleavedButton)) macro [i].channelMode = MACROINTERLEAVED; else macro [i].channelMode = MACROSEPARATED; if (fl_get_button (macroForm->byteButton)) macro [i].dataFormat = MACROBYTEFORMAT; else if (fl_get_button (macroForm->shortButton)) macro [i].dataFormat = MACROSHORTFORMAT; else if (fl_get_button (macroForm->long24Button)) macro [i].dataFormat = MACROLONG24FORMAT; else if (fl_get_button (macroForm->long32Button)) macro [i].dataFormat = MACROLONG32FORMAT; else if (fl_get_button (macroForm->floatButton)) macro [i].dataFormat = MACROFLOATFORMAT; else macro [i].dataFormat = MACRODOUBLEFORMAT; if (fl_get_button (macroForm->signedButton)) macro [i].dataSigned = MACROSIGNED; else macro [i].dataSigned = MACROUNSIGNED; if (fl_get_button (macroForm->bigEndianButton)) macro [i].endian = MACROBIGENDIAN; else if (fl_get_button (macroForm->littleEndianButton)) macro [i].endian = MACROLITTLEENDIAN; else macro [i].endian = MACRODEFENDIAN; if (fl_get_button (macroForm->bufferInput)) macro [i].input = MACROBUFFERINPUT; else if (fl_get_button (macroForm->rangeInput)) macro [i].input = MACRORANGEINPUT; else if (fl_get_button (macroForm->eitherInput)) macro [i].input = MACROEITHERINPUT; else macro [i].input = MACRONONEINPUT; if (fl_get_button (macroForm->bufferOutput)) macro [i].output = MACROBUFFEROUTPUT; else if (fl_get_button (macroForm->dialogOutput)) macro [i].output = MACRODIALOGOUTPUT; else macro [i].output = MACRONONEOUTPUT; cmd = fl_safe_get_input (macroForm->command); strncpy (macro [i].command,cmd,MACROCOMMANDLENGTH); currentMacro = i; fl_select_browser_line (macroForm->browser,currentMacro + 1); macrosChanged = TRUE; updateMacroForm (); } /*--------------------------------------------------------------------------- | CALLBACK macroDeleteButton_cb ---------------------------------------------------------------------------*/ void macroDeleteButton_cb (FL_OBJECT *,long) { int i; int j; if ((i = currentMacro) >= 0) { for (j=i; j<(numberMacros-1); j++) { strcpy (macro [j].name,macro [j+1].name); macro [j].bufferMode = macro [j+1].bufferMode; macro [j].processMode = macro [j+1].processMode; macro [j].channelMode = macro [j+1].channelMode; macro [j].input = macro [j+1].input; macro [j].output = macro [j+1].output; macro [j].dataFormat = macro [j+1].dataFormat; macro [j].dataSigned = macro [j+1].dataSigned; macro [j].endian = macro [j+1].endian; strcpy (macro [j].command,macro [j+1].command); } fl_deselect_browser (macroForm->browser); fl_delete_browser_line (macroForm->browser,i + 1); fl_delete_browser_line (macroexecForm->browser,i + 1); numberMacros--; macrosChanged = TRUE; if (currentMacro >= numberMacros) currentMacro = numberMacros - 1; if (currentMacro < 0) fl_call_object_callback (macroForm->newButton); updateMacroForm (); } else { fl_call_object_callback (macroForm->newButton); } } /*--------------------------------------------------------------------------- | CALLBACK macroOK_cb ---------------------------------------------------------------------------*/ void macroOK_cb (FL_OBJECT *,long) { fl_hide_form (macroForm->macroForm); } /*--------------------------------------------------------------------------- | CALLBACK macroInfoButton_cb ---------------------------------------------------------------------------*/ void macroInfoButton_cb (FL_OBJECT *,long) { fl_show_form (macroinfoForm->macroinfoForm, FL_PLACE_MOUSE,FL_FULLBORDER,"Macro Information"); } /*--------------------------------------------------------------------------- | CALLBACK macroinfoOK_cb ---------------------------------------------------------------------------*/ void macroinfoOK_cb (FL_OBJECT *,long) { fl_hide_form (macroinfoForm->macroinfoForm); } /*--------------------------------------------------------------------------- | CALLBACK macrooutputOK_cb ---------------------------------------------------------------------------*/ void macrooutputOK_cb (FL_OBJECT *ob,long) { fl_hide_form (ob->form); fl_free_form (ob->form); } /*--------------------------------------------------------------------------- | CALLBACK macroexecName_cb ---------------------------------------------------------------------------*/ void macroexecName_cb (FL_OBJECT *,long) { } /*--------------------------------------------------------------------------- | CALLBACK macroexecBrowserDbl_cb ---------------------------------------------------------------------------*/ void macroexecBrowserDbl_cb (FL_OBJECT *,long) { fl_call_object_callback (macroexecForm->browser); fl_call_object_callback (macroexecForm->OK); } /*--------------------------------------------------------------------------- | CALLBACK macroexecBrowser_cb ---------------------------------------------------------------------------*/ void macroexecBrowser_cb (FL_OBJECT *,long) { int i = fl_get_browser (macroexecForm->browser) - 1; if (i >= 0 && i < numberMacros) fl_set_input (macroexecForm->name,macro [i].name); else fl_set_input (macroexecForm->name,""); } /*--------------------------------------------------------------------------- | CALLBACK macroexecOK_cb ---------------------------------------------------------------------------*/ void macroexecOK_cb (FL_OBJECT *,long) { DPSample *sample = fl_get_sample (mainForm->sample); const char *name = fl_safe_get_input (macroexecForm->name); char *errorMessage; int macroNumber; if ((macroNumber = findMacro (name)) >= 0 && macro [macroNumber].output == MACROBUFFEROUTPUT) updateBuffers ("Undo macro"); waitCursorOn (); errorMessage = executeMacro (name); waitCursorOff (); if (errorMessage) fl_show_alert ("Warning","Cannot execute macro",errorMessage,TRUE); updateSample (sample); } /*--------------------------------------------------------------------------- | CALLBACK macroexecCancel_cb ---------------------------------------------------------------------------*/ void macroexecCancel_cb (FL_OBJECT *,long) { fl_hide_form (macroexecForm->macroexecForm); } /*--------------------------------------------------------------------------- | FUNCTION updateMacroForm ---------------------------------------------------------------------------*/ void updateMacroForm (void) { // Check for inconsistencies and sort them out if (fl_get_button (macroForm->aiffTemp)) { if (fl_get_button (macroForm->noneInput)) fl_set_button (macroForm->eitherInput,1); } else if (fl_get_button (macroForm->aiffSave)) { if (!fl_get_button (macroForm->bufferInput)) fl_set_button (macroForm->bufferInput,1); } if (currentMacro >= numberMacros) currentMacro = -1; if (currentMacro < 0) { fl_deselect_browser (macroForm->browser); fl_set_input (macroForm->name,"Untitled"); fl_set_input (macroForm->command,""); fl_set_button (macroForm->currentBuffer,1); fl_set_button (macroForm->pipeRaw,1); fl_set_button (macroForm->interleavedButton,1); fl_set_button (macroForm->byteButton,1); fl_set_button (macroForm->signedButton,1); fl_set_button (macroForm->defaultEndianButton,1); fl_set_button (macroForm->noneInput,1); fl_set_button (macroForm->noneOutput,1); } else { int i = currentMacro; fl_set_input (macroForm->name,macro [i].name); fl_set_input (macroForm->command,macro [i].command); switch (macro [i].bufferMode) { case MACROCURRENTBUFFER : fl_set_button (macroForm->currentBuffer,1); break; case MACROALLBUFFERS : fl_set_button (macroForm->allBuffers,1); break; default : break; } switch (macro [i].processMode) { case MACRORAWMODE : fl_set_button (macroForm->pipeRaw,1); break; case MACROTEXTMODE : fl_set_button (macroForm->pipeText,1); break; case MACROTEMPAIFFMODE : fl_set_button (macroForm->aiffTemp,1); break; case MACROSAVEAIFFMODE : fl_set_button (macroForm->aiffSave,1); break; default : break; } switch (macro [i].channelMode) { case MACROINTERLEAVED : fl_set_button (macroForm->interleavedButton,1); break; case MACROSEPARATED : fl_set_button (macroForm->separatedButton,1); break; default : break; } switch (macro [i].dataFormat) { case MACROBYTEFORMAT : fl_set_button (macroForm->byteButton,1); break; case MACROSHORTFORMAT : fl_set_button (macroForm->shortButton,1); break; case MACROLONG24FORMAT : fl_set_button (macroForm->long24Button,1); break; case MACROLONG32FORMAT : fl_set_button (macroForm->long32Button,1); break; case MACROFLOATFORMAT : fl_set_button (macroForm->floatButton,1); break; case MACRODOUBLEFORMAT : fl_set_button (macroForm->doubleButton,1); break; default : break; } switch (macro [i].dataSigned) { case MACROSIGNED : fl_set_button (macroForm->signedButton,1); break; case MACROUNSIGNED : fl_set_button (macroForm->unsignedButton,1); break; default : break; } switch (macro [i].endian) { case MACROBIGENDIAN : fl_set_button (macroForm->bigEndianButton,1); break; case MACROLITTLEENDIAN : fl_set_button (macroForm->littleEndianButton,1); break; case MACRODEFENDIAN : fl_set_button (macroForm->defaultEndianButton,1); break; default : break; } switch (macro [i].input) { case MACROBUFFERINPUT : fl_set_button (macroForm->bufferInput,1); break; case MACRORANGEINPUT : fl_set_button (macroForm->rangeInput,1); break; case MACROEITHERINPUT : fl_set_button (macroForm->eitherInput,1); break; case MACRONONEINPUT : fl_set_button (macroForm->noneInput,1); break; default : break; } switch (macro [i].output) { case MACROBUFFEROUTPUT : fl_set_button (macroForm->bufferOutput,1); break; case MACRODIALOGOUTPUT : fl_set_button (macroForm->dialogOutput,1); break; case MACRONONEOUTPUT : fl_set_button (macroForm->noneOutput,1); break; default : break; } fl_select_browser_line (macroForm->browser,currentMacro + 1); } } /*--------------------------------------------------------------------------- | FUNCTION findMacro ---------------------------------------------------------------------------*/ int findMacro (const char *name) { int i=0; int found=FALSE; if (!name) return -1; while (i= 8) return "Illegal buffer number"; sample = buffer [bufferNumber]; if (macro [macroNumber].channelMode == MACROINTERLEAVED || sample->getChannels() == 1) { return executeSingleMacro (macroNumber,bufferNumber); } // Separated macro and more than one channel int i; char *errorMessage; int emulating = FALSE; int rangeStartBak = sample->getRangeStart (); int rangeEndBak = sample->getRangeEnd (); int rangeValidBak = sample->getRangeValid (); int inputModeBak = macro [macroNumber].input; int editModeBak = fl_get_sample_edit (mainForm->sample); if (macro [macroNumber].input == MACROBUFFERINPUT || (macro [macroNumber].input == MACROEITHERINPUT && !sample->getRangeValid ())) { // Need to emulate buffer mode using range of whole sample emulating = TRUE; macro [macroNumber].input = MACRORANGEINPUT; } else if (fl_get_sample_edit (mainForm->sample) != 2) { // However, if single edit mode just do as normal return executeSingleMacro (macroNumber,bufferNumber); } // OK - multi-channel macro to be separated into different runs !! for (i=0; igetChannels(); i++) { // Set range to avoid differing ranges over channels if (emulating) { sample->rangeAll(); } else { sample->setRange (rangeStartBak,rangeEndBak); sample->setRangeValid (rangeValidBak); } if (i < 2) fl_set_sample_edit (mainForm->sample,i); else fl_set_sample_edit (mainForm->sample,i + 1); errorMessage = executeSingleMacro (macroNumber,bufferNumber); if (errorMessage) return errorMessage; } // Restore values fl_set_sample_edit (mainForm->sample,editModeBak); macro [macroNumber].input = inputModeBak; if (emulating) { sample->setRange (rangeStartBak,rangeEndBak); sample->setRangeValid (rangeValidBak); } return 0; } /*--------------------------------------------------------------------------- | FUNCTION executeSingleMacro ---------------------------------------------------------------------------*/ char *executeSingleMacro (int macroNumber,int bufferNumber) { // Can assume macroNumber is valid macro // Can assume bufferNumber is valid DPSample *sample; sample = buffer [bufferNumber]; if (macro [macroNumber].processMode == MACROSAVEAIFFMODE && !sample->getValid ()) return 0; // No error if (macro [macroNumber].processMode == MACROTEMPAIFFMODE && !sample->getValid ()) return 0; // No error if ((macro [macroNumber].input != MACRONONEINPUT || macro [macroNumber].output == MACROBUFFEROUTPUT) && !sample->getValid ()) return 0; // No error if (macro [macroNumber].input == MACRORANGEINPUT && !sample->getRangeValid ()) return 0; // No error switch (macro [macroNumber].processMode) { case MACRORAWMODE : case MACROTEXTMODE : { FILE *pipeFile; FILE *tempFile; const char *tempDir = fl_get_sample_tempdir (mainForm->sample); char *tempNameTemplate; char *mktempFileName; char *tempFileName; char *tempCommand; char *command = macro [macroNumber].command; int i; int j; signed char tempSignedChar; unsigned char tempUnsignedChar; signed short tempSignedShort; unsigned short tempUnsignedShort; signed int tempSignedLong; unsigned int tempUnsignedLong; float tempFloat; double tempDouble; tempNameTemplate = new char [strlen (tempDir) + 8]; strcpy (tempNameTemplate,tempDir); if (strlen (tempNameTemplate) > 0 && tempNameTemplate [strlen (tempNameTemplate) - 1] != '/') strcat (tempNameTemplate,"/"); strcat (tempNameTemplate,"XXXXXX"); mktempFileName = mktemp (tempNameTemplate); delete [] tempNameTemplate; if (!mktempFileName) { return "Unable to create temporary filename"; } tempFileName = new char [strlen (mktempFileName) + 1]; strcpy (tempFileName,mktempFileName); delete [] mktempFileName; tempCommand = new char [strlen (command) + 3 + strlen (tempFileName)]; strcpy (tempCommand,command); strcat (tempCommand," >"); strcat (tempCommand,tempFileName); pipeFile = popen (tempCommand,"w"); delete [] tempCommand; if (!pipeFile) { delete [] tempFileName; return "Cannot open pipe file"; } #ifdef BIGENDIAN setBigEndian (macro [macroNumber].endian == MACROBIGENDIAN || macro [macroNumber].endian == MACRODEFENDIAN); #else setBigEndian (macro [macroNumber].endian == MACROBIGENDIAN); #endif // Input to command if (macro [macroNumber].input != MACRONONEINPUT) { int inputStart; int inputEnd; int inputChannels; int inputSingleChannel; int inputSingleChannelNumber = 0; int inputSample; int finished; int editMode; inputChannels = sample->getChannels (); inputSingleChannel = FALSE; if (macro [macroNumber].input == MACROBUFFERINPUT || (macro [macroNumber].input == MACROEITHERINPUT && !sample->getRangeValid ())) { inputStart = 0; inputEnd = sample->getFrames (); } else { inputStart = sample->getRangeStart (); inputEnd = sample->getRangeEnd (); if ((editMode = fl_get_sample_edit (mainForm->sample)) != 2) { inputSingleChannel = TRUE; if (editMode < 2) inputSingleChannelNumber = editMode; else inputSingleChannelNumber = editMode - 1; } } finished = FALSE; if (macro [macroNumber].processMode == MACRORAWMODE) { for (i=inputStart; igetFrame24 (i,j); if (macro [macroNumber].dataSigned == MACROSIGNED) { switch (macro [macroNumber].dataFormat) { case MACROBYTEFORMAT : tempSignedChar = inputSample / 65536; if (cWriteF (pipeFile,tempSignedChar) != 1) finished = TRUE; break; case MACROSHORTFORMAT : tempSignedShort = inputSample / 256; if (sWriteF (pipeFile,tempSignedShort) != 1) finished = TRUE; break; case MACROLONG24FORMAT : tempSignedLong = inputSample; if (iWriteF (pipeFile,tempSignedLong) != 1) finished = TRUE; break; case MACROLONG32FORMAT : tempSignedLong = inputSample * 256; if (iWriteF (pipeFile,tempSignedLong) != 1) finished = TRUE; break; case MACROFLOATFORMAT : tempFloat = ((float) inputSample) / MAX23; if (fWriteF (pipeFile,tempFloat) != 1) finished = TRUE; break; case MACRODOUBLEFORMAT : tempDouble = ((double) inputSample) / MAX23; if (dWriteF (pipeFile,tempDouble) != 1) finished = TRUE; break; default : break; } } else { switch (macro [macroNumber].dataFormat) { case MACROBYTEFORMAT : tempUnsignedChar = inputSample / 65536 + MAX7; if (ucWriteF (pipeFile,tempUnsignedChar) != 1) finished = TRUE; break; case MACROSHORTFORMAT : tempUnsignedShort = inputSample / 256 + MAX15; if (usWriteF (pipeFile,tempUnsignedShort) != 1) finished = TRUE; break; case MACROLONG24FORMAT : tempUnsignedLong = inputSample + MAX23; if (uiWriteF (pipeFile,tempUnsignedLong) != 1) finished = TRUE; break; case MACROLONG32FORMAT : tempUnsignedLong = inputSample * 256 + MAX31; if (uiWriteF (pipeFile,tempUnsignedLong) != 1) finished = TRUE; break; case MACROFLOATFORMAT : tempFloat = ((float) inputSample) / MAX24 + 0.5; if (fWriteF (pipeFile,tempFloat) != 1) finished = TRUE; break; case MACRODOUBLEFORMAT : tempDouble = ((double) inputSample) / MAX24 + 0.5; if (dWriteF (pipeFile,tempDouble) != 1) finished = TRUE; break; default : break; } } } } } else { for (i=inputStart; igetFrame24 (i,j); if (macro [macroNumber].dataSigned == MACROSIGNED) { switch (macro [macroNumber].dataFormat) { case MACROBYTEFORMAT : tempSignedChar = inputSample / 65536; if (fprintf (pipeFile,"%d\n",tempSignedChar) <= 0) finished = TRUE; break; case MACROSHORTFORMAT : tempSignedShort = inputSample / 256; if (fprintf (pipeFile,"%hd\n",tempSignedShort) <= 0) finished = TRUE; break; case MACROLONG24FORMAT : tempSignedLong = inputSample; if (fprintf (pipeFile,"%d\n",tempSignedLong) <= 0) finished = TRUE; break; case MACROLONG32FORMAT : tempSignedLong = inputSample * 256; if (fprintf (pipeFile,"%d\n",tempSignedLong) <= 0) finished = TRUE; break; case MACROFLOATFORMAT : tempFloat = ((float) inputSample) / MAX23; if (fprintf (pipeFile,"%.20f\n",tempFloat) <= 0) finished = TRUE; break; case MACRODOUBLEFORMAT : tempDouble = ((double) inputSample) / MAX23; if (fprintf (pipeFile,"%.20f\n",tempDouble) <= 0) finished = TRUE; break; default : break; } } else { switch (macro [macroNumber].dataFormat) { case MACROBYTEFORMAT : tempUnsignedChar = inputSample / 65536 + MAX7; if (fprintf (pipeFile,"%u\n",tempUnsignedChar) <= 0) finished = TRUE; break; case MACROSHORTFORMAT : tempUnsignedShort = inputSample / 256 + MAX15; if (fprintf (pipeFile,"%hu\n",tempUnsignedShort) <= 0) finished = TRUE; break; case MACROLONG24FORMAT : tempUnsignedLong = inputSample + MAX23; if (fprintf (pipeFile,"%u\n",tempUnsignedLong) <= 0) finished = TRUE; break; case MACROLONG32FORMAT : tempUnsignedLong = inputSample * 256 + MAX31; if (fprintf (pipeFile,"%u\n",tempUnsignedLong) <= 0) finished = TRUE; break; case MACROFLOATFORMAT : tempFloat = ((float) inputSample) / MAX24 + 0.5; if (fprintf (pipeFile,"%.20f\n",tempFloat) <= 0) finished = TRUE; break; case MACRODOUBLEFORMAT : tempDouble = ((double) inputSample) / MAX24 + 0.5; if (fprintf (pipeFile,"%.20f\n",tempDouble) <= 0) finished = TRUE; break; default : break; } } } } } } pclose (pipeFile); // Output from command if (macro [macroNumber].output == MACRODIALOGOUTPUT) { FD_macrooutputForm *macrooutputForm; macrooutputForm = create_form_macrooutputForm (); fl_set_form_minsize (macrooutputForm->macrooutputForm,260,180); fl_set_form_atclose (macrooutputForm->macrooutputForm, closeMacroOutputForm, 0); if (!fl_load_browser (macrooutputForm->browser,tempFileName)) { delete [] tempFileName; return "Cannot load temp file into browser"; } changeBorderWidthForm (macrooutputForm->macrooutputForm, fl_get_sample_borderwidth (mainForm->sample)); fl_show_form (macrooutputForm->macrooutputForm, FL_PLACE_MOUSE | FL_FREE_SIZE,FL_FULLBORDER, "Command Output"); } else if (macro [macroNumber].output == MACROBUFFEROUTPUT) { tempFile = fopen (tempFileName,"r"); if (!tempFile) { delete [] tempFileName; return "Cannot open temp file"; } // Read data back into temp sample DPSample tempSample; int tempSampleLength; int outputChannels; int outputSingleChannel; int outputSingleChannelNumber; int outputSample = 0; int finished; int editMode = 0; outputChannels = sample->getChannels (); outputSingleChannel = FALSE; if (!(macro [macroNumber].input == MACROBUFFERINPUT || (macro [macroNumber].input == MACROEITHERINPUT && !sample->getRangeValid ()))) { if ((editMode = fl_get_sample_edit (mainForm->sample)) != 2) { outputSingleChannel = TRUE; if (editMode < 2) outputSingleChannelNumber = editMode; else outputSingleChannelNumber = editMode - 1; } } /* Only use one channel if in single edit mode */ if (outputSingleChannel) outputChannels = 1; // Default to one second of current sample format if (!tempSample.fresh (sample->getRate (),sample->getWidth (), outputChannels,(int)sample->getRate ())) { fclose (tempFile); delete [] tempFileName; return "Unable to create temp sample"; } // Read samples in (set tempSampleLength to actual length) finished = FALSE; i = 0; if (macro [macroNumber].processMode == MACRORAWMODE) { while (!finished) { for (j=0; jgetRangeValid ())) { // Whole buffer sample->cloneData (tempSample); } else { int singleMode = FALSE; // Special case for single channel edit mode - minimise length if (!(macro [macroNumber].input == MACROBUFFERINPUT || (macro [macroNumber].input == MACROEITHERINPUT && !sample->getRangeValid ()))) { if ((editMode = fl_get_sample_edit (mainForm->sample)) != 2) singleMode = TRUE; } // Range only - preserve range, display, loops int rangeStartBak = sample->getRangeStart (); int rangeEndBak = sample->getRangeEnd (); int displayStartBak = sample->getDisplayStart (); int displayEndBak = sample->getDisplayEnd (); int sustainModeBak = sample->getSusLoopMode (); int sustainStartBak = sample->getSusLoopStart (); int sustainEndBak = sample->getSusLoopEnd (); int releaseModeBak = sample->getRelLoopMode (); int releaseStartBak = sample->getRelLoopStart (); int releaseEndBak = sample->getRelLoopEnd (); sample->cut (&tempClip,editMode); sample->setRange (rangeStartBak,rangeEndBak); sample->paste (&tempSample,editMode); sample->setDisplay (displayStartBak,displayEndBak); sample->setSusLoopMode (sustainModeBak); sample->setSusLoop (sustainStartBak,sustainEndBak); sample->setRelLoopMode (releaseModeBak); sample->setRelLoop (releaseStartBak,releaseEndBak); // If single edit mode trim extra space generated if (singleMode) sample->trim (); } } updateSample (sample); if (remove (tempFileName) == -1) fl_show_alert ("Warning","Unable to remove temporary file", tempFileName,TRUE); delete [] tempFileName; return 0; } case MACROTEMPAIFFMODE : case MACROSAVEAIFFMODE : { // Save AIFF file char *filename; char *reloadFilename; char *tempOutputFilename; char *error; int rangeOnly; if (macro [macroNumber].processMode == MACROSAVEAIFFMODE || macro [macroNumber].input == MACRONONEINPUT) rangeOnly = FALSE; else if (macro [macroNumber].input == MACROBUFFERINPUT || (macro [macroNumber].input == MACROEITHERINPUT && !sample->getRangeValid ())) rangeOnly = FALSE; else rangeOnly = TRUE; // Generate temp filenames const char *tempDir = fl_get_sample_tempdir (mainForm->sample); char *tempNameTemplate; char *mktempFileName; // Filename used for reload tempNameTemplate = new char [strlen (tempDir) + 9]; strcpy (tempNameTemplate,tempDir); if (strlen (tempNameTemplate) > 0 && tempNameTemplate [strlen (tempNameTemplate) - 1] != '/') strcat (tempNameTemplate,"/"); strcat (tempNameTemplate,"aXXXXXX"); mktempFileName = mktemp (tempNameTemplate); delete [] tempNameTemplate; if (!mktempFileName) { return "Unable to create temporary filename"; } reloadFilename = new char [strlen (mktempFileName) + 1]; strcpy (reloadFilename,mktempFileName); delete [] mktempFileName; // Filename used for temporary file output tempNameTemplate = new char [strlen (tempDir) + 9]; strcpy (tempNameTemplate,tempDir); if (strlen (tempNameTemplate) > 0 && tempNameTemplate [strlen (tempNameTemplate) - 1] != '/') strcat (tempNameTemplate,"/"); strcat (tempNameTemplate,"bXXXXXX"); mktempFileName = mktemp (tempNameTemplate); delete [] tempNameTemplate; if (!mktempFileName) { delete [] reloadFilename; return "Unable to create temporary filename (for temp output)"; } tempOutputFilename = new char [strlen (mktempFileName) + 1]; strcpy (tempOutputFilename,mktempFileName); delete [] mktempFileName; // Filename used for saving if (macro [macroNumber].processMode == MACROSAVEAIFFMODE) { if (sample->getFilename ()) { filename = new char [strlen (sample->getFilename ()) + 1]; strcpy (filename,sample->getFilename ()); } else { filename = 0; } } else { tempNameTemplate = new char [strlen (tempDir) + 9]; strcpy (tempNameTemplate,tempDir); if (strlen (tempNameTemplate) > 0 && tempNameTemplate [strlen (tempNameTemplate) - 1] != '/') strcat (tempNameTemplate,"/"); strcat (tempNameTemplate,"cXXXXXX"); mktempFileName = mktemp (tempNameTemplate); delete [] tempNameTemplate; if (!mktempFileName) { delete [] reloadFilename; delete [] tempOutputFilename; return "Unable to create temporary filename (for reload)"; } filename = new char [strlen (mktempFileName) + 1]; strcpy (filename,mktempFileName); delete [] mktempFileName; } delete [] tempNameTemplate; if (!filename) { const char *tempFilename = fselector ("Please enter the filename to save","*.aiff",0,sample); if (tempFilename) { int irixFile = open (tempFilename,O_RDONLY); if (irixFile != -1) { close (irixFile); if (!fl_show_question_old (tempFilename,"exists already - overwrite ?",0)) ENDAIFFMACRO } filename = new char [strlen (tempFilename) + 1]; strcpy (filename,tempFilename); } else { ENDAIFFMACRO } } if ((error = sample->saveAIFF (filename,rangeOnly, fl_get_sample_soxcompatible (mainForm->sample),FALSE))) { fl_show_alert ("Warning - Could not save file", filename,error,TRUE); ENDAIFFMACRO } else { sample->consolidate (); sample->removeExtra (); } // Execute command char *command = macro [macroNumber].command; char *tempCommand; int tempCommandLen; int reloadUsed = FALSE; int fReplacements = 0; int gReplacements = 0; int percentFound; int i; int j; // Count number of replacements needed // If %g found reloadUsed = TRUE; percentFound = FALSE; for (i=0; i<(signed)strlen (command); i++) { if (command [i] == '%') { percentFound = TRUE; } else { if (command [i] == 'f' && percentFound) fReplacements++; else if (command [i] == 'g' && percentFound) gReplacements++; percentFound = FALSE; } } if (gReplacements) reloadUsed = TRUE; tempCommandLen = strlen (command) + (fReplacements * (strlen (filename) - 2)) + (gReplacements * (strlen (reloadFilename) - 2)) + strlen (tempOutputFilename) + 3; tempCommand = new char [tempCommandLen]; // Replace %f in command with filename // Replace %g in command with reload filename j = 0; percentFound = FALSE; for (i=0; i<(signed)strlen (command); i++) { if (command [i] == '%') { if (percentFound) tempCommand [j++] = '%'; percentFound = TRUE; } else { if (command [i] == 'f' && percentFound) { tempCommand [j] = 0; strcat (tempCommand,filename); j = strlen (tempCommand); } else if (command [i] == 'g' && percentFound) { tempCommand [j] = 0; strcat (tempCommand,reloadFilename); j = strlen (tempCommand); } else { if (percentFound) tempCommand [j++] = '%'; tempCommand [j++] = command [i]; } percentFound = FALSE; } } if (percentFound) tempCommand [j++] = '%'; tempCommand [j] = 0; if (macro [macroNumber].output == MACRODIALOGOUTPUT) { strcat (tempCommand," >"); strcat (tempCommand,tempOutputFilename); } // New command in tempCommand system (tempCommand); delete [] tempCommand; if (macro [macroNumber].output == MACRODIALOGOUTPUT) { FD_macrooutputForm *macrooutputForm; macrooutputForm = create_form_macrooutputForm (); fl_set_form_minsize (macrooutputForm->macrooutputForm,260,180); fl_set_form_atclose (macrooutputForm->macrooutputForm, closeMacroOutputForm, 0); if (!fl_load_browser (macrooutputForm->browser,tempOutputFilename)) { REMOVETEMPFILES delete [] reloadFilename; delete [] tempOutputFilename; if (macro [macroNumber].processMode == MACROTEMPAIFFMODE) delete [] filename; return "Cannot load temp file into browser"; } fl_show_form (macrooutputForm->macrooutputForm, FL_PLACE_MOUSE | FL_FREE_SIZE,FL_FULLBORDER, "Command Output"); } else if (macro [macroNumber].output == MACROBUFFEROUTPUT) { // Reload sample or new temporary filename (as reloadUsed) char *reloadName; if (reloadUsed) reloadName = reloadFilename; else reloadName = filename; // Possibly as range only so be careful !! (as rangeOnly) DPSample tempSample; if ((error = tempSample.loadAIFF (reloadName))) { fl_show_alert ("Warning - Could not reload file", reloadName,error,TRUE); REMOVETEMPFILES ENDAIFFMACRO } if (!rangeOnly) { tempSample.setFilename (sample->getFilename ()); *sample = tempSample; } else { // Range only - preserve range, display DPSample tempClip; int rangeStartBak = sample->getRangeStart (); int displayStartBak = sample->getDisplayStart (); int displayEndBak = sample->getDisplayEnd (); sample->cut (&tempClip,2); sample->setRange (rangeStartBak,rangeStartBak); sample->paste (&tempSample,2); sample->setDisplay (displayStartBak,displayEndBak); } updateSample (sample); } REMOVETEMPFILES delete [] reloadFilename; delete [] tempOutputFilename; delete [] filename; return 0; } default : { return "Unknown macro process mode"; } } } /*--------------------------------------------------------------------------- | FUNCTION findNonSpace ---------------------------------------------------------------------------*/ int findNonSpace (const char *name) { int i; if (!name) return 0; i = 0; while (name [i] && isspace (name [i])) i++; return i; } /*--------------------------------------------------------------------------- | FUNCTION closeMacroOutputForm ---------------------------------------------------------------------------*/ int closeMacroOutputForm (FL_FORM *form,void *) { fl_hide_form (form); fl_free_form (form); return FL_IGNORE; } /***************************************************************************/