void LoopMachine::prepareToPlay(int samplesPerBlockExpected, double sampleRate) { if (expectedBufferSize == 0) expectedBufferSize = samplesPerBlockExpected; // std::cout << "MPD: CPP: LoopMachine::prepareToPlay:samplesPerBlockExpected=" << samplesPerBlockExpected << ", sampleRate=" << sampleRate << std::endl; audioEngine.getTransport().setLatency(0); for (int i = 0; i < groupIxToLoopInfo.size(); i++) { for (int j = 0; j < groupIxToLoopInfo[i]->size(); j++) { // std::cout << "MPD: CPP: LoopMachine::prepareToPlay:group " << i << ", sample " << j << std::endl; (*groupIxToLoopInfo[i])[j]->reader->prepareToPlay(samplesPerBlockExpected, sampleRate); } } if (!dirac) { // std::cout << "MPD: CPP: LoopMachine::prepareToPlay:creating dirac FX object" << std::endl; // out with the old style... // dirac = DiracFxCreate(kDiracQualityGood, fixedBpmTransport.getSampleRate(), 1); // latency = DiracFxLatencyFrames(fixedBpmTransport.getSampleRate()); // audioEngine.getTransport().setLatency(latency); // ...in with the new (but nothings new bout being hocked by a few) mthis = this; dirac = DiracCreate(kDiracLambdaPreview, kDiracQualityPreview, 1, sampleRate, DiracDataProviderCb, this); // std::cout << "MPD: F*****G BUG: " << dirac << " and " << this << std::endl; if (!dirac) throw AudioEngineException("!! ERROR !!\n\n\tCould not create Dirac instance\n\tCheck sample rate!\n"); DiracSetProperty(kDiracPropertyTimeFactor, 1, dirac); DiracSetProperty(kDiracPropertyPitchFactor, 1, dirac); } prevBpm = audioEngine.getTransport().getBpm(); }
int main() { // Create and init output file "out.aif" #ifdef __APPLE__ char infileName[]="voice.aif"; #else char infileName[]="../../voice.aif"; #endif char oufileName[]="out.aif"; long numChannels = 1; // DIRAC LE allows mono only, PRO can do stereo (and more) as well float sr = mAiffGetSampleRate(infileName); // get sample rate from our input file if (sr <= 0.) { printf("ERROR: File not found\n"); exit(-1); } // We stuff all our programs' state variables that we need to access in order to read from the file in a struct // You will normally pass your instance pointer "this" as userData, but since this is not a class we cannot do this here userDataStruct state; state.sNumChannels = numChannels; state.sReadPosition = 0; state.sInFileName = new char[strlen(infileName)+1]; memmove(state.sInFileName, infileName, (strlen(infileName)+1)*sizeof(char)); // First we set up DIRAC to process numChannels of audio void *dirac = DiracCreate(kDiracLambda1, kDiracQualityBest, numChannels, sr, &myReadData, (void*)&state); if (!dirac) { printf("!! ERROR !!\n\n\tCould not create DIRAC instance\n\tCheck number of channels and sample rate!\n"); exit(-1); } // Initialize our output file mAiffInitFile(oufileName, sr /* sample rate */, 16 /* bits */, numChannels); // these are arbitrary regions in the file */ #define NUM_PARTS 17 SoundFileRegion regions[NUM_PARTS] = { {0, 4257, 1.0, 1.0}, {4257, 10741, 1.0, 1.0}, {14999, -20471, 1.0, 1.5}, /* negative length means reverse playback direction */ {35470, -12161, 1.0, 1.0}, {47631, 9323, 2.0, 1.0}, {56954, 18647, 1.0, 1.5}, {75601, 9121, 2.0, 1.0}, {84722, 22903, 1.0, 1.0}, {107625, 19863, 1.0, 1.0}, {107625, 19863, 1.0, pow(2., 1./12.)}, /* repeat and change pitch */ {107625, 19863, 1.0, pow(2., 2./12.)}, /* repeat and change pitch */ {127488, 39117, 1.0, .5}, {166605, -11553, 2.0, 1.0}, {178158, 20269, 1.0, 1.0}, {198427, 17430, 2.0, 1.0}, {215857, 23309, 1.0, 1.5}, {239166, 35266, 1.0, 1.0} }; for (int i=0; i<NUM_PARTS; i++) { printf("Processing region \t%d: {start: %d, length: %d} \twith time stretch %1.2f and pitch shift %1.2f\n", i, regions[i].sStartFrameInFile, regions[i].sNumFrames, (float)regions[i].sTimeStretchFactor, (float)regions[i].sPitchShiftFactor); /* determine the region length (output) in frames by multiplying input region length with time stretch factor */ long numOutFrames = regions[i].sTimeStretchFactor * abs(regions[i].sNumFrames); /* set Dirac properties according to desired settings */ DiracSetProperty(kDiracPropertyTimeFactor, regions[i].sTimeStretchFactor, dirac); DiracSetProperty(kDiracPropertyPitchFactor, regions[i].sPitchShiftFactor, dirac); DiracSetProperty(kDiracPropertyFormantFactor, 1./regions[i].sPitchShiftFactor, dirac); /* optional */ /* allocate buffer to hold output frames */ float **audio = mAiffAllocateAudioBuffer(numChannels, numOutFrames); /* set read position to begin of region */ state.sReadPosition = regions[i].sStartFrameInFile; /* process region */ DiracProcess(audio, numOutFrames, dirac); /* fade region to prevent glitches */ if (regions[i].sNumFrames < 0) reverseBlock(audio, numChannels, numOutFrames); fadeBlock(audio, numChannels, numOutFrames); /* write region to file */ mAiffWriteData(oufileName, audio, numOutFrames, numChannels); /* get rid of audio buffer */ mAiffDeallocateAudioBuffer(audio, numChannels); /* reset Dirac instance for next region */ DiracReset(false, dirac); } // destroy DIRAC instance DiracDestroy( dirac ); // free our file name delete[] state.sInFileName; // Done! printf("\nDone!\n"); putchar(7); /* Open audio file via system call */ #ifdef __APPLE__ system("open out.aif"); #elif defined _WIN32 system("start out.aif"); #elif defined __unix__ system("xdg-open out.aif"); #endif return 0; }
int main() { // Create and init output file "out.aif" #ifdef __APPLE__ char infileName[]="test.aif"; #else char infileName[]="../../test.aif"; #endif char oufileName[]="out.aif"; long numChannels = 1; // DIRAC LE allows mono only, our PRO Demo can do stereo (and more) as well float sr = mAiffGetSampleRate(infileName); // get sample rate from our input file if (sr <= 0.) { printf("ERROR: File not found\n"); exit(-1); } // We stuff all our programs' state variables that we need to access in order to read from the file in a struct // You will normally pass your instance pointer "this" as userData, but since this is not a class we cannot do this here userDataStruct state; state.sNumChannels = numChannels; state.sReadPosition = 0; state.sInFileName = new char[strlen(infileName)+1]; memmove(state.sInFileName, infileName, (strlen(infileName)+1)*sizeof(char)); // First we set up DIRAC to process numChannels of audio // N.b.: The fastest option is kDiracLambdaPreview / kDiracQualityPreview, best is kDiracLambda3 / kDiracQualityBest // For extreme stretch ratios we recommend kDiracLambdaTranscribe / kDiracQualityGood as this will produce less artifacts // The probably best default option for general purpose signals is kDiracLambda3 / kDiracQualityGood void *dirac = DiracCreate(kDiracLambdaPreview, kDiracQualityPreview, numChannels, sr, &myReadData, (void*)&state); // (1) fastest //void *dirac = DiracCreate(kDiracLambda1, kDiracQualityBest, numChannels, sr, &myReadData, (void*)&state); // (2) best for voice //void *dirac = DiracCreate(kDiracLambda3, kDiracQualityBest, numChannels, sr, &myReadData, (void*)&state); // (3) best general purpose option //void *dirac = DiracCreate(kDiracLambdaTranscribe, kDiracQualityBest, numChannels, sr, &myReadData, (void*)&state); // (4) for extreme ratios if (!dirac) { printf("!! ERROR !!\n\n\tCould not create DIRAC instance\n\tCheck number of channels and sample rate!\n"); exit(-1); } // Initialize our output file mAiffInitFile(oufileName, sr /* sample rate */, 16 /* bits */, numChannels); // Here we set our time an pitch manipulation values float time = 1.13; // 113% length float pitch = pow(2., 0./12.); // pitch shift (0 semitones) float formant = pow(2., 0./12.); // formant shift (0 semitones). N.b. formants are reciprocal to pitch in natural transposing. Setting this != 1.0 uses a lot more CPU! // Pass the values to our DIRAC instance DiracSetProperty(kDiracPropertyTimeFactor, time, dirac); DiracSetProperty(kDiracPropertyPitchFactor, pitch, dirac); DiracSetProperty(kDiracPropertyFormantFactor, formant, dirac); // Print our settings to the console DiracPrintSettings(dirac); printf("Running DIRAC version %s\nStarting processing\n", DiracVersion()); // Get the number of frames from the file to display our simplistic progress bar float numf = mAiffGetNumberOfFrames(infileName); unsigned long outframes = 0; unsigned long newOutframe = numf*time; long lastPercent = -1; // This is an arbitrary number of frames. Change as you see fit long numFrames = 8192; // Allocate buffer for output float **audio = mAiffAllocateAudioBuffer(numChannels, numFrames); // for time measurement double bavg = 0; // MAIN PROCESSING LOOP STARTS HERE for(;;) { DiracStartClock(); // ............................. start timer .......................................... // Call the DIRAC process function with current time and pitch settings // Returns: the number of frames in audio long ret = DiracProcess(audio, numFrames, dirac); bavg += (numFrames/sr); gExecTimeTotal += DiracClockTimeSeconds(); // ............................. stop timer .......................................... // print performance measurements long percent = 100.f*(double)outframes / (double)newOutframe; if (lastPercent != percent) { printf("\t%d%% done, avg. algorithm speed vs. realtime = %3.2f : 1 (DSP only), CPU load (peak, DSP+disk): %3.2f%%\n", (int)percent, bavg/gExecTimeTotal, DiracPeakCpuUsagePercent(dirac)); lastPercent = percent; fflush(stdout); } // Write the data to the output file mAiffWriteData(oufileName, audio, numFrames, numChannels); // Increase our counter for the percentage outframes += numFrames; // As soon as we've written enough frames we exit the main loop if (ret <= 0) break; } // Free buffers mAiffDeallocateAudioBuffer(audio, numChannels); // destroy DIRAC instance DiracDestroy( dirac ); // free our file name delete[] state.sInFileName; // Done! printf("\nDone!\n"); putchar(7); /* Open audio file via system call */ #ifdef __APPLE__ system("open out.aif"); #elif defined _WIN32 system("start out.aif"); #elif defined __unix__ system("xdg-open out.aif"); #endif return 0; }