/**************************************************************************** | Digital Audio Processor | ======================= | | Filename : DPTich_effect_cb.cc | | Object : None | | Description : XForms callback code | | (c) Richard Kent 1996 | | $Id: DPTich_effect_cb.cc,v 1.1 2003/09/10 00:06:24 rk Exp $ | ****************************************************************************/ static char DPTich_effect_cb_cc [] = "$Id: DPTich_effect_cb.cc,v 1.1 2003/09/10 00:06:24 rk Exp $"; #include "DPTich_main.h" #define PARAM effects->effect [effectNo].param [data] #define HEADER "TichDSPEffect" #define POSTMIXNAME "PostMixerPlayPort" #define POSTMIXQUEUETIME 0.5 #define POSTMIXCHECKTIME 0.2 // #define SNEAKYCHECK #define DOEFFECT(effectName,functionName) \ { \ fl_hide_form (initialForm->initialForm); \ fl_show_form (executeForm->executeForm, \ FL_PLACE_MOUSE,FL_FULLBORDER,effectName); \ fl_set_idle_delta (heavyIdle); \ if (channels == 2) \ { \ fl_set_object_label (executeForm->sliderTitle,"Percent Complete"); \ error = \ functionName (inputSample,outputSample,susLoops,relLoops); \ } \ else \ { \ fl_set_object_label (executeForm->sliderTitle, \ "Percent Complete - Stereo 1"); \ error = \ functionName (inputSample,outputSample,susLoops,relLoops, \ TRUE,channel_a,channel_b); \ if (!error && !DSPStop && !DSPCancel) \ { \ fl_set_object_label (executeForm->sliderTitle, \ "Percent Complete - Stereo 2"); \ error = \ functionName (inputSample,outputSample,susLoops,relLoops, \ FALSE,channel_c,channel_d); \ } \ } \ fl_set_idle_delta (normalIdle); \ } /*--------------------------------------------------------------------------- | CALLBACK effectSlider_cb ---------------------------------------------------------------------------*/ void effectSlider_cb (FL_OBJECT *ob,long data) { char tempString [50]; int effectNo = fl_get_choice (initialForm->type) - 1; PARAM.realValue = fl_get_slider_value (ob); if (PARAM.realValue < PARAM.realMin) PARAM.realValue = PARAM.realMin; else if (PARAM.realValue > PARAM.realMax) PARAM.realValue = PARAM.realMax; fl_set_slider_value (ob,PARAM.realValue); sprintf (tempString,PARAM.realPrintString,PARAM.realValue); fl_set_input (DSPinput [data],tempString); } /*--------------------------------------------------------------------------- | CALLBACK effectInput_cb ---------------------------------------------------------------------------*/ void effectInput_cb (FL_OBJECT *ob,long data) { char tempString [50]; int effectNo = fl_get_choice (initialForm->type) - 1; if (!sscanf (fl_safe_get_input (ob),"%lf",&(PARAM.realValue))) return; if (PARAM.realValue < PARAM.realMin) PARAM.realValue = PARAM.realMin; else if (PARAM.realValue > PARAM.realMax) PARAM.realValue = PARAM.realMax; fl_set_slider_value (DSPslider [data],PARAM.realValue); sprintf (tempString,PARAM.realPrintString,PARAM.realValue); fl_set_input (ob,tempString); } /*--------------------------------------------------------------------------- | CALLBACK effectChoice_cb ---------------------------------------------------------------------------*/ void effectChoice_cb (FL_OBJECT *ob,long data) { int effectNo = fl_get_choice (initialForm->type) - 1; PARAM.enumValue = fl_get_choice (ob) - 1; } /*--------------------------------------------------------------------------- | CALLBACK effectOK_cb ---------------------------------------------------------------------------*/ void effectOK_cb (FL_OBJECT *,long) { fl_hide_form (effectForm->effectForm); fl_activate_form (initialForm->initialForm); } /*--------------------------------------------------------------------------- | CALLBACK initialType_cb ---------------------------------------------------------------------------*/ void initialType_cb (FL_OBJECT *,long) { } /*--------------------------------------------------------------------------- | CALLBACK initialQuadro_cb ---------------------------------------------------------------------------*/ void initialQuadro_cb (FL_OBJECT *,long) { } /*--------------------------------------------------------------------------- | CALLBACK initialParams_cb ---------------------------------------------------------------------------*/ void initialParams_cb (FL_OBJECT *,long data) { char tempString [50]; int i; int j; int effectNo = fl_get_choice (initialForm->type) - 1; fl_set_object_label (effectForm->title,effects->effect [effectNo].name); for (i=0; ieffect [effectNo].paramNo) { fl_set_object_label (DSPname [i],PARAM.name); if (PARAM.chan && strlen (PARAM.chan) > 0) { fl_show_object (DSPchan [i]); fl_set_object_label (DSPchan [i],PARAM.chan); } else { fl_hide_object (DSPchan [i]); } if (PARAM.type == 0) { // Real type fl_show_object (DSPname [i]); fl_show_object (DSPinput [i]); fl_show_object (DSPslider [i]); fl_hide_object (DSPchoice [i]); fl_set_slider_bounds (DSPslider [i],PARAM.realMin,PARAM.realMax); fl_set_slider_step (DSPslider [i],PARAM.realStep); if (PARAM.realUnits && strlen (PARAM.realUnits) > 0) { fl_show_object (DSPunits [i]); fl_set_object_label (DSPunits [i],PARAM.realUnits); } else { fl_hide_object (DSPunits [i]); } fl_set_slider_value (DSPslider [i],PARAM.realValue); sprintf (tempString,PARAM.realPrintString,PARAM.realValue); fl_set_input (DSPinput [i],tempString); } else { // Enum type fl_show_object (DSPname [i]); fl_hide_object (DSPinput [i]); fl_hide_object (DSPunits [i]); fl_hide_object (DSPslider [i]); fl_show_object (DSPchoice [i]); fl_clear_choice (DSPchoice [i]); for (j=0; jeffect [effectNo].paramNo) * 20); fl_set_form_size(effectForm->effectForm,w,h); fl_deactivate_form (initialForm->initialForm); changeBorderWidthForm (effectForm->effectForm, fl_get_sample_borderwidth (mainForm->sample)); fl_show_form (effectForm->effectForm, FL_PLACE_MOUSE,FL_FULLBORDER,"DSP Effect Parameters"); } /*--------------------------------------------------------------------------- | CALLBACK initialSusLoops_cb ---------------------------------------------------------------------------*/ void initialSusLoops_cb (FL_OBJECT *ob,long) { int loops; if (!sscanf (fl_safe_get_input (ob),"%d",&loops)) return; if (loops < 0) { loops = 0; fl_set_slider_value (initialForm->susSlider,0); fl_set_input (ob,"0"); } else if (loops > 50) loops = 50; fl_set_slider_value (initialForm->susSlider,(double) loops); } /*--------------------------------------------------------------------------- | CALLBACK initialRelLoops_cb ---------------------------------------------------------------------------*/ void initialRelLoops_cb (FL_OBJECT *ob,long) { int loops; if (!sscanf (fl_safe_get_input (ob),"%d",&loops)) return; if (loops < 0) { loops = 0; fl_set_slider_value (initialForm->relSlider,0); fl_set_input (ob,"0"); } else if (loops > 50) loops = 50; fl_set_slider_value (initialForm->relSlider,(double) loops); } /*--------------------------------------------------------------------------- | CALLBACK initialSusSlider_cb ---------------------------------------------------------------------------*/ void initialSusSlider_cb (FL_OBJECT *ob,long) { char tempString [20]; int loops = (int) fl_get_slider_value (ob); sprintf (tempString,"%d",loops); fl_set_input (initialForm->susLoops,tempString); } /*--------------------------------------------------------------------------- | CALLBACK initialRelSlider_cb ---------------------------------------------------------------------------*/ void initialRelSlider_cb (FL_OBJECT *ob,long) { char tempString [20]; int loops = (int) fl_get_slider_value (ob); sprintf (tempString,"%d",loops); fl_set_input (initialForm->relLoops,tempString); } /*--------------------------------------------------------------------------- | CALLBACK initialExecute_cb ---------------------------------------------------------------------------*/ void initialExecute_cb (FL_OBJECT *,long) { int effectNo = fl_get_choice (initialForm->type) - 1; int susLoops; int relLoops; DPSample *inputSample = fl_get_sample (mainForm->sample); DPSample *outputSample = new DPSample; int channels; int channel_a = 0; int channel_b = 0; int channel_c = 0; int channel_d = 0; char *error; if (inputSample->getChannels () == 4) { channels = 4; channel_a = fl_get_choice (initialForm->quadro1Left); channel_b = fl_get_choice (initialForm->quadro1Right); channel_c = fl_get_choice (initialForm->quadro2Left); channel_d = fl_get_choice (initialForm->quadro2Right); } else { channels = 2; channel_a = 0; channel_b = 1; } fl_call_object_callback (playForm->stopButton); fl_call_object_callback (recordForm->stopButton); if (!sscanf (fl_safe_get_input (initialForm->susLoops),"%d",&susLoops)) return; if (!sscanf (fl_safe_get_input (initialForm->relLoops),"%d",&relLoops)) return; fl_set_object_label (executeForm->frames,"0"); fl_set_object_label (executeForm->time,"00:00:00"); fl_set_object_label (executeForm->elapsedTime,"00:00:00"); fl_set_object_label (executeForm->remainTime,"00:00:00"); fl_set_object_label (executeForm->percentComp,"0"); fl_set_slider_value (executeForm->percentCompSlider,0.0); switch (effectNo) { case 0 : DOEFFECT ("DSP Execution - Reverberation",DSPReverberation); break; case 2 : DOEFFECT ("DSP Execution - Stereo Delay",DSPStereoDelay); break; case 3 : DOEFFECT ("DSP Execution - Modulated Delay",DSPModulatedDelay); case 4 : DOEFFECT ("DSP Execution - Multi Tap Delay",DSPMultiTapDelay); break; case 5 : DOEFFECT ("DSP Execution - Multi Delay",DSPMultiDelay); break; case 6 : DOEFFECT ("DSP Execution - Flanger",DSPFlanger); break; case 7 : DOEFFECT ("DSP Execution - Phaser",DSPPhaser); break; case 8 : DOEFFECT ("DSP Execution - Distortion",DSPDistortion); break; case 9 : DOEFFECT ("DSP Execution - Filter",DSPFilter); break; case 10 : DOEFFECT ("DSP Execution - Auto Pan",DSPAutoPan); break; case 12 : DOEFFECT ("DSP Execution - Gate",DSPGate); break; case 13 : DOEFFECT ("DSP Execution - Compressor",DSPCompressor); break; default : fl_show_alert ("Notice", "This effect is not yet functional", "Pester me if you want it finished !!",TRUE); delete outputSample; return; } fl_hide_form (executeForm->executeForm); if (error) { fl_show_alert ("Error","Processing Incomplete",error,TRUE); delete outputSample; fl_show_form (initialForm->initialForm, FL_PLACE_MOUSE,FL_FULLBORDER,"DSP Initialisation"); return; } if (DSPCancel) { delete outputSample; fl_show_form (initialForm->initialForm, FL_PLACE_MOUSE,FL_FULLBORDER,"DSP Initialisation"); return; } // Restore initial form to normal size if (inputSample->getChannels () == 4) { fl_set_form_size ( initialForm->initialForm, initialForm->initialForm->w, initialFormHeight - 80); } if (!(outputSample->consolidate ())) { fl_show_alert ( "Warning", "Could not defragment sample - out of memory", "Please save sample immediately and reload into editor",TRUE); const char *filename = fselector ("Please enter the filename to save","*.aiff",0,outputSample); if (filename) { int irixFile = open (filename,O_RDONLY); int writeFile = TRUE; if (irixFile != -1) { close (irixFile); if (!fl_show_question_old (filename,"exists already - overwrite ?",0)) { writeFile = FALSE; } } if (writeFile) { waitCursorOn (); if ((error = outputSample->saveAIFF ((char *) filename, 0,fl_get_sample_soxcompatible (mainForm->sample),1))) { waitCursorOff (); fl_show_alert ("Warning","Could not save file",error,TRUE); } else { waitCursorOff (); } } } outputSample->removeExtra (); } postForm->vdata = outputSample; fl_set_slider_value (postForm->master,1.0); fl_set_slider_value (postForm->mix,0.5); DSPMaster = 1.0; DSPMix = 0.5; fl_show_form (postForm->postForm, FL_PLACE_MOUSE,FL_FULLBORDER,"DSP Post Processing"); } /*--------------------------------------------------------------------------- | CALLBACK initialCancel_cb ---------------------------------------------------------------------------*/ void initialCancel_cb (FL_OBJECT *,long) { fl_hide_form (initialForm->initialForm); fl_set_button (mainForm->effects,0); DPSample *inputSample = fl_get_sample (mainForm->sample); // Restore initial form to normal size if (inputSample->getChannels () == 4) { fl_set_form_size ( initialForm->initialForm, initialForm->initialForm->w, initialFormHeight - 80); } fl_activate_all_forms (); if (fl_get_sample_autowindows (mainForm->sample)) rememberForms (1); fl_activate_object (mainForm->effects); } /*--------------------------------------------------------------------------- | CALLBACK initialSave_cb ---------------------------------------------------------------------------*/ void initialSave_cb (FL_OBJECT *,long) { const char *filename; filename = fselector ("Please enter the effects filename to save","*.dsp",0,0); if (filename) { // Open file int irixFile = open (filename,O_RDONLY); if (irixFile != -1) { close (irixFile); if (!fl_show_question_old (filename,"exists already - overwrite ?",0)) return; } irixFile = open (filename,O_WRONLY | O_CREAT,0600); if (irixFile == -1) { fl_show_alert ("Warning","Unable to create effects file",filename,1); return; } int ok = 1; // Save out effects parameters if (write (irixFile,HEADER,sizeof (HEADER)) < (signed) sizeof (HEADER)) ok = 0; int effectNo = fl_get_choice (initialForm->type) - 1; int effectNoTemp = effectNo; #ifdef BIGENDIAN effectNoTemp = swapbytes_int (effectNoTemp); #endif if (write (irixFile,&effectNoTemp,sizeof (effectNoTemp)) < (signed) sizeof (effectNoTemp)) ok = 0; if (ok) { for (int data=0; dataeffect [effectNo].paramNo && ok; data++) { if (PARAM.type == 0) { double realValueTemp = PARAM.realValue; #ifdef BIGENDIAN realValueTemp = swapbytes_double (realValueTemp); #endif if (write (irixFile,&realValueTemp,sizeof (realValueTemp)) < (signed) sizeof (realValueTemp)) ok = 0; } else { int enumValueTemp = PARAM.enumValue; #ifdef BIGENDIAN enumValueTemp = swapbytes_int (enumValueTemp); #endif if (write (irixFile,&enumValueTemp,sizeof (enumValueTemp)) < (signed) sizeof (enumValueTemp)) ok = 0; } } } close (irixFile); if (!ok) { fl_show_alert ("Warning","Error while saving effects file",filename,1); } } } /*--------------------------------------------------------------------------- | CALLBACK initialOpen_cb ---------------------------------------------------------------------------*/ void initialOpen_cb (FL_OBJECT *,long data) { const char *filename; char *fileHeader; filename = fselector ("Please enter the effects filename to load","*.dsp",0,0); if (filename) { // Open file int irixFile = open (filename,O_RDONLY); if (irixFile == -1) { fl_show_alert ("Warning","Unable to load effects file",filename,TRUE); return; } int ok = 1; // Load effects parameters fileHeader = new char [sizeof (HEADER) + 1]; if (read (irixFile,fileHeader,sizeof (HEADER)) < (signed) sizeof (HEADER)) ok = 0; if (ok) { fileHeader [sizeof (HEADER)] = 0; if (strcmp (fileHeader,HEADER)) ok = 0; } delete [] fileHeader; if (!ok) { fl_show_alert ("Warning","Error - file is not a valid effects file",filename,1); return; } int effectNo; if (read (irixFile,&effectNo,sizeof (effectNo)) < (signed) sizeof (effectNo)) ok = 0; #ifdef BIGENDIAN effectNo = swapbytes_int (effectNo); #endif if (ok) { if (effectNo < 0 || effectNo >= effects->effectNo) ok = 0; } if (ok) { for (int data=0; dataeffect [effectNo].paramNo && ok; data++) { if (PARAM.type == 0) { if (read (irixFile,&(PARAM.realDefault), sizeof (PARAM.realDefault)) < (signed) sizeof (PARAM.realDefault)) ok = 0; #ifdef BIGENDIAN PARAM.realDefault = swapbytes_double (PARAM.realDefault); #endif } else { if (read (irixFile,&(PARAM.enumDefault), sizeof (PARAM.enumDefault)) < (signed) sizeof (PARAM.enumDefault)) ok = 0; #ifdef BIGENDIAN PARAM.enumDefault = swapbytes_int (PARAM.enumDefault); #endif } } } close (irixFile); if (!ok) { fl_show_alert ("Warning","Error while loading effects file",filename,1); return; } // Transfer over data for (data=0; dataeffect [effectNo].paramNo; data++) { if (PARAM.type == 0) { if (PARAM.realDefault < PARAM.realMin) PARAM.realDefault = PARAM.realMin; else if (PARAM.realDefault > PARAM.realMax) PARAM.realDefault = PARAM.realMax; PARAM.realValue = PARAM.realDefault; } else { if (PARAM.enumDefault < 0) PARAM.enumDefault = 0; else if (PARAM.enumDefault >= PARAM.enumNo) PARAM.enumDefault = PARAM.enumNo - 1; PARAM.enumValue = PARAM.enumDefault; } } fl_set_choice (initialForm->type,effectNo + 1); } } /*--------------------------------------------------------------------------- | CALLBACK executePercentCompSlider_cb ---------------------------------------------------------------------------*/ void executePercentCompSlider_cb (FL_OBJECT *,long) { } /*--------------------------------------------------------------------------- | CALLBACK executeStop_cb ---------------------------------------------------------------------------*/ void executeStop_cb (FL_OBJECT *,long) { if (fl_show_question_old ("Stop","Are you really sure ?",0)) DSPStop = TRUE; } /*--------------------------------------------------------------------------- | CALLBACK executeCancel_cb ---------------------------------------------------------------------------*/ void executeCancel_cb (FL_OBJECT *,long) { if (fl_show_question_old ("Cancel","Are you really sure ?",0)) DSPCancel = TRUE; } /*--------------------------------------------------------------------------- | CALLBACK postStop_cb ---------------------------------------------------------------------------*/ void postStop_cb (FL_OBJECT *,long) { DSPPlayStop = 1; } /*--------------------------------------------------------------------------- | CALLBACK postSave_cb ---------------------------------------------------------------------------*/ void postSave_cb (FL_OBJECT *,long) { DPSample saveSample; DPSample *sample = &saveSample; DPSample *outputSample = (DPSample *) postForm->vdata; const char *filename; char *error; waitCursorOn (); if (!(sample->clone (*outputSample))) { waitCursorOff (); fl_show_alert ("Warning","Unable to save sample - out of memory", "Please return to the editor and save from there",TRUE); return; } postMixGenerate (sample); waitCursorOff (); filename = fselector ("Please enter the filename to save","*.aiff",0,sample); if (filename) { int irixFile = open (filename,O_RDONLY); if (irixFile != -1) { close (irixFile); if (!fl_show_question_old (filename,"exists already - overwrite ?",0)) return; } waitCursorOn (); if ((error = sample->saveAIFF ((char *) filename,0, fl_get_sample_soxcompatible (mainForm->sample),1))) { waitCursorOff (); fl_show_alert ("Warning","Could not save file",error,TRUE); } else { waitCursorOff (); } } } /*--------------------------------------------------------------------------- | CALLBACK postMix_cb ---------------------------------------------------------------------------*/ void postMix_cb (FL_OBJECT *ob,long) { DSPMix = fl_get_slider_value (ob); } /*--------------------------------------------------------------------------- | CALLBACK postMaster_cb ---------------------------------------------------------------------------*/ void postMaster_cb (FL_OBJECT *ob,long) { DSPMaster = fl_get_slider_value (ob); } /*--------------------------------------------------------------------------- | CALLBACK postLeftSlider_cb ---------------------------------------------------------------------------*/ void postLeftSlider_cb (FL_OBJECT *ob,long) { fl_set_slider_value (playForm->leftSlider,fl_get_slider_value (ob)); fl_call_object_callback (playForm->leftSlider); } /*--------------------------------------------------------------------------- | CALLBACK postRightSlider_cb ---------------------------------------------------------------------------*/ void postRightSlider_cb (FL_OBJECT *ob,long) { fl_set_slider_value (playForm->rightSlider,fl_get_slider_value (ob)); fl_call_object_callback (playForm->rightSlider); } /*--------------------------------------------------------------------------- | CALLBACK postLockButton_cb ---------------------------------------------------------------------------*/ void postLockButton_cb (FL_OBJECT *ob,long) { fl_set_button (playForm->lockButton,fl_get_button (ob)); fl_call_object_callback (playForm->lockButton); } /*--------------------------------------------------------------------------- | CALLBACK postMuteHiddenButton_cb ---------------------------------------------------------------------------*/ void postMuteHiddenButton_cb (FL_OBJECT *ob,long) { fl_set_button (playForm->muteHiddenButton,fl_get_button (ob)); fl_call_object_callback (playForm->muteHiddenButton); } /*--------------------------------------------------------------------------- | CALLBACK postMuteButton_cb ---------------------------------------------------------------------------*/ void postMuteButton_cb (FL_OBJECT *ob,long) { #ifdef LINUX fl_set_button (playForm->muteButton,fl_get_button (ob)); fl_call_object_callback (playForm->muteButton); #endif } /*--------------------------------------------------------------------------- | CALLBACK postRateChoice_cb ---------------------------------------------------------------------------*/ void postRateChoice_cb (FL_OBJECT *ob,long) { fl_set_choice (playForm->rateChoice,fl_get_choice (ob)); fl_call_object_callback (playForm->rateChoice); } /*--------------------------------------------------------------------------- | CALLBACK postOK_cb ---------------------------------------------------------------------------*/ void postOK_cb (FL_OBJECT *,long) { DPSample *outputSample = (DPSample *) postForm->vdata; updateBuffers ("Undo DSP") waitCursorOn (); postMixGenerate (outputSample); waitCursorOff (); delete buffer [current]; buffer [current] = outputSample; DPSample *sample = buffer [current]; fl_set_sample (mainForm->sample,sample); updateAudioGlobals (0,0); updateSamplePrefs (); updateDisplayDetails (); updateRangeDetails (); updateLoopDetails (); fl_redraw_object (mainForm->sample); fl_redraw_object (mainForm->scrollBarSlider); fl_redraw_object (mainForm->zoomBarSlider); int sampleFormat = sample->getFormat (); int sampleCompression = sample->getCompression (); updateSaveFormatCompression (sampleFormat,sampleCompression); updateConvertMenu (); updateNameBox (); fl_set_sample_edit (mainForm->sample,2); updateEditModeChoice (sample->getChannels ()); updateBufferBrowser (); fl_hide_form (postForm->postForm); fl_set_button (mainForm->effects,0); fl_activate_all_forms (); if (fl_get_sample_autowindows (mainForm->sample)) rememberForms (1); fl_activate_object (mainForm->effects); } /*--------------------------------------------------------------------------- | CALLBACK postCancel_cb ---------------------------------------------------------------------------*/ void postCancel_cb (FL_OBJECT *,long) { DPSample *outputSample = (DPSample *) postForm->vdata; if (fl_show_question_old ("Cancel","Are you sure",0)) { delete outputSample; fl_hide_form (postForm->postForm); fl_set_button (mainForm->effects,0); fl_activate_all_forms (); if (fl_get_sample_autowindows (mainForm->sample)) rememberForms (1); fl_activate_object (mainForm->effects); } } /*--------------------------------------------------------------------------- | CALLBACK postPlay_cb ---------------------------------------------------------------------------*/ void postPlay_cb (FL_OBJECT *,long) { char *error; #ifdef LINUX closeGlobalPorts (); #endif #ifndef LINUX long pvBuffer1 [2]; long pvBuffer2 [2]; pvBuffer1 [0] = AL_MONITOR_CTL; pvBuffer2 [0] = AL_MONITOR_CTL; pvBuffer2 [1] = 0; ALgetparams (AL_DEFAULT_DEVICE,pvBuffer1,2); if (fl_get_sample_autoglobals (mainForm->sample)) ALsetparams (AL_DEFAULT_DEVICE,pvBuffer2,2); #endif if ((error = postMixPlay ())) fl_show_alert ("Warning","Unable to play buffers",error,TRUE); #ifndef LINUX if (fl_get_sample_autoglobals (mainForm->sample)) ALsetparams (AL_DEFAULT_DEVICE,pvBuffer1,2); #endif } /*--------------------------------------------------------------------------- | CALLBACK postRateMenu_cb ---------------------------------------------------------------------------*/ void postRateMenu_cb (FL_OBJECT *ob,long) { int item; char tempString [50]; item=fl_get_menu (ob); switch (item) { case 1 : sprintf (tempString,"%d",8000); fl_set_input (postForm->rateInput,tempString); break; case 2 : sprintf (tempString,"%d",11025); fl_set_input (postForm->rateInput,tempString); break; case 3 : sprintf (tempString,"%d",16000); fl_set_input (postForm->rateInput,tempString); break; case 4 : sprintf (tempString,"%d",22050); fl_set_input (postForm->rateInput,tempString); break; case 5 : sprintf (tempString,"%d",32000); fl_set_input (postForm->rateInput,tempString); break; case 6 : sprintf (tempString,"%d",44100); fl_set_input (postForm->rateInput,tempString); break; case 7 : sprintf (tempString,"%d",48000); fl_set_input (postForm->rateInput,tempString); break; default: break; } fl_call_object_callback (postForm->rateInput); } /*--------------------------------------------------------------------------- | CALLBACK postRateInput_cb ---------------------------------------------------------------------------*/ void postRateInput_cb (FL_OBJECT *,long) { int rate; const char *rateString; rateString = fl_safe_get_input (postForm->rateInput); if (!sscanf (rateString,"%d",&rate)) return; if (rate < 1) { rate = 1; fl_set_input (postForm->rateInput,"1"); } long pvBuffer [2]; pvBuffer [0] = AL_OUTPUT_RATE; pvBuffer [1] = rate; ALsetparams (AL_DEFAULT_DEVICE,pvBuffer,2); updateAudioGlobals (0,0); #ifdef LINUX fl_set_input (playForm->rateInput,rateString); fl_set_input (mixplayForm->rateInput,rateString); #endif } /*--------------------------------------------------------------------------- | FUNCTION postMixPlay ---------------------------------------------------------------------------*/ char *postMixPlay () { int susLoops; int relLoops; DSPKitDPReader reader_L; DSPKitDPReader reader_R; DSPKitDPReader reader_3; DSPKitDPReader reader_4; DPSample *inputSample = fl_get_sample (mainForm->sample); DPSample *outputSample = (DPSample *) postForm->vdata; if (!sscanf (fl_safe_get_input (initialForm->susLoops),"%d",&susLoops)) return "Unable to read sustain loops input box"; if (!sscanf (fl_safe_get_input (initialForm->relLoops),"%d",&relLoops)) return "Unable to read release loops input box"; ALconfig audioConfig; ALport audioPort; int queueSize; int channels; double playRate; int intOutputRate; intOutputRate = getOutputRate (); if (intOutputRate == AL_RATE_UNDEFINED) playRate = outputSample->getRate (); else playRate = intOutputRate; // Disable void handler ALseterrorhandler (0); // Determine number of channels channels = outputSample->getChannels (); // Set up new audio configuration audioConfig = ALnewconfig (); if (!audioConfig) return "Unable to create new audio configuration"; // Set sample format and width ALsetsampfmt (audioConfig,AL_SAMPFMT_TWOSCOMP); ALsetwidth (audioConfig,AL_SAMPLE_16); // Set number of channels ALsetchannels (audioConfig,channels); // Set queue size (POSTMIXQUEUETIME seconds at playback rate) queueSize = (int) (playRate * channels * POSTMIXQUEUETIME); limitQueueSize (channels,&queueSize); if (ALsetqueuesize (audioConfig,queueSize)) { ALfreeconfig (audioConfig); return "Unable to establish audio queue"; } // Open new audio port with given configuration audioPort = ALopenport (POSTMIXNAME,"w",audioConfig); if (!audioPort) { ALfreeconfig (audioConfig); return "Unable to open audio port"; } int i = 0; int checkReset = (int) (playRate * POSTMIXCHECKTIME); int check = 1; int frames = outputSample->getFrames (); DSPPlayStop = 0; double inputMix; double inputSamples [4]; int tempBuf [4]; short tempBufOut [4]; int overloaded; fl_show_object (postForm->playing); fl_deactivate_object (postForm->play); fl_deactivate_object (postForm->save); fl_deactivate_object (postForm->ok); fl_deactivate_object (postForm->cancel); #ifndef LINUX long pvBuffer1 [2]; long pvBuffer2 [2]; pvBuffer1 [0] = AL_MONITOR_CTL; pvBuffer2 [0] = AL_MONITOR_CTL; pvBuffer2 [1] = 0; ALgetparams (AL_DEFAULT_DEVICE,pvBuffer1,2); if (fl_get_sample_autoglobals (mainForm->sample)) ALsetparams (AL_DEFAULT_DEVICE,pvBuffer2,2); #endif int quadro = (channels == 4); #ifdef SNEAKYCHECK XEvent newEvent; #endif reader_L.setReaderInput (inputSample,0,susLoops,relLoops); reader_R.setReaderInput (inputSample,1,susLoops,relLoops); if (quadro) { reader_3.setReaderInput (inputSample,2,susLoops,relLoops); reader_4.setReaderInput (inputSample,3,susLoops,relLoops); } while (i >= 0 && i < frames && !DSPPlayStop) { reader_L.getSample (inputSamples [0]); reader_R.getSample (inputSamples [1]); inputMix = 1.0 - DSPMix; inputSamples [0] = (inputMix * inputSamples [0]) + (DSPMix * (outputSample->getFrameDb (i,0))); inputSamples [1] = (inputMix * inputSamples [1]) + (DSPMix * (outputSample->getFrameDb (i,1))); tempBuf [0] = (int) (DSPMaster * MAX23 * inputSamples [0]); tempBuf [1] = (int) (DSPMaster * MAX23 * inputSamples [1]); if (tempBuf [0] > MAX23_1) tempBuf [0] = MAX23_1; else if (tempBuf [0] < -MAX23) tempBuf [0] = -MAX23; if (tempBuf [1] > MAX23_1) tempBuf [1] = MAX23_1; else if (tempBuf [1] < -MAX23) tempBuf [1] = -MAX23; tempBufOut [0] = (short) (tempBuf [0] / 256); tempBufOut [1] = (short) (tempBuf [1] / 256); overloaded = 0; if (tempBufOut [0] > 30720 || tempBufOut [0] < -30720) overloaded++; if (tempBufOut [1] > 30720 || tempBufOut [1] < -30720) overloaded++; if (quadro) { reader_3.getSample (inputSamples [2]); reader_4.getSample (inputSamples [3]); inputMix = 1.0 - DSPMix; inputSamples [2] = (inputMix * inputSamples [2]) + (DSPMix * (outputSample->getFrameDb (i,2))); inputSamples [3] = (inputMix * inputSamples [3]) + (DSPMix * (outputSample->getFrameDb (i,3))); tempBuf [2] = (int) (DSPMaster * MAX23 * inputSamples [2]); tempBuf [3] = (int) (DSPMaster * MAX23 * inputSamples [3]); if (tempBuf [2] > MAX23_1) tempBuf [2] = MAX23_1; else if (tempBuf [2] < -MAX23) tempBuf [2] = -MAX23; if (tempBuf [3] > MAX23_1) tempBuf [3] = MAX23_1; else if (tempBuf [3] < -MAX23) tempBuf [3] = -MAX23; tempBufOut [2] = (short) (tempBuf [2] / 256); tempBufOut [3] = (short) (tempBuf [3] / 256); if (tempBufOut [2] > 30720 || tempBufOut [2] < -30720) overloaded++; if (tempBufOut [3] > 30720 || tempBufOut [3] < -30720) overloaded++; } if (overloaded) fl_set_object_color (postForm->overloaded,FL_RED,FL_RED); else fl_set_object_color (postForm->overloaded,FL_COL1,FL_COL1); ALwritesamps (audioPort,tempBufOut,channels); if (i == (frames - 1)) { reader_L.setReaderInput (inputSample,0,susLoops,relLoops); reader_R.setReaderInput (inputSample,1,susLoops,relLoops); if (quadro) { reader_3.setReaderInput (inputSample,2,susLoops,relLoops); reader_4.setReaderInput (inputSample,3,susLoops,relLoops); } i = 0; } if (!--check) { check = checkReset; #ifdef SNEAKYCHECK if (XCheckWindowEvent (fl_display, postForm->postForm->window,~(int)0,&newEvent) || XCheckWindowEvent (fl_display, mixerForm->mixerForm->window,~(int)0,&newEvent)) { XPutBackEvent (fl_display,&newEvent); fl_check_forms (); } #else fl_check_forms (); #endif } i++; } // Wait until port cleared if (!DSPStop) { #ifdef LINUX ALflush (audioPort,0); #else while (ALgetfilled (audioPort)) {} #endif } // Close the port, free the configuration and return ALcloseport (audioPort); ALfreeconfig (audioConfig); #ifndef LINUX if (fl_get_sample_autoglobals (mainForm->sample)) ALsetparams (AL_DEFAULT_DEVICE,pvBuffer1,2); #endif fl_activate_object (postForm->play); fl_activate_object (postForm->save); fl_activate_object (postForm->ok); fl_activate_object (postForm->cancel); fl_hide_object (postForm->playing); return 0; } /*--------------------------------------------------------------------------- | FUNCTION postMixGenerate ---------------------------------------------------------------------------*/ void postMixGenerate (DPSample *newSample) { // Note - newSample may be same as outputSample // Function assumes newSample already allocated using fresh int susLoops; int relLoops; DSPKitDPReader reader_L; DSPKitDPReader reader_R; DSPKitDPReader reader_3; DSPKitDPReader reader_4; DPSample *inputSample = fl_get_sample (mainForm->sample); DPSample *outputSample = (DPSample *) postForm->vdata; if (!sscanf (fl_safe_get_input (initialForm->susLoops),"%d",&susLoops)) return; if (!sscanf (fl_safe_get_input (initialForm->relLoops),"%d",&relLoops)) return; int i = 0; int frames = outputSample->getFrames (); int channels = outputSample->getChannels (); int quadro = (channels == 4); double inputMix; reader_L.setReaderInput (inputSample,0,susLoops,relLoops); reader_R.setReaderInput (inputSample,1,susLoops,relLoops); if (quadro) { reader_3.setReaderInput (inputSample,2,susLoops,relLoops); reader_4.setReaderInput (inputSample,3,susLoops,relLoops); } double inputSamples [4]; int tempBuf [4]; while (i >= 0 && i < frames) { reader_L.getSample (inputSamples [0]); reader_R.getSample (inputSamples [1]); inputMix = 1.0 - DSPMix; inputSamples [0] = (inputMix * inputSamples [0]) + (DSPMix * (outputSample->getFrameDb (i,0))); inputSamples [1] = (inputMix * inputSamples [1]) + (DSPMix * (outputSample->getFrameDb (i,1))); tempBuf [0] = (int) (DSPMaster * MAX23 * inputSamples [0]); tempBuf [1] = (int) (DSPMaster * MAX23 * inputSamples [1]); if (tempBuf [0] > MAX23_1) tempBuf [0] = MAX23_1; else if (tempBuf [0] < -MAX23) tempBuf [0] = -MAX23; if (tempBuf [1] > MAX23_1) tempBuf [1] = MAX23_1; else if (tempBuf [1] < -MAX23) tempBuf [1] = -MAX23; newSample->setFrame24 (i,0,tempBuf [0]); newSample->setFrame24 (i,1,tempBuf [1]); if (quadro) { reader_3.getSample (inputSamples [2]); reader_4.getSample (inputSamples [3]); inputMix = 1.0 - DSPMix; inputSamples [2] = (inputMix * inputSamples [2]) + (DSPMix * (outputSample->getFrameDb (i,2))); inputSamples [3] = (inputMix * inputSamples [3]) + (DSPMix * (outputSample->getFrameDb (i,3))); tempBuf [2] = (int) (DSPMaster * MAX23 * inputSamples [2]); tempBuf [3] = (int) (DSPMaster * MAX23 * inputSamples [3]); if (tempBuf [2] > MAX23_1) tempBuf [2] = MAX23_1; else if (tempBuf [2] < -MAX23) tempBuf [2] = -MAX23; if (tempBuf [3] > MAX23_1) tempBuf [3] = MAX23_1; else if (tempBuf [3] < -MAX23) tempBuf [3] = -MAX23; newSample->setFrame24 (i,2,tempBuf [2]); newSample->setFrame24 (i,3,tempBuf [3]); } i++; } newSample->setChanged (TRUE); } /***************************************************************************/