//const double PitchDetector::detectFrequency(INT16 * samples, NoteDesc * noteDesc, double * pDeviation)
const double PitchDetector::detectFrequency(SamplesNode * pSamplesNode)
{
    double      freqDetected   = -1.0;
    
    if (NULL == pSamplesNode) {
        return -1.0;
    }

    /* todo, sample_count vs. 4096 */
    freqDetected = dywapitch_computepitch(&_pitchTracker,
                                           pSamplesNode->samples,
                                           0,
                                           pSamplesNode->sampleSize);
    freqDetected = freqDetected * 2;
    if (freqDetected >= 16.352 && freqDetected <= 7902) {
        pSamplesNode->noteDesc.pitchName = getPitchName(freqDetected,
                                           &pSamplesNode->noteDesc.deviation);
        pSamplesNode->noteDesc.pitchValue = freqDetected;
        pSamplesNode->noteDesc.toneName = notationNames[pSamplesNode->noteDesc.pitchName[0]-'A'];
    }
    
    return freqDetected;
}
Example #2
0
//--------------------------------------------------------------
void testApp::audioIn(float * input, int bufferSize, int nChannels){	

	float* left = new float[bufferSize];
	float* right = new float[bufferSize];

	for (int i = 0; i < bufferSize; i++){
		left[i]		= input[i*2];
		right[i]	= input[i*2+1];
	}

	// Find max signal for this sample
	double maxSignalLocal = 0;
	for (int i = 0; i < AUDIO_BUFFER_SIZE; i++)
	{
		maxSignalLocal = max(maxSignalLocal, (double)abs(left[i]));
	}
	// Update max signal or slightly reduce it
	maxSignal = maxSignalLocal > maxSignal
		? maxSignalLocal
		: maxSignal * config.maxSignalClampRate;

	// Gate signal with half of maxSignal value
	for (int i = 0; i < AUDIO_BUFFER_SIZE; i++)
	{
		if (abs(left[i]) > maxSignal * config.gateThreshold) {
			continue;
		}
		
		left[i] = 0;
	}

	//Get fft
	fft->setSignal(left);
	size_t count = fft->getBinSize();
	float* amplitudes = fft->getAmplitude();

	// Find average aplitude and clamp signal range
	const size_t minIndex = MIN_VOICE_FREQ * AUDIO_BUFFER_SIZE / SAMPLE_RATE;
	const size_t maxIndex = MAX_VOICE_FREQ * AUDIO_BUFFER_SIZE / SAMPLE_RATE;
	float averageAmp = 0;
	for (size_t i = 0; i < count; i++)
	{
		if (i < minIndex || i >= maxIndex)
		{
			amplitudes[i] = 0;
		}

		averageAmp += amplitudes[i];
	}
	averageAmp /= maxIndex - minIndex;

	// Gate amplitudes with average amp. And pow 2 the rest.
	for (size_t i = minIndex; i <= maxIndex; i++)
	{
		amplitudes[i] = amplitudes[i] > averageAmp 
			? amplitudes[i] * amplitudes[i]
			: 0;
	}

	// Get filtered signal with inverse fft.
	float* filteredSignal = new float[AUDIO_BUFFER_SIZE];
	memcpy(filteredSignal, fft->getSignal(), sizeof(float) * AUDIO_BUFFER_SIZE);

	// Convert signal to double array.
	double* samples = new double[AUDIO_BUFFER_SIZE];
	for (int i = 0; i < AUDIO_BUFFER_SIZE; i++)
	{
		samples[i] = left[i];
	}

	// Get pitch
	dywapitchtracker pitchtracker;
	dywapitch_inittracking(&pitchtracker);
	double freq =  max(0.0, dywapitch_computepitch(&pitchtracker, samples, 0, AUDIO_BUFFER_SIZE));

	// Get rid off the array
	delete[] filteredSignal;

	double freqLog = 0;
	double delta = 0;

	// Calculate delata (control signal)
	if (freq > 0)
	{
		freqLog = log(freq);

		if (freqLog < minFreqLog) {
			minFreqLog = freqLog;
		}
		else {
			minFreqLog *= 1.0 + config.rangeClampRate;
		}

		if (freqLog > maxFreqLog) {
			maxFreqLog = freqLog;
		}
		else {
			maxFreqLog *= 1.0 - config.rangeClampRate;
		}

		double centralFreqLog = (minFreqLog + maxFreqLog) /2;
		
		delta = freqLog - centralFreqLog;

		delta = smoothSignal(delta, control);
	}

	// Append data
	soundMutex.lock();
	control.push_back(delta);
	pitches.push_back(freqLog);
	soundMutex.unlock();

	delete[] left;
	delete[] right;
}