#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)
{
m_guitarTunerUI = new QDeclarativeView(QUrl("qrc:/src/application.qml"), this);
setCentralWidget(m_guitarTunerUI);
m_guitarTunerUI->setResizeMode(QDeclarativeView::SizeRootObjectToView);
qmlObject = m_guitarTunerUI->rootObject();
initAudioOutput();
initAudioInput();
connect(m_guitarTunerUI->engine(), SIGNAL(quit()), SLOT(close()));
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(qmlObject, SIGNAL(modeChanged(bool)),
SLOT(modeChanged(bool)));
connect(qmlObject, SIGNAL(microphoneSensitivityChanged(qreal)),
m_analyzer, SLOT(setCutOffPercentage(qreal)));
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)));
qmlObject->setProperty("maxVoiceDifference",
m_analyzer->getMaximumVoiceDifference());
connect(qmlObject, SIGNAL(targetFrequencyChanged(qreal)),
SLOT(targetFrequencyChanged(qreal)));
modeChanged(qmlObject->property("isInput").toBool());
}
void GuitarTuner::initAudioOutput()
{
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);
QAudioDeviceInfo outputDeviceInfo(
QAudioDeviceInfo::defaultOutputDevice());
if (!outputDeviceInfo.isFormatSupported(m_format_output)) {
m_format_output = outputDeviceInfo.nearestFormat(m_format_output);
}
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, SIGNAL(stateChanged(QAudio::State)),
SLOT(outputStateChanged(QAudio::State)));
}
void GuitarTuner::initAudioInput()
{
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);
QAudioDeviceInfo inputDeviceInfo(
QAudioDeviceInfo::defaultInputDevice());
if (!inputDeviceInfo.isFormatSupported(m_format_input)) {
m_format_input = inputDeviceInfo.nearestFormat(m_format_input);
}
m_audioInput = new QAudioInput(inputDeviceInfo, m_format_input, this);
m_analyzer = new VoiceAnalyzer(m_format_input, this);
m_analyzer->setCutOffPercentage(qmlObject->property("sensitivity").toReal());
}
void GuitarTuner::modeChanged(bool isInput)
{
if (isInput) {
m_audioOutput->stop();
m_voicegenerator->stop();
m_analyzer->start(qmlObject->property("frequency").toReal());
m_audioInput->start(m_analyzer);
}
else {
m_audioInput->stop();
m_analyzer->stop();
if (m_voicegenerator->frequency() != qmlObject->property("frequency").toReal()) {
m_voicegenerator->setFrequency(qmlObject->property("frequency").toReal());
}
m_voicegenerator->start();
m_audioOutput->start(m_voicegenerator);
setMaxVolumeLevel(qmlObject->property("volume").toReal());
}
}
void GuitarTuner::outputStateChanged(QAudio::State state)
{
if (QAudio::ActiveState == state && qmlObject->property("isMuted").toBool()) {
m_audioOutput->suspend();
}
}
void GuitarTuner::muteStateChanged(bool isMuted)
{
if (isMuted) {
m_audioOutput->suspend();
}
else {
m_audioOutput->resume();
}
}
void GuitarTuner::targetFrequencyChanged(qreal targetFrequency)
{
if (!qmlObject->property("isInput").toBool()) {
m_audioOutput->stop();
m_voicegenerator->stop();
m_voicegenerator->setFrequency(targetFrequency);
m_voicegenerator->start();
m_audioOutput->start(m_voicegenerator);
setMaxVolumeLevel(qmlObject->property("volume").toReal());
}
else {
m_audioInput->stop();
m_analyzer->stop();
m_analyzer->start(targetFrequency);
m_audioInput->start(m_analyzer);
}
}
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;
#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
}
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
}