void KeyAnalysisThread::analyzeSingleKey()
{
	DBG("Thread: " << this->getThreadName() << " analyzing single key of: " << fileToAnalyze->getUUID());
	//skip already-analyzed files
	if (fileToAnalyze->isFileAnalyzed() == "Yes")
	{
		DBG("Skipping analysis of " << fileToAnalyze->getFileName() << " : Already analyzed.");
		return;
	}
	//DBG("File being analyzed: " << fileToAnalyze.getFileToBeAnalyzed().getFileName());
//	r> audioFormatReader = audioFormatManager.createReaderFor(fileToAnalyze.getFileToBeAnalyzed());

	size_t numSamples = audioFormatReader->lengthInSamples;
	size_t numChannels = audioFormatReader->numChannels;
	size_t sampleRate = audioFormatReader->sampleRate;
	//size_t numFrames = numSamples / numChannels;
	//DBG("Samples:" + String(numSamples) + " Channels:" + String(numChannels) + " Frames:" + String(numFrames));
	audioData.addToSampleCount(numSamples*numChannels);
	audioData.setChannels(numChannels);
	audioData.setFrameRate(sampleRate);

	AudioBuffer<float> audioBuffer(numChannels, numSamples);

	// #TODO(Casey): Fix either audiobuffer or audioData to allow direct move of sample array (Performance)
	// #TODO(Casey): integrate libsndfile as primary choice

	//DBG("Reading wav to buffer");
	audioFormatReader->read(&audioBuffer, 0, numSamples, 0, true, true);


	//DBG("Copying buffer samples to audioData");
	for (size_t i = 0; i < numSamples; ++i)
	{
		//DBG("On sample " + String(i) + " of " + String(numSamples));
		for (size_t currChannel = 0; currChannel < numChannels; ++currChannel)
		{
			audioData.setSampleByFrame(i, currChannel, audioBuffer.getSample(currChannel, i));
		}
		//audioData.setSampleByFrame(i, 1, audioBuffer.getSample(1, i));
	}

	//DBG("Detecting key...");

	static KeyFinder::KeyFinder keyFinder;

	KeyFinder::key_t key = keyFinder.keyOfAudio(audioData);

	//KeyFinder::key_t key = KeyFinder::key_t::C_MAJOR;

	fileToAnalyze->setDetectedKey(key);

	String foundKey(fileToAnalyze->getDetectedKeyAsString());

	DBG("Detected key in analyzeAudioFiles: " + foundKey);
}
const char* kfinder_get_key(short signed int   *samples,
                            unsigned int        nb_samples,
                            short unsigned int  frame_rate,
                            short unsigned int  nb_channels)
{
    // Check input parameter.
    if ((samples == NULL) || (nb_samples == 0) || (frame_rate == 0) || (nb_channels == 0))
    {
        return "";
    }

    // Build the main computing object.
    KeyFinder::KeyFinder k;

    // Build an empty audio object
    KeyFinder::AudioData a;

    // Prepare the object for your audio stream
    a.setFrameRate(frame_rate);
    a.setChannels(nb_channels);
    a.addToSampleCount(nb_samples);

    // Copy your audio into the object (as float).
    for (unsigned int i = 0; i < nb_samples; i++)
    {
        a.setSample(i, (float)samples[i]);
    }

    // Run the analysis
    KeyFinder::key_t r;
    try
    {
        r =  k.keyOfAudio(a);
    }
    catch(const std::exception& e)
    {
        cerr << "libKeyFinder: exception: " << e.what() << endl;
        return "";
    }
    catch(...)
    {
        cerr << "libKeyFinder: unknown exception" << endl;
        return "";
    }


    // And do something with the result!
    switch(r)
    {
        case KeyFinder::A_MAJOR:      return "AM";
        case KeyFinder::A_MINOR:      return "Am";
        case KeyFinder::B_FLAT_MAJOR: return "BbM";
        case KeyFinder::B_FLAT_MINOR: return "Bbm";
        case KeyFinder::B_MAJOR:      return "BM";
        case KeyFinder::B_MINOR:      return "Bm";
        case KeyFinder::C_MAJOR:      return "CM";
        case KeyFinder::C_MINOR:      return "Cm";
        case KeyFinder::D_FLAT_MAJOR: return "DbM";
        case KeyFinder::D_FLAT_MINOR: return "Dbm";
        case KeyFinder::D_MAJOR:      return "DM";
        case KeyFinder::D_MINOR:      return "Dm";
        case KeyFinder::E_FLAT_MAJOR: return "EbM";
        case KeyFinder::E_FLAT_MINOR: return "Ebm";
        case KeyFinder::E_MAJOR:      return "EM";
        case KeyFinder::E_MINOR:      return "Em";
        case KeyFinder::F_MAJOR:      return "FM";
        case KeyFinder::F_MINOR:      return "Fm";
        case KeyFinder::G_FLAT_MAJOR: return "GbM";
        case KeyFinder::G_FLAT_MINOR: return "Gbm";
        case KeyFinder::G_MAJOR:      return "GM";
        case KeyFinder::G_MINOR:      return "Gm";
        case KeyFinder::A_FLAT_MAJOR: return "AbM";
        case KeyFinder::A_FLAT_MINOR: return "Abm";
        case KeyFinder::SILENCE:      return "";
        default:                      return "";
    }
}