Toggle navigation

Step 5: Implementing the voice analyser

In this step, you will implement the VoiceAnalyzer class and the related parts in the GuitarTuner class. This makes the application able to analyse the voice frequency.

VoiceAnalyzer is given a target frequency. It then reads audio input data, analyses the voice, and emits the difference of the main frequency of the voice as compared to the target frequency periodically. To restrict the complexity of the calculations needed, only a fraction of the audio data is taken to be analysed.

Implementing the GuitarTuner class methods related to the audio input

  1. Implement the GuitarTuner initAudioInput method so that m_format_input, m_audioInput, and m_analyzer are set up based on comments.
  2. Add implementation into GuitarTuner modeChanged as follows. In the if (isInput) branch, which is executed when the input mode is changed to be active, stop output and start input based on code comments. The else branch, which was otherwise implemented in Step 3.3, also needs to be changed as follows. Add code to stop audio input and voice analyser, before the line // Set up the audio output.

Implementing the VoiceAnalyzer class

The voice analyser collects voice samples from the audio stream at regural intervals, analyses them with a Fast Fourier Transform (FFT), and then signals the results.

  1. Add implementation into the VoiceAnalyzer constructor as follows. Init the m_format, m_frequency, m_position, and m_fftHelper properties. m_totalSampleCount stores the amount of voice samples to be taken; equation 6 in the Math Behind the Curtains of GuitarTuner is a formula for this (explanations are also included in the document). Set m_totalSampleCount to be equal to the following:
    ,
    where is the same as the M_SAMPLE_COUNT_MULTIPLIER macro. Prepare m_samples to hold m_totalSampleCount values. Set m_maximumVoiceDifference so that the following equality holds:
    m_maximumVoiceDifference = log_2(TargetFrequencyParameter) * 12.
    The reasons are given in Section 3.1. of Math Behind the Curtains of GuitarTuner. Init the cut-off percentage with the setCutOffPercentage method.
  2. Implement the VoiceAnalyzer start and stop methods. The start method must initialise m_stepSize, which is the interval of the samples taken to be analysed. Equation 4 in the Math Behind the Curtains of GuitarTuner is the formula for this; explanations are also provided. Set m_stepSize to sampleRate divided by 2 * frequency * TargetFrequencyParameter, where frequency is the provided parameter. Store the frequency with m_frequency; finally, open the parent QIODevice in write-only mode. The stop method must close the parent QIODevice and clear m_samples which are already collected.
  3. Implement the VoiceAnalyzer writeData method. In writeData, obtain each m_stepSize voice sample with the getValueInt16 method, and append the value into the m_samples list. If the m_totalSampleCount samples have been appended into m_samples, call the analyzeVoice method to analyse the voice and emit appropriate signals, after which m_samples must be reset.
  4. Implement the VoiceAnalyzer getValueInt16 method. Use reinterpret_cast to cast ptr into const quint8* or const quint16* pointer. Then read and scale the value appropriately, depending on the audio format sampleType, sampleSize, and byteOrder. Use the qFromLittleEndian and qFromBigEndian methods to make the code be align-safe. Finally, return the obtained value.
  5. Implement the VoiceAnalyzer setCutOffPercentage method. This method must call m_fftHelper setCutOffForDensity with a parameter, which should be some fraction of the maximum density that can be noticed in a signal. The following formula is a good choice for a parameter:
    CutOffScaler * cutoff * m_totalSampleCount * X,
    where X is either M_MAX_AMPLITUDE_8BIT_SIGNED or M_MAX_AMPLITUDE_16BIT_SIGNED.
  6. Implement the VoiceAnalyzer frequency, getMaximumVoiceDifference, and getMaximumPrecisionPerNote methods. These are ordinary getters, which return the corresponding values m_frequency, m_maximumVoiceDifference, and PrecisionPerNote, respectively.

The analyzeVoice method is already implemented because it is not very closely related to the topic of this hands-on lab, that is, working with Qt Mobility Multimedia classes. In the analyzeVoice method, the maximum density index (the index corresponding to the main frequency) is calculated from m_samples with m_fftHelper. Depending on the result, the lowVoice, voiceDifference, and correctFrequency signals are emitted. The value emitted in the voiceDifference signal represents the difference of the obtained main frequency of the voice and the target frequency.

Now the building should be successful. However, you cannot change the input mode to be active. This will be corrected in the next step.

If the application is not working properly, download and use the files in this zip file.

You can test the changes in this step by changing the GuitarTuner constructor code temporarily so that modeChanged is called with a true parameter, corresponding to the input mode.


Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2013 All rights reserved