summaryrefslogtreecommitdiffstats
path: root/demos/mobile/guitartuner/src
diff options
context:
space:
mode:
Diffstat (limited to 'demos/mobile/guitartuner/src')
-rw-r--r--demos/mobile/guitartuner/src/application.qml328
-rw-r--r--demos/mobile/guitartuner/src/constants.h54
-rw-r--r--demos/mobile/guitartuner/src/fastfouriertransformer.cpp184
-rw-r--r--demos/mobile/guitartuner/src/fastfouriertransformer.h67
-rw-r--r--demos/mobile/guitartuner/src/fftpack.c1406
-rw-r--r--demos/mobile/guitartuner/src/guitartuner.cpp359
-rw-r--r--demos/mobile/guitartuner/src/guitartuner.h95
-rw-r--r--demos/mobile/guitartuner/src/guitartuner.rc23
-rw-r--r--demos/mobile/guitartuner/src/guitartuner.ui178
-rw-r--r--demos/mobile/guitartuner/src/guitartunerui.cpp341
-rw-r--r--demos/mobile/guitartuner/src/guitartunerui.h111
-rw-r--r--demos/mobile/guitartuner/src/guitartunerui.ui178
-rw-r--r--demos/mobile/guitartuner/src/main.cpp60
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/Adjuster.qml131
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/Meter.qml112
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/NoteButtonView.qml84
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/NotesModel.qml105
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/ToggleButton.qml110
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/adjustbars.js89
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/big_a.pngbin0 -> 575 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/big_b.pngbin0 -> 599 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/big_d.pngbin0 -> 465 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/big_e.pngbin0 -> 327 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/big_g.pngbin0 -> 610 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/glowing_a.pngbin0 -> 2978 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/glowing_b.pngbin0 -> 3084 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/glowing_d.pngbin0 -> 2940 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/glowing_e.pngbin0 -> 2696 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/glowing_g.pngbin0 -> 3046 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/guitartuner_malli.pngbin0 -> 143243 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/guitartuner_skin.pngbin0 -> 129068 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/lcdFrame.pngbin0 -> 176107 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/meterBG.pngbin0 -> 8378 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/mute.pngbin0 -> 3630 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/pointer.pngbin0 -> 965 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/pointerShadow.pngbin0 -> 1694 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/power.pngbin0 -> 3190 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/quit.pngbin0 -> 1363 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/sensitivity.pngbin0 -> 835 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_a.pngbin0 -> 3233 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_a_on.pngbin0 -> 3068 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_auto.pngbin0 -> 3619 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_auto_on.pngbin0 -> 3281 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_b.pngbin0 -> 3324 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_b_on.pngbin0 -> 3132 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_d.pngbin0 -> 3266 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_d_on.pngbin0 -> 3009 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_e.pngbin0 -> 3171 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_e_on.pngbin0 -> 2955 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_g.pngbin0 -> 3292 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/tuner_g_on.pngbin0 -> 3089 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/voicemode_off.pngbin0 -> 3775 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/voicemode_on.pngbin0 -> 3484 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/volume.pngbin0 -> 351 bytes
-rw-r--r--demos/mobile/guitartuner/src/mycomponents/images/volume_off.pngbin0 -> 2235 bytes
-rw-r--r--demos/mobile/guitartuner/src/voiceanalyzer.cpp295
-rw-r--r--demos/mobile/guitartuner/src/voiceanalyzer.h93
-rw-r--r--demos/mobile/guitartuner/src/voicegenerator.cpp246
-rw-r--r--demos/mobile/guitartuner/src/voicegenerator.h86
59 files changed, 4735 insertions, 0 deletions
diff --git a/demos/mobile/guitartuner/src/application.qml b/demos/mobile/guitartuner/src/application.qml
new file mode 100644
index 00000000..c18e64c5
--- /dev/null
+++ b/demos/mobile/guitartuner/src/application.qml
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+import "mycomponents"
+
+/* The base canvas for all QML drawing. */
+Rectangle {
+ id: application
+
+ property int targetNoteIndex: 0
+ property alias frequency: noteChooser.currentFrequency
+ //Data provided to C++.
+ property bool isInput: true
+ property bool isMuted: false
+ property bool isAuto: true
+ property alias maxVoiceDifference: voiceDifferenceMeter.maxValue
+ property real volume: 0.5
+ property real sensitivity: 0.5
+
+ //Signals to C++.
+ signal volumeChanged(real volume)
+ signal microphoneSensitivityChanged(real sensitivity)
+ signal targetFrequencyChanged(real frequency)
+ signal modeChanged(bool isInput)
+ signal muteStateChanged(bool isMuted)
+
+ //Slots for signals coming from C++.
+ function voiceDifferenceChanged(difference) {
+ if (isAuto) timer.running = true;
+ voiceDifferenceMeter.valueChanged(difference);
+ noteImage.glowing = false
+ }
+ function correctFrequencyObtained() {
+ noteImage.glowing = true
+ }
+ function lowVoice() {
+ noteImage.glowing = false
+ }
+
+ //Private function for changing the target frequency automatically.
+ function calculateTargetFrequency(difference) {
+ var tempDifference = Math.abs(difference);
+ var tempIndex = targetNoteIndex
+ while (!(difference < 0 && tempIndex == 0) &&
+ tempDifference >= notes.get(tempIndex-(difference<0)).interval/2) {
+ tempDifference -= notes.get(tempIndex-(difference<0)).interval;
+ tempIndex += difference/Math.abs(difference);
+ }
+ if (tempIndex != targetNoteIndex) {
+ targetNoteIndex = tempIndex
+ noteChooser.currentFrequency = notes.get(targetNoteIndex).frequency;
+ targetFrequencyChanged(frequency);
+ }
+ }
+
+ width: 360; height: 640
+ color: "black"
+
+ //Provides data for functions.
+ NotesModel {id: notes}
+
+ /* A timer for changing the target frequency automatically.
+ * This is needed for avoiding recursion. */
+ Timer {
+ id: timer
+
+ interval: 1
+ onTriggered: calculateTargetFrequency(voiceDifferenceMeter.value)
+ }
+
+ //A meter for showing the difference between current and target frequency.
+ Meter {
+ id: voiceDifferenceMeter
+
+ maxValue: 12
+ minValue: -maxValue
+ height: imageSize.height/background.sourceSize.height*parent.height
+ width: imageSize.width/background.sourceSize.width*parent.width
+ anchors {
+ topMargin: 100/background.sourceSize.height*parent.height
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ }
+ }
+
+ Image {
+ id: background
+
+ anchors.fill: parent
+ smooth: true
+ source: "./mycomponents/images/guitartuner_skin.png"
+ }
+
+ //A button for quitting the application.
+ Image {
+ id: quitButton
+
+ width: sourceSize.width/background.sourceSize.width*parent.width
+ height: sourceSize.height/background.sourceSize.height*parent.height
+ source: "./mycomponents/images/power.png"
+ smooth: true
+ KeyNavigation.up: volumeAdjuster
+ KeyNavigation.down: modeButton
+ Keys.onEnterPressed: Qt.quit()
+ anchors{
+ leftMargin: 297/background.sourceSize.width*parent.width
+ left: parent.left;
+ topMargin: 17/background.sourceSize.height*parent.height
+ top: parent.top
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: Qt.quit()
+ }
+ }
+
+ //An image for showing the target note.
+ Image {
+ id: noteImage
+
+ property bool glowing: false
+
+ width: sourceSize.width/background.sourceSize.width*parent.width
+ height: sourceSize.height/background.sourceSize.height*parent.height
+ source: glowing ? notes.get(targetNoteIndex).glowSource : notes.get(targetNoteIndex).bigSource
+
+ anchors {
+ topMargin: 273/background.sourceSize.height*parent.height
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ //A button for choosing the input/output mode.
+ Image {
+ id: modeButton
+
+ function buttonPressed() {
+ isInput = !isInput
+ modeChanged(isInput)
+ if (isInput) {
+ soundIcons.source = "./mycomponents/images/sensitivity.png"
+ source = "./mycomponents/images/voicemode_off.png"
+ volumeAdjuster.setValue(sensitivity)
+ }
+ else {
+ //Change off from "auto" mode
+ if (isAuto) {
+ noteChooser.pushButton(targetNoteIndex)
+ }
+ if (isMuted) {
+ soundIcons.source = "./mycomponents/images/volume_off.png";
+ }
+ else
+ soundIcons.source = "./mycomponents/images/volume.png"
+ source = "./mycomponents/images/voicemode_on.png"
+ volumeAdjuster.setValue(volume)
+ }
+ }
+
+ width: sourceSize.width/background.sourceSize.width*parent.width
+ height: sourceSize.height/background.sourceSize.height*parent.height
+ smooth: true
+ source: "./mycomponents/images/voicemode_off.png"
+ KeyNavigation.up: quitButton
+ KeyNavigation.down: noteChooser
+ Keys.onEnterPressed: buttonPressed()
+ anchors {
+ leftMargin: 16/background.sourceSize.width*parent.width
+ left: parent.left
+ topMargin: 353/background.sourceSize.height*parent.height
+ top: parent.top
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ parent.focus = true
+ parent.scale = 0.95
+ }
+ onReleased: {
+ parent.scale = 1/0.95
+ }
+ onClicked: parent.buttonPressed()
+ }
+ }
+
+ //Buttons for choosing the target note.
+ NoteButtonView {
+ id: noteChooser
+
+ width: parent.width*0.95; height: width/model.count
+ onNoteSelected: {
+ if (note == "Auto") {
+ if (!isAuto) {
+ isAuto = true
+ }
+ if (!isInput) {
+ modeButton.buttonPressed()
+ }
+ }
+ else {
+ timer.running = false;
+ isAuto = false
+ targetNoteIndex = index
+ targetFrequencyChanged(frequency)
+ }
+ focus = true
+ }
+ KeyNavigation.up: modeButton
+ KeyNavigation.down: soundIcons
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ topMargin: 454/background.sourceSize.height*parent.height
+ top: parent.top
+ }
+ }
+
+ //An element for showing the mode and changing the mute state.
+ Image {
+ id: soundIcons
+
+ function stateChanged() {
+ isMuted = !isMuted
+ muteStateChanged(isMuted)
+ if (isMuted) {
+ source = "qrc:/src/mycomponents/images/volume_off.png"
+ }
+ else {
+ source = "qrc:/src/mycomponents/images/volume.png"
+ }
+ }
+
+ width: sourceSize.width/background.sourceSize.width*parent.width
+ height: sourceSize.height/background.sourceSize.height*parent.height
+ smooth: true
+ source: "./mycomponents/images/sensitivity.png"
+ Keys.onEnterPressed: stateChanged()
+ KeyNavigation.up: noteChooser
+ KeyNavigation.down: quitButton
+ KeyNavigation.left: volumeAdjuster
+ KeyNavigation.right: volumeAdjuster
+ anchors {
+ leftMargin: 42/background.sourceSize.width*parent.width
+ left: parent.left
+ topMargin: 565/background.sourceSize.height*parent.height
+ top: parent.top
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (!isInput) {
+ parent.stateChanged()
+ }
+ parent.focus = true
+ }
+ }
+ }
+
+ //An element for adjusting volume.
+ Adjuster {
+ id: volumeAdjuster
+
+ max: 1
+ value: 0.5
+ width: 222/background.sourceSize.width*parent.width
+ height: parent.height*0.1
+ onFocusChangedByClick: focus = true
+ onArrowPressedWhenValueOverLimits: soundIcons.focus = true
+ KeyNavigation.up: modeButton
+ KeyNavigation.down: quitButton
+ anchors {
+ leftMargin: 98/background.sourceSize.width*parent.width
+ left: parent.left
+ verticalCenter: soundIcons.verticalCenter
+ }
+ onValueChanged: {
+ if (isInput) {
+ sensitivity = value;
+ microphoneSensitivityChanged(1-sensitivity)
+ }
+ else {
+ volume = value
+ volumeChanged(volume)
+ }
+ }
+ }
+}
diff --git a/demos/mobile/guitartuner/src/constants.h b/demos/mobile/guitartuner/src/constants.h
new file mode 100644
index 00000000..ab53cbea
--- /dev/null
+++ b/demos/mobile/guitartuner/src/constants.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+#define M_MAX_AMPLITUDE_8BIT_SIGNED 127
+#define M_MAX_AMPLITUDE_8BIT_UNSIGNED 255
+#define M_MAX_AMPLITUDE_16BIT_SIGNED 32767
+#define M_MAX_AMPLITUDE_16BIT_UNSIGNED 65535
+
+#define M_TWELTH_ROOT_OF_2 1.05946309435930000000
+
+// M_SAMPLE_COUNT_MULTIPLIER is 2/(M_TWELTH_ROOT_OF_2 - 1)
+#define M_SAMPLE_COUNT_MULTIPLIER 33.63430749021150000000
+
+#endif // CONSTANTS_H
diff --git a/demos/mobile/guitartuner/src/fastfouriertransformer.cpp b/demos/mobile/guitartuner/src/fastfouriertransformer.cpp
new file mode 100644
index 00000000..275d36b2
--- /dev/null
+++ b/demos/mobile/guitartuner/src/fastfouriertransformer.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fastfouriertransformer.h"
+#include "math.h"
+
+#define STIN inline
+#define __STATIC
+
+#include "fftpack.c"
+
+// called by __ogg_fdrffti
+__STATIC void drfti1(int n, float *wa, int *ifac);
+void __ogg_fdrffti(int n, float *wsave, int *ifac);
+void __ogg_fdcosqi(int n, float *wsave, int *ifac);
+// called by drftf1
+STIN void dradf2(int ido,int l1,float *cc,float *ch,float *wa1);
+// called by drftf1
+STIN void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
+ float *wa2,float *wa3);
+// called by drftf1
+STIN void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
+ float *c2,float *ch,float *ch2,float *wa);
+// called by drftf1
+STIN void drftf1(int n,float *c,float *ch,float *wa,int *ifac);
+void __ogg_fdrfftf(int n,float *r,float *wsave,int *ifac);
+STIN void dcsqf1(int n,float *x,float *w,float *xh,int *ifac);
+void __ogg_fdcosqf(int n,float *x,float *wsave,int *ifac);
+STIN void dradb2(int ido,int l1,float *cc,float *ch,float *wa1);
+STIN void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,
+ float *wa2);
+STIN void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
+ float *wa2,float *wa3);
+STIN void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
+ float *c2,float *ch,float *ch2,float *wa);
+STIN void drftb1(int n, float *c, float *ch, float *wa, int *ifac);
+void __ogg_fdrfftb(int n, float *r, float *wsave, int *ifac);
+STIN void dcsqb1(int n,float *x,float *w,float *xh,int *ifac);
+void __ogg_fdcosqb(int n,float *x,float *wsave,int *ifac);
+
+FastFourierTransformer::FastFourierTransformer(QObject *parent) :
+ QObject(parent),
+ m_waveFloat(0),
+ m_workingArray(0),
+ m_ifac(0),
+ m_last_n(-1)
+{
+}
+
+FastFourierTransformer::~FastFourierTransformer()
+{
+ if (m_waveFloat != 0) {
+ delete [] m_waveFloat;
+ }
+ if (m_workingArray != 0) {
+ delete [] m_workingArray;
+ }
+ if (m_ifac != 0) {
+ delete [] m_ifac;
+ }
+}
+
+/**
+ * Prepares the arrays to be of length n.
+ */
+void FastFourierTransformer::reserve(int n)
+{
+ Q_ASSERT(n>0);
+ if (m_waveFloat != 0) {
+ delete [] m_waveFloat;
+ }
+ if (m_workingArray != 0) {
+ delete [] m_workingArray;
+ }
+ if (m_ifac != 0) {
+ delete [] m_ifac;
+ }
+ m_workingArray = new float[2*n+15];
+ m_waveFloat = new float[n];
+ m_ifac = new int[n];
+ __ogg_fdrffti(n, m_workingArray, m_ifac);
+ m_last_n = n;
+}
+
+/**
+ * Calculates the Fast Fourier Transformation (FFT).
+ */
+void FastFourierTransformer::calculateFFT(QList<qint16> wave)
+{
+ const int n = wave.size();
+ if (m_last_n != n) {
+ reserve(n);
+ }
+ for (int i = 0; i < n; i++) {
+ m_waveFloat[i] = (float) wave.at(i);
+ }
+
+ __ogg_fdrfftf(n, m_waveFloat, m_workingArray, m_ifac);
+
+}
+
+/**
+ * Returns the index which corresponds to the maximum density
+ * of the FFT.
+ */
+int FastFourierTransformer::getMaximumDensityIndex()
+{
+ const int halfN = m_last_n / 2;
+ float maxDensity = 0;
+ int maxDensityIndex = 0;
+ float densitySquared = 0.f;
+ for (int k = 1; k < halfN; k++) {
+ // Here, we calculate the frequency k/N.
+ // k=1, the wave oscillation time is N, and the frequency
+ // is 1/sample.
+ // k=2, the wave oscillation time is N/2, and the frequency
+ // is 2/sample.
+ // k=3, the wave oscillation time is N/3, and the frequency
+ // is 3/sample.
+ // Note, that the documentation is for Fortran, so indexes in the
+ // documentation does not match.
+ // The sine and cosine coefficients are obtained thus as follows:
+ const float cosCoefficient = qAbs(m_waveFloat[2*k-1]);
+ const float sinCoefficient = qAbs(m_waveFloat[2*k]);
+
+ densitySquared = sinCoefficient*sinCoefficient + cosCoefficient*cosCoefficient;
+ if (densitySquared > maxDensity) {
+ maxDensity = densitySquared;
+ maxDensityIndex = k;
+ }
+ }
+
+ if (m_cutOffForDensitySquared < maxDensity) {
+ return maxDensityIndex;
+ }
+ else {
+ return -1;
+ }
+}
+
+/**
+ * Sets the cutoff density.
+ */
+void FastFourierTransformer::setCutOffForDensity(float cutoff)
+{
+ m_cutOffForDensitySquared = cutoff*cutoff;
+}
diff --git a/demos/mobile/guitartuner/src/fastfouriertransformer.h b/demos/mobile/guitartuner/src/fastfouriertransformer.h
new file mode 100644
index 00000000..b8064f7a
--- /dev/null
+++ b/demos/mobile/guitartuner/src/fastfouriertransformer.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FASTFOURIERTRANSFORM_H
+#define FASTFOURIERTRANSFORM_H
+
+#include <QObject>
+#include <QList>
+
+class FastFourierTransformer : public QObject
+{
+ Q_OBJECT
+
+public:
+ FastFourierTransformer(QObject *parent = 0);
+ ~FastFourierTransformer();
+ void reserve(int n);
+ void calculateFFT(QList<qint16> wave);
+ int getMaximumDensityIndex();
+ void setCutOffForDensity(float cutoff);
+
+private:
+ float *m_waveFloat;
+ float *m_workingArray;
+ int *m_ifac;
+ int m_last_n;
+ float m_cutOffForDensitySquared;
+};
+
+#endif // FASTFOURIERTRANSFORM_H
diff --git a/demos/mobile/guitartuner/src/fftpack.c b/demos/mobile/guitartuner/src/fftpack.c
new file mode 100644
index 00000000..43109408
--- /dev/null
+++ b/demos/mobile/guitartuner/src/fftpack.c
@@ -0,0 +1,1406 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/********************************************************************
+
+ The routines in this file are from http://www.netlib.org/fftpack/.
+ According to the comments in the original file (which are provided below)
+ and according to the wikipedia article about the FFTPACK[1],
+ they are released as public domain.
+
+ For information about the author of the original, Fortran routines,
+ and the author of the C translation these routines,
+ see the comments below.
+
+ [1] http://en.wikipedia.org/wiki/FFTPACK, referenced 2010-12-21.
+
+ ********************************************************************/
+
+/********************************************************************
+
+ file: fft.c
+ function: Fast discrete Fourier and cosine transforms and inverses
+ author: Monty <xiphmont@mit.edu>
+ modifications by: Monty
+ last modification date: Jul 1 1996
+
+ ********************************************************************/
+
+/* These Fourier routines were originally based on the Fourier
+ routines of the same names from the NETLIB bihar and fftpack
+ fortran libraries developed by Paul N. Swarztrauber at the National
+ Center for Atmospheric Research in Boulder, CO USA. They have been
+ reimplemented in C and optimized in a few ways for OggSquish. */
+
+/* As the original fortran libraries are public domain, the C Fourier
+ routines in this file are hereby released to the public domain as
+ well. The C routines here produce output exactly equivalent to the
+ original fortran routines. Of particular interest are the facts
+ that (like the original fortran), these routines can work on
+ arbitrary length vectors that need not be powers of two in
+ length. */
+
+#include <math.h>
+
+__STATIC void drfti1(int n, float *wa, int *ifac){
+ static int ntryh[4] = { 4,2,3,5 };
+ static float tpi = 6.28318530717958647692528676655900577;
+ float arg,argh,argld,fi;
+ int ntry=0,i,j=-1;
+ int k1, l1, l2, ib;
+ int ld, ii, ip, is, nq, nr;
+ int ido, ipm, nfm1;
+ int nl=n;
+ int nf=0;
+
+ L101:
+ j++;
+ if (j < 4)
+ ntry=ntryh[j];
+ else
+ ntry+=2;
+
+ L104:
+ nq=nl/ntry;
+ nr=nl-ntry*nq;
+ if (nr!=0) goto L101;
+
+ nf++;
+ ifac[nf+1]=ntry;
+ nl=nq;
+ if (ntry!=2) goto L107;
+ if (nf==1) goto L107;
+
+ for (i=1;i<nf;i++){
+ ib=nf-i+1;
+ ifac[ib+1]=ifac[ib];
+ }
+ ifac[2] = 2;
+
+ L107:
+ if (nl!=1) goto L104;
+ ifac[0]=n;
+ ifac[1]=nf;
+ argh=tpi/n;
+ is=0;
+ nfm1=nf-1;
+ l1=1;
+
+ if (nfm1==0) return;
+
+ for (k1=0;k1<nfm1;k1++){
+ ip=ifac[k1+2];
+ ld=0;
+ l2=l1*ip;
+ ido=n/l2;
+ ipm=ip-1;
+
+ for (j=0;j<ipm;j++){
+ ld+=l1;
+ i=is;
+ argld=(float)ld*argh;
+ fi=0.;
+ for (ii=2;ii<ido;ii+=2){
+ fi+=1.;
+ arg=fi*argld;
+ wa[i++]=cos(arg);
+ wa[i++]=sin(arg);
+ }
+ is+=ido;
+ }
+ l1=l2;
+ }
+}
+
+void __ogg_fdrffti(int n, float *wsave, int *ifac){
+
+ if (n == 1) return;
+ drfti1(n, wsave+n, ifac);
+}
+
+void __ogg_fdcosqi(int n, float *wsave, int *ifac){
+ static float pih = 1.57079632679489661923132169163975;
+ static int k;
+ static float fk, dt;
+
+ dt=pih/n;
+ fk=0.;
+ for (k=0;k<n;k++){
+ fk+=1.;
+ wsave[k] = cos(fk*dt);
+ }
+
+ __ogg_fdrffti(n, wsave+n,ifac);
+}
+
+STIN void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
+ int i,k;
+ float ti2,tr2;
+ int t0,t1,t2,t3,t4,t5,t6;
+
+ t1=0;
+ t0=(t2=l1*ido);
+ t3=ido<<1;
+ for (k=0;k<l1;k++){
+ ch[t1<<1]=cc[t1]+cc[t2];
+ ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
+ t1+=ido;
+ t2+=ido;
+ }
+
+ if (ido<2) return;
+ if (ido==2) goto L105;
+
+ t1=0;
+ t2=t0;
+ for (k=0;k<l1;k++){
+ t3=t2;
+ t4=(t1<<1)+(ido<<1);
+ t5=t1;
+ t6=t1+t1;
+ for (i=2;i<ido;i+=2){
+ t3+=2;
+ t4-=2;
+ t5+=2;
+ t6+=2;
+ tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
+ ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
+ ch[t6]=cc[t5]+ti2;
+ ch[t4]=ti2-cc[t5];
+ ch[t6-1]=cc[t5-1]+tr2;
+ ch[t4-1]=cc[t5-1]-tr2;
+ }
+ t1+=ido;
+ t2+=ido;
+ }
+
+ if (ido%2==1) return;
+
+ L105:
+ t3=(t2=(t1=ido)-1);
+ t2+=t0;
+ for (k=0;k<l1;k++){
+ ch[t1]=-cc[t2];
+ ch[t1-1]=cc[t3];
+ t1+=ido<<1;
+ t2+=ido;
+ t3+=ido;
+ }
+}
+
+STIN void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
+ float *wa2,float *wa3){
+ static float hsqt2 = .70710678118654752440084436210485;
+ int i,k,t0,t1,t2,t3,t4,t5,t6;
+ float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
+ t0=l1*ido;
+
+ t1=t0;
+ t4=t1<<1;
+ t2=t1+(t1<<1);
+ t3=0;
+
+ for (k=0;k<l1;k++){
+ tr1=cc[t1]+cc[t2];
+ tr2=cc[t3]+cc[t4];
+ ch[t5=t3<<2]=tr1+tr2;
+ ch[(ido<<2)+t5-1]=tr2-tr1;
+ ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
+ ch[t5]=cc[t2]-cc[t1];
+
+ t1+=ido;
+ t2+=ido;
+ t3+=ido;
+ t4+=ido;
+ }
+
+ if (ido<2) return;
+ if (ido==2) goto L105;
+
+ t1=0;
+ for (k=0;k<l1;k++){
+ t2=t1;
+ t4=t1<<2;
+ t5=(t6=ido<<1)+t4;
+ for (i=2;i<ido;i+=2){
+ t3=(t2+=2);
+ t4+=2;
+ t5-=2;
+
+ t3+=t0;
+ cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
+ ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
+ t3+=t0;
+ cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
+ ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
+ t3+=t0;
+ cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
+ ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
+
+ tr1=cr2+cr4;
+ tr4=cr4-cr2;
+ ti1=ci2+ci4;
+ ti4=ci2-ci4;
+ ti2=cc[t2]+ci3;
+ ti3=cc[t2]-ci3;
+ tr2=cc[t2-1]+cr3;
+ tr3=cc[t2-1]-cr3;
+
+
+ ch[t4-1]=tr1+tr2;
+ ch[t4]=ti1+ti2;
+
+ ch[t5-1]=tr3-ti4;
+ ch[t5]=tr4-ti3;
+
+ ch[t4+t6-1]=ti4+tr3;
+ ch[t4+t6]=tr4+ti3;
+
+ ch[t5+t6-1]=tr2-tr1;
+ ch[t5+t6]=ti1-ti2;
+ }
+ t1+=ido;
+ }
+ if (ido%2==1) return;
+
+ L105:
+
+ t2=(t1=t0+ido-1)+(t0<<1);
+ t3=ido<<2;
+ t4=ido;
+ t5=ido<<1;
+ t6=ido;
+
+ for (k=0;k<l1;k++){
+ ti1=-hsqt2*(cc[t1]+cc[t2]);
+ tr1=hsqt2*(cc[t1]-cc[t2]);
+ ch[t4-1]=tr1+cc[t6-1];
+ ch[t4+t5-1]=cc[t6-1]-tr1;
+ ch[t4]=ti1-cc[t1+t0];
+ ch[t4+t5]=ti1+cc[t1+t0];
+ t1+=ido;
+ t2+=ido;
+ t4+=t3;
+ t6+=ido;
+ }
+}
+
+STIN void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
+ float *c2,float *ch,float *ch2,float *wa){
+
+ static float tpi=6.28318530717958647692528676655900577;
+ int idij,ipph,i,j,k,l,ic,ik,is;
+ int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+ float dc2,ai1,ai2,ar1,ar2,ds2;
+ int nbd;
+ float dcp,arg,dsp,ar1h,ar2h;
+ int idp2,ipp2;
+
+ arg=tpi/(float)ip;
+ dcp=cos(arg);
+ dsp=sin(arg);
+ ipph=(ip+1)>>1;
+ ipp2=ip;
+ idp2=ido;
+ nbd=(ido-1)>>1;
+ t0=l1*ido;
+ t10=ip*ido;
+
+ if (ido==1) goto L119;
+ for (ik=0;ik<idl1;ik++)ch2[ik]=c2[ik];
+
+ t1=0;
+ for (j=1;j<ip;j++){
+ t1+=t0;
+ t2=t1;
+ for (k=0;k<l1;k++){
+ ch[t2]=c1[t2];
+ t2+=ido;
+ }
+ }
+
+ is=-ido;
+ t1=0;
+ if (nbd>l1){
+ for (j=1;j<ip;j++){
+ t1+=t0;
+ is+=ido;
+ t2= -ido+t1;
+ for (k=0;k<l1;k++){
+ idij=is-1;
+ t2+=ido;
+ t3=t2;
+ for (i=2;i<ido;i+=2){
+ idij+=2;
+ t3+=2;
+ ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
+ ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
+ }
+ }
+ }
+ }else{
+
+ for (j=1;j<ip;j++){
+ is+=ido;
+ idij=is-1;
+ t1+=t0;
+ t2=t1;
+ for (i=2;i<ido;i+=2){
+ idij+=2;
+ t2+=2;
+ t3=t2;
+ for (k=0;k<l1;k++){
+ ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
+ ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
+ t3+=ido;
+ }
+ }
+ }
+ }
+
+ t1=0;
+ t2=ipp2*t0;
+ if (nbd<l1){
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+ for (i=2;i<ido;i+=2){
+ t3+=2;
+ t4+=2;
+ t5=t3-ido;
+ t6=t4-ido;
+ for (k=0;k<l1;k++){
+ t5+=ido;
+ t6+=ido;
+ c1[t5-1]=ch[t5-1]+ch[t6-1];
+ c1[t6-1]=ch[t5]-ch[t6];
+ c1[t5]=ch[t5]+ch[t6];
+ c1[t6]=ch[t6-1]-ch[t5-1];
+ }
+ }
+ }
+ }else{
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+ for (k=0;k<l1;k++){
+ t5=t3;
+ t6=t4;
+ for (i=2;i<ido;i+=2){
+ t5+=2;
+ t6+=2;
+ c1[t5-1]=ch[t5-1]+ch[t6-1];
+ c1[t6-1]=ch[t5]-ch[t6];
+ c1[t5]=ch[t5]+ch[t6];
+ c1[t6]=ch[t6-1]-ch[t5-1];
+ }
+ t3+=ido;
+ t4+=ido;
+ }
+ }
+ }
+
+L119:
+ for (ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
+
+ t1=0;
+ t2=ipp2*idl1;
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1-ido;
+ t4=t2-ido;
+ for (k=0;k<l1;k++){
+ t3+=ido;
+ t4+=ido;
+ c1[t3]=ch[t3]+ch[t4];
+ c1[t4]=ch[t4]-ch[t3];
+ }
+ }
+
+ ar1=1.;
+ ai1=0.;
+ t1=0;
+ t2=ipp2*idl1;
+ t3=(ip-1)*idl1;
+ for (l=1;l<ipph;l++){
+ t1+=idl1;
+ t2-=idl1;
+ ar1h=dcp*ar1-dsp*ai1;
+ ai1=dcp*ai1+dsp*ar1;
+ ar1=ar1h;
+ t4=t1;
+ t5=t2;
+ t6=t3;
+ t7=idl1;
+
+ for (ik=0;ik<idl1;ik++){
+ ch2[t4++]=c2[ik]+ar1*c2[t7++];
+ ch2[t5++]=ai1*c2[t6++];
+ }
+
+ dc2=ar1;
+ ds2=ai1;
+ ar2=ar1;
+ ai2=ai1;
+
+ t4=idl1;
+ t5=(ipp2-1)*idl1;
+ for (j=2;j<ipph;j++){
+ t4+=idl1;
+ t5-=idl1;
+
+ ar2h=dc2*ar2-ds2*ai2;
+ ai2=dc2*ai2+ds2*ar2;
+ ar2=ar2h;
+
+ t6=t1;
+ t7=t2;
+ t8=t4;
+ t9=t5;
+ for (ik=0;ik<idl1;ik++){
+ ch2[t6++]+=ar2*c2[t8++];
+ ch2[t7++]+=ai2*c2[t9++];
+ }
+ }
+ }
+
+ t1=0;
+ for (j=1;j<ipph;j++){
+ t1+=idl1;
+ t2=t1;
+ for (ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++];
+ }
+
+ if (ido<l1) goto L132;
+
+ t1=0;
+ t2=0;
+ for (k=0;k<l1;k++){
+ t3=t1;
+ t4=t2;
+ for (i=0;i<ido;i++)cc[t4++]=ch[t3++];
+ t1+=ido;
+ t2+=t10;
+ }
+
+ goto L135;
+
+ L132:
+ for (i=0;i<ido;i++){
+ t1=i;
+ t2=i;
+ for (k=0;k<l1;k++){
+ cc[t2]=ch[t1];
+ t1+=ido;
+ t2+=t10;
+ }
+ }
+
+ L135:
+ t1=0;
+ t2=ido<<1;
+ t3=0;
+ t4=ipp2*t0;
+ for (j=1;j<ipph;j++){
+
+ t1+=t2;
+ t3+=t0;
+ t4-=t0;
+
+ t5=t1;
+ t6=t3;
+ t7=t4;
+
+ for (k=0;k<l1;k++){
+ cc[t5-1]=ch[t6];
+ cc[t5]=ch[t7];
+ t5+=t10;
+ t6+=ido;
+ t7+=ido;
+ }
+ }
+
+ if (ido==1) return;
+ if (nbd<l1) goto L141;
+
+ t1=-ido;
+ t3=0;
+ t4=0;
+ t5=ipp2*t0;
+ for (j=1;j<ipph;j++){
+ t1+=t2;
+ t3+=t2;
+ t4+=t0;
+ t5-=t0;
+ t6=t1;
+ t7=t3;
+ t8=t4;
+ t9=t5;
+ for (k=0;k<l1;k++){
+ for (i=2;i<ido;i+=2){
+ ic=idp2-i;
+ cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1];
+ cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1];
+ cc[i+t7]=ch[i+t8]+ch[i+t9];
+ cc[ic+t6]=ch[i+t9]-ch[i+t8];
+ }
+ t6+=t10;
+ t7+=t10;
+ t8+=ido;
+ t9+=ido;
+ }
+ }
+ return;
+
+ L141:
+
+ t1=-ido;
+ t3=0;
+ t4=0;
+ t5=ipp2*t0;
+ for (j=1;j<ipph;j++){
+ t1+=t2;
+ t3+=t2;
+ t4+=t0;
+ t5-=t0;
+ for (i=2;i<ido;i+=2){
+ t6=idp2+t1-i;
+ t7=i+t3;
+ t8=i+t4;
+ t9=i+t5;
+ for (k=0;k<l1;k++){
+ cc[t7-1]=ch[t8-1]+ch[t9-1];
+ cc[t6-1]=ch[t8-1]-ch[t9-1];
+ cc[t7]=ch[t8]+ch[t9];
+ cc[t6]=ch[t9]-ch[t8];
+ t6+=t10;
+ t7+=t10;
+ t8+=ido;
+ t9+=ido;
+ }
+ }
+ }
+}
+
+STIN void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
+ int i,k1,l1,l2;
+ int na,kh,nf;
+ int ip,iw,ido,idl1,ix2,ix3;
+
+ nf=ifac[1];
+ na=1;
+ l2=n;
+ iw=n;
+
+ for (k1=0;k1<nf;k1++){
+ kh=nf-k1;
+ ip=ifac[kh+1];
+ l1=l2/ip;
+ ido=n/l2;
+ idl1=ido*l1;
+ iw-=(ip-1)*ido;
+ na=1-na;
+
+ if (ip!=4) goto L102;
+
+ ix2=iw+ido;
+ ix3=ix2+ido;
+ if (na!=0)
+ dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
+ else
+ dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
+ goto L110;
+
+ L102:
+ if (ip!=2) goto L104;
+ if (na!=0) goto L103;
+
+ dradf2(ido,l1,c,ch,wa+iw-1);
+ goto L110;
+
+ L103:
+ dradf2(ido,l1,ch,c,wa+iw-1);
+ goto L110;
+
+ L104:
+ if (ido==1)na=1-na;
+ if (na!=0) goto L109;
+
+ dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
+ na=1;
+ goto L110;
+
+ L109:
+ dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
+ na=0;
+
+ L110:
+ l2=l1;
+ }
+
+ if (na==1) return;
+
+ for (i=0;i<n;i++)c[i]=ch[i];
+}
+
+void __ogg_fdrfftf(int n,float *r,float *wsave,int *ifac){
+ if (n==1) return;
+ drftf1(n,r,wsave,wsave+n,ifac);
+}
+
+STIN void dcsqf1(int n,float *x,float *w,float *xh,int *ifac){
+ int modn,i,k,kc;
+ int np2,ns2;
+ float xim1;
+
+ ns2=(n+1)>>1;
+ np2=n;
+
+ kc=np2;
+ for (k=1;k<ns2;k++){
+ kc--;
+ xh[k]=x[k]+x[kc];
+ xh[kc]=x[k]-x[kc];
+ }
+
+ modn=n%2;
+ if (modn==0)xh[ns2]=x[ns2]+x[ns2];
+
+ for (k=1;k<ns2;k++){
+ kc=np2-k;
+ x[k]=w[k-1]*xh[kc]+w[kc-1]*xh[k];
+ x[kc]=w[k-1]*xh[k]-w[kc-1]*xh[kc];
+ }
+
+ if (modn==0)x[ns2]=w[ns2-1]*xh[ns2];
+
+ __ogg_fdrfftf(n,x,xh,ifac);
+
+ for (i=2;i<n;i+=2){
+ xim1=x[i-1]-x[i];
+ x[i]=x[i-1]+x[i];
+ x[i-1]=xim1;
+ }
+}
+
+void __ogg_fdcosqf(int n,float *x,float *wsave,int *ifac){
+ static float sqrt2=1.4142135623730950488016887242097;
+ float tsqx;
+
+ switch (n){
+ case 0:case 1:
+ return;
+ case 2:
+ tsqx=sqrt2*x[1];
+ x[1]=x[0]-tsqx;
+ x[0]+=tsqx;
+ return;
+ default:
+ dcsqf1(n,x,wsave,wsave+n,ifac);
+ return;
+ }
+}
+
+STIN void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
+ int i,k,t0,t1,t2,t3,t4,t5,t6;
+ float ti2,tr2;
+
+ t0=l1*ido;
+
+ t1=0;
+ t2=0;
+ t3=(ido<<1)-1;
+ for (k=0;k<l1;k++){
+ ch[t1]=cc[t2]+cc[t3+t2];
+ ch[t1+t0]=cc[t2]-cc[t3+t2];
+ t2=(t1+=ido)<<1;
+ }
+
+ if (ido<2) return;
+ if (ido==2) goto L105;
+
+ t1=0;
+ t2=0;
+ for (k=0;k<l1;k++){
+ t3=t1;
+ t5=(t4=t2)+(ido<<1);
+ t6=t0+t1;
+ for (i=2;i<ido;i+=2){
+ t3+=2;
+ t4+=2;
+ t5-=2;
+ t6+=2;
+ ch[t3-1]=cc[t4-1]+cc[t5-1];
+ tr2=cc[t4-1]-cc[t5-1];
+ ch[t3]=cc[t4]-cc[t5];
+ ti2=cc[t4]+cc[t5];
+ ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
+ ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
+ }
+ t2=(t1+=ido)<<1;
+ }
+
+ if (ido%2==1) return;
+
+L105:
+ t1=ido-1;
+ t2=ido-1;
+ for (k=0;k<l1;k++){
+ ch[t1]=cc[t2]+cc[t2];
+ ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
+ t1+=ido;
+ t2+=ido<<1;
+ }
+}
+
+STIN void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,
+ float *wa2){
+ static float taur = -.5;
+ static float taui = .86602540378443864676372317075293618;
+ int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+ float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2;
+ t0=l1*ido;
+
+ t1=0;
+ t2=t0<<1;
+ t3=ido<<1;
+ t4=ido+(ido<<1);
+ t5=0;
+ for (k=0;k<l1;k++){
+ tr2=cc[t3-1]+cc[t3-1];
+ cr2=cc[t5]+(taur*tr2);
+ ch[t1]=cc[t5]+tr2;
+ ci3=taui*(cc[t3]+cc[t3]);
+ ch[t1+t0]=cr2-ci3;
+ ch[t1+t2]=cr2+ci3;
+ t1+=ido;
+ t3+=t4;
+ t5+=t4;
+ }
+
+ if (ido==1) return;
+
+ t1=0;
+ t3=ido<<1;
+ for (k=0;k<l1;k++){
+ t7=t1+(t1<<1);
+ t6=(t5=t7+t3);
+ t8=t1;
+ t10=(t9=t1+t0)+t0;
+
+ for (i=2;i<ido;i+=2){
+ t5+=2;
+ t6-=2;
+ t7+=2;
+ t8+=2;
+ t9+=2;
+ t10+=2;
+ tr2=cc[t5-1]+cc[t6-1];
+ cr2=cc[t7-1]+(taur*tr2);
+ ch[t8-1]=cc[t7-1]+tr2;
+ ti2=cc[t5]-cc[t6];
+ ci2=cc[t7]+(taur*ti2);
+ ch[t8]=cc[t7]+ti2;
+ cr3=taui*(cc[t5-1]-cc[t6-1]);
+ ci3=taui*(cc[t5]+cc[t6]);
+ dr2=cr2-ci3;
+ dr3=cr2+ci3;
+ di2=ci2+cr3;
+ di3=ci2-cr3;
+ ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2;
+ ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2;
+ ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3;
+ ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3;
+ }
+ t1+=ido;
+ }
+}
+
+STIN void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
+ float *wa2,float *wa3){
+ static float sqrt2=1.4142135623730950488016887242097;
+ int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
+ float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
+ t0=l1*ido;
+
+ t1=0;
+ t2=ido<<2;
+ t3=0;
+ t6=ido<<1;
+ for (k=0;k<l1;k++){
+ t4=t3+t6;
+ t5=t1;
+ tr3=cc[t4-1]+cc[t4-1];
+ tr4=cc[t4]+cc[t4];
+ tr1=cc[t3]-cc[(t4+=t6)-1];
+ tr2=cc[t3]+cc[t4-1];
+ ch[t5]=tr2+tr3;
+ ch[t5+=t0]=tr1-tr4;
+ ch[t5+=t0]=tr2-tr3;
+ ch[t5+=t0]=tr1+tr4;
+ t1+=ido;
+ t3+=t2;
+ }
+
+ if (ido<2) return;
+ if (ido==2) goto L105;
+
+ t1=0;
+ for (k=0;k<l1;k++){
+ t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
+ t7=t1;
+ for (i=2;i<ido;i+=2){
+ t2+=2;
+ t3+=2;
+ t4-=2;
+ t5-=2;
+ t7+=2;
+ ti1=cc[t2]+cc[t5];
+ ti2=cc[t2]-cc[t5];
+ ti3=cc[t3]-cc[t4];
+ tr4=cc[t3]+cc[t4];
+ tr1=cc[t2-1]-cc[t5-1];
+ tr2=cc[t2-1]+cc[t5-1];
+ ti4=cc[t3-1]-cc[t4-1];
+ tr3=cc[t3-1]+cc[t4-1];
+ ch[t7-1]=tr2+tr3;
+ cr3=tr2-tr3;
+ ch[t7]=ti2+ti3;
+ ci3=ti2-ti3;
+ cr2=tr1-tr4;
+ cr4=tr1+tr4;
+ ci2=ti1+ti4;
+ ci4=ti1-ti4;
+
+ ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
+ ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
+ ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
+ ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
+ ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
+ ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
+ }
+ t1+=ido;
+ }
+
+ if (ido%2 == 1) return;
+
+ L105:
+
+ t1=ido;
+ t2=ido<<2;
+ t3=ido-1;
+ t4=ido+(ido<<1);
+ for (k=0;k<l1;k++){
+ t5=t3;
+ ti1=cc[t1]+cc[t4];
+ ti2=cc[t4]-cc[t1];
+ tr1=cc[t1-1]-cc[t4-1];
+ tr2=cc[t1-1]+cc[t4-1];
+ ch[t5]=tr2+tr2;
+ ch[t5+=t0]=sqrt2*(tr1-ti1);
+ ch[t5+=t0]=ti2+ti2;
+ ch[t5+=t0]=-sqrt2*(tr1+ti1);
+
+ t3+=ido;
+ t1+=t2;
+ t4+=t2;
+ }
+}
+
+STIN void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
+ float *c2,float *ch,float *ch2,float *wa){
+ static float tpi=6.28318530717958647692528676655900577;
+ int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
+ t11,t12;
+ float dc2,ai1,ai2,ar1,ar2,ds2;
+ int nbd;
+ float dcp,arg,dsp,ar1h,ar2h;
+ int ipp2;
+
+ t10=ip*ido;
+ t0=l1*ido;
+ arg=tpi/(float)ip;
+ dcp=cos(arg);
+ dsp=sin(arg);
+ nbd=(ido-1)>>1;
+ ipp2=ip;
+ ipph=(ip+1)>>1;
+ if (ido<l1) goto L103;
+
+ t1=0;
+ t2=0;
+ for (k=0;k<l1;k++){
+ t3=t1;
+ t4=t2;
+ for (i=0;i<ido;i++){
+ ch[t3]=cc[t4];
+ t3++;
+ t4++;
+ }
+ t1+=ido;
+ t2+=t10;
+ }
+ goto L106;
+
+ L103:
+ t1=0;
+ for (i=0;i<ido;i++){
+ t2=t1;
+ t3=t1;
+ for (k=0;k<l1;k++){
+ ch[t2]=cc[t3];
+ t2+=ido;
+ t3+=t10;
+ }
+ t1++;
+ }
+
+ L106:
+ t1=0;
+ t2=ipp2*t0;
+ t7=(t5=ido<<1);
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+ t6=t5;
+ for (k=0;k<l1;k++){
+ ch[t3]=cc[t6-1]+cc[t6-1];
+ ch[t4]=cc[t6]+cc[t6];
+ t3+=ido;
+ t4+=ido;
+ t6+=t10;
+ }
+ t5+=t7;
+ }
+
+ if (ido == 1) goto L116;
+ if (nbd<l1) goto L112;
+
+ t1=0;
+ t2=ipp2*t0;
+ t7=0;
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+
+ t7+=(ido<<1);
+ t8=t7;
+ for (k=0;k<l1;k++){
+ t5=t3;
+ t6=t4;
+ t9=t8;
+ t11=t8;
+ for (i=2;i<ido;i+=2){
+ t5+=2;
+ t6+=2;
+ t9+=2;
+ t11-=2;
+ ch[t5-1]=cc[t9-1]+cc[t11-1];
+ ch[t6-1]=cc[t9-1]-cc[t11-1];
+ ch[t5]=cc[t9]-cc[t11];
+ ch[t6]=cc[t9]+cc[t11];
+ }
+ t3+=ido;
+ t4+=ido;
+ t8+=t10;
+ }
+ }
+ goto L116;
+
+ L112:
+ t1=0;
+ t2=ipp2*t0;
+ t7=0;
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+ t7+=(ido<<1);
+ t8=t7;
+ t9=t7;
+ for (i=2;i<ido;i+=2){
+ t3+=2;
+ t4+=2;
+ t8+=2;
+ t9-=2;
+ t5=t3;
+ t6=t4;
+ t11=t8;
+ t12=t9;
+ for (k=0;k<l1;k++){
+ ch[t5-1]=cc[t11-1]+cc[t12-1];
+ ch[t6-1]=cc[t11-1]-cc[t12-1];
+ ch[t5]=cc[t11]-cc[t12];
+ ch[t6]=cc[t11]+cc[t12];
+ t5+=ido;
+ t6+=ido;
+ t11+=t10;
+ t12+=t10;
+ }
+ }
+ }
+
+L116:
+ ar1=1.;
+ ai1=0.;
+ t1=0;
+ t9=(t2=ipp2*idl1);
+ t3=(ip-1)*idl1;
+ for (l=1;l<ipph;l++){
+ t1+=idl1;
+ t2-=idl1;
+
+ ar1h=dcp*ar1-dsp*ai1;
+ ai1=dcp*ai1+dsp*ar1;
+ ar1=ar1h;
+ t4=t1;
+ t5=t2;
+ t6=0;
+ t7=idl1;
+ t8=t3;
+ for (ik=0;ik<idl1;ik++){
+ c2[t4++]=ch2[t6++]+ar1*ch2[t7++];
+ c2[t5++]=ai1*ch2[t8++];
+ }
+ dc2=ar1;
+ ds2=ai1;
+ ar2=ar1;
+ ai2=ai1;
+
+ t6=idl1;
+ t7=t9-idl1;
+ for (j=2;j<ipph;j++){
+ t6+=idl1;
+ t7-=idl1;
+ ar2h=dc2*ar2-ds2*ai2;
+ ai2=dc2*ai2+ds2*ar2;
+ ar2=ar2h;
+ t4=t1;
+ t5=t2;
+ t11=t6;
+ t12=t7;
+ for (ik=0;ik<idl1;ik++){
+ c2[t4++]+=ar2*ch2[t11++];
+ c2[t5++]+=ai2*ch2[t12++];
+ }
+ }
+ }
+
+ t1=0;
+ for (j=1;j<ipph;j++){
+ t1+=idl1;
+ t2=t1;
+ for (ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++];
+ }
+
+ t1=0;
+ t2=ipp2*t0;
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+ for (k=0;k<l1;k++){
+ ch[t3]=c1[t3]-c1[t4];
+ ch[t4]=c1[t3]+c1[t4];
+ t3+=ido;
+ t4+=ido;
+ }
+ }
+
+ if (ido==1) goto L132;
+ if (nbd<l1) goto L128;
+
+ t1=0;
+ t2=ipp2*t0;
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+ for (k=0;k<l1;k++){
+ t5=t3;
+ t6=t4;
+ for (i=2;i<ido;i+=2){
+ t5+=2;
+ t6+=2;
+ ch[t5-1]=c1[t5-1]-c1[t6];
+ ch[t6-1]=c1[t5-1]+c1[t6];
+ ch[t5]=c1[t5]+c1[t6-1];
+ ch[t6]=c1[t5]-c1[t6-1];
+ }
+ t3+=ido;
+ t4+=ido;
+ }
+ }
+ goto L132;
+
+ L128:
+ t1=0;
+ t2=ipp2*t0;
+ for (j=1;j<ipph;j++){
+ t1+=t0;
+ t2-=t0;
+ t3=t1;
+ t4=t2;
+ for (i=2;i<ido;i+=2){
+ t3+=2;
+ t4+=2;
+ t5=t3;
+ t6=t4;
+ for (k=0;k<l1;k++){
+ ch[t5-1]=c1[t5-1]-c1[t6];
+ ch[t6-1]=c1[t5-1]+c1[t6];
+ ch[t5]=c1[t5]+c1[t6-1];
+ ch[t6]=c1[t5]-c1[t6-1];
+ t5+=ido;
+ t6+=ido;
+ }
+ }
+ }
+
+L132:
+ if (ido==1) return;
+
+ for (ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
+
+ t1=0;
+ for (j=1;j<ip;j++){
+ t2=(t1+=t0);
+ for (k=0;k<l1;k++){
+ c1[t2]=ch[t2];
+ t2+=ido;
+ }
+ }
+
+ if (nbd>l1) goto L139;
+
+ is= -ido-1;
+ t1=0;
+ for (j=1;j<ip;j++){
+ is+=ido;
+ t1+=t0;
+ idij=is;
+ t2=t1;
+ for (i=2;i<ido;i+=2){
+ t2+=2;
+ idij+=2;
+ t3=t2;
+ for (k=0;k<l1;k++){
+ c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
+ c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
+ t3+=ido;
+ }
+ }
+ }
+ return;
+
+ L139:
+ is= -ido-1;
+ t1=0;
+ for (j=1;j<ip;j++){
+ is+=ido;
+ t1+=t0;
+ t2=t1;
+ for (k=0;k<l1;k++){
+ idij=is;
+ t3=t2;
+ for (i=2;i<ido;i+=2){
+ idij+=2;
+ t3+=2;
+ c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
+ c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
+ }
+ t2+=ido;
+ }
+ }
+}
+
+STIN void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
+ int i,k1,l1,l2;
+ int na;
+ int nf,ip,iw,ix2,ix3,ido,idl1;
+
+ nf=ifac[1];
+ na=0;
+ l1=1;
+ iw=1;
+
+ for (k1=0;k1<nf;k1++){
+ ip=ifac[k1 + 2];
+ l2=ip*l1;
+ ido=n/l2;
+ idl1=ido*l1;
+ if (ip!=4) goto L103;
+ ix2=iw+ido;
+ ix3=ix2+ido;
+
+ if (na!=0)
+ dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
+ else
+ dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
+ na=1-na;
+ goto L115;
+
+ L103:
+ if (ip!=2) goto L106;
+
+ if (na!=0)
+ dradb2(ido,l1,ch,c,wa+iw-1);
+ else
+ dradb2(ido,l1,c,ch,wa+iw-1);
+ na=1-na;
+ goto L115;
+
+ L106:
+ if (ip!=3) goto L109;
+
+ ix2=iw+ido;
+ if (na!=0)
+ dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1);
+ else
+ dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1);
+ na=1-na;
+ goto L115;
+
+ L109:
+/* The radix five case can be translated later..... */
+/* if (ip!=5) goto L112;
+
+ ix2=iw+ido;
+ ix3=ix2+ido;
+ ix4=ix3+ido;
+ if (na!=0)
+ dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
+ else
+ dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
+ na=1-na;
+ goto L115;
+
+ L112:*/
+ if (na!=0)
+ dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
+ else
+ dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
+ if (ido==1)na=1-na;
+
+ L115:
+ l1=l2;
+ iw+=(ip-1)*ido;
+ }
+
+ if (na==0) return;
+
+ for (i=0;i<n;i++)c[i]=ch[i];
+}
+
+void __ogg_fdrfftb(int n, float *r, float *wsave, int *ifac){
+ if (n == 1) return;
+ drftb1(n, r, wsave, wsave+n, ifac);
+}
+
+STIN void dcsqb1(int n,float *x,float *w,float *xh,int *ifac){
+ int modn,i,k,kc;
+ int np2,ns2;
+ float xim1;
+
+ ns2=(n+1)>>1;
+ np2=n;
+
+ for (i=2;i<n;i+=2){
+ xim1=x[i-1]+x[i];
+ x[i]-=x[i-1];
+ x[i-1]=xim1;
+ }
+
+ x[0]+=x[0];
+ modn=n%2;
+ if (modn==0)x[n-1]+=x[n-1];
+
+ __ogg_fdrfftb(n,x,xh,ifac);
+
+ kc=np2;
+ for (k=1;k<ns2;k++){
+ kc--;
+ xh[k]=w[k-1]*x[kc]+w[kc-1]*x[k];
+ xh[kc]=w[k-1]*x[k]-w[kc-1]*x[kc];
+ }
+
+ if (modn==0)x[ns2]=w[ns2-1]*(x[ns2]+x[ns2]);
+
+ kc=np2;
+ for (k=1;k<ns2;k++){
+ kc--;
+ x[k]=xh[k]+xh[kc];
+ x[kc]=xh[k]-xh[kc];
+ }
+ x[0]+=x[0];
+}
+
+void __ogg_fdcosqb(int n,float *x,float *wsave,int *ifac){
+ static float tsqrt2 = 2.8284271247461900976033774484194;
+ float x1;
+
+ if (n<2){
+ x[0]*=4;
+ return;
+ }
+ if (n==2){
+ x1=(x[0]+x[1])*4;
+ x[1]=tsqrt2*(x[0]-x[1]);
+ x[0]=x1;
+ return;
+ }
+
+ dcsqb1(n,x,wsave,wsave+n,ifac);
+}
+
+
+
diff --git a/demos/mobile/guitartuner/src/guitartuner.cpp b/demos/mobile/guitartuner/src/guitartuner.cpp
new file mode 100644
index 00000000..43222f2d
--- /dev/null
+++ b/demos/mobile/guitartuner/src/guitartuner.cpp
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "guitartuner.h"
+
+#ifdef Q_OS_SYMBIAN
+#include <SoundDevice.h>
+#endif // Q_OS_SYMBIAN
+
+#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK)
+#include <eikenv.h>
+#include <eikappui.h>
+#include <aknenv.h>
+#include <aknappui.h>
+#endif // Q_OS_SYMBIAN && ORIENTATIONLOCK
+
+GuitarTuner::GuitarTuner(QWidget *parent) :
+ QMainWindow(parent)
+{
+
+ // Set up the QML.
+ m_guitarTunerUI = new QDeclarativeView(QUrl("qrc:/src/application.qml"), this);
+ setCentralWidget(m_guitarTunerUI);
+ m_guitarTunerUI->setResizeMode(QDeclarativeView::SizeRootObjectToView);
+ qmlObject = m_guitarTunerUI->rootObject();
+
+ // Init audio output and input.
+ initAudioOutput();
+ initAudioInput();
+
+ // Connect the quit signal of m_guitarTunerUI
+ // into the close slot of this.
+ connect(m_guitarTunerUI->engine(), SIGNAL(quit()), SLOT(close()));
+
+ // Connect the signals from qmlObject into proper slots
+ // of this and m_voicegenerator.
+ connect(qmlObject, SIGNAL(muteStateChanged(bool)),
+ SLOT(muteStateChanged(bool)));
+ connect(qmlObject, SIGNAL(volumeChanged(qreal)),
+ m_voicegenerator, SLOT(setAmplitude(qreal)));
+ connect(qmlObject, SIGNAL(volumeChanged(qreal)),
+ SLOT(setMaxVolumeLevel(qreal)));
+
+ // Connect the modeChanged signal from qmlObject
+ // into modeChanged slot of this class.
+ connect(qmlObject, SIGNAL(modeChanged(bool)),
+ SLOT(modeChanged(bool)));
+
+ // Connect the microphoneSensitivityChanged signal from
+ // m_guitarTunerUI into setCutOffPercentage slot of m_analyzer class.
+ connect(qmlObject, SIGNAL(microphoneSensitivityChanged(qreal)),
+ m_analyzer, SLOT(setCutOffPercentage(qreal)));
+
+ // Connect the signals from m_analyzer into slots of qmlObject.
+ connect(m_analyzer, SIGNAL(lowVoice()),
+ qmlObject, SLOT(lowVoice()));
+ connect(m_analyzer, SIGNAL(correctFrequency()),
+ qmlObject, SLOT(correctFrequencyObtained()));
+ connect(m_analyzer, SIGNAL(voiceDifference(QVariant)),
+ qmlObject, SLOT(voiceDifferenceChanged(QVariant)));
+
+ // Initialise the MaximumVoiceDifference
+ // value of qmlObject with the value obtained from m_analyzer.
+ qmlObject->setProperty("maxVoiceDifference",
+ m_analyzer->getMaximumVoiceDifference());
+
+ // Connect the targetFrequencyChanged signal of qmlObject
+ // into targetFrequencyChanged slot of this class.
+ connect(qmlObject, SIGNAL(targetFrequencyChanged(qreal)),
+ SLOT(targetFrequencyChanged(qreal)));
+
+ // Start voice output or input by using the modeChanged function,
+ // depending of the current mode.
+ modeChanged(qmlObject->property("isInput").toBool());
+
+}
+
+/**
+ * Inits audio output.
+ */
+void GuitarTuner::initAudioOutput()
+{
+ // Set up the output format.
+ m_format_output.setFrequency(DataFrequencyHzOutput);
+ m_format_output.setCodec("audio/pcm");
+ m_format_output.setSampleSize(16);
+ m_format_output.setChannels(1);
+ m_format_output.setByteOrder(QAudioFormat::LittleEndian);
+ m_format_output.setSampleType(QAudioFormat::SignedInt);
+
+ // Obtain a default output device, and if the format is not
+ // supported, find the nearest format available.
+ QAudioDeviceInfo outputDeviceInfo(
+ QAudioDeviceInfo::defaultOutputDevice());
+ if (!outputDeviceInfo.isFormatSupported(m_format_output)) {
+ m_format_output = outputDeviceInfo.nearestFormat(m_format_output);
+ }
+
+ // Create new QAudioOutput and VoiceGenerator instances, and store
+ // them in m_audioOutput and m_voicegenerator, respectively.
+ m_audioOutput = new QAudioOutput(outputDeviceInfo,
+ m_format_output, this);
+ m_voicegenerator = new VoiceGenerator(m_format_output,
+ qmlObject->property("frequency").toReal(),
+ qmlObject->property("volume").toReal(),
+ this);
+
+ // Connect m_audioOutput stateChanged signal to outputStateChanged.
+ connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)),
+ SLOT(outputStateChanged(QAudio::State)));
+}
+
+/**
+ * Inits audio input.
+ */
+void GuitarTuner::initAudioInput()
+{
+ // Set up the input format.
+ m_format_input.setFrequency(DataFrequencyHzInput);
+ m_format_input.setCodec("audio/pcm");
+ m_format_input.setSampleSize(16);
+ m_format_input.setChannels(1);
+ m_format_input.setByteOrder(QAudioFormat::LittleEndian);
+ m_format_input.setSampleType(QAudioFormat::SignedInt);
+
+ // Obtain a default input device, and if the format is not
+ // supported, find the nearest format available.
+ QAudioDeviceInfo inputDeviceInfo(
+ QAudioDeviceInfo::defaultInputDevice());
+ if (!inputDeviceInfo.isFormatSupported(m_format_input)) {
+ m_format_input = inputDeviceInfo.nearestFormat(m_format_input);
+ }
+
+ // Create new QAudioInput and VoiceAnalyzer instances, and store
+ // them in m_audioInput and m_analyzer, respectively.
+ // Remember to set the cut-off percentage for voice analyzer.
+ m_audioInput = new QAudioInput(inputDeviceInfo, m_format_input, this);
+ m_analyzer = new VoiceAnalyzer(m_format_input, this);
+ m_analyzer->setCutOffPercentage(qmlObject->property("sensitivity").toReal());
+
+}
+
+/**
+ * Receives a mode changed signal.
+ */
+void GuitarTuner::modeChanged(bool isInput)
+{
+
+
+
+ // If the mode must be changed to input mode:
+ if (isInput) {
+
+ // Stop audio output and audio generator.
+ m_audioOutput->stop();
+ m_voicegenerator->stop();
+ // Start the audio analyzer and then the audio input.
+ m_analyzer->start(qmlObject->property("frequency").toReal());
+ m_audioInput->start(m_analyzer);
+
+ }
+ // Else:
+ else {
+
+ // Stop audio input and audio analyzer.
+ m_audioInput->stop();
+ m_analyzer->stop();
+
+ // Set up the audio output.
+
+ // If the current frequency of voice generator
+ // is not the same as the target frequency selected in the UI,
+ // update voice generator's frequency.
+ if (m_voicegenerator->frequency() != qmlObject->property("frequency").toReal()) {
+ m_voicegenerator->setFrequency(qmlObject->property("frequency").toReal());
+ }
+
+ // Start the voice generator and then the audio output.
+ m_voicegenerator->start();
+ m_audioOutput->start(m_voicegenerator);
+ // Call setMaxVolumeLevel(1) to set the maximum volume louder.
+ setMaxVolumeLevel(qmlObject->property("volume").toReal());
+
+ // If the voice is muted, the voice is suspended
+ // in the outputStateChanged slot.
+
+ }
+}
+
+/**
+ * Receives a output state changed signal.
+ * Suspends the audio output, if the state is ActiveState
+ * and the voice is muted.
+ */
+void GuitarTuner::outputStateChanged(QAudio::State state)
+{
+ if (QAudio::ActiveState == state && qmlObject->property("isMuted").toBool()) {
+ // If the voice is muted, suspend the voice.
+ m_audioOutput->suspend();
+ }
+}
+
+/**
+ * Receives a mute state changed signal.
+ * Suspends the audio output or resumes it, depending of the
+ * isMuted parameter.
+ */
+void GuitarTuner::muteStateChanged(bool isMuted)
+{
+ if (isMuted) {
+ m_audioOutput->suspend();
+ }
+ else {
+ m_audioOutput->resume();
+ }
+}
+
+/**
+ * Receives a target frequency signal.
+ */
+void GuitarTuner::targetFrequencyChanged(qreal targetFrequency)
+{
+ // If the output mode is active:
+ if (!qmlObject->property("isInput").toBool()) {
+ // Stop the audio output and voice generator.
+ m_audioOutput->stop();
+ m_voicegenerator->stop();
+ // Set the voice generator's frequency to the target frequency.
+ m_voicegenerator->setFrequency(targetFrequency);
+ // Start the voice generator and audio output.
+ m_voicegenerator->start();
+ m_audioOutput->start(m_voicegenerator);
+ // Call setMaxVolumeLevel(1) to set the maximum volume louder.
+ setMaxVolumeLevel(qmlObject->property("volume").toReal());
+
+ // If the voice is muted, the voice is suspended
+ // in the outputStateChanged slot.
+
+ }
+ // Else:
+ else {
+
+ // Stop the audio input and voice analyzer.
+ m_audioInput->stop();
+ m_analyzer->stop();
+ // Start the voice analyzer with new frequency and audio input.
+ m_analyzer->start(targetFrequency);
+ m_audioInput->start(m_analyzer);
+
+ }
+}
+
+/**
+ * This method provides a hack to set the maximum volume level in
+ * Symbian.
+ */
+void GuitarTuner::setMaxVolumeLevel(qreal percent)
+{
+ if (percent >= 1.0) {
+ percent = 1.0;
+ }
+ else if (percent <= 0.0) {
+ percent = 0.0;
+ }
+ percent = percent*0.5 + 0.5;
+ // Warning! This is a hack, which can break when the QtMobility
+ // changes. Use at your own risk.
+#ifdef Q_OS_SYMBIAN
+ unsigned int *pointer_to_abstract_audio
+ = (unsigned int*)( (unsigned char*)m_audioOutput + 8 );
+ unsigned int *dev_sound_wrapper
+ = (unsigned int*)(*pointer_to_abstract_audio) + 16;
+ unsigned int *temp
+ = ((unsigned int*)(*dev_sound_wrapper) + 6);
+ CMMFDevSound *dev_sound = (CMMFDevSound*)(*temp);
+ dev_sound->SetVolume((unsigned int)
+ (percent*(float)dev_sound->MaxVolume()));
+#endif
+}
+
+/**
+ * A function used to lock the orientation.
+ */
+void GuitarTuner::setOrientation(Orientation orientation)
+{
+#ifdef Q_OS_SYMBIAN
+ if (orientation != Auto) {
+#if defined(ORIENTATIONLOCK)
+ const CAknAppUiBase::TAppUiOrientation uiOrientation =
+ (orientation == LockPortrait)
+ ? CAknAppUi::EAppUiOrientationPortrait
+ : CAknAppUi::EAppUiOrientationLandscape;
+ CAknAppUi* appUi = dynamic_cast<CAknAppUi*>
+ (CEikonEnv::Static()->AppUi());
+ TRAPD(error,
+ if (appUi)
+ appUi->SetOrientationL(uiOrientation);
+ );
+#else // ORIENTATIONLOCK
+ qWarning(QString("'ORIENTATIONLOCK' needs to be defined on")
+ +QString(" Symbian when locking the orientation."));
+#endif // ORIENTATIONLOCK
+ }
+#elif defined(Q_WS_MAEMO_5)
+ Qt::WidgetAttribute attribute;
+ switch (orientation) {
+ case LockPortrait:
+ attribute = Qt::WA_Maemo5PortraitOrientation;
+ break;
+ case LockLandscape:
+ attribute = Qt::WA_Maemo5LandscapeOrientation;
+ break;
+ case Auto:
+ default:
+ attribute = Qt::WA_Maemo5AutoOrientation;
+ break;
+ }
+ setAttribute(attribute, true);
+#else // Q_OS_SYMBIAN
+ Q_UNUSED(orientation);
+#endif // Q_OS_SYMBIAN
+}
diff --git a/demos/mobile/guitartuner/src/guitartuner.h b/demos/mobile/guitartuner/src/guitartuner.h
new file mode 100644
index 00000000..fbb16f7c
--- /dev/null
+++ b/demos/mobile/guitartuner/src/guitartuner.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QtDeclarative>
+#include <QAudioDeviceInfo>
+#include <QAudioOutput>
+#include <QAudioInput>
+#include "voicegenerator.h"
+#include "voiceanalyzer.h"
+
+const int DataFrequencyHzOutput = 44100;
+const int DataFrequencyHzInput = 48000;
+
+#define MAX_INPUT_VALUE 50
+#define MIN_INPUT_VALUE -50
+
+class GuitarTuner : public QMainWindow
+{
+ Q_OBJECT
+public:
+ enum Orientation {
+ LockPortrait,
+ LockLandscape,
+ Auto
+ };
+ explicit GuitarTuner(QWidget *parent = 0);
+ qreal getVolume();
+ qreal getMicrophoneSensitivity();
+ bool getMuteState();
+ void setOrientation(Orientation orientation);
+
+signals:
+
+public slots:
+ void modeChanged(bool isInput);
+ void muteStateChanged(bool isMuted);
+ void targetFrequencyChanged(qreal targetFrequency);
+ void outputStateChanged(QAudio::State state);
+ void setMaxVolumeLevel(qreal);
+
+private:
+ void initAudioOutput();
+ void initAudioInput();
+ VoiceGenerator *m_voicegenerator;
+ VoiceAnalyzer *m_analyzer;
+ QObject *qmlObject;
+ QAudioOutput *m_audioOutput;
+ QAudioInput *m_audioInput;
+ QAudioFormat m_format_output;
+ QAudioFormat m_format_input;
+ QDeclarativeView *m_guitarTunerUI;
+};
+
+#endif // MAINWINDOW_H
diff --git a/demos/mobile/guitartuner/src/guitartuner.rc b/demos/mobile/guitartuner/src/guitartuner.rc
new file mode 100644
index 00000000..5cd35118
--- /dev/null
+++ b/demos/mobile/guitartuner/src/guitartuner.rc
@@ -0,0 +1,23 @@
+IDI_ICON1 ICON DISCARDABLE "/../images/guitartuner_icon.ico"
+
+1 VERSIONINFO
+FILEVERSION 1,2,0,0
+PRODUCTVERSION 1,2,0,0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation\0"
+ VALUE "FileDescription", "Qt Quick example application.\0"
+ VALUE "FileVersion", "1.2.0\0"
+ VALUE "LegalCopyright", "Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "ProductName", "Guitar Tuner\0"
+ VALUE "ProductVersion", "1.2.0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/demos/mobile/guitartuner/src/guitartuner.ui b/demos/mobile/guitartuner/src/guitartuner.ui
new file mode 100644
index 00000000..36ee1bd8
--- /dev/null
+++ b/demos/mobile/guitartuner/src/guitartuner.ui
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>GuitarTuner</class>
+ <widget class="QWidget" name="GuitarTuner">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>187</width>
+ <height>279</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>GuitarTuner</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="tabulatorIcon">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../guitartuner.qrc">:/images/guitartab.svg</pixmap>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="correctSoundSlider">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="minimum">
+ <number>-50</number>
+ </property>
+ <property name="maximum">
+ <number>50</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ <property name="tickInterval">
+ <number>50</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="buttonPrev">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::LeftArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="noteLabel">
+ <property name="text">
+ <string>A</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonNext">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="autoRaise">
+ <bool>false</bool>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::RightArrow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPushButton" name="modeButton">
+ <property name="text">
+ <string>Change mode</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QSlider" name="soundSlider">
+ <property name="value">
+ <number>65</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="soundButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../guitartuner.qrc">
+ <normaloff>:/images/note.svg</normaloff>
+ <normalon>:/images/noteNo.svg</normalon>
+ <activeon>:/images/noteNo.svg</activeon>:/images/note.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>30</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="micSensitivityLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>microphone
+sensitivity</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+ <include location="../guitartuner.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/demos/mobile/guitartuner/src/guitartunerui.cpp b/demos/mobile/guitartuner/src/guitartunerui.cpp
new file mode 100644
index 00000000..24357b3b
--- /dev/null
+++ b/demos/mobile/guitartuner/src/guitartunerui.cpp
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QTimer>
+
+#include "guitartunerui.h"
+#include "ui_guitartunerui.h"
+
+GuitarTunerUI::GuitarTunerUI(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::GuitarTunerUI),
+ m_maximumPrecision(0)
+{
+ ui->setupUi(this);
+
+ // Set up the class attributes to proper values.
+ m_outputActive = false;
+ m_muted = false;
+ m_outputVolumeLevel = getVolumeFromSoundSlider();
+ m_inputVolumeLevel = 1.0 - m_outputVolumeLevel;
+
+ // Set up the current tone, the frequency, and the name for it.
+ m_currentToneIndex = 5;
+ updateFrequencyByToneIndex(m_currentToneIndex);
+
+ // Connect the signals from UI into proper slots.
+ connect(ui->soundSlider, SIGNAL(valueChanged(int)),
+ SLOT(changeVolume()));
+ connect(ui->soundButton, SIGNAL(toggled(bool)),
+ SLOT(toggleSound(bool)));
+ connect(ui->modeButton, SIGNAL(clicked()),
+ SLOT(toggleInputOrOutput()));
+ connect(ui->buttonNext, SIGNAL(clicked()), SLOT(next()));
+ connect(ui->buttonPrev, SIGNAL(clicked()), SLOT(prev()));
+
+ // Initialise up the UI by calling toggleInputOrOutput
+ // for the first time.
+ toggleInputOrOutput();
+}
+
+GuitarTunerUI::~GuitarTunerUI()
+{
+ delete ui;
+}
+
+void GuitarTunerUI::changeEvent(QEvent *e)
+{
+ QWidget::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Returns a value from 0 to 1, representing the volume.
+ */
+qreal GuitarTunerUI::getVolumeFromSoundSlider() const
+{
+ qreal value = ui->soundSlider->value();
+ return value/ui->soundSlider->maximum();
+}
+
+/**
+ * Updates the m_currentToneFrequency and m_currentToneString,
+ * according to the given index. Also updates the UI.
+ */
+void GuitarTunerUI::updateFrequencyByToneIndex(int index)
+{
+
+ switch (index) {
+ case 0: {
+ m_currentToneFrequency = FrequencyE;
+ m_currentToneString = "E";
+ break;
+ }
+ case 1: {
+ m_currentToneFrequency = FrequencyA;
+ m_currentToneString = "A";
+ break;
+ }
+ case 2: {
+ m_currentToneFrequency = FrequencyD;
+ m_currentToneString = "D";
+ break;
+ }
+ case 3: {
+ m_currentToneFrequency = FrequencyG;
+ m_currentToneString = "G";
+ break;
+ }
+ case 4: {
+ m_currentToneFrequency = FrequencyB;
+ m_currentToneString = "B";
+ break;
+ }
+ case 5: {
+ m_currentToneFrequency = FrequencyE2;
+ m_currentToneString = "e";
+ break;
+ }
+ default: {
+ qDebug() << "invalid index!" << index;
+ }
+ }
+ // Set the noteLabel text according to the current tone.
+ ui->noteLabel->setText(m_currentToneString);
+}
+
+/**
+ * Returns the volume.
+ */
+qreal GuitarTunerUI::getVolume() const
+{
+ return m_outputVolumeLevel;
+}
+
+/**
+ * Returns true if the sound is muted.
+ */
+bool GuitarTunerUI::getMuteState() const
+{
+ return m_muted;
+}
+
+
+/**
+ * Returns the microphone sensitivity.
+ */
+qreal GuitarTunerUI::getMicrophoneSensitivity() const
+{
+ return m_inputVolumeLevel;
+}
+
+/**
+ * Returns whether the input mode is active.
+ */
+bool GuitarTunerUI::isInputModeActive() const
+{
+ return !m_outputActive;
+}
+
+/**
+ * Returns the current target frequency.
+ */
+qreal GuitarTunerUI::getFrequency() const
+{
+ return m_currentToneFrequency;
+}
+
+/**
+ * Toggles the sound according to the parameter.
+ * Has no effect if output is not active.
+ */
+void GuitarTunerUI::toggleSound(bool noSound)
+{
+ if (!m_outputActive) {
+ return;
+ }
+ m_muted = noSound;
+ emit muteChanged(m_muted);
+}
+
+/**
+ * Changes the volume or microphone sensitivity.
+ */
+void GuitarTunerUI::changeVolume()
+{
+ qreal resultingAmplitude = getVolumeFromSoundSlider();
+ qDebug() << "resultingAmplitude" << resultingAmplitude;
+ if (m_outputActive) {
+ m_outputVolumeLevel = resultingAmplitude;
+ emit volumeChanged(resultingAmplitude);
+ }
+ else {
+ m_inputVolumeLevel = resultingAmplitude;
+ emit microphoneSensitivityChanged(1.0-resultingAmplitude);
+ }
+}
+
+/**
+ * Toggles input or output, depending of the current state.
+ */
+void GuitarTunerUI::toggleInputOrOutput()
+{
+ // If output mode is active:
+ if (m_outputActive) {
+ // Change UI to correspond to the input mode.
+ m_outputActive = false;
+ ui->soundSlider->setValue(m_inputVolumeLevel*100);
+ ui->soundButton->setDisabled(true);
+ ui->soundButton->hide();
+ ui->micSensitivityLabel->show();
+ emit modeChanged(true);
+ ui->modeButton->setText("To tone mode");
+ }
+ // Else:
+ else {
+ // Change UI to correspond to the output mode.
+ m_outputActive = true;
+ ui->soundSlider->setValue(m_outputVolumeLevel*100);
+ ui->soundButton->setDisabled(false);
+ ui->micSensitivityLabel->hide();
+ ui->soundButton->show();
+ emit modeChanged(false);
+ ui->modeButton->setText("To listen mode");
+ }
+}
+
+/**
+ * Receives the low voice signal.
+ */
+void GuitarTunerUI::lowVoice()
+{
+ if (ui->noteLabel->font().bold()) {
+ QFont font;
+ font.setBold(false);
+ font.setUnderline(false);
+ ui->noteLabel->setFont(font);
+ }
+}
+
+/**
+ * Receives the voice difference signal.
+ * The difference is qreal, where increase of 1 corresponds
+ * to increase of 1 tone to the target frequency.
+ */
+void GuitarTunerUI::voiceDifference(qreal difference)
+{
+ if (ui->noteLabel->font().bold()) {
+ QFont font;
+ font.setBold(false);
+ font.setUnderline(false);
+ ui->noteLabel->setFont(font);
+ }
+ ui->correctSoundSlider->setValue(difference*m_maximumPrecision);
+}
+
+/**
+ * Receives the correct frequency signal.
+ * Makes the UI to visualize correct frequency event.
+ */
+void GuitarTunerUI::correctFrequencyObtained()
+{
+ qDebug() << "CORRECT FREQUENCY";
+ QFont font;
+ font.setBold(true);
+ font.setUnderline(true);
+ ui->noteLabel->setFont(font);
+}
+
+/**
+ * Sets up the maximum voice difference.
+ */
+void GuitarTunerUI::setMaximumVoiceDifference(int max)
+{
+ // Assert that the maximum precision is known.
+ Q_ASSERT(m_maximumPrecision != 0);
+ // Set the maximum and minimum values of the correctSoundSlider
+ // to the +- max*m_maximumPrecision, and set the tick interval
+ // to be m_maximumPrecision.
+ ui->correctSoundSlider->setMaximum(max*m_maximumPrecision);
+ ui->correctSoundSlider->setMinimum(-max*m_maximumPrecision);
+ ui->correctSoundSlider->setTickInterval(max*m_maximumPrecision);
+}
+
+/**
+ * Stores the maximum precision per note. Used to setup the
+ * correct sound slider.
+ */
+void GuitarTunerUI::setMaximumPrecisionPerNote(int max)
+{
+ m_maximumPrecision = max;
+}
+
+/**
+ * Changes the tone to the next value.
+ */
+void GuitarTunerUI::next()
+{
+ changeTone((m_currentToneIndex + 1) % 6);
+}
+
+/**
+ * Changes the tone to the previous value.
+ */
+void GuitarTunerUI::prev()
+{
+ changeTone((m_currentToneIndex + 5) % 6);
+}
+
+/**
+ * Changes the tone according to the new index.
+ */
+void GuitarTunerUI::changeTone(int newIndex)
+{
+ m_currentToneIndex = newIndex;
+ updateFrequencyByToneIndex(m_currentToneIndex);
+ qDebug() << "targetFrequencyChanged" << m_currentToneFrequency;
+ emit targetFrequencyChanged(m_currentToneFrequency);
+}
diff --git a/demos/mobile/guitartuner/src/guitartunerui.h b/demos/mobile/guitartuner/src/guitartunerui.h
new file mode 100644
index 00000000..79c92e3e
--- /dev/null
+++ b/demos/mobile/guitartuner/src/guitartunerui.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GUITARTUNERUI_H
+#define GUITARTUNERUI_H
+
+#include <QWidget>
+#include <QDebug>
+
+namespace Ui {
+ class GuitarTunerUI;
+}
+
+const qreal FrequencyE = 82.407;
+const qreal FrequencyA = 110.00;
+const qreal FrequencyD = 146.83;
+const qreal FrequencyG = 196.00;
+const qreal FrequencyB = 246.94;
+const qreal FrequencyE2 = 329.63;
+
+class GuitarTunerUI : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit GuitarTunerUI(QWidget *parent = 0);
+ ~GuitarTunerUI();
+
+ qreal getVolume() const;
+ bool getMuteState() const;
+ qreal getMicrophoneSensitivity() const;
+ bool isInputModeActive() const;
+ qreal getFrequency() const;
+ int getScaleMaximumValue() const;
+ void setMaximumVoiceDifference(int max);
+ void setMaximumPrecisionPerNote(int max);
+
+public slots:
+ void toggleSound(bool off);
+ void next();
+ void prev();
+ void changeVolume();
+ void toggleInputOrOutput();
+
+ void lowVoice();
+ void voiceDifference(qreal difference);
+ void correctFrequencyObtained();
+
+signals:
+ void modeChanged(bool isInput);
+ void volumeChanged(qreal volume);
+ void microphoneSensitivityChanged(qreal sensitivity);
+ void muteChanged(bool isMuted);
+ void targetFrequencyChanged(qreal targetFrequency);
+
+protected:
+ void changeEvent(QEvent *e);
+
+private:
+ Ui::GuitarTunerUI *ui;
+ void changeTone(int newIndex);
+ qreal getVolumeFromSoundSlider() const;
+ int m_currentToneIndex;
+ QString m_currentToneString;
+ qreal m_currentToneFrequency;
+ void updateFrequencyByToneIndex(int index);
+ bool m_outputActive;
+ bool m_muted;
+ qreal m_outputVolumeLevel;
+ qreal m_inputVolumeLevel;
+ int m_maximumPrecision;
+};
+
+#endif // GUITARTUNERUI_H
diff --git a/demos/mobile/guitartuner/src/guitartunerui.ui b/demos/mobile/guitartuner/src/guitartunerui.ui
new file mode 100644
index 00000000..af7b585b
--- /dev/null
+++ b/demos/mobile/guitartuner/src/guitartunerui.ui
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>GuitarTunerUI</class>
+ <widget class="QWidget" name="GuitarTunerUI">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>187</width>
+ <height>279</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>GuitarTunerUI</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="tabulatorIcon">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../GuitarTuner.qrc">:/images/guitartab.svg</pixmap>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="correctSoundSlider">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="minimum">
+ <number>-50</number>
+ </property>
+ <property name="maximum">
+ <number>50</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ <property name="tickInterval">
+ <number>50</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="buttonPrev">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::LeftArrow</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="noteLabel">
+ <property name="text">
+ <string>A</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="buttonNext">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="autoRaise">
+ <bool>false</bool>
+ </property>
+ <property name="arrowType">
+ <enum>Qt::RightArrow</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPushButton" name="modeButton">
+ <property name="text">
+ <string>Change mode</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QSlider" name="soundSlider">
+ <property name="value">
+ <number>65</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="soundButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../GuitarTuner.qrc">
+ <normaloff>:/images/note.svg</normaloff>
+ <normalon>:/images/noteNo.svg</normalon>
+ <activeon>:/images/noteNo.svg</activeon>:/images/note.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>30</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="micSensitivityLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>microphone
+sensitivity</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+ <include location="../GuitarTuner.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/demos/mobile/guitartuner/src/main.cpp b/demos/mobile/guitartuner/src/main.cpp
new file mode 100644
index 00000000..7ddd1f78
--- /dev/null
+++ b/demos/mobile/guitartuner/src/main.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QApplication>
+#include "guitartuner.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ GuitarTuner w;
+ w.setOrientation(GuitarTuner::LockPortrait);
+
+#ifdef Q_OS_SYMBIAN
+ w.showFullScreen();
+#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
+ w.showMaximized();
+#else
+ w.show();
+#endif
+
+ return a.exec();
+}
+
diff --git a/demos/mobile/guitartuner/src/mycomponents/Adjuster.qml b/demos/mobile/guitartuner/src/mycomponents/Adjuster.qml
new file mode 100644
index 00000000..e5e67eb8
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/Adjuster.qml
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+import "adjustbars.js" as AdjustBars
+
+/* A barchart-like adjuster component. */
+Rectangle {
+ id: adjuster
+
+ property real max: 100
+ property real value: 0
+ property bool created: false
+
+ signal valueChanged(real value)
+ signal focusChangedByClick()
+ signal arrowPressedWhenValueOverLimits()
+
+ function setValue(pValue) {
+ value = pValue;
+ AdjustBars.fillBars(value/max*AdjustBars.maxBars);
+ valueChanged(value);
+ }
+
+ height: 60; width: 300
+ color: "transparent"
+ Keys.onRightPressed: {
+ var val = value+max/AdjustBars.maxBars;
+ if (val <= max) {
+ value = val;
+ AdjustBars.fillBars(value/max*AdjustBars.maxBars);
+ valueChanged(value);
+ }
+ else {
+ arrowPressedWhenValueOverLimits()
+ }
+ }
+ Keys.onLeftPressed: {
+ var val = value-max/AdjustBars.maxBars;
+ if (0 <= val) {
+ value = val;
+ AdjustBars.fillBars(value/max*AdjustBars.maxBars);
+ valueChanged(value);
+ }
+ else {
+ arrowPressedWhenValueOverLimits()
+ }
+ }
+ Component.onCompleted: {
+ AdjustBars.createBars();
+ AdjustBars.fillBars(value/max*AdjustBars.maxBars);
+ created = true;
+ }
+ Component.onDestruction: {
+ AdjustBars.destroyBars;
+ }
+ //Dynamic objects have to be recreated when the window size changes.
+ onWidthChanged: {
+ if (created) {
+ AdjustBars.destroyBars();
+ AdjustBars.createBars();
+ AdjustBars.fillBars(value/max*AdjustBars.maxBars);
+ }
+ }
+ onHeightChanged: {
+ if (created) {
+ AdjustBars.destroyBars();
+ AdjustBars.createBars();
+ AdjustBars.fillBars(value/max*AdjustBars.maxBars);
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPositionChanged: {
+ focusChangedByClick();
+ var val = mouse.x/parent.width*parent.max;
+ if (0 < val && val < max) {
+ parent.value = val;
+ AdjustBars.fillBars(parent.value/parent.max*AdjustBars.maxBars);
+ valueChanged(parent.value);
+ }
+ }
+ onClicked: {
+ focusChangedByClick();
+ var val = mouse.x/parent.width*parent.max;
+ if (0 < val && val < max) {
+ parent.value = val;
+ AdjustBars.fillBars(parent.value/parent.max*AdjustBars.maxBars);
+ valueChanged(parent.value);
+ }
+ }
+ }
+}
diff --git a/demos/mobile/guitartuner/src/mycomponents/Meter.qml b/demos/mobile/guitartuner/src/mycomponents/Meter.qml
new file mode 100644
index 00000000..1b175493
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/Meter.qml
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+/* A meter component. */
+Rectangle {
+ id: meter
+
+ property real value: 0
+ property real minValue: -1
+ property real maxValue: 1
+ property alias imageSize: meterImage.sourceSize
+
+ function valueChanged(pValue) {
+ value = pValue;
+ scaleValueToAngle();
+ }
+ function scaleValueToAngle() {
+ pointer.angle = (((value-minValue)/(maxValue-minValue))*
+ (pointer.angleMax-pointer.angleMin))+
+ pointer.angleMin;
+ }
+
+ color: "transparent"
+
+ Image {
+ id: meterImage
+
+ smooth: true
+ source: "./images/meterBG.png"
+ anchors.fill: parent
+ }
+
+ Image {
+ id:pointerShadow
+
+ x: pointer.x - 2
+ y: pointer.y - 2
+ height: pointer.height
+ smooth: true
+ source: "./images/pointerShadow.png"
+ transform: Rotation {
+ origin.x: 2
+ origin.y: height
+ angle: -pointer.angle
+ }
+ }
+
+ Image {
+ id: pointer
+
+ property real angle: 0
+ property real angleMax: -45
+ property real angleMin: 45
+
+ height: parent.height*0.92
+ transformOrigin: "Bottom"
+ rotation: -angle
+ smooth: true
+ source: "./images/pointer.png"
+ anchors {
+ bottomMargin: 2
+ bottom: parent.bottom;
+ horizontalCenter: parent.horizontalCenter
+ }
+
+ Behavior on angle {
+ SpringAnimation {
+ spring: 1.4
+ damping: 0.15
+ }
+ }
+ }
+}
diff --git a/demos/mobile/guitartuner/src/mycomponents/NoteButtonView.qml b/demos/mobile/guitartuner/src/mycomponents/NoteButtonView.qml
new file mode 100644
index 00000000..04a78dd4
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/NoteButtonView.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+/* A view component for buttons for choosing notes. */
+ListView {
+ id: noteChooser
+
+ property real currentFrequency: 82.407
+
+ signal noteSelected(string note, real frequency, int index)
+
+ //Press down the button corresponding to the given note.
+ function pushButton(index) {
+ currentIndex = index;
+ }
+
+ width: 50*model.count + spacing*(model.count-1); height: 50
+ orientation: ListView.Horizontal
+ model: NotesModel {}
+ delegate: notesDelegate
+ keyNavigationWraps: true
+ boundsBehavior: Flickable.StopAtBounds
+
+ Component {
+ id: notesDelegate
+
+ ToggleButton {
+ id: noteButton
+
+ width: height; height: noteChooser.height
+ offImageSource: offSource
+ onImageSource: onSource
+ state: noteButton.ListView.isCurrentItem ? "pressed" : "unPressed"
+ onSelected: {
+ noteChooser.noteSelected(note, frequency, index)
+ if (note != "Auto") {
+ currentFrequency = frequency
+ }
+ }
+ onPushed: {
+ noteButton.ListView.view.currentIndex = index
+ }
+ }
+ }
+}
diff --git a/demos/mobile/guitartuner/src/mycomponents/NotesModel.qml b/demos/mobile/guitartuner/src/mycomponents/NotesModel.qml
new file mode 100644
index 00000000..1aecc051
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/NotesModel.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+/* The model component for the NoteButtonView. */
+ListModel {
+ ListElement {
+ note: "E"
+ offSource: "./images/tuner_e.png"
+ onSource: "./images/tuner_e_on.png"
+ bigSource: "./mycomponents/images/big_e.png"
+ glowSource: "./mycomponents/images/glowing_e.png"
+ frequency: "82.407"
+ interval: "5"
+ }
+ ListElement {
+ note: "A"
+ offSource: "./images/tuner_a.png"
+ onSource: "./images/tuner_a_on.png"
+ bigSource: "./mycomponents/images/big_a.png"
+ glowSource: "./mycomponents/images/glowing_a.png"
+ frequency: "110.00"
+ interval: "5"
+ }
+ ListElement {
+ note: "D"
+ offSource: "./images/tuner_d.png"
+ onSource: "./images/tuner_d_on.png"
+ bigSource: "./mycomponents/images/big_d.png"
+ glowSource: "./mycomponents/images/glowing_d.png"
+ frequency: "146.83"
+ interval: "5"
+ }
+ ListElement {
+ note: "G"
+ offSource: "./images/tuner_g.png"
+ onSource: "./images/tuner_g_on.png"
+ bigSource: "./mycomponents/images/big_g.png"
+ glowSource: "./mycomponents/images/glowing_g.png"
+ frequency: "196.00"
+ interval: "4"
+ }
+ ListElement {
+ note: "B"
+ offSource: "./images/tuner_b.png"
+ onSource: "./images/tuner_b_on.png"
+ bigSource: "./mycomponents/images/big_b.png"
+ glowSource: "./mycomponents/images/glowing_b.png"
+ frequency: "246.94"
+ interval: "5"
+ }
+ ListElement {
+ note: "e"
+ offSource: "./images/tuner_e.png"
+ onSource: "./images/tuner_e_on.png"
+ bigSource: "./mycomponents/images/big_e.png"
+ glowSource: "./mycomponents/images/glowing_e.png"
+ frequency: "329.63"
+ interval: "9999" //Big enough that we can't move over this note
+ }
+ ListElement {
+ note: "Auto"
+ offSource: "./images/tuner_auto.png"
+ onSource: "./images/tuner_auto_on.png"
+ frequency: "82.407"
+ }
+}
diff --git a/demos/mobile/guitartuner/src/mycomponents/ToggleButton.qml b/demos/mobile/guitartuner/src/mycomponents/ToggleButton.qml
new file mode 100644
index 00000000..de46b9f0
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/ToggleButton.qml
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+/* A toggle button component. */
+Rectangle {
+ id: toggleButton
+
+ property url offImageSource: ""
+ property url onImageSource: ""
+ property alias imageSource: buttonImage.source
+
+ signal selected()
+ signal pushed()
+
+ color: "transparent"
+ state: "unPressed"
+ onStateChanged: {
+ if (state == "pressed") {
+ selected()
+ }
+ }
+
+ Image {
+ id: buttonImage
+
+ smooth: true
+ anchors.fill: parent
+ }
+ MouseArea {
+ id: mouseArea
+
+ anchors.fill: parent
+ onPressed: {
+ if (parent.state == "unPressed") {
+ pushed()
+ }
+ }
+ }
+
+ states: [
+ State {
+ name: "pressed"
+ PropertyChanges {
+ target: toggleButton
+ scale: 0.95
+ imageSource: onImageSource
+ }
+ },
+ State {
+ name: "unPressed"
+ PropertyChanges {
+ target: toggleButton
+ scale: 1/0.95
+ imageSource: offImageSource
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "unPressed"
+ to: "pressed"
+ reversible: true
+ PropertyAnimation {
+ target: toggleButton
+ properties: "scale"
+ duration: 100
+ }
+ }
+ ]
+}
diff --git a/demos/mobile/guitartuner/src/mycomponents/adjustbars.js b/demos/mobile/guitartuner/src/mycomponents/adjustbars.js
new file mode 100644
index 00000000..ba652a6f
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/adjustbars.js
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/* JavaScript functions for creating, handling and
+ * destroying the bars of the adjuster component. */
+
+var maxBars = 10;
+var firstBarHeight = 5;
+var bars = new Array(maxBars);
+var colors = new Array(maxBars);
+var barWidthFactor = 2.3;
+
+function createBars() {
+ var barWidth = adjuster.width/maxBars/barWidthFactor;
+ for (var i = 1; i <= maxBars; i++) {
+ //Create, configure and store the bars.
+ var bar = Qt.createQmlObject('import QtQuick 1.0; Rectangle {smooth: true}', adjuster, "dynamicBar");
+ bar.width = barWidth;
+ bar.height = firstBarHeight+(i/maxBars)*(adjuster.height*0.8-firstBarHeight);
+ bar.radius = bar.width/2;
+ bar.x = (i-1)*(barWidthFactor*barWidth);
+ bar.y = adjuster.height/2 - bar.height/2;
+ bars[i-1] = bar;
+
+ //Calculate and store the colors
+ if (i < maxBars/2) {
+ colors[i-1] = Qt.rgba(1-i/(maxBars/2), 1, 1-i/(maxBars/2), i);
+ }
+ else {
+ colors[i-1] = Qt.rgba((i-(maxBars/2))/(maxBars/2), 1-((i-(maxBars/2))/(maxBars/2)), 0, i);
+ }
+ }
+}
+
+function destroyBars() {
+ for (var i = 0; i < maxBars; i++) {
+ bars[i].color = "transparent" //Colors must be set to transparent or otherwise the bars will stay appeared.
+ bars[i].destroy();
+ }
+}
+
+function fillBars(barNumber) {
+ //Set the color for the bars (transparent from the selected bar to the end).
+ for (var i = 0; i < maxBars; i++) {
+ if (i < barNumber) {
+ bars[i].color = colors[i];
+ }
+ else {
+ bars[i].color = "black";
+ }
+ }
+}
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_a.png b/demos/mobile/guitartuner/src/mycomponents/images/big_a.png
new file mode 100644
index 00000000..3838e766
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/big_a.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_b.png b/demos/mobile/guitartuner/src/mycomponents/images/big_b.png
new file mode 100644
index 00000000..114b32d3
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/big_b.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_d.png b/demos/mobile/guitartuner/src/mycomponents/images/big_d.png
new file mode 100644
index 00000000..3ede9f0f
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/big_d.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_e.png b/demos/mobile/guitartuner/src/mycomponents/images/big_e.png
new file mode 100644
index 00000000..cc1f4885
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/big_e.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_g.png b/demos/mobile/guitartuner/src/mycomponents/images/big_g.png
new file mode 100644
index 00000000..804177b3
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/big_g.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_a.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_a.png
new file mode 100644
index 00000000..b6fd0e20
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_a.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_b.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_b.png
new file mode 100644
index 00000000..b5fa016a
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_b.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_d.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_d.png
new file mode 100644
index 00000000..32f1a291
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_d.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_e.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_e.png
new file mode 100644
index 00000000..4be9f2a7
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_e.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_g.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_g.png
new file mode 100644
index 00000000..4216d828
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_g.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_malli.png b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_malli.png
new file mode 100644
index 00000000..dbe3fc79
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_malli.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_skin.png b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_skin.png
new file mode 100644
index 00000000..5d53df9b
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_skin.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/lcdFrame.png b/demos/mobile/guitartuner/src/mycomponents/images/lcdFrame.png
new file mode 100644
index 00000000..ff8dffc6
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/lcdFrame.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/meterBG.png b/demos/mobile/guitartuner/src/mycomponents/images/meterBG.png
new file mode 100644
index 00000000..4046355c
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/meterBG.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/mute.png b/demos/mobile/guitartuner/src/mycomponents/images/mute.png
new file mode 100644
index 00000000..382e6047
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/mute.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/pointer.png b/demos/mobile/guitartuner/src/mycomponents/images/pointer.png
new file mode 100644
index 00000000..d0cb21b8
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/pointer.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/pointerShadow.png b/demos/mobile/guitartuner/src/mycomponents/images/pointerShadow.png
new file mode 100644
index 00000000..a7086391
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/pointerShadow.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/power.png b/demos/mobile/guitartuner/src/mycomponents/images/power.png
new file mode 100644
index 00000000..8ec0c5ce
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/power.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/quit.png b/demos/mobile/guitartuner/src/mycomponents/images/quit.png
new file mode 100644
index 00000000..2a9443ec
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/quit.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/sensitivity.png b/demos/mobile/guitartuner/src/mycomponents/images/sensitivity.png
new file mode 100644
index 00000000..c3d2ea31
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/sensitivity.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_a.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a.png
new file mode 100644
index 00000000..a1823e59
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_a_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a_on.png
new file mode 100644
index 00000000..7c78cbd8
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a_on.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto.png
new file mode 100644
index 00000000..b9e494bd
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto_on.png
new file mode 100644
index 00000000..d5608d85
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto_on.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_b.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b.png
new file mode 100644
index 00000000..94977f87
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_b_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b_on.png
new file mode 100644
index 00000000..78841dc0
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b_on.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_d.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d.png
new file mode 100644
index 00000000..293ee55a
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_d_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d_on.png
new file mode 100644
index 00000000..705de41d
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d_on.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_e.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e.png
new file mode 100644
index 00000000..569d2c65
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_e_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e_on.png
new file mode 100644
index 00000000..1342a914
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e_on.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_g.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g.png
new file mode 100644
index 00000000..a8f0de57
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_g_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g_on.png
new file mode 100644
index 00000000..6fdca419
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g_on.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/voicemode_off.png b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_off.png
new file mode 100644
index 00000000..0701dd34
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_off.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/voicemode_on.png b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_on.png
new file mode 100644
index 00000000..986d589a
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_on.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/volume.png b/demos/mobile/guitartuner/src/mycomponents/images/volume.png
new file mode 100644
index 00000000..46fdb7fa
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/volume.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/mycomponents/images/volume_off.png b/demos/mobile/guitartuner/src/mycomponents/images/volume_off.png
new file mode 100644
index 00000000..a97e4224
--- /dev/null
+++ b/demos/mobile/guitartuner/src/mycomponents/images/volume_off.png
Binary files differ
diff --git a/demos/mobile/guitartuner/src/voiceanalyzer.cpp b/demos/mobile/guitartuner/src/voiceanalyzer.cpp
new file mode 100644
index 00000000..5c179638
--- /dev/null
+++ b/demos/mobile/guitartuner/src/voiceanalyzer.cpp
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "voiceanalyzer.h"
+
+/**
+ * Constant used to scale the cut-off density for the fft helper.
+ */
+const static float CutOffScaler = 0.05;
+
+/**
+ * Force the precision to be "1/PrecisionPerNote" notes
+ * near the target frequency.
+ */
+const static int PrecisionPerNote = 4;
+
+/**
+ * TargetFrequencyParameter is a constant which implies the index at
+ * which corresponds to the target frequency.
+ * 0.5 * N * 1/TargetFrequencyParameter is (about) the index which
+ * corresponds to the given target frequency.
+ * Effectively TargetFrequencyParameter = 2^z, and the z*TargetFrequency
+ * is the maximum frequency that can be noticed.
+ */
+const static int TargetFrequencyParameter = 4;
+
+
+VoiceAnalyzer::VoiceAnalyzer(const QAudioFormat &format, QObject *parent):
+ QIODevice(parent),
+ m_format(format),
+ m_frequency(0),
+ m_position(0),
+ m_fftHelper(new FastFourierTransformer(this))
+{
+ Q_ASSERT(qFuzzyCompare(M_SAMPLE_COUNT_MULTIPLIER,
+ float(2)/(M_TWELTH_ROOT_OF_2 -1.0)));
+ m_totalSampleCount = qRound(qreal(PrecisionPerNote)
+ *TargetFrequencyParameter
+ *M_SAMPLE_COUNT_MULTIPLIER);
+ m_samples.reserve(m_totalSampleCount);
+ int i = 2;
+ int j = 1;
+ for (; i < TargetFrequencyParameter; i *= 2) {
+ j++;
+ }
+ m_maximumVoiceDifference = j*12;
+
+ setCutOffPercentage(CutOffScaler);
+}
+
+/**
+ * Opens the parent QIODevice. Sets up the analysation parameters.
+ */
+void VoiceAnalyzer::start(qreal frequency)
+{
+ m_stepSize = (qreal) 1.0 * m_format.sampleRate()
+ / (TargetFrequencyParameter*2*frequency);
+ m_frequency = frequency;
+ open(QIODevice::WriteOnly);
+}
+
+/**
+ * Closes the parent QIODevice, thus the voice is not analysed anymore.
+ * Resets the m_samples QList.
+ */
+void VoiceAnalyzer::stop()
+{
+ m_samples.clear();
+ m_samples.reserve(m_totalSampleCount);
+ close();
+}
+
+/**
+ * Called when data is obtained. Stores each m_stepSize sample
+ * into a QList to be analysed.
+ */
+qint64 VoiceAnalyzer::writeData(const char *data, qint64 maxlen)
+{
+ const int channelBytes = m_format.sampleSize() / 8;
+ int sampleSize = m_format.channels() * channelBytes;
+ int m_stepSizeInBytes = m_stepSize*sampleSize;
+ // assert that each sample fits fully into the data
+ Q_ASSERT((m_position % sampleSize)==0);
+ const uchar *ptr = reinterpret_cast<const uchar *>(data);
+ while (m_position < maxlen) {
+ if (m_samples.size() < m_totalSampleCount) {
+ m_samples.append(getValueInt16(ptr+m_position));
+ }
+ else {
+ analyzeVoice();
+ m_samples.clear();
+ m_samples.reserve(m_totalSampleCount);
+ // fast forward position to the first position after maxlen or to the maxlen
+ m_position += ((m_stepSizeInBytes - 1 + maxlen - m_position) /
+ m_stepSizeInBytes) * m_stepSizeInBytes;
+ break;
+ }
+ m_position += m_stepSizeInBytes;
+ }
+ m_position -= maxlen;
+ return maxlen;
+}
+
+/**
+ * Interprets ptr as a pointer to int value and returns it.
+ */
+qint16 VoiceAnalyzer::getValueInt16(const uchar *ptr)
+{
+ qint16 realValue = 0;
+ if (m_format.sampleSize() == 8)
+ {
+ const qint16 value = *reinterpret_cast<const quint8*>(ptr);
+ if (m_format.sampleType() == QAudioFormat::UnSignedInt) {
+ realValue = value - M_MAX_AMPLITUDE_8BIT_SIGNED - 1;
+ } else if (m_format.sampleType() == QAudioFormat::SignedInt) {
+ realValue = value;
+ }
+ } else if (m_format.sampleSize() == 16) {
+ qint16 value = 0;
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ value = qFromLittleEndian<quint16>(ptr);
+ else
+ value = qFromBigEndian<quint16>(ptr);
+
+ if (m_format.sampleType() == QAudioFormat::UnSignedInt) {
+ realValue = value - M_MAX_AMPLITUDE_16BIT_SIGNED;
+ } else if (m_format.sampleType() == QAudioFormat::SignedInt) {
+ realValue = value;
+ }
+ }
+ return realValue;
+}
+
+/**
+ * Takes a number between 0 and 1, scales it with CutOffScaler,
+ * multiplies it with maximum density, and then gives it
+ * to the fft helper.
+ */
+void VoiceAnalyzer::setCutOffPercentage(qreal cutoff)
+{
+ cutoff = CutOffScaler*cutoff;
+ if (m_format.sampleSize() == 8) {
+ float t = cutoff*m_totalSampleCount*M_MAX_AMPLITUDE_8BIT_SIGNED;
+ m_fftHelper->setCutOffForDensity(t);
+ }
+ else if (m_format.sampleSize() == 16) {
+ float t = cutoff*m_totalSampleCount*M_MAX_AMPLITUDE_16BIT_SIGNED;
+ m_fftHelper->setCutOffForDensity(t);
+ }
+}
+
+/**
+ * Returns the current target frequency.
+ */
+qreal VoiceAnalyzer::frequency()
+{
+ return m_frequency;
+}
+
+/**
+ * Returns the maximum absolute value sent by
+ * the voiceDifference() signal.
+ */
+int VoiceAnalyzer::getMaximumVoiceDifference()
+{
+ return m_maximumVoiceDifference;
+}
+
+/**
+ * Returns the maximum precision per note
+ * near the target frequency.
+ */
+int VoiceAnalyzer::getMaximumPrecisionPerNote()
+{
+ return PrecisionPerNote;
+}
+
+/**
+ * Analyzes the voice frequency and emits appropriate signals.
+ */
+void VoiceAnalyzer::analyzeVoice()
+{
+ m_fftHelper->calculateFFT(m_samples);
+ int index = m_fftHelper->getMaximumDensityIndex();
+
+ // If index == -1
+ if (index == -1) {
+ // The voice is to be filtered away.
+ // Emit the lowVoice signal and return.
+ emit lowVoice();
+ qDebug() << "low voice";
+ return;
+ }
+ // Else, continue
+
+ // Let the correctIndex to be
+ // the nearest index corresponding to the correct frequency.
+ qreal stepSizeInFrequency = (qreal)m_format.sampleRate()
+ / (m_totalSampleCount * m_stepSize);
+ qreal newFrequency = qreal(index) * stepSizeInFrequency;
+ // Calculate the nearest index corresponding to the correct frequency.
+ int correctIndex = qRound(m_frequency / stepSizeInFrequency);
+ qreal value = 0;
+
+ // If the obtained frequency is more than
+ // log_2(TargetFrequencyParameter) octaves less than the m_frequency:
+
+ // Note:
+ // Instead of m_frequency/TargetFrequencyParameter > newFrequency,
+ // the comparison is done without a div instructions by
+ // m_frequency > newFrequency * TargetFrequencyParameter.
+
+ if (m_frequency > newFrequency * TargetFrequencyParameter) {
+ // Set the difference value to be -m_maximumVoiceDifference.
+ qDebug() << "compare" << "low" << newFrequency << m_frequency - stepSizeInFrequency * correctIndex << (m_frequency - stepSizeInFrequency * correctIndex) / stepSizeInFrequency;
+ value = -m_maximumVoiceDifference;
+ }
+ // Else, if the obtained frequency is more than
+ // log_2(TargetFrequencyParameter) octaves more than the m_frequency:
+ else if (m_frequency*TargetFrequencyParameter < newFrequency) {
+ // Set the difference value to be m_maximumVoiceDifference.
+ qDebug() << "compare" << "high" << newFrequency << m_frequency - stepSizeInFrequency * correctIndex << (m_frequency - stepSizeInFrequency * correctIndex) / stepSizeInFrequency;
+ value = m_maximumVoiceDifference;
+ }
+ // Else:
+ else {
+ // Calculate the difference between the obtained and the correct
+ // frequency in tones.
+ // Use stepSizeInFrequency * correctIndex instead of
+ // m_frequency so that the value is zero when there is correct
+ // voice obtained. Set the difference value to be
+ // log(frequency / target frequency) * 12 / log(2).
+ value = log(newFrequency / (stepSizeInFrequency * correctIndex))
+ * 12 / M_LN2;
+ qDebug() << "compare" << value << newFrequency << m_frequency - stepSizeInFrequency * correctIndex << (m_frequency - stepSizeInFrequency * correctIndex) / stepSizeInFrequency;
+ }
+
+ // Emit voiceDifference signal.
+ QVariant valueVar(value); //Has to be QVariant for QML
+ emit voiceDifference(valueVar);
+
+ // If the correctIndex is index, emit the correctFrequency signal.
+ if (correctIndex == index) {
+ emit(correctFrequency());
+ }
+}
+
+/**
+ * Empty implementation for readData, since no data is provided
+ * by the VoiceAnalyzer class.
+ */
+qint64 VoiceAnalyzer::readData(char *data, qint64 maxlen)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxlen);
+
+ return 0;
+}
diff --git a/demos/mobile/guitartuner/src/voiceanalyzer.h b/demos/mobile/guitartuner/src/voiceanalyzer.h
new file mode 100644
index 00000000..8957c2e9
--- /dev/null
+++ b/demos/mobile/guitartuner/src/voiceanalyzer.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VOICEANALYZER_H
+#define VOICEANALYZER_H
+
+#include <QObject>
+#include <QAudioFormat>
+#include <QDebug>
+#include <QtCore/qmath.h>
+#include <QtCore/qendian.h>
+#include <QVariant>
+
+#include "constants.h"
+#include "fastfouriertransformer.h"
+#include "math.h"
+
+class VoiceAnalyzer : public QIODevice
+{
+ Q_OBJECT
+public:
+ VoiceAnalyzer(const QAudioFormat &format, QObject *parent = 0);
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 maxlen);
+ void start(qreal frequency);
+ void stop();
+ qreal frequency();
+ int getMaximumVoiceDifference();
+ int getMaximumPrecisionPerNote();
+
+public slots:
+ void setCutOffPercentage(qreal cutoff);
+
+private:
+ const QAudioFormat m_format;
+ QList<qint16> m_samples;
+ int m_totalSampleCount;
+ int m_maximumVoiceDifference;
+
+ qint16 getValueInt16(const uchar *ptr);
+ int m_stepSize;
+ qreal m_frequency;
+ qint64 m_position;
+ FastFourierTransformer *m_fftHelper;
+ void analyzeVoice();
+signals:
+ void voiceDifference(QVariant frequency);
+ void correctFrequency();
+ void lowVoice();
+
+public slots:
+
+};
+
+
+#endif // VOICEANALYZER_H
diff --git a/demos/mobile/guitartuner/src/voicegenerator.cpp b/demos/mobile/guitartuner/src/voicegenerator.cpp
new file mode 100644
index 00000000..046f75ef
--- /dev/null
+++ b/demos/mobile/guitartuner/src/voicegenerator.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "voicegenerator.h"
+
+const int BufferSizeMilliseconds = 100;
+
+VoiceGenerator::VoiceGenerator(const QAudioFormat &format,
+ qreal frequency, qreal amplitude,
+ QObject *parent) :
+ QIODevice(parent),
+ m_format(format),
+ m_amplitude(0.5)
+{
+ Q_ASSERT(m_format.sampleSize() % 8 == 0);
+ int sampleBytes = m_format.channels() * (m_format.sampleSize() / 8);
+ // + 1 to round up, just to be sure that all samples fit.
+ qint64 samplesInBuffer = m_format.sampleRate()
+ * BufferSizeMilliseconds / 1000 + 1;
+ qint64 length = samplesInBuffer * sampleBytes;
+ m_buffer.resize(length);
+ m_max_position = 0;
+ m_position = 0;
+ m_amplitude = amplitude;
+ setFrequency(frequency);
+}
+
+VoiceGenerator::~VoiceGenerator()
+{
+}
+
+/**
+ * Opens the parent QIODevice.
+ */
+void VoiceGenerator::start()
+{
+ open(QIODevice::ReadOnly);
+}
+
+/**
+ * Closes the parent QIODevice. Resets the m_position to zero.
+ */
+void VoiceGenerator::stop()
+{
+ close();
+ m_position = 0;
+}
+
+/**
+ * Sets the frequency to new frequency.
+ */
+void VoiceGenerator::setFrequency(qreal frequency)
+{
+ Q_ASSERT(1 / frequency < BufferSizeMilliseconds);
+ this->m_frequency = frequency;
+ refreshData();
+}
+
+/**
+ * Sets the amplitude for the voice.
+ */
+void VoiceGenerator::setAmplitude(qreal amplitude)
+{
+ Q_ASSERT(amplitude >= 0);
+ m_amplitude = amplitude;
+ refreshData();
+}
+
+/**
+ * Returns the current frequency.
+ */
+qreal VoiceGenerator::frequency()
+{
+ return m_frequency;
+}
+
+/**
+ * Generates voice data corresponding a sine voice with target frequency.
+ * The number of data generated is calculated
+ * and stored to m_max_position.
+ */
+void VoiceGenerator::refreshData()
+{
+ const int channelBytes = m_format.sampleSize() / 8;
+ const int sampleSize = m_format.channels() * channelBytes;
+ const qint64 voiceOscillationsInBuffer = BufferSizeMilliseconds
+ * m_frequency / 1000;
+ const qint64 voiceSamplesInBuffer = voiceOscillationsInBuffer
+ * m_format.sampleRate() / m_frequency;
+ m_max_position = voiceSamplesInBuffer * sampleSize;
+ qint64 dataGenerationLength = m_buffer.size();
+
+
+ Q_ASSERT(m_max_position % (sampleSize) == 0);
+ Q_ASSERT(dataGenerationLength <= m_buffer.size());
+
+ short *t = (short*)m_buffer.data();
+
+
+/*
+ int te ;
+ static float fpos = 0.0f;
+ //dataGenerationLength>>=1; // in words
+ for (int f=0; f<dataGenerationLength; f++) {
+ te = (short)((sinf(fpos))* (65536.0f/2.0f));
+ fpos += m_frequency/2000.0f;
+ t[f]= te;
+ };
+
+ m_amplitude = 1.0f; */
+ uchar *ptr = reinterpret_cast<uchar *>(m_buffer.data());
+ int sampleIndex = 0;
+ while (dataGenerationLength > 0) {
+ qreal realValue = 0;
+ if (sampleIndex < voiceSamplesInBuffer) {
+ realValue = m_amplitude
+ *qSin(2.0f * M_PI * m_frequency
+ * qreal(sampleIndex % m_format.sampleRate())
+ / m_format.sampleRate());
+ }
+ for (int i=0; i<m_format.channels(); ++i) {
+ setValue(ptr, realValue);
+ ptr += channelBytes;
+ dataGenerationLength -= channelBytes;
+ }
+ ++sampleIndex;
+ }
+}
+
+/**
+ * Stores the realValue into bytes pointed by ptr as an int value.
+ * Align-safe.
+ */
+void VoiceGenerator::setValue(uchar *ptr, qreal realValue) {
+ if (m_format.sampleSize() == 8)
+ {
+ quint8 value = 0;
+ if (m_format.sampleType() == QAudioFormat::UnSignedInt) {
+ value = static_cast<quint8>(
+ qRound((1.0 + realValue) / 2
+ * M_MAX_AMPLITUDE_8BIT_UNSIGNED));
+ } else if (m_format.sampleType() == QAudioFormat::SignedInt) {
+ value = static_cast<qint8>(
+ qRound(realValue
+ * M_MAX_AMPLITUDE_8BIT_SIGNED));
+ }
+ *reinterpret_cast<quint8*>(ptr) = value;
+ } else if (m_format.sampleSize() == 16) {
+ quint16 value = 0;
+ if (m_format.sampleType() == QAudioFormat::UnSignedInt) {
+ value = static_cast<quint16>(
+ qRound((1.0 + realValue) / 2
+ * M_MAX_AMPLITUDE_16BIT_UNSIGNED));
+ } else if (m_format.sampleType() == QAudioFormat::SignedInt) {
+ value = static_cast<qint16>(
+ qRound(realValue
+ * M_MAX_AMPLITUDE_16BIT_SIGNED));
+ }
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ qToLittleEndian<qint16>(value, ptr);
+ else
+ qToBigEndian<qint16>(value, ptr);
+ }
+}
+
+qint64 VoiceGenerator::bytesAvailable() const
+{
+ return m_max_position + QIODevice::bytesAvailable();
+}
+
+/**
+ * Called by the QIODevice. Puts maxlen amount of voice
+ * samples into the data array.
+ */
+qint64 VoiceGenerator::readData(char *data, qint64 maxlen)
+{
+ qint64 total = 0;
+ qint64 chunk = 0;
+ while (total < maxlen) {
+ if (maxlen - total >= m_max_position - m_position) {
+ // the needed buffer is longer than the currently
+ // available buffer from m_position to the m_max_position
+ chunk = m_max_position - m_position;
+ memcpy(data, m_buffer.constData() + m_position, chunk);
+ m_position = 0;
+ }
+ else {
+ // we can copy the needed data directly, and the loop will end
+ chunk = maxlen - total;
+ memcpy(data, m_buffer.constData() + m_position, chunk);
+ m_position = (m_position + chunk) % m_max_position;
+ }
+ data += chunk;
+ total += chunk;
+ }
+ return total;
+}
+
+/**
+ * Empty implementation for writeData, since no data is provided
+ * for the VoiceGenerator class.
+ */
+qint64 VoiceGenerator::writeData(const char *data, qint64 maxlen)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(maxlen);
+
+ return 0;
+}
diff --git a/demos/mobile/guitartuner/src/voicegenerator.h b/demos/mobile/guitartuner/src/voicegenerator.h
new file mode 100644
index 00000000..ed2292b7
--- /dev/null
+++ b/demos/mobile/guitartuner/src/voicegenerator.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VOICEGENERATOR_H
+#define VOICEGENERATOR_H
+
+#include <QIODevice>
+#include <QByteArray>
+#include <QAudioFormat>
+#include <QtCore/qmath.h>
+#include <QtCore/qendian.h>
+#include <QDebug>
+
+#include "constants.h"
+
+
+class VoiceGenerator : public QIODevice
+{
+ Q_OBJECT
+public:
+ VoiceGenerator(const QAudioFormat &format, qreal frequency, qreal amplitude, QObject *parent = 0);
+ ~VoiceGenerator();
+ void setFrequency(qreal frequency);
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 maxlen);
+ qint64 bytesAvailable() const;
+ qreal frequency();
+signals:
+
+public slots:
+ void setAmplitude(qreal amplitude);
+ void start();
+ void stop();
+
+private:
+ void setValue(uchar *ptr, qreal realValue);
+ void refreshData();
+ const QAudioFormat m_format;
+ // buffer to store the data
+ QByteArray m_buffer;
+ // current position in buffer
+ qint64 m_position;
+ // max position depends on the sample rate of format and the frequency of voice
+ qint64 m_max_position;
+ qreal m_amplitude;
+ qreal m_frequency;
+};
+
+#endif // VOICEGENERATOR_H