Esempio n. 1
0
	void onAudio(AudioIOData& io){
		float pshift = 1.7831; //pshift = 1./pshift;

		while(io()){
			float s = play(); play.loop();

			if(stft(s)){
		
				enum{
					PREV_MAG=0,
					TEMP_MAG,
					TEMP_FRQ
				};

				// Compute spectral flux (L^1 norm on positive changes)
				float flux = 0;
				for(unsigned k=0; k<stft.numBins(); ++k){
					float mcurr = stft.bin(k)[0];
					float mprev = stft.aux(PREV_MAG)[k];

					if(mcurr > mprev){
						flux += mcurr - mprev;
					}
				}

				//printf("%g\n", flux);
				//gam::printPlot(flux); printf("\n");

				// Store magnitudes for next frame
				stft.copyBinsToAux(0, PREV_MAG);

				// Given an onset, we would like the phases of the output frame
				// to match the input frame in order to preserve transients.
				if(flux > 0.2){
					stft.resetPhases();
				}

				// Initialize buffers to store pitch-shifted spectrum
				for(unsigned k=0; k<stft.numBins(); ++k){
					stft.aux(TEMP_MAG)[k] = 0.;
					stft.aux(TEMP_FRQ)[k] = k*stft.binFreq();
				}

				// Perform the pitch shift:
				// Here we contract or expand the bins. For overlapping bins,
				// we simply add the magnitudes and replace the frequency.
				// Reference:
				// http://oldsite.dspdimension.com/dspdimension.com/src/smbPitchShift.cpp
				if(pshift > 0){
					unsigned kmax = stft.numBins() / pshift;
					if(kmax >= stft.numBins()) kmax = stft.numBins()-1;
					for(unsigned k=1; k<kmax; ++k){
						unsigned j = k*pshift;
						stft.aux(TEMP_MAG)[j] += stft.bin(k)[0];
						stft.aux(TEMP_FRQ)[j] = stft.bin(k)[1]*pshift;
					}
				}

				// Copy pitch-shifted spectrum over to bins
				stft.copyAuxToBins(TEMP_MAG, 0);
				stft.copyAuxToBins(TEMP_FRQ, 1);
			}

			s = stft();

			io.out(0) = io.out(1) = s;
		}
	}