diff options
author | Justin McPherson <justin.mcpherson@nokia.com> | 2010-03-29 12:06:17 +1000 |
---|---|---|
committer | Justin McPherson <justin.mcpherson@nokia.com> | 2010-03-29 12:06:17 +1000 |
commit | 89b549d8580551dab3c2ec4389e3035d79849450 (patch) | |
tree | e6e34129596c4e35466210b88f7c0eb3cfcad14e /plugins/multimedia/symbian/mmf/audiosource/s60audiocapturesession.cpp | |
parent | e66c077991a63fa862e8ae28477d8f73add246b8 (diff) |
Merge lastest from master.
Diffstat (limited to 'plugins/multimedia/symbian/mmf/audiosource/s60audiocapturesession.cpp')
-rw-r--r-- | plugins/multimedia/symbian/mmf/audiosource/s60audiocapturesession.cpp | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/plugins/multimedia/symbian/mmf/audiosource/s60audiocapturesession.cpp b/plugins/multimedia/symbian/mmf/audiosource/s60audiocapturesession.cpp new file mode 100644 index 0000000000..089f2bdabf --- /dev/null +++ b/plugins/multimedia/symbian/mmf/audiosource/s60audiocapturesession.cpp @@ -0,0 +1,494 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "s60audiocapturesession.h" +#include <QtCore/qdebug.h> +#include <QtCore/qurl.h> +#include <QDir> + +#include <Mda\Common\Audio.h> +#include <Mda\Common\Resource.h> +#include <Mda\Client\Utility.h> +#include <MdaAudioSampleEditor.h> +#include <mmf\common\mmfcontrollerpluginresolver.h> +#include <mmf\common\mmfcontroller.h> +#include <BADESCA.H> +#include <BAUTILS.H> +#include <coemain.h> + +_LIT(KAudioDummyFile, "c:\\data\\temp\\temp.wav"); + +S60AudioCaptureSession::S60AudioCaptureSession(QObject *parent): + QObject(parent) + , m_recorderUtility(NULL) + , m_captureState(ENotInitialized) + , m_controllerIdMap(QHash<QString, ControllerData>()) + , m_audioCodeclist(QHash<QString, CodecData>()) +{ + TRAPD(err, initializeSessionL()); + qWarning()<<err; +} + +void S60AudioCaptureSession::initializeSessionL() +{ + m_recorderUtility = CMdaAudioRecorderUtility::NewL(*this, 0, 80,(TMdaPriorityPreference) 0x5210001); + updateAudioContainersL(); + populateAudioCodecsDataL(); + setDefaultSettings(); +} + +S60AudioCaptureSession::~S60AudioCaptureSession() +{ + delete m_recorderUtility; +} + +QAudioFormat S60AudioCaptureSession::format() const +{ + return m_format; +} + +bool S60AudioCaptureSession::setFormat(const QAudioFormat &format) +{ + m_format = format; + return true; +} + +QStringList S60AudioCaptureSession::supportedAudioCodecs() const +{ + return m_audioCodeclist.keys(); +} + +QStringList S60AudioCaptureSession::supportedAudioContainers() const +{ + return m_controllerIdMap.keys(); +} + +QString S60AudioCaptureSession::codecDescription(const QString &codecName) +{ + if (m_audioCodeclist.keys().contains(codecName)) + return m_audioCodeclist[codecName].codecDescription; + else + return QString(); +} + +QString S60AudioCaptureSession::audioContainerDescription(const QString &containerName) +{ + if (m_controllerIdMap.keys().contains(containerName)) + return m_controllerIdMap[containerName].destinationFormatDescription; + else + return QString(); +} + +bool S60AudioCaptureSession::setAudioCodec(const QString &codecName) +{ + QStringList codecs = supportedAudioCodecs(); + if(codecs.contains(codecName)) { + m_format.setCodec(codecName); + return true; + } + return false; +} + +bool S60AudioCaptureSession::setAudioContainer(const QString &containerMimeType) +{ + QStringList containers = supportedAudioContainers(); + if(containers.contains(containerMimeType)) { + m_container = containerMimeType; + return true; + } + return false; +} + +QString S60AudioCaptureSession::audioCodec() const +{ + return m_format.codec(); +} + +QString S60AudioCaptureSession::audioContainer() const +{ + return m_container; +} + +QUrl S60AudioCaptureSession::outputLocation() const +{ + return m_sink; +} + +bool S60AudioCaptureSession::setOutputLocation(const QUrl& sink) +{ + QString filename = QDir::toNativeSeparators(m_sink.toString()); + TPtrC16 path(reinterpret_cast<const TUint16*>(filename.utf16())); + TRAPD(err, BaflUtils::EnsurePathExistsL(CCoeEnv::Static()->FsSession(),path)); + if (err==KErrNone) { + m_sink = sink; + return true; + }else + return false; +} + +qint64 S60AudioCaptureSession::position() const +{ + if ((m_captureState != ERecording) || !m_recorderUtility) + return 0; + + return m_recorderUtility->Duration().Int64() / 1000; +} + +void S60AudioCaptureSession::record() +{ + if (!m_recorderUtility) + return; + + if (m_captureState == EInitialized || m_captureState == ERecordComplete) { + QString filename = QDir::toNativeSeparators(m_sink.toString()); + TPtrC16 sink(reinterpret_cast<const TUint16*>(filename.utf16())); + TUid controllerUid(TUid::Uid(m_controllerIdMap[m_container].controllerUid)); + TUid formatUid(TUid::Uid(m_controllerIdMap[m_container].destinationFormatUid)); + + TRAPD(err, + if (m_container != "audio/amr") + m_recorderUtility->OpenFileL(sink, controllerUid, KNullUid, formatUid); + else + m_recorderUtility->OpenFileL(sink); + ); + qWarning() << err; + }else if (m_captureState == EPaused) { + m_recorderUtility->SetPosition(m_pausedPosition); + TRAPD(error, m_recorderUtility->RecordL()); + qWarning() << error; + m_captureState = ERecording; + emit stateChanged(m_captureState); + } +} + +void S60AudioCaptureSession::setDefaultSettings() +{ + // Setting AMR to default format if supported + if (m_controllerIdMap.count() > 0) { + if ( m_controllerIdMap.contains("audio/amr")) + m_container = QString("audio/amr"); + else + m_container = m_controllerIdMap.keys()[0]; + } + if (m_audioCodeclist.keys().count() > 0) { + if (m_audioCodeclist.keys().contains("AMR")) + m_format.setCodec("AMR"); + else + m_format.setCodec(m_audioCodeclist.keys()[0]); + } +} + +void S60AudioCaptureSession::pause() +{ + if (!m_recorderUtility) + return; + + m_pausedPosition = m_recorderUtility->Position(); + m_recorderUtility->Stop(); + m_captureState = EPaused; + emit stateChanged(m_captureState); +} + +void S60AudioCaptureSession::stop() +{ + if (!m_recorderUtility) + return; + + m_recorderUtility->Stop(); + m_recorderUtility->Close(); + m_captureState = ERecordComplete; + emit stateChanged(m_captureState); +} + +void S60AudioCaptureSession::setCaptureDevice(const QString &deviceName) +{ + m_captureDevice = deviceName; +} + +void S60AudioCaptureSession::MoscoStateChangeEvent(CBase* aObject, + TInt aPreviousState, TInt aCurrentState, TInt aErrorCode) +{ + TRAPD(err, MoscoStateChangeEventL(aObject, aPreviousState, aCurrentState, NULL)); + qWarning() << err; +} + +void S60AudioCaptureSession::MoscoStateChangeEventL(CBase* aObject, + TInt aPreviousState, TInt aCurrentState, TInt aErrorCode) +{ + if (aObject != m_recorderUtility) + return; + + switch(aCurrentState) { + case CMdaAudioClipUtility::EOpen: { + if(aPreviousState == CMdaAudioClipUtility::ENotReady) { + if (m_captureState == EInitializing) { + retrieveSupportedAudioSampleRatesL(); + m_recorderUtility->Close(); + m_captureState = EInitialized; + emit stateChanged(m_captureState); + }else { + applyAudioSettingsL(); + m_recorderUtility->SetAudioDeviceMode(CMdaAudioRecorderUtility::ELocal); + m_recorderUtility->SetGain(m_recorderUtility->MaxGain()); + m_recorderUtility->SetPosition(TTimeIntervalMicroSeconds(0)); + m_recorderUtility->CropL(); + m_recorderUtility->RecordL(); + m_captureState = EOpenCompelete; + emit stateChanged(m_captureState); + } + break; + } + } + case CMdaAudioClipUtility::ENotReady: { + m_captureState = EInitialized; + emit stateChanged(m_captureState); + break; + } + case CMdaAudioClipUtility::ERecording: { + m_captureState = ERecording; + emit stateChanged(m_captureState); + break; + } + default: { + break; + } + } +} + +void S60AudioCaptureSession::updateAudioContainersL() +{ + CMMFControllerPluginSelectionParameters* pluginParameters = + CMMFControllerPluginSelectionParameters::NewLC(); + CMMFFormatSelectionParameters* formatParameters = + CMMFFormatSelectionParameters::NewLC(); + + pluginParameters->SetRequiredRecordFormatSupportL(*formatParameters); + + RArray<TUid> ids; + CleanupClosePushL(ids); + User::LeaveIfError(ids.Append(KUidMediaTypeAudio)); + + pluginParameters->SetMediaIdsL(ids, + CMMFPluginSelectionParameters::EAllowOnlySuppliedMediaIds); + + RMMFControllerImplInfoArray controllers; + CleanupResetAndDestroyPushL(controllers); + + //Get all audio record controllers/formats that are supported + pluginParameters->ListImplementationsL(controllers); + + for (TInt index=0; index<controllers.Count(); index++) { + const RMMFFormatImplInfoArray& recordFormats = + controllers[index]->RecordFormats(); + for (TInt j=0; j<recordFormats.Count(); j++) { + const CDesC8Array& mimeTypes = recordFormats[j]->SupportedMimeTypes(); + TInt count = mimeTypes.Count(); + if (count > 0) { + TPtrC8 mimeType = mimeTypes[0]; + QString type = QString::fromUtf8((char *)mimeType.Ptr(), mimeType.Length()); + if (type != "audio/mp4") { + ControllerData data; + data.controllerUid = controllers[index]->Uid().iUid; + data.destinationFormatUid = recordFormats[j]->Uid().iUid; + data.destinationFormatDescription = QString::fromUtf16( + recordFormats[j]->DisplayName().Ptr(), + recordFormats[j]->DisplayName().Length()); + m_controllerIdMap[type] = data; + } + } + } + } + CleanupStack::PopAndDestroy(4);//controllers, ids, formatParameters, pluginParameters +} + +void S60AudioCaptureSession::retrieveSupportedAudioSampleRatesL() +{ + if (!m_recorderUtility || m_captureState != EInitializing) + return; + + RArray<TUint> supportedSampleRates; + CleanupClosePushL(supportedSampleRates); + m_recorderUtility->GetSupportedSampleRatesL(supportedSampleRates); + for (TInt j = 0; j < supportedSampleRates.Count(); j++ ) { + m_supportedSampleRates.append(supportedSampleRates[j]); + //qDebug()<<"S60AudioCaptureSession::doPopulateAudioCodecsDataL, samplerate: "<<m_supportedSampleRates[j]; + } + CleanupStack::PopAndDestroy(&supportedSampleRates); +} + +QList<int> S60AudioCaptureSession::supportedAudioSampleRates() const +{ + return m_supportedSampleRates; +} + +void S60AudioCaptureSession::populateAudioCodecsDataL() +{ + //qDebug() << "S60AudioCaptureSession::doInitializeAudioRecorderL START"; + if (!m_recorderUtility) + return; + + if (m_controllerIdMap.contains("audio/amr")) { + CodecData data; + data.codecDescription = QString("GSM AMR Codec"); + m_audioCodeclist[QString("AMR")]=data; + } + if (m_controllerIdMap.contains("audio/basic")) { + CodecData data; + data.fourCC = KMMFFourCCCodeALAW; + data.codecDescription = QString("Sun/Next ""Au"" audio codec"); + m_audioCodeclist[QString("AULAW")]=data; + } + if (m_controllerIdMap.contains("audio/wav")) { + CodecData data; + data.fourCC = KMMFFourCCCodePCM16; + data.codecDescription = QString("Pulse code modulation"); + m_audioCodeclist[QString("PCM")]=data; + } + if (m_controllerIdMap.contains("audio/mp4")) { + CodecData data; + data.fourCC = KMMFFourCCCodeAAC; + data.codecDescription = QString("Advanced Audio Codec"); + m_audioCodeclist[QString("AAC")]=data; + } + + if (m_controllerIdMap.contains("audio/wav")) { + TMdaFileClipLocation location; + location.iName = KAudioDummyFile(); + TMdaWavClipFormat format; + m_captureState = EInitializing; + m_recorderUtility->OpenL(&location, &format); + } +} + +void S60AudioCaptureSession::applyAudioSettingsL() +{ + //qDebug() << "S60AudioCaptureSession::applyAudioSettings START"; + if (!m_recorderUtility) + return; + + TFourCC fourCC = m_audioCodeclist[m_format.codec()].fourCC; + + //set destination datatype + RArray<TFourCC> supportedDataTypes; + CleanupClosePushL(supportedDataTypes); + m_recorderUtility->GetSupportedDestinationDataTypesL(supportedDataTypes); + //qDebug() << "S60AudioCaptureSession::applyAudioSettingsL, datatype count"<<supportedDataTypes.Count(); + + for (TInt k = 0; k < supportedDataTypes.Count(); k++ ) { + qDebug() << "S60AudioCaptureSession::applyAudioSettingsL, codec"<<m_format.codec()<<"datatype"<<supportedDataTypes[k].FourCC(); + if (supportedDataTypes[k].FourCC() == fourCC.FourCC()) { + //qDebug() << "S60AudioCaptureSession::applyAudioSettingsL, codec"<<m_format.codec()<<"matched datatype"<<supportedDataTypes[k].FourCC(); + m_recorderUtility->SetDestinationDataTypeL(supportedDataTypes[k]); + break; + } + } + CleanupStack::PopAndDestroy(&supportedDataTypes); + + RArray<TUint> supportedSampleRates; + CleanupClosePushL(supportedSampleRates); + m_recorderUtility->GetSupportedSampleRatesL(supportedSampleRates); + for (TInt i = 0; i < supportedSampleRates.Count(); i++ ) { + TUint supportedSampleRate = supportedSampleRates[i]; + if (supportedSampleRate == m_format.frequency()) { + m_recorderUtility->SetDestinationSampleRateL(m_format.frequency()); + break; + } + } + CleanupStack::PopAndDestroy(&supportedSampleRates); + + RArray<TUint> supportedChannels; + CleanupClosePushL(supportedChannels); + m_recorderUtility->GetSupportedNumberOfChannelsL(supportedChannels); + for (TInt l = 0; l < supportedChannels.Count(); l++ ) { + if (supportedChannels[l] == m_format.channels()) { + m_recorderUtility->SetDestinationNumberOfChannelsL(m_format.channels()); + break; + } + } + CleanupStack::PopAndDestroy(&supportedChannels); + //qDebug() << "S60AudioCaptureSession::applyAudioSettings END"; +} + +TFourCC S60AudioCaptureSession::determinePCMFormat() +{ + //qDebug() << "S60AudioCaptureSession::determinePCMSampleSize START"; + TFourCC fourCC; + + if (m_format.sampleSize() == 8) { + // 8 bit + switch (m_format.sampleType()) { + case QAudioFormat::SignedInt: { + fourCC.Set(KMMFFourCCCodePCM8); + break; + } + case QAudioFormat::UnSignedInt: { + fourCC.Set(KMMFFourCCCodePCMU8); + break; + } + case QAudioFormat::Float: + case QAudioFormat::Unknown: + default: { + fourCC.Set(KMMFFourCCCodePCM8); + break; + } + } + } else if (m_format.sampleSize() == 16) { + // 16 bit + switch (m_format.sampleType()) { + case QAudioFormat::SignedInt: { + fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian? + KMMFFourCCCodePCM16B:KMMFFourCCCodePCM16); + break; + } + case QAudioFormat::UnSignedInt: { + fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian? + KMMFFourCCCodePCMU16B:KMMFFourCCCodePCMU16); + break; + } + default: { + fourCC.Set(KMMFFourCCCodePCM16); + break; + } + } + } + //qDebug() << "S60AudioCaptureSession::determinePCMSampleSize END"; + return fourCC; +} |