/**************************************************************************** | Digital Audio Processor | ======================= | | Filename : DPSample.cc | | Object : DPSample | | Description : DPSample class for handling audio samples | | (c) Richard Kent 1996 | | $Id: DPSample.cc,v 1.1 2003/09/10 00:06:25 rk Exp $ | ****************************************************************************/ static char DPSample_cc [] = "$Id: DPSample.cc,v 1.1 2003/09/10 00:06:25 rk Exp $"; #include "DPSample.h" // defines // #define NOFORMS to compile without using xforms // #define SNEAKYCHECK for xforms sneaky check #define PORTNAME "TichPort" #define ANNONEW " edited with Digital Audio Processor - Richard Kent" #define ZOOMFACTOR 1.50 #define CHECKTIME 0.20 #define LINETIME 0.50 #define DRAWTIME 1.00 #define PLAYQUEUETIME 0.50 #define RECORDQUEUETIME 1.00 // Global variables used when playing samples int DPSampleStop; int DPSampleRelease1; int DPSampleRelease2; int DPSampleInc; #define COPYREST \ if (stereoMono) \ { \ if (mode == 0) \ { \ for (i=0; i 0) { data = new char [bytes]; if (data) { for (int i=0; i 0) { data = new char [bytes]; if (data) { for (int i=0; i (double)(frames - 1)) return 0; if (channels == 1) channel = 0; else if (channels == 2) channel = channel % 2; else channel = channel % 4; if (frames == 0) { return 0; } if (frames == 1) { return getFrame24 (0,channel); } if (frames == 2) { int val = (int) rint ((1.0 - frame) * getFrame24 (0,channel) + frame * getFrame24 (1,channel)); if (val > MAX23_1) val = MAX23_1; if (val < -MAX23) val = -MAX23; return val; } if (frames == 3) { double x = frame; int x0 = 0; int x1 = 1; int x2 = 2; int f0 = getFrame24 (x0,channel); int f1 = getFrame24 (x1,channel); int f2 = getFrame24 (x2,channel); int df0 = f1 - f0; int df1 = f2 - f1; int ddf0 = df1 - df0; int val = (int) rint (f0 + ((x - x0) * df0) + ((x - x0) * (x - x1) * ddf0 / 2.0)); if (val > MAX23_1) val = MAX23_1; if (val < -MAX23) val = -MAX23; return val; } double x = frame; int x0; int x1; int x2; int x3; if (frame < 1.0) x1 = 1; else if (frame > (double)(frames - 3)) x1 = frames - 3; else x1 = (int) frame; x0 = x1 - 1; x2 = x1 + 1; x3 = x2 + 1; int f0 = getFrame24 (x0,channel); int f1 = getFrame24 (x1,channel); int f2 = getFrame24 (x2,channel); int f3 = getFrame24 (x3,channel); int df0 = f1 - f0; int df1 = f2 - f1; int df2 = f3 - f2; int ddf0 = df1 - df0; int ddf1 = df2 - df1; int dddf0 = ddf1 - ddf0; int val = (int) rint (f0 + ((x - x0) * df0) + ((x - x0) * (x - x1) * ddf0 / 2.0) + ((x - x0) * (x - x1) * (x - x2) * dddf0 / 6.0)); if (val > MAX23_1) val = MAX23_1; if (val < -MAX23) val = -MAX23; return val; } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::getFrame16Interp ---------------------------------------------------------------------------*/ short DPSample::getFrame16Interp (double frame,int channel) { return ((short)((getFrame24Interp (frame,channel)) / 256)); } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::getFrameDbInterp ---------------------------------------------------------------------------*/ double DPSample::getFrameDbInterp (double frame,int channel) { return (((double) getFrame24Interp (frame,channel)) / MAX23); } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::loadAIFF ---------------------------------------------------------------------------*/ char *DPSample::loadAIFF (char *newFilename) { //cerr << "DPSample::loadAIFF" << endl; return load (newFilename,AF_FORMAT_AIFF,0,0,0,0); } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::loadWAV ---------------------------------------------------------------------------*/ char *DPSample::loadWAV (char *newFilename) { //cerr << "DPSample::loadWAV" << endl; return load (newFilename,AF_FORMAT_WAV,0,0,0,0); } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::loadRAW ---------------------------------------------------------------------------*/ char *DPSample::loadRAW ( char *newFilename, int rawChannels, int rawDataFormat, int rawSignedData, int rawEndian) { //cerr << "DPSample::loadRAW" << endl; return load (newFilename,AF_FORMAT_RAW,rawChannels,rawDataFormat, rawSignedData,rawEndian); } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::load ---------------------------------------------------------------------------*/ char *DPSample::load ( char *newFilename, int sampleFormat, int rawChannels, int rawDataFormat, int rawSignedData, int rawEndian) { FHandle irixFile; AFfilesetup fileSetup; AFfilehandle file; long bits; long byteFormat; int license; int licensevoid; char *licenseString; int markerCount; long *markerIDs; int *markerFrames; int instCount; long *instIDs; int susLoopID; int relLoopID; int susStartID; int relStartID; int susEndID; int relEndID; int miscCount; long *miscIDs; //cerr << "DPSample::load" << endl; clear (); // Open requested irix file irixFile = mOpenRead (newFilename); if (!mCheckFile (irixFile)) return "Cannot open specified file"; // Check irix file format if (sampleFormat == AF_FORMAT_AIFF) { format = AFidentifyfd (irixFile); switch (format) { case AF_FILE_AIFF : case AF_FILE_AIFFC : break; case AF_FILE_UNSUPPORTED : mClose (irixFile); return "Unsupported file format"; case AF_FILE_UNKNOWN : default: mClose (irixFile); return "Unknown file format"; } } mClose (irixFile); // Disable void handling AFseterrorhandler (DPSampleAudiofileError); // Create new audio file setup fileSetup = AFnewfilesetup (); switch (sampleFormat) { case AF_FORMAT_AIFF : AFsetsampleformat (fileSetup,AF_FORMAT_AIFF); break; case AF_FORMAT_WAV : AFsetsampleformat (fileSetup,AF_FORMAT_WAV); break; case AF_FORMAT_RAW : if (rawDataFormat < AF_BYTE_FORMAT || rawDataFormat > AF_DOUBLE_FORMAT) return "Invalid raw data format"; if (rawSignedData != AF_SIGNED_FORMAT && rawSignedData != AF_UNSIGNED_FORMAT) return "Invalid raw signed format"; if (rawEndian < AF_DEF_ENDIAN_FORMAT || rawEndian > AF_LITTLE_ENDIAN_FORMAT) return "Invalid raw endian format"; if (rawChannels != 1 && rawChannels != 2 && rawChannels != 4) return "Invalid raw number of channels"; AFsetsampleformat (fileSetup,AF_FORMAT_RAW); AFinitchannels (fileSetup,AF_DEFAULT_TRACK,rawChannels); AFsetrawdataformat (fileSetup,rawDataFormat); AFsetrawsigneddata (fileSetup,rawSignedData); AFsetrawendian (fileSetup,rawEndian); AFsetrawchannels (fileSetup,rawChannels); break; default : return "Unknown sample format specified for loading"; } // Create audio file handle file = AFopenfile (newFilename,"r",fileSetup); if (file == AF_NULL_FILEHANDLE) { AFfreefilesetup (fileSetup); return "Cannot create audio file handle"; } // Get audio track sample rate, format and bits rate = AFgetrate (file,AF_DEFAULT_TRACK); AFgetsampfmt (file,AF_DEFAULT_TRACK,&byteFormat,&bits); // Check sample format switch (byteFormat) { case AF_SAMPFMT_TWOSCOMP : break; default : AFclosefile (file); AFfreefilesetup (fileSetup); return "Unknown sample format"; } // Check audio track no. of bits and calculate byte width (byte // widths allowed are 1 (char) and 2 (short) for up to 16 bits) if (bits > 16) { AFclosefile (file); AFfreefilesetup (fileSetup); return "Bit resolution of more than 16 not supported"; } width = ((bits - 1) / 8) + 1; // Get number of audio track sample channels channels = AFgetchannels (file,AF_DEFAULT_TRACK); if (channels != 1 && channels != 2 && channels != 4) { AFclosefile (file); AFfreefilesetup (fileSetup); return "Only 1,2 or 4 channel AIFF files supported"; } // Get audio track compression compression = AFgetcompression (file,AF_DEFAULT_TRACK); switch (compression) { #ifndef LINUX case AF_COMPRESSION_NONE : case AF_COMPRESSION_G722 : case AF_COMPRESSION_G711_ULAW : case AF_COMPRESSION_G711_ALAW : break; #else case AF_COMPRESSION_NONE : break; case AF_COMPRESSION_G722 : case AF_COMPRESSION_G711_ULAW : case AF_COMPRESSION_G711_ALAW : AFclosefile (file); AFfreefilesetup (fileSetup); return "Unsupported compression method"; #endif case AF_COMPRESSION_AWARE_MPEG : license = AUchecklicense (AU_LICENSE_AWARE_MPEG_DECODER,&licensevoid,&licenseString); if (license != AU_LICENSE_OK) { AFclosefile (file); AFfreefilesetup (fileSetup); return "MPEG decoder not available"; } break; case AF_COMPRESSION_AWARE_MULTIRATE : license = AUchecklicense (AU_LICENSE_AWARE_MULTIRATE_DECODER,&licensevoid,&licenseString); if (license != AU_LICENSE_OK) { AFclosefile (file); AFfreefilesetup (fileSetup); return "Multirate decoder not available"; } break; case AF_COMPRESSION_APPLE_ACE2 : case AF_COMPRESSION_APPLE_ACE8 : case AF_COMPRESSION_APPLE_MAC3 : case AF_COMPRESSION_APPLE_MAC6 : AFclosefile (file); AFfreefilesetup (fileSetup); return "Unsupported compression method"; case AF_COMPRESSION_UNKNOWN : default : AFclosefile (file); AFfreefilesetup (fileSetup); return "Unknown compression method"; } // Get AES data (if any) AESused = AFgetaeschanneldata (file,AF_DEFAULT_TRACK,AES); // Get audio track frame count (and calculate samples and bytes) frames = AFgetframecnt (file,AF_DEFAULT_TRACK); samples = frames * channels; bytes = samples * width; // Get audio track markers markerCount = AFgetmarkids (file,AF_DEFAULT_TRACK,NULL); if (markerCount == 0) { markerIDs = 0; markerFrames = 0; } else { markerIDs = new long [markerCount]; markerFrames = new int [markerCount]; AFgetmarkids (file,AF_DEFAULT_TRACK,markerIDs); for (int i=0; i AF_DOUBLE_FORMAT) return "Invalid raw data format"; if (rawSignedData != AF_SIGNED_FORMAT && rawSignedData != AF_UNSIGNED_FORMAT) return "Invalid raw signed format"; if (rawEndian < AF_DEF_ENDIAN_FORMAT || rawEndian > AF_LITTLE_ENDIAN_FORMAT) return "Invalid raw endian format"; if (rawChannels != 1 && rawChannels != 2 && rawChannels != 4) return "Invalid raw number of channels"; AFsetsampleformat (fileSetup,AF_FORMAT_RAW); AFinitchannels (fileSetup,AF_DEFAULT_TRACK,rawChannels); AFsetrawdataformat (fileSetup,rawDataFormat); AFsetrawsigneddata (fileSetup,rawSignedData); AFsetrawendian (fileSetup,rawEndian); AFsetrawchannels (fileSetup,rawChannels); break; default : return "Unknown sample format specified for saving"; } AFinitfilefmt (fileSetup,format); AFinitrate (fileSetup,AF_DEFAULT_TRACK,rate); AFinitsampfmt (fileSetup,AF_DEFAULT_TRACK,AF_SAMPFMT_TWOSCOMP,width * 8); AFinitchannels (fileSetup,AF_DEFAULT_TRACK,channels); if (AESused) AFinitaeschanneldata (fileSetup,AF_DEFAULT_TRACK); if (format == AF_FILE_AIFF && compression != AF_COMPRESSION_NONE) return "Cannot use compression with AIFF samples"; if (format == AF_FILE_AIFFC) { switch (compression) { case AF_COMPRESSION_NONE : break; #ifndef LINUX case AF_COMPRESSION_G722 : if (width != 2) { AFfreefilesetup (fileSetup); return "G722 encoding can only be used on 16 bit samples"; } AFinitcompression (fileSetup,AF_DEFAULT_TRACK,compression); break; case AF_COMPRESSION_G711_ULAW : if (width != 2) { AFfreefilesetup (fileSetup); return "G711 ulaw encoding can only be used on 16 bit samples"; } AFinitcompression (fileSetup,AF_DEFAULT_TRACK,compression); break; case AF_COMPRESSION_G711_ALAW : if (width != 2) { AFfreefilesetup (fileSetup); return "G711 alaw encoding can only be used on 16 bit samples"; } AFinitcompression (fileSetup,AF_DEFAULT_TRACK,compression); break; #else case AF_COMPRESSION_G722 : case AF_COMPRESSION_G711_ULAW : case AF_COMPRESSION_G711_ALAW : AFfreefilesetup (fileSetup); return "Unsupported compression method"; #endif case AF_COMPRESSION_AWARE_MPEG : case AF_COMPRESSION_AWARE_DEFAULT_MPEG_I : case AF_COMPRESSION_AWARE_DEFAULT_MPEG_II : license = AUchecklicense (AU_LICENSE_AWARE_MPEG_ENCODER,&licensevoid,&licenseString); if (license != AU_LICENSE_OK) { AFfreefilesetup (fileSetup); return "MPEG encoder not available"; } AFinitcompression (fileSetup,AF_DEFAULT_TRACK,compression); break; case AF_COMPRESSION_AWARE_MULTIRATE : case AF_COMPRESSION_AWARE_DEFAULT_MULTIRATE : case AF_COMPRESSION_AWARE_DEFAULT_LOSSLESS : license = AUchecklicense (AU_LICENSE_AWARE_MULTIRATE_ENCODER,&licensevoid,&licenseString); if (license != AU_LICENSE_OK) { AFfreefilesetup (fileSetup); return "Multirate encoder not available"; } AFinitcompression (fileSetup,AF_DEFAULT_TRACK,compression); break; default : AFfreefilesetup (fileSetup); return "Unsupported compression method"; } } long markerIDs [] = {1,2,3,4}; AFinitmarkids (fileSetup,AF_DEFAULT_TRACK,markerIDs,4); AFinitmarkname (fileSetup,AF_DEFAULT_TRACK,1,"sustain loop start"); AFinitmarkname (fileSetup,AF_DEFAULT_TRACK,2,"sustain loop end"); AFinitmarkname (fileSetup,AF_DEFAULT_TRACK,3,"release loop start"); AFinitmarkname (fileSetup,AF_DEFAULT_TRACK,4,"release loop end"); long instIDs [] = {AF_DEFAULT_INST}; AFinitinstids (fileSetup,instIDs,1); long loopIDs [] = {1,2}; AFinitloopids (fileSetup,AF_DEFAULT_TRACK,loopIDs,2); char *newName = ""; char *newCopyright = ""; char *newAuthor = ""; char *newAnnotation = ""; if (name) newName = name; if (copyright) newCopyright = copyright; if (author) newAuthor = author; if (annotation) newAnnotation = annotation; char *tempAnnotation = 0; if (!strstr (newAnnotation,ANNONEW)) { tempAnnotation = new char [strlen (newAnnotation) + strlen (ANNONEW) + 1]; strcpy (tempAnnotation,newAnnotation); strcpy (tempAnnotation + strlen (newAnnotation),ANNONEW); newAnnotation = tempAnnotation; } long miscIDs [] = {1,2,3,4}; if (soxcompatible && sampleFormat == AF_FORMAT_AIFF) { // Current version of sox cannot handle odd length string :( AFinitmiscids (fileSetup,miscIDs,0); } else { AFinitmiscids (fileSetup,miscIDs,4); AFinitmisctype (fileSetup,1,AF_MISC_AIFF_NAME); AFinitmisctype (fileSetup,2,AF_MISC_AIFF_AUTH); AFinitmisctype (fileSetup,3,AF_MISC_AIFF_ANNO); AFinitmisctype (fileSetup,4,AF_MISC_AIFF_COPY); AFinitmiscsize (fileSetup,1,strlen (newName)); AFinitmiscsize (fileSetup,2,strlen (newAuthor)); AFinitmiscsize (fileSetup,3,strlen (newAnnotation)); AFinitmiscsize (fileSetup,4,strlen (newCopyright)); } if (newFilename) file = AFopenfile (newFilename,"w",fileSetup); else file = AFopenfile (filename,"w",fileSetup); if (!file) { AFfreefilesetup (fileSetup); delete [] tempAnnotation; return "Unable to open file for writing"; } if (newFilename && replaceFilename) { delete [] filename; filename = new char [strlen (newFilename) + 1]; strcpy (filename,newFilename); } if (!rangeonly) { AFsetmarkpos (file,AF_DEFAULT_TRACK,1,susLoopStart); AFsetmarkpos (file,AF_DEFAULT_TRACK,2,susLoopEnd-1); AFsetmarkpos (file,AF_DEFAULT_TRACK,3,relLoopStart); AFsetmarkpos (file,AF_DEFAULT_TRACK,4,relLoopEnd-1); } else { AFsetmarkpos (file,AF_DEFAULT_TRACK,1,0); AFsetmarkpos (file,AF_DEFAULT_TRACK,2,0); AFsetmarkpos (file,AF_DEFAULT_TRACK,3,0); AFsetmarkpos (file,AF_DEFAULT_TRACK,4,0); } if (AESused) AFsetaeschanneldata (file,AF_DEFAULT_TRACK,AES); if (!rangeonly) { AFwriteframes (file,AF_DEFAULT_TRACK,data,frames); if (extra) { extraListEntry *e; e = extra; while (e) { AFwriteframes (file,AF_DEFAULT_TRACK,e->data,e->end - e->start + 1); e = e->next; } } } else { char *dataRangeStart; int dataRangeLen; dataRangeStart = (char *) data + (rangeStart * channels * width); dataRangeLen = rangeEnd - rangeStart; AFwriteframes (file,AF_DEFAULT_TRACK,dataRangeStart,dataRangeLen); } if (!rangeonly) { AFsetinstparamint (file,AF_DEFAULT_INST,AF_INST_SUSLOOPID,1); AFsetinstparamint (file,AF_DEFAULT_INST,AF_INST_RELLOOPID,2); AFsetloopmode (file,AF_DEFAULT_INST,1,susLoopMode); AFsetloopmode (file,AF_DEFAULT_INST,2,relLoopMode); AFsetloopstart (file,AF_DEFAULT_INST,1,1); AFsetloopend (file,AF_DEFAULT_INST,1,2); AFsetloopstart (file,AF_DEFAULT_INST,2,3); AFsetloopend (file,AF_DEFAULT_INST,2,4); } else { AFsetinstparamint (file,AF_DEFAULT_INST,AF_INST_SUSLOOPID,1); AFsetinstparamint (file,AF_DEFAULT_INST,AF_INST_RELLOOPID,2); AFsetloopmode (file,AF_DEFAULT_INST,1,AF_LOOP_MODE_NOLOOP); AFsetloopmode (file,AF_DEFAULT_INST,2,AF_LOOP_MODE_NOLOOP); AFsetloopstart (file,AF_DEFAULT_INST,1,1); AFsetloopend (file,AF_DEFAULT_INST,1,2); AFsetloopstart (file,AF_DEFAULT_INST,2,3); AFsetloopend (file,AF_DEFAULT_INST,2,4); } if (!soxcompatible || sampleFormat != AF_FORMAT_AIFF) { AFwritemisc (file,1,newName,strlen (newName)); AFwritemisc (file,2,newAuthor,strlen (newAuthor)); AFwritemisc (file,3,newAnnotation,strlen (newAnnotation)); AFwritemisc (file,4,newCopyright,strlen (newCopyright)); } AFclosefile (file); AFfreefilesetup (fileSetup); delete [] tempAnnotation; changed = FALSE; return 0; } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::play ---------------------------------------------------------------------------*/ char *DPSample::play (int playMode,FL_OBJECT *object) { //cerr << "DPSample::play" << endl; // Range = mode 0 // Display = mode 1 // All = mode 2 ALconfig audioConfig; ALport audioPort; int queueSize; if (!valid) { // No valid sample (not an error) return 0; } if (playMode == 0 && !rangeValid) { // No valid sample range (not an error) return 0; } int intPlayRate; double playRate; intPlayRate = getOutputRate (); if (intPlayRate == AL_RATE_UNDEFINED) playRate = rate; else playRate = intPlayRate; // Disable error handler ALseterrorhandler (0); // 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); if (width == 1) ALsetwidth (audioConfig,AL_SAMPLE_8); else ALsetwidth (audioConfig,AL_SAMPLE_16); // Set number of channels ALsetchannels (audioConfig,channels); // Set queue size (PLAYQUEUETIME seconds at playback rate) queueSize = (int) (playRate * channels * PLAYQUEUETIME); limitQueueSize (channels,&queueSize); if (ALsetqueuesize (audioConfig,queueSize)) { ALfreeconfig (audioConfig); return "Unable to establish audio queue"; } // Open new audio port with given configuration audioPort = ALopenport (PORTNAME,"w",audioConfig); if (!audioPort) { ALfreeconfig (audioConfig); return "Unable to open audio port"; } // Play the sample int playStart; int playEnd; int susLoopIncrement = 1; int relLoopIncrement = 1; int tempSusLoopMode = susLoopMode; int tempRelLoopMode = relLoopMode; DPSampleInc = 1; DPSampleStop = FALSE; DPSampleRelease1 = FALSE; DPSampleRelease2 = FALSE; if (playMode == 0) { playStart = rangeStart; if (rangeStart == rangeEnd) playEnd = frames; else playEnd = rangeEnd; } else if (playMode == 1) { playStart = displayStart; playEnd = displayEnd; } else { playStart = 0; playEnd = frames; } if (playEnd <= playStart) { // No sample data to play (not an error) ALcloseport (audioPort); ALfreeconfig (audioConfig); return 0; } #ifdef NOFORMS #ifndef LINUX sigset (SIGTSTP,DPSampleReleaseCatch); sigset (SIGINT,DPSampleStopCatch); #else signal (SIGTSTP,DPSampleReleaseCatch); signal (SIGINT,DPSampleStopCatch); #endif #endif // No looping if playing range or display if (playMode == 0 || playMode == 1) { tempSusLoopMode = AF_LOOP_MODE_NOLOOP; tempRelLoopMode = AF_LOOP_MODE_NOLOOP; } else { // Catch special case (loops of duration zero and one) if (susLoopStart == susLoopEnd) tempSusLoopMode = AF_LOOP_MODE_NOLOOP; if (relLoopStart == relLoopEnd) tempRelLoopMode = AF_LOOP_MODE_NOLOOP; if (susLoopStart == susLoopEnd - 1) susLoopIncrement = 0; if (relLoopStart == relLoopEnd - 1) relLoopIncrement = 0; } int i = playStart; int checkReset = (int) (playRate * CHECKTIME); int check = 1; int lineReset = (int) (playRate * LINETIME); int line = 1; int drawReset = (int) (playRate * DRAWTIME); int draw = 1; int oldDisplay = -1; #ifdef SNEAKYCHECK XEvent newEvent; #endif while (i >= playStart && i < playEnd && !DPSampleStop) { ALwritesamps (audioPort,((char *) data) + (i * width * channels),channels); if (!DPSampleRelease1) { if (tempSusLoopMode == AF_LOOP_MODE_FORW && i == susLoopEnd - 1) i = susLoopStart - 1; else if (tempSusLoopMode == AF_LOOP_MODE_FORWBAKW) { if (i == susLoopEnd - 1) DPSampleInc = -susLoopIncrement; else if (i == susLoopStart) DPSampleInc = susLoopIncrement; } } else if (!DPSampleRelease2) { if (tempRelLoopMode == AF_LOOP_MODE_FORW && i == relLoopEnd - 1) i = relLoopStart - 1; else if (tempRelLoopMode == AF_LOOP_MODE_FORWBAKW) { if (i == relLoopEnd - 1) DPSampleInc = -relLoopIncrement; else if (i == relLoopStart) DPSampleInc = relLoopIncrement; } } currentPos = i; if (object) { if (!--check) { check = checkReset; #ifndef NOFORMS #ifdef SNEAKYCHECK if (XCheckWindowEvent (fl_display, playForm->playForm->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 // SNEAKYCHECK #endif // NOFORMS } if (!--line) { line = lineReset; redraw = 1; #ifndef NOFORMS fl_redraw_object (object); #endif redraw = 0; } if (!--draw) { draw = drawReset; if (displayStart != oldDisplay) { #ifndef NOFORMS fl_redraw_object (mainForm->scrollBarSlider); updateDisplayDetails (); #endif oldDisplay = displayStart; } } } i += DPSampleInc; } #ifdef NOFORMS #ifndef LINUX sigset (SIGTSTP,SIG_DFL); sigset (SIGINT,SIG_DFL); #else signal (SIGTSTP,SIG_DFL); signal (SIGINT,SIG_DFL); #endif #endif // Wait until port cleared if (!DPSampleStop) { #ifdef LINUX ALflush (audioPort,0); #else while (ALgetfilled (audioPort)) {} #endif } // Close the port, free the configuration and return ALcloseport (audioPort); ALfreeconfig (audioConfig); currentPos = -1; if (object) { #ifndef NOFORMS redraw = 1; fl_redraw_object (object); redraw = 0; fl_redraw_object (mainForm->scrollBarSlider); updateDisplayDetails (); #endif } return 0; } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::record ---------------------------------------------------------------------------*/ char *DPSample::record (int recordMode,int trigger,FL_OBJECT *object) { ALconfig audioConfig; ALport audioPort; int queueSize; //cerr << "DPSample::record" << endl; if (!valid) { // No valid sample (not an error) return 0; } if (recordMode == 0 && !rangeValid) { // No valid sample range (not an error) return 0; } int intRecordRate; double recordRate; intRecordRate = getInputRate (); if (intRecordRate == AL_RATE_UNDEFINED) recordRate = rate; else recordRate = intRecordRate; // Disable error handler ALseterrorhandler (0); // 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); if (width == 1) ALsetwidth (audioConfig,AL_SAMPLE_8); else ALsetwidth (audioConfig,AL_SAMPLE_16); // Set number of channels ALsetchannels (audioConfig,channels); // Set queue size (RECORDQUEUETIME seconds at record rate) queueSize = (int) (recordRate * channels * RECORDQUEUETIME); limitQueueSize (channels,&queueSize); if (ALsetqueuesize (audioConfig,queueSize)) { ALfreeconfig (audioConfig); return "Unable to establish audio queue"; } // Open new audio port with given configuration audioPort = ALopenport (PORTNAME,"r",audioConfig); if (!audioPort) { ALfreeconfig (audioConfig); return "Unable to open audio port"; } // Record the sample int recordStart; int recordEnd; DPSampleStop = FALSE; if (recordMode == 0) { recordStart = rangeStart; if (rangeStart == rangeEnd) recordEnd = frames; else recordEnd = rangeEnd; } else if (recordMode == 1) { recordStart = displayStart; recordEnd = displayEnd; } else { recordStart = 0; recordEnd = frames; } if (recordEnd <= recordStart) { // No sample data to record (not an error) ALcloseport (audioPort); ALfreeconfig (audioConfig); return 0; } #ifdef NOFORMS #ifndef LINUX sigset (SIGINT,DPSampleStopCatch); #else signal (SIGINT,DPSampleStopCatch); #endif #endif int i = recordStart; int checkReset = (int) (recordRate * CHECKTIME); int check = 1; int lineReset = (int) (recordRate * LINETIME); int line = 1; int drawReset = (int) (recordRate * DRAWTIME); int draw = 1; int oldDisplay = -1; char *tempbuf = new char [channels * width]; int trigval = trigger; int usingExtra = FALSE; extraListEntry *e = 0; #ifdef SNEAKYCHECK XEvent newEvent; #endif removeExtra (); if (width == 2) trigval *= 256; if (trigval >= 0) { int trigset = 0; while (!trigset && !DPSampleStop) { ALreadsamps (audioPort,(char *) tempbuf,channels); if (width == 1) { if (((signed char *) tempbuf) [0] >= trigval || ((signed char *) tempbuf) [0] <= -trigval) trigset = 1; if ((channels == 2 || channels == 4) && (((signed char *) tempbuf) [1] >= trigval || ((signed char *) tempbuf) [1] <= -trigval)) trigset = 1; if (channels == 4 && (((signed char *) tempbuf) [2] >= trigval || ((signed char *) tempbuf) [2] <= -trigval)) trigset = 1; if (channels == 4 && (((signed char *) tempbuf) [3] >= trigval || ((signed char *) tempbuf) [3] <= -trigval)) trigset = 1; } else { if (((short *) tempbuf) [0] >= trigval || ((short *) tempbuf) [0] <= -trigval) trigset = 1; if ((channels == 2 || channels == 4) && (((short *) tempbuf) [1] >= trigval || ((short *) tempbuf) [1] <= -trigval)) trigset = 1; if (channels == 4 && (((short *) tempbuf) [2] >= trigval || ((short *) tempbuf) [2] <= -trigval)) trigset = 1; if (channels == 4 && (((short *) tempbuf) [3] >= trigval || ((short *) tempbuf) [3] <= -trigval)) trigset = 1; } if (object) { if (!--check) { check = checkReset; #ifndef NOFORMS #ifdef SNEAKYCHECK if (XCheckWindowEvent (fl_display, recordForm->recordForm->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 // SNEAKYCHECK #endif // NOFORMS } if (!--line) { line = lineReset; redraw = 1; #ifndef NOFORMS fl_redraw_object (object); #endif redraw = 0; } if (!--draw) { draw = drawReset; redraw = 2; #ifndef NOFORMS fl_redraw_object (object); #endif redraw = 0; if (displayStart != oldDisplay) { #ifndef NOFORMS fl_redraw_object (mainForm->scrollBarSlider); updateDisplayDetails (); #endif oldDisplay = displayStart; } } } } } while (i >= recordStart && i <= recordEnd && !DPSampleStop) { if (i == recordEnd) { if (recordMode == 2 && (e = expand (1.0))) { usingExtra = TRUE; recordEnd = e->end + 1; } else { DPSampleStop = TRUE; break; } } if (!usingExtra) { ALreadsamps (audioPort,((char *) data) + (i * width * channels),channels); currentPos = i; } else { ALreadsamps (audioPort,((char *) e->data) + ((i - e->start) * width * channels),channels); } if (object) { if (!--check) { check = checkReset; #ifndef NOFORMS #ifdef SNEAKYFORMS if (XCheckWindowEvent (fl_display, recordForm->recordForm->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 // SNEAKYCHECK #endif // NOFORMS } if (!--line) { line = lineReset; redraw = 1; #ifndef NOFORMS fl_redraw_object (object); #endif redraw = 0; } if (!--draw) { draw = drawReset; redraw = 2; #ifndef NOFORMS fl_redraw_object (object); #endif redraw = 0; if (displayStart != oldDisplay) { #ifndef NOFORMS fl_redraw_object (mainForm->scrollBarSlider); updateDisplayDetails (); #endif oldDisplay = displayStart; } } } i++; } #ifdef NOFORMS #ifndef LINUX sigset (SIGINT,SIG_DFL); #else signal (SIGINT,SIG_DFL); #endif #endif // Close the port, free the configuration and return ALcloseport (audioPort); ALfreeconfig (audioConfig); currentPos = -1; if (object) { #ifndef NOFORMS redraw = 2; fl_redraw_object (object); redraw = 0; fl_redraw_object (mainForm->scrollBarSlider); updateDisplayDetails (); #endif } delete tempbuf; // Adjust DC for calibration between recordStart and i int rangeValidBak = rangeValid; int rangeStartBak = rangeStart; int rangeEndBak = rangeEnd; rangeValid = TRUE; rangeStart = recordStart; rangeEnd = i - 1; #ifndef NOFORMS if (recordAdjustLeft != 0.0) adjustDC ((int) recordAdjustLeft,0); if ((channels == 2 || channels == 4) && recordAdjustRight != 0.0) adjustDC ((int) recordAdjustRight,1); if (channels == 4 && recordAdjustThree != 0.0) adjustDC ((int) recordAdjustThree,2); if (channels == 4 && recordAdjustFour != 0.0) adjustDC ((int) recordAdjustFour,3); #endif setRange (rangeStartBak,rangeEndBak); rangeValid = rangeValidBak; changed = TRUE; return 0; } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::clear ---------------------------------------------------------------------------*/ void DPSample::clear () { //cerr << "DPSample::clear" << endl; // Note by default clear resets changed to FALSE // (this may not be as intended - use setChanged if necessary) delete [] filename; delete [] name; delete [] author; delete [] copyright; delete [] annotation; delete [] data; valid = FALSE; changed = FALSE; format = AF_FILE_AIFF; compression = AF_COMPRESSION_NONE; rate = 44100.0; width = 1; channels = 1; frames = 0; samples = 0; bytes = 0; AESused = 0; for (int i=0; i<24; i++) AES [i] = 0; filename = 0; name = 0; copyright = 0; author = 0; annotation = 0; susLoopMode = AF_LOOP_MODE_NOLOOP; susLoopStart = 0; susLoopEnd = 0; relLoopMode = AF_LOOP_MODE_NOLOOP; relLoopStart = 0; relLoopEnd = 0; rangeValid = FALSE; rangeStart = 0; rangeEnd = 0; displayStart = 0; displayEnd = 0; displayVertLow = -MAX23; displayVertHigh = MAX23_1; redraw = 0; currentPos = -1; data = 0; removeExtra (); } /*--------------------------------------------------------------------------- | PUBLIC METHOD DPSample::fresh ---------------------------------------------------------------------------*/ int DPSample::fresh ( double newRate, int newWidth, int newChannels, int newFrames) { //cerr << "DPSample::fresh" << endl; clear (); rate = newRate; width = newWidth; channels = newChannels; frames = newFrames; samples = frames * channels; bytes = samples * width; if (!frames) { displayStart = 0; displayEnd = frames; displayVertLow = -MAX23; displayVertHigh = MAX23_1; valid = FALSE; return NOERROR; } data = new char [bytes]; if (data) { for (int i=0; i frames) newDisplayEnd = frames; } else if (newDisplayEnd > frames) { newDisplayStart -= (newDisplayEnd - frames); newDisplayEnd = frames; if (newDisplayStart < 0) newDisplayStart = 0; } displayStart = newDisplayStart; displayEnd = newDisplayEnd; } /*--------------------------------------------------------------------------- | Scroll functions ---------------------------------------------------------------------------*/ void DPSample::scrollLstart () { //cerr << "DPSample::scrollLstart" << endl; int displayWidth; displayWidth = displayEnd - displayStart; displayStart = 0; displayEnd = displayWidth; } void DPSample::scrollL (int scrollFrames) { //cerr << "DPSample::scrollL" << endl; int newDisplayStart; int displayWidth; displayWidth = displayEnd - displayStart; newDisplayStart = displayStart - scrollFrames; if (newDisplayStart < 0) newDisplayStart = 0; displayStart = newDisplayStart; displayEnd = newDisplayStart + displayWidth; } void DPSample::scrollR (int scrollFrames) { //cerr << "DPSample::scrollR" << endl; int newDisplayEnd; int displayWidth; displayWidth = displayEnd - displayStart; newDisplayEnd = displayEnd + scrollFrames; if (newDisplayEnd > frames) newDisplayEnd = frames; displayStart = newDisplayEnd - displayWidth; displayEnd = newDisplayEnd; } void DPSample::scrollRend () { //cerr << "DPSample::scrollRend" << endl; int displayWidth; displayWidth = displayEnd - displayStart; displayStart = frames - displayWidth; displayEnd = frames; } /*--------------------------------------------------------------------------- | Vertical zoom functions ---------------------------------------------------------------------------*/ void DPSample::zoomVertIn (int minHeight) { //cerr << "DPSample::zoomVertIn" << endl; int displayHeight = displayVertHigh - displayVertLow; int newDisplayHeight = (int) (displayHeight / ZOOMFACTOR); if (newDisplayHeight == displayHeight) newDisplayHeight -= 2; if (newDisplayHeight < minHeight) newDisplayHeight = minHeight; zoomVertHeight (newDisplayHeight); } void DPSample::zoomVertOut () { //cerr << "DPSample::zoomVertOut" << endl; int displayHeight = displayVertHigh - displayVertLow; int newDisplayHeight = (int) (displayHeight * ZOOMFACTOR); if (newDisplayHeight == displayHeight) newDisplayHeight += 2; zoomVertHeight (newDisplayHeight); } void DPSample::zoomVertAll () { //cerr << "DPSample::zoomVertAll" << endl; displayVertLow = -MAX23; displayVertHigh = MAX23_1; } void DPSample::zoomVertHeight (int height) { //cerr << "DPSample::zoomVertHeight" << endl; int newDisplayVertLow; int newDisplayVertHigh; int displayHeight; if (height < 1) height = 1; displayHeight = displayVertHigh - displayVertLow; newDisplayVertLow = (int) (displayVertLow + ((displayHeight - height) / 2.0)); newDisplayVertHigh = (int) (displayVertLow + ((displayHeight + height) / 2.0)); if (newDisplayVertLow < -MAX23) { newDisplayVertHigh -= (newDisplayVertLow + MAX23); newDisplayVertLow = -MAX23; if (newDisplayVertHigh > MAX23_1) newDisplayVertHigh = MAX23_1; } else if (newDisplayVertHigh > MAX23_1) { newDisplayVertLow -= (newDisplayVertHigh - MAX23_1); newDisplayVertHigh = MAX23_1; if (newDisplayVertLow < -MAX23) newDisplayVertLow = -MAX23; } displayVertLow = newDisplayVertLow; displayVertHigh = newDisplayVertHigh; } /*--------------------------------------------------------------------------- | Vertical scroll functions ---------------------------------------------------------------------------*/ void DPSample::scrollVertBottom () { //cerr << "DPSample::scrollVertBottom" << endl; int displayHeight; displayHeight = displayVertHigh - displayVertLow; displayVertLow = -MAX23; displayVertHigh = -MAX23 + displayHeight; } void DPSample::scrollVertDown (int scrollAmount) { //cerr << "DPSample::scrollVertDown" << endl; int newDisplayVertLow; int displayHeight; displayHeight = displayVertHigh - displayVertLow; newDisplayVertLow = displayVertLow - scrollAmount; if (newDisplayVertLow < -MAX23) newDisplayVertLow = -MAX23; displayVertLow = newDisplayVertLow; displayVertHigh = newDisplayVertLow + displayHeight; } void DPSample::scrollVertCentre () { //cerr << "DPSample::scrollVertCentre" << endl; int displayHeight; displayHeight = displayVertHigh - displayVertLow; displayVertLow = -(displayHeight / 2); displayVertHigh = displayHeight / 2; if (displayVertLow == displayVertHigh) displayVertHigh++; } void DPSample::scrollVertUp (int scrollAmount) { //cerr << "DPSample::scrollVertUp" << endl; int newDisplayVertHigh; int displayHeight; displayHeight = displayVertHigh - displayVertLow; newDisplayVertHigh = displayVertHigh + scrollAmount; if (newDisplayVertHigh > MAX23_1) newDisplayVertHigh = MAX23_1; displayVertLow = newDisplayVertHigh - displayHeight; displayVertHigh = newDisplayVertHigh; } void DPSample::scrollVertTop () { //cerr << "DPSample::scrollVertTop" << endl; int displayHeight; displayHeight = displayVertHigh - displayVertLow; displayVertLow = MAX23_1 - displayHeight; displayVertHigh = MAX23_1; } /*--------------------------------------------------------------------------- | Conversion functions ---------------------------------------------------------------------------*/ void DPSample::to8bit () { if (!valid || width == 1) return; DPSample newSamp; if (!newSamp.fresh (rate,1,channels,frames)) return; int i; int temp; int stereo = (channels == 2); int quadro = (channels == 4); for (i=0; i= 0 && !done) { if (getFrame24 (i,0) != 0) done = TRUE; else i--; } } else if (channels == 2) { while (i >= 0 && !done) { if (getFrame24 (i,0) != 0 || getFrame24 (i,1) != 0) done = TRUE; else i--; } } else { while (i >= 0 && !done) { if (getFrame24 (i,0) != 0 || getFrame24 (i,1) != 0 || getFrame24 (i,2) != 0 || getFrame24 (i,3) != 0) done = TRUE; else i--; } } int rangeValidBak = rangeValid; int rangeStartBak = rangeStart; int rangeEndBak = rangeEnd; rangeValid = TRUE; rangeStart = i+1; rangeEnd = frames; del (2); setRange (rangeStartBak,rangeEndBak); rangeValid = rangeValidBak; changed = TRUE; } /*--------------------------------------------------------------------------- | Cut & paste functions ---------------------------------------------------------------------------*/ void DPSample::cut (DPSample *clip,int mode) { if (!valid || !rangeValid) return; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return; int newBufferLen = frames - rangeLen; DPSample newSamp; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (stereoMono || quadroMono) { newBufferLen = frames; if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; if (!clip->fresh (rate,width,1,rangeLen)) return; } else { if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; if (!clip->fresh (rate,width,channels,rangeLen)) return; } int i; int x; int temp; for (i=0; i= rangeEnd) { x = i - rangeLen; if (left) { temp = getFrame24 (i,0); newSamp.setFrame24 (x,0,temp); } if (right) { temp = getFrame24 (i,1); newSamp.setFrame24 (x,1,temp); } if (three) { temp = getFrame24 (i,2); newSamp.setFrame24 (x,2,temp); } if (four) { temp = getFrame24 (i,3); newSamp.setFrame24 (x,3,temp); } } else { x = i - rangeStart; if (left) { temp = getFrame24 (i,0); clip->setFrame24 (x,0,temp); } if (right) { temp = getFrame24 (i,1); clip->setFrame24 (x,1,temp); } if (three) { temp = getFrame24 (i,2); clip->setFrame24 (x,2,temp); } if (four) { temp = getFrame24 (i,3); clip->setFrame24 (x,3,temp); } } } COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; // Sort out markers if (!stereoMono && !quadroMono) { int displayDuration = displayEnd - displayStart; if (displayEnd > frames) displayEnd = frames; displayStart = displayEnd - displayDuration; if (displayStart < 0) displayStart = 0; if (susLoopStart >= rangeEnd) susLoopStart -= rangeLen; else if (susLoopStart >= rangeStart) susLoopStart = rangeStart; if (susLoopEnd >= rangeEnd) susLoopEnd -= rangeLen; else if (susLoopEnd >= rangeStart) susLoopEnd = rangeStart; if (relLoopStart >= rangeEnd) relLoopStart -= rangeLen; else if (relLoopStart >= rangeStart) relLoopStart = rangeStart; if (relLoopEnd >= rangeEnd) relLoopEnd -= rangeLen; else if (relLoopEnd >= rangeStart) relLoopEnd = rangeStart; } rangeStart = 0; rangeEnd = 0; rangeValid = FALSE; changed = TRUE; } void DPSample::del (int mode) { if (!valid || !rangeValid) return; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return; int newBufferLen = frames - rangeLen; DPSample newSamp; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (stereoMono || quadroMono) { newBufferLen = frames; if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; } else { if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; } int i; int x; int temp; for (i=0; i= rangeEnd) { x = i - rangeLen; if (left) { temp = getFrame24 (i,0); newSamp.setFrame24 (x,0,temp); } if (right) { temp = getFrame24 (i,1); newSamp.setFrame24 (x,1,temp); } if (three) { temp = getFrame24 (i,2); newSamp.setFrame24 (x,2,temp); } if (four) { temp = getFrame24 (i,3); newSamp.setFrame24 (x,3,temp); } } } COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; // Sort out markers if (!stereoMono && !quadroMono) { int displayDuration = displayEnd - displayStart; if (displayEnd > frames) displayEnd = frames; displayStart = displayEnd - displayDuration; if (displayStart < 0) displayStart = 0; if (susLoopStart >= rangeEnd) susLoopStart -= rangeLen; else if (susLoopStart >= rangeStart) susLoopStart = rangeStart; if (susLoopEnd >= rangeEnd) susLoopEnd -= rangeLen; else if (susLoopEnd >= rangeStart) susLoopEnd = rangeStart; if (relLoopStart >= rangeEnd) relLoopStart -= rangeLen; else if (relLoopStart >= rangeStart) relLoopStart = rangeStart; if (relLoopEnd >= rangeEnd) relLoopEnd -= rangeLen; else if (relLoopEnd >= rangeStart) relLoopEnd = rangeStart; } rangeStart = 0; rangeEnd = 0; rangeValid = FALSE; changed = TRUE; } void DPSample::copy (DPSample *clip,int mode) { if (!valid || !rangeValid) return; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (stereoMono || quadroMono) { if (!clip->fresh (rate,width,1,rangeLen)) return; } else { if (!clip->fresh (rate,width,channels,rangeLen)) return; } int i; int x; int temp; for (i=rangeStart; isetFrame24 (x,0,temp); } if (right) { temp = getFrame24 (i,1); clip->setFrame24 (x,1,temp); } if (three) { temp = getFrame24 (i,2); clip->setFrame24 (x,2,temp); } if (four) { temp = getFrame24 (i,3); clip->setFrame24 (x,3,temp); } } } void DPSample::paste (DPSample *clip,int mode) { if (!valid || !rangeValid || !clip->valid) return; int rangeLen = clip->frames; if (rangeLen == 0) return; int newBufferLen = frames + rangeLen; DPSample newSamp; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (stereoMono || quadroMono) { if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; } else { if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; } rangeEnd = rangeStart + rangeLen; int i; int x; int temp; for (i=0; i= rangeEnd) { x = i - rangeLen; if (left) { temp = getFrame24 (x,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = getFrame24 (x,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = getFrame24 (x,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = getFrame24 (x,3); newSamp.setFrame24 (i,3,temp); } } else { x = i - rangeStart; if (left) { temp = clip->getFrame24 (x,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = clip->getFrame24 (x,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = clip->getFrame24 (x,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = clip->getFrame24 (x,3); newSamp.setFrame24 (i,3,temp); } } } COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; // Sort out markers if (!stereoMono && !quadroMono) { if (susLoopStart >= rangeStart) susLoopStart += rangeLen; if (susLoopEnd >= rangeStart) susLoopEnd += rangeLen; if (relLoopStart >= rangeStart) relLoopStart += rangeLen; if (relLoopEnd >= rangeStart) relLoopEnd += rangeLen; } changed = TRUE; } void DPSample::keep (DPSample *clip,int mode) { if (!valid || !rangeValid) return; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return; int newBufferLen = rangeLen; DPSample newSamp; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (stereoMono || quadroMono) { newBufferLen = frames; if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; if (!clip->fresh (rate,width,1,frames - rangeLen)) return; } else { if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; if (!clip->fresh (rate,width,channels,frames - rangeLen)) return; } int i; int x; int temp; for (i=0; isetFrame24 (i,0,temp); } if (right) { temp = getFrame24 (i,1); clip->setFrame24 (i,1,temp); } if (three) { temp = getFrame24 (i,2); clip->setFrame24 (i,2,temp); } if (four) { temp = getFrame24 (i,3); clip->setFrame24 (i,3,temp); } } else if (i >= rangeEnd) { x = i - rangeLen; if (left) { temp = getFrame24 (i,0); clip->setFrame24 (x,0,temp); } if (right) { temp = getFrame24 (i,1); clip->setFrame24 (x,1,temp); } if (three) { temp = getFrame24 (i,2); clip->setFrame24 (x,2,temp); } if (four) { temp = getFrame24 (i,3); clip->setFrame24 (x,3,temp); } } else { x = i - rangeStart; if (left) { temp = getFrame24 (i,0); newSamp.setFrame24 (x,0,temp); } if (right) { temp = getFrame24 (i,1); newSamp.setFrame24 (x,1,temp); } if (three) { temp = getFrame24 (i,2); newSamp.setFrame24 (x,2,temp); } if (four) { temp = getFrame24 (i,3); newSamp.setFrame24 (x,3,temp); } } } COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; // Sort out markers if (!stereoMono && !quadroMono) { displayStart = displayStart - rangeStart; displayEnd = displayEnd - rangeStart; if (displayStart < 0) displayStart = 0; if (displayEnd > frames) displayEnd = frames; if (displayStart > frames || displayEnd < 0) { displayStart = 0; displayEnd = frames; } if (susLoopStart >= rangeEnd) susLoopStart = frames; else if (susLoopStart >= rangeStart) susLoopStart -= rangeStart; else susLoopStart = 0; if (susLoopEnd >= rangeEnd) susLoopEnd = frames; else if (susLoopEnd >= rangeStart) susLoopEnd -= rangeStart; else susLoopEnd = 0; if (relLoopStart >= rangeEnd) relLoopStart = frames; else if (relLoopStart >= rangeStart) relLoopStart -= rangeStart; else relLoopStart = 0; if (relLoopEnd >= rangeEnd) relLoopEnd = frames; else if (relLoopEnd >= rangeStart) relLoopEnd -= rangeStart; else relLoopEnd = 0; } rangeStart = 0; rangeEnd = 0; rangeValid = FALSE; changed = TRUE; } void DPSample::overwriteRange (DPSample *clip,int mode) { mixRange (clip,0,100,0,0,mode); } void DPSample::mixRange ( DPSample *clip, double buffVol, double clipVol, int mixin, int mixout, int mode) { if (!valid || !rangeValid || !clip->valid) return; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return; int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); int i; int x; int y; int temp; double clipVolume; double buffVolume; for (i=rangeStart; igetFrame24 (x,0)) + (buffVolume * getFrame24 (i,0))); setFrame24 (i,0,temp); } if (right) { temp = (int) ((clipVolume * clip->getFrame24 (x,1)) + (buffVolume * getFrame24 (i,1))); setFrame24 (i,1,temp); } if (three) { temp = (int) ((clipVolume * clip->getFrame24 (x,2)) + (buffVolume * getFrame24 (i,2))); setFrame24 (i,2,temp); } if (four) { temp = (int) ((clipVolume * clip->getFrame24 (x,3)) + (buffVolume * getFrame24 (i,3))); setFrame24 (i,3,temp); } } else if (i > rangeEnd - mixout) { y = i - rangeStart; x = rangeEnd - i; clipVolume = (x * clipVol) / (mixout * 100.0); buffVolume = 1.0 - ((x * (100.0 - buffVol)) / (mixout * 100.0)); if (left) { temp = (int) ((clipVolume * clip->getFrame24 (y,0)) + (buffVolume * getFrame24 (i,0))); setFrame24 (i,0,temp); } if (right) { temp = (int) ((clipVolume * clip->getFrame24 (y,1)) + (buffVolume * getFrame24 (i,1))); setFrame24 (i,1,temp); } if (three) { temp = (int) ((clipVolume * clip->getFrame24 (y,2)) + (buffVolume * getFrame24 (i,2))); setFrame24 (i,2,temp); } if (four) { temp = (int) ((clipVolume * clip->getFrame24 (y,3)) + (buffVolume * getFrame24 (i,3))); setFrame24 (i,3,temp); } } else { y = i - rangeStart; if (left) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,0)) + ((buffVol / 100.0) * getFrame24 (i,0))); setFrame24 (i,0,temp); } if (right) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,1)) + ((buffVol / 100.0) * getFrame24 (i,1))); setFrame24 (i,1,temp); } if (three) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,2)) + ((buffVol / 100.0) * getFrame24 (i,2))); setFrame24 (i,2,temp); } if (four) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,3)) + ((buffVol / 100.0) * getFrame24 (i,3))); setFrame24 (i,3,temp); } } } changed = TRUE; } void DPSample::overwrite (DPSample *clip,int mode) { mix (clip,0,100,0,0,mode); } void DPSample::mix ( DPSample *clip, double buffVol, double clipVol, int mixin, int mixout, int mode) { if (!valid || !rangeValid || !clip->valid) return; int rangeLen = clip->frames; if (rangeLen == 0) return; int temp = (rangeStart + rangeLen) - frames; if (temp < 0) temp = 0; int newBufferLen = frames + temp; DPSample newSamp; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; rangeEnd = rangeStart + rangeLen; int i; int x; int y; double clipVolume; double buffVolume; for (i=0; i= rangeEnd) { if (left) { temp = getFrame24 (i,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = getFrame24 (i,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = getFrame24 (i,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = getFrame24 (i,3); newSamp.setFrame24 (i,3,temp); } } else if (i < rangeStart + mixin) { x = i - rangeStart; clipVolume = (x * clipVol) / (mixin * 100.0); buffVolume = 1.0 - ((x * (100.0 - buffVol)) / (mixin * 100.0)); if (left) { temp = (int) ((clipVolume * clip->getFrame24 (x,0)) + (buffVolume * getFrame24 (i,0))); newSamp.setFrame24 (i,0,temp); } if (right) { temp = (int) ((clipVolume * clip->getFrame24 (x,1)) + (buffVolume * getFrame24 (i,1))); newSamp.setFrame24 (i,1,temp); } if (three) { temp = (int) ((clipVolume * clip->getFrame24 (x,2)) + (buffVolume * getFrame24 (i,2))); newSamp.setFrame24 (i,2,temp); } if (four) { temp = (int) ((clipVolume * clip->getFrame24 (x,3)) + (buffVolume * getFrame24 (i,3))); newSamp.setFrame24 (i,3,temp); } } else if (i > rangeEnd - mixout) { y = i - rangeStart; x = rangeEnd - i; clipVolume = (x * clipVol) / (mixout * 100.0); buffVolume = 1.0 - ((x * (100.0 - buffVol)) / (mixout * 100.0)); if (left) { temp = (int) ((clipVolume * clip->getFrame24 (y,0)) + (buffVolume * getFrame24 (i,0))); newSamp.setFrame24 (i,0,temp); } if (right) { temp = (int) ((clipVolume * clip->getFrame24 (y,1)) + (buffVolume * getFrame24 (i,1))); newSamp.setFrame24 (i,1,temp); } if (three) { temp = (int) ((clipVolume * clip->getFrame24 (y,2)) + (buffVolume * getFrame24 (i,2))); newSamp.setFrame24 (i,2,temp); } if (four) { temp = (int) ((clipVolume * clip->getFrame24 (y,3)) + (buffVolume * getFrame24 (i,3))); newSamp.setFrame24 (i,3,temp); } } else { y = i - rangeStart; if (left) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,0)) + ((buffVol / 100.0) * getFrame24 (i,0))); newSamp.setFrame24 (i,0,temp); } if (right) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,1)) + ((buffVol / 100.0) * getFrame24 (i,1))); newSamp.setFrame24 (i,1,temp); } if (three) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,2)) + ((buffVol / 100.0) * getFrame24 (i,2))); newSamp.setFrame24 (i,2,temp); } if (four) { temp = (int) (((clipVol / 100.0) * clip->getFrame24 (y,3)) + ((buffVol / 100.0) * getFrame24 (i,3))); newSamp.setFrame24 (i,3,temp); } } } COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; changed = TRUE; } /*--------------------------------------------------------------------------- | Range functions ---------------------------------------------------------------------------*/ void DPSample::reverse (int mode) { if (!valid || !rangeValid) return; if (rangeStart == rangeEnd) return; int i = rangeStart; int j = rangeEnd - 1; int temp1; int temp2; int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); while (i < j) { if (left) { temp1 = getFrame24 (i,0); temp2 = getFrame24 (j,0); setFrame24 (i,0,temp2); setFrame24 (j,0,temp1); } if (right) { temp1 = getFrame24 (i,1); temp2 = getFrame24 (j,1); setFrame24 (i,1,temp2); setFrame24 (j,1,temp1); } if (three) { temp1 = getFrame24 (i,2); temp2 = getFrame24 (j,2); setFrame24 (i,2,temp2); setFrame24 (j,2,temp1); } if (four) { temp1 = getFrame24 (i,3); temp2 = getFrame24 (j,3); setFrame24 (i,3,temp2); setFrame24 (j,3,temp1); } i++; j--; } changed = TRUE; } void DPSample::invert (int mode) { if (!valid || !rangeValid) return; if (rangeStart == rangeEnd) return; int i; int temp; int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); for (i=rangeStart; i,->) (0,1,2) if (channels == 1) return; if (!valid || !rangeValid) return; if (rangeStart == rangeEnd) return; if (channels == 2) { int i; int temp1; int temp2; int zero = (channelMode == 0); int one = (channelMode == 1); for (i=rangeStart; i> 2) & 3; int mode = (channelMode >> 4) & 3; for (i=rangeStart; i= rangeEnd) { x = i - rangeLenAfter + rangeLenBefore; if (left) { temp = getFrame24 (x,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = getFrame24 (x,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = getFrame24 (x,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = getFrame24 (x,3); newSamp.setFrame24 (i,3,temp); } } else { x = rangeStart + ((i - rangeStart) % rangeLenBefore); if (left) { temp = getFrame24 (x,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = getFrame24 (x,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = getFrame24 (x,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = getFrame24 (x,3); newSamp.setFrame24 (i,3,temp); } } } COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; // Sort out markers if (!stereoMono && !quadroMono) { if (susLoopStart >= rangeStart) susLoopStart += rangeLenAfter - rangeLenBefore; if (susLoopEnd >= rangeStart) susLoopEnd += rangeLenAfter - rangeLenBefore; if (relLoopStart >= rangeStart) relLoopStart += rangeLenAfter - rangeLenBefore; if (relLoopEnd >= rangeStart) relLoopEnd += rangeLenAfter - rangeLenBefore; if (displayEnd >= rangeStart) displayEnd += rangeLenAfter - rangeLenBefore; } changed = TRUE; } void DPSample::panorama (int amount,int ltor,int rtol,int panChannels) { // Quadro // pan Channels == Binary number 0 to 15 // 0 to 3 (left) 0 to 3 (right) if (channels == 1) return; if (!valid || !rangeValid) return; if (rangeStart == rangeEnd) return; int i; int tempLa; int tempRa; int tempLaDel; int tempRaDel; int tempLb; int tempRb; double mix1 = amount / 200.0; double mix2 = mix1; if (mix1 < 0.0) mix1 = -mix1; mix1 = 1.0 - mix1; if (channels == 2) { for (i=rangeStart; i> 2) & 3; for (i=rangeStart; i= rangeEnd) { x = i - newFrames; if (left) { temp = getFrame24 (x,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = getFrame24 (x,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = getFrame24 (x,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = getFrame24 (x,3); newSamp.setFrame24 (i,3,temp); } } else { if (left) { newSamp.setFrame24 (i,0,0); } if (right) { newSamp.setFrame24 (i,1,0); } if (three) { newSamp.setFrame24 (i,2,0); } if (four) { newSamp.setFrame24 (i,3,0); } } } char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; COPYREST // Sort out markers if (!stereoMono && !quadroMono) { if (susLoopStart >= rangeStart) susLoopStart += newFrames; if (susLoopEnd >= rangeStart) susLoopEnd += newFrames; if (relLoopStart >= rangeStart) relLoopStart += newFrames; if (relLoopEnd >= rangeStart) relLoopEnd += newFrames; } changed = TRUE; } /*--------------------------------------------------------------------------- | Amplitude functions ---------------------------------------------------------------------------*/ void DPSample::percentage ( double lamount, double ramount, double amount3, double amount4, int wrap, int mode) { if (!valid || !rangeValid) return; if (rangeStart == rangeEnd) return; int i; int temp; int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); for (i=rangeStart; i max) max = temp; } if (right) { temp = getFrame24 (i,1); if (temp < min) min = temp; else if (temp > max) max = temp; } if (three) { temp = getFrame24 (i,2); if (temp < min) min = temp; else if (temp > max) max = temp; } if (four) { temp = getFrame24 (i,3); if (temp < min) min = temp; else if (temp > max) max = temp; } } if (max == 0 && min == 0) return; if (-min > max) percent = 100.0 * (double) MAX23 / -min; else percent = 100.0 * (double) MAX23_1 / max; percentage (percent,percent,percent,percent,FALSE,mode); } void DPSample::fadeIn (int mode) { ramp (0.0,100.0,FALSE,mode); } void DPSample::fadeOut (int mode) { ramp (100.0,0.0,FALSE,mode); } void DPSample::bounce (int bounceMode) { // For Stereo // bounceMode == 0 for left to right // bounceMode == 1 for right to left // For Quadro // bounceMode == Binary number 0 to 31 // for 0 to 3 (source) 0 to 3 (dest) mode (->,<-) (0,1) if (channels == 1) return; if (channels == 2) { if (bounceMode == 0) { ramp (100.0,000.0,FALSE,0); ramp (000.0,100.0,FALSE,1); } else { ramp (000.0,100.0,FALSE,0); ramp (100.0,000.0,FALSE,1); } } else { int source = bounceMode & 3; int dest = (bounceMode >> 2) & 3; int mode = (bounceMode >> 4) & 1; if (source == 2) source = 3; else if (source == 3) source = 4; if (dest == 2) dest = 3; else if (dest == 3) dest = 4; if (mode == 0) { ramp (100.0,000.0,FALSE,source); ramp (000.0,100.0,FALSE,dest); } else { ramp (100.0,000.0,FALSE,dest); ramp (000.0,100.0,FALSE,source); } } } void DPSample::ramp ( double startamount, double endamount, int wrap, int mode) { // mode == 0 for left only // mode == 1 for right only // mode == 2 for both left and right // mode == 3 for three only // mode == 4 for four only if (!valid || !rangeValid) return; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return; int i; int x; int temp; double amount; int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (left) { temp = getFrame24 (rangeStart,0); temp = (int) rint ((double) temp * startamount / 100.0); limitValue (&temp,wrap); setFrame24 (rangeStart,0,temp); } if (right) { temp = getFrame24 (rangeStart,1); temp = (int) rint ((double) temp * startamount / 100.0); limitValue (&temp,wrap); setFrame24 (rangeStart,1,temp); } if (three) { temp = getFrame24 (rangeStart,2); temp = (int) rint ((double) temp * startamount / 100.0); limitValue (&temp,wrap); setFrame24 (rangeStart,2,temp); } if (four) { temp = getFrame24 (rangeStart,3); temp = (int) rint ((double) temp * startamount / 100.0); limitValue (&temp,wrap); setFrame24 (rangeStart,3,temp); } rangeLen--; if (rangeLen == 0) return; for (i=rangeStart+1; i MAX23_1) { if (*value > MAX23_1) if (wrap) *value = MAX23_1 - (*value - MAX23_1); else *value = MAX23_1; if (*value < -MAX23) if (wrap) *value = -MAX23 + (-*value - MAX23); else *value = -MAX23; } } /*--------------------------------------------------------------------------- | FUNCTION DPSampleAudiofileError ---------------------------------------------------------------------------*/ void DPSampleAudiofileError (long,const char *) { } /*--------------------------------------------------------------------------- | FUNCTION DPSampleStopCatch ---------------------------------------------------------------------------*/ void DPSampleStopCatch (int) { DPSampleStop = TRUE; } /*--------------------------------------------------------------------------- | FUNCTION DPSampleReleaseCatch ---------------------------------------------------------------------------*/ void DPSampleReleaseCatch (int) { if (!DPSampleRelease1) { DPSampleRelease1 = TRUE; DPSampleInc = 1; } else { DPSampleRelease2 = TRUE; DPSampleInc = 1; } } /*--------------------------------------------------------------------------- | Resampling functions ---------------------------------------------------------------------------*/ void DPSample::nonTimeStretch (int newFrames,double newRate,int mode) { if (!valid || !rangeValid) return; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return; int newBufferLen = frames - rangeLen + newFrames; DPSample newSamp; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (stereoMono || quadroMono) { if (newBufferLen < frames) newBufferLen = frames; if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; } else { if (!newSamp.fresh (rate,width,channels,newBufferLen)) return; } rangeEnd = rangeStart + newFrames; int i; int x; int temp; double y; for (i=0; i= rangeEnd) { x = i - newFrames + rangeLen; if (left) { temp = getFrame24 (x,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = getFrame24 (x,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = getFrame24 (x,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = getFrame24 (x,3); newSamp.setFrame24 (i,3,temp); } } else { x = i - rangeStart; y = rangeStart + (double) x * rangeLen / newFrames; if (left) { temp = getFrame24Interp (y,0); newSamp.setFrame24 (i,0,temp); } if (right) { temp = getFrame24Interp (y,1); newSamp.setFrame24 (i,1,temp); } if (three) { temp = getFrame24Interp (y,2); newSamp.setFrame24 (i,2,temp); } if (four) { temp = getFrame24Interp (y,3); newSamp.setFrame24 (i,3,temp); } } } COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; // Sort out markers if (!stereoMono && !quadroMono) { rangeEnd = rangeStart + rangeLen; if (susLoopStart >= rangeEnd) susLoopStart += newFrames - rangeLen; else if (susLoopStart >= rangeStart) susLoopStart = rangeStart + ((susLoopStart - rangeStart) * newFrames) / rangeLen; if (susLoopEnd >= rangeEnd) susLoopEnd += newFrames - rangeLen; else if (susLoopEnd >= rangeStart) susLoopEnd = rangeStart + ((susLoopEnd - rangeStart) * newFrames) / rangeLen; if (relLoopStart >= rangeEnd) relLoopStart += newFrames - rangeLen; else if (relLoopStart >= rangeStart) relLoopStart = rangeStart + ((relLoopStart - rangeStart) * newFrames) / rangeLen; if (relLoopEnd >= rangeEnd) relLoopEnd += newFrames - rangeLen; else if (relLoopEnd >= rangeStart) relLoopEnd = rangeStart + ((relLoopEnd - rangeStart) * newFrames) / rangeLen; if (displayStart >= rangeEnd) displayStart += newFrames - rangeLen; else if (displayStart >= rangeStart) displayStart = rangeStart + ((displayStart - rangeStart) * newFrames) / rangeLen; if (displayEnd >= rangeEnd) displayEnd += newFrames - rangeLen; else if (displayEnd >= rangeStart) displayEnd = rangeStart + ((displayEnd - rangeStart) * newFrames) / rangeLen; rangeEnd = rangeStart + newFrames; } // Update sample rate setRate (newRate); changed = TRUE; } int DPSample::timeStretch ( double pitchChange, double framesChange, double newRate, int lowestFreq, int quality, int mode) { if (!valid || !rangeValid) return 0; int rangeLen = rangeEnd - rangeStart; if (rangeLen == 0) return 0; // Must round framesChange so calculate vocoder parameters here !! int R; int N; int Nw; int D; int I; double P; double synt; N = 1; R = (int) rate; while ((R / N) > lowestFreq) N = 2 * N; Nw = quality * N; D = Nw / 8; I = (int)(D * framesChange / 100.0); P = pitchChange / 100.0; synt = 0.0; double newFramesChange = (double) I / D; int newFrames = (int) (rangeLen * newFramesChange); int newBufferLen = frames - rangeLen + newFrames; DPSample newSamp; int stereoMono = (channels == 2 && mode != 2); int quadroMono = (channels == 4 && mode != 2); int left = (channels == 1 || (mode == 2 || mode == 0)); int right = (channels != 1 && (mode == 2 || mode == 1)); int three = (channels == 4 && (mode == 2 || mode == 3)); int four = (channels == 4 && (mode == 2 || mode == 4)); if (stereoMono || quadroMono) { if (newBufferLen < frames) newBufferLen = frames; if (!newSamp.fresh (rate,width,channels,newBufferLen)) return 0; } else { if (!newSamp.fresh (rate,width,channels,newBufferLen)) return 0; } rangeEnd = rangeStart + newFrames; int i; int x; int temp; for (i=0; i 0) { #ifndef NOFORMS if (channels == 4) fl_set_object_label (stretchForm->label,"Percent Complete - Channel 1"); else if (channels == 2) fl_set_object_label (stretchForm->label,"Percent Complete - Left Channel"); else fl_set_object_label (stretchForm->label,"Percent Complete"); #endif if (!resample (this,&newSamp,0,R,N,Nw,D,I,P,synt)) return 0; } #ifndef NOFORMS if (stretchCancel) return 0; fl_set_slider_value (stretchForm->percentCompSlider,0.0); fl_set_object_label (stretchForm->percentComp,"0"); #endif // Channel 2 = Right if (right && newFrames > 0) { #ifndef NOFORMS if (channels == 4) fl_set_object_label (stretchForm->label,"Percent Complete - Channel 2"); else fl_set_object_label (stretchForm->label,"Percent Complete - Right Channel"); #endif if (!resample (this,&newSamp,1,R,N,Nw,D,I,P,synt)) return 0; } #ifndef NOFORMS if (stretchCancel) return 0; fl_set_slider_value (stretchForm->percentCompSlider,0.0); fl_set_object_label (stretchForm->percentComp,"0"); #endif // Channel 3 if (three && newFrames > 0) { #ifndef NOFORMS fl_set_object_label (stretchForm->label,"Percent Complete - Channel 3"); #endif if (!resample (this,&newSamp,2,R,N,Nw,D,I,P,synt)) return 0; } #ifndef NOFORMS if (stretchCancel) return 0; fl_set_slider_value (stretchForm->percentCompSlider,0.0); fl_set_object_label (stretchForm->percentComp,"0"); #endif // Channel 4 if (four && newFrames > 0) { #ifndef NOFORMS fl_set_object_label (stretchForm->label,"Percent Complete - Channel 4"); #endif if (!resample (this,&newSamp,3,R,N,Nw,D,I,P,synt)) return 0; } #ifndef NOFORMS if (stretchCancel) return 0; fl_set_slider_value (stretchForm->percentCompSlider,0.0); fl_set_object_label (stretchForm->percentComp,"0"); #endif rangeEnd = rangeStart + newFrames; COPYREST char *tempPointer = data; data = newSamp.data; newSamp.data = tempPointer; frames = newBufferLen; samples = frames * channels; bytes = samples * width; // Sort out markers if (!stereoMono && !quadroMono) { rangeEnd = rangeStart + rangeLen; if (susLoopStart >= rangeEnd) susLoopStart += newFrames - rangeLen; else if (susLoopStart >= rangeStart) susLoopStart = rangeStart + ((susLoopStart - rangeStart) * newFrames) / rangeLen; if (susLoopEnd >= rangeEnd) susLoopEnd += newFrames - rangeLen; else if (susLoopEnd >= rangeStart) susLoopEnd = rangeStart + ((susLoopEnd - rangeStart) * newFrames) / rangeLen; if (relLoopStart >= rangeEnd) relLoopStart += newFrames - rangeLen; else if (relLoopStart >= rangeStart) relLoopStart = rangeStart + ((relLoopStart - rangeStart) * newFrames) / rangeLen; if (relLoopEnd >= rangeEnd) relLoopEnd += newFrames - rangeLen; else if (relLoopEnd >= rangeStart) relLoopEnd = rangeStart + ((relLoopEnd - rangeStart) * newFrames) / rangeLen; if (displayStart >= rangeEnd) displayStart += newFrames - rangeLen; else if (displayStart >= rangeStart) displayStart = rangeStart + ((displayStart - rangeStart) * newFrames) / rangeLen; if (displayEnd >= rangeEnd) displayEnd += newFrames - rangeLen; else if (displayEnd >= rangeStart) displayEnd = rangeStart + ((displayEnd - rangeStart) * newFrames) / rangeLen; rangeEnd = rangeStart + newFrames; } // Update sample rate setRate (newRate); changed = TRUE; return 1; } /*--------------------------------------------------------------------------- | Dynamic memory functions ---------------------------------------------------------------------------*/ extraListEntry *DPSample::expand (double newTime) { int newFrames; int newBytes; newFrames = (int) (newTime * rate); newBytes = newFrames * channels * width; extraListEntry *e; extraListEntry *newE; int i; if (!extra) { e = new extraListEntry; e->start = frames; e->end = e->start + newFrames - 1; e->data = new char [newBytes]; e->next = 0; if (!(e->data)) { delete e; return 0; } for (i=0; idata)) [i] = 0; extra = e; return e; } e = extra; while (e->next) e = e->next; newE = new extraListEntry; newE->start = e->end + 1; newE->end = newE->start + newFrames - 1; newE->data = new char [newBytes]; newE->next = 0; if (!(newE->data)) { delete newE; return 0; } for (i=0; idata)) [i] = 0; e->next = newE; return newE; } int DPSample::consolidate () { int stereo = (channels == 2); int quadro = (channels == 4); if (extra) { extraListEntry *e; e = extra; while (e->next) e = e->next; int newBufferLen = e->end + 1; DPSample newSamp; if (!(newSamp.fresh (rate,width,channels,newBufferLen))) return 0; int i; int temp; for (i=0; idata; etemp = e->next; delete e; e = etemp; } extra = 0; } } /*--------------------------------------------------------------------------- | General routines ---------------------------------------------------------------------------*/ int getInputRate () { long pvbuffer [6]; pvbuffer [0] = AL_INPUT_RATE; pvbuffer [2] = AL_INPUT_SOURCE; pvbuffer [4] = AL_DIGITAL_INPUT_RATE; ALgetparams (AL_DEFAULT_DEVICE,pvbuffer,6); if (pvbuffer [1] == AL_RATE_AES_1 || pvbuffer [3] == AL_INPUT_DIGITAL) { if (ALgetdefault (AL_DEFAULT_DEVICE,AL_DIGITAL_INPUT_RATE) >= 0) return pvbuffer [5]; } else if (pvbuffer [1] > 0) { return pvbuffer [1]; } return AL_RATE_UNDEFINED; } int getOutputRate () { long pvbuffer [4]; pvbuffer [0] = AL_OUTPUT_RATE; pvbuffer [2] = AL_DIGITAL_INPUT_RATE; ALgetparams (AL_DEFAULT_DEVICE,pvbuffer,4); if (pvbuffer [1] > 0) { return pvbuffer [1]; } else { if (pvbuffer [1] == AL_RATE_AES_1) { if (ALgetdefault (AL_DEFAULT_DEVICE,AL_DIGITAL_INPUT_RATE) >= 0) return pvbuffer [3]; } else if (pvbuffer [1] == AL_RATE_INPUTRATE) { return getInputRate (); } return AL_RATE_UNDEFINED; } } void limitQueueSize (int channels,int *queueSize) { switch (channels) { case 1 : if (*queueSize < 512) *queueSize = 512; else if (*queueSize > 131068) *queueSize = 131068; break; case 2 : if (*queueSize < 1024) *queueSize = 1024; else if (*queueSize > 262136) *queueSize = 262136; break; case 4 : if (*queueSize < 2048) *queueSize = 2048; else if (*queueSize > 262136) *queueSize = 262136; break; default : break; } } /***************************************************************************/