qtmobility/plugins/multimedia/symbian/audiosource/s60audiocapturesession.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtCore/qdebug.h>
       
    43 #include <QtCore/qurl.h>
       
    44 
       
    45 #include <QMediaRecorder>
       
    46 
       
    47 #include "s60audiocapturesession.h"
       
    48 
       
    49 #include <Mda\Common\Audio.h>
       
    50 #include <Mda\Common\Resource.h>
       
    51 #include <Mda\Client\Utility.h>
       
    52 #include <MdaAudioSampleEditor.h>
       
    53 
       
    54 #include <QDir>
       
    55 
       
    56 #include <mmf\common\mmfcontrollerpluginresolver.h>
       
    57 #include <mmf\common\mmfcontroller.h>
       
    58 
       
    59 #include <private/qcore_symbian_p.h>
       
    60 
       
    61 #include <BADESCA.H>
       
    62 
       
    63 S60AudioCaptureSession::S60AudioCaptureSession(QObject *parent):
       
    64     QObject(parent), m_recorderUtility(NULL)
       
    65 {
       
    66     TRAPD(err, m_recorderUtility = CMdaAudioRecorderUtility::NewL(*this));
       
    67     qWarning() << err;
       
    68     
       
    69     TRAP(err, fetchAudioCodecsL());
       
    70     qWarning() << err;
       
    71     
       
    72 }
       
    73 
       
    74 S60AudioCaptureSession::~S60AudioCaptureSession()
       
    75 {
       
    76     stop();
       
    77     
       
    78     if(m_recorderUtility)
       
    79         delete m_recorderUtility;
       
    80 }
       
    81 
       
    82 QAudioFormat S60AudioCaptureSession::format() const
       
    83 {
       
    84     return m_format;
       
    85 }
       
    86 
       
    87 bool S60AudioCaptureSession::isFormatSupported(const QAudioFormat &format) const
       
    88 {
       
    89 
       
    90     return false;
       
    91 }
       
    92 
       
    93 bool S60AudioCaptureSession::setFormat(const QAudioFormat &format)
       
    94 {
       
    95 	if (m_recorderUtility) {
       
    96 		m_format = format;
       
    97 	}
       
    98 
       
    99     return false;
       
   100 }
       
   101 
       
   102 QStringList S60AudioCaptureSession::supportedAudioCodecs() const
       
   103 {
       
   104 	return m_controllerIdMap.keys();
       
   105 }
       
   106 
       
   107 
       
   108 QString S60AudioCaptureSession::codecDescription(const QString &codecName)
       
   109 {
       
   110     return m_controllerIdMap[codecName].destinationFormatDescription;
       
   111 }
       
   112 
       
   113 
       
   114 bool S60AudioCaptureSession::setAudioCodec(const QString &codecName)
       
   115 {
       
   116 
       
   117     if(m_recorderUtility) {
       
   118         QStringList codecs = supportedAudioCodecs();
       
   119         if(codecs.contains(codecName)) {
       
   120             m_format.setCodec(codecName);
       
   121             return true;
       
   122         }
       
   123     }
       
   124 
       
   125     return false;
       
   126 }
       
   127 
       
   128 QString S60AudioCaptureSession::audioCodec() const
       
   129 {
       
   130     return m_format.codec();
       
   131 }
       
   132 
       
   133 QUrl S60AudioCaptureSession::outputLocation() const
       
   134 {
       
   135     return m_sink;
       
   136 }
       
   137 
       
   138 bool S60AudioCaptureSession::setOutputLocation(const QUrl& sink)
       
   139 {
       
   140     m_sink = sink;
       
   141     return true;
       
   142 }
       
   143 
       
   144 qint64 S60AudioCaptureSession::position() const
       
   145 {
       
   146     return m_position;
       
   147 }
       
   148 
       
   149 int S60AudioCaptureSession::state() const
       
   150 {
       
   151     return int(m_state);
       
   152 }
       
   153 
       
   154 void S60AudioCaptureSession::record()
       
   155 {    
       
   156     QString filename = QDir::toNativeSeparators(m_sink.toString());
       
   157     TPtrC16 sink(reinterpret_cast<const TUint16*>(filename.utf16()));    
       
   158 
       
   159     TUid controllerUid(TUid::Uid(m_controllerIdMap[m_format.codec()].controllerUid));
       
   160     TUid formatUid(TUid::Uid(m_controllerIdMap[m_format.codec()].destinationFormatUid));
       
   161     
       
   162     TRAPD(err, m_recorderUtility->OpenFileL(sink, controllerUid, KNullUid, formatUid));
       
   163     qWarning() << err;
       
   164 
       
   165     m_state = QMediaRecorder::RecordingState;
       
   166 }
       
   167 
       
   168 void S60AudioCaptureSession::pause()
       
   169 {
       
   170     //TODO:
       
   171     /*
       
   172     if(m_audioInput)
       
   173         m_audioInput->stop();
       
   174     */
       
   175 
       
   176     m_state = QMediaRecorder::PausedState;
       
   177 }
       
   178 
       
   179 void S60AudioCaptureSession::stop()
       
   180 {
       
   181     if (m_recorderUtility) {
       
   182         m_recorderUtility->Stop();
       
   183         m_recorderUtility->Close();
       
   184     }    
       
   185     m_state = QMediaRecorder::StoppedState;
       
   186 }
       
   187 
       
   188 void S60AudioCaptureSession::stateChanged(QAudio::State state)
       
   189 {
       
   190     switch(state) {
       
   191         case QAudio::ActiveState:
       
   192             emit stateChanged(QMediaRecorder::RecordingState);
       
   193             break;
       
   194         default:
       
   195             if(!((m_state == QMediaRecorder::PausedState) || (m_state == QMediaRecorder::StoppedState)))
       
   196                 m_state = QMediaRecorder::StoppedState;
       
   197 
       
   198             emit stateChanged(m_state);
       
   199             break;
       
   200     }
       
   201 }
       
   202 
       
   203 void S60AudioCaptureSession::notify()
       
   204 {
       
   205     //TODO:
       
   206     //m_position += m_audioInput->notifyInterval();
       
   207     m_position = 0;
       
   208     emit positionChanged(m_position);
       
   209 }
       
   210 
       
   211 void S60AudioCaptureSession::setCaptureDevice(const QString &deviceName)
       
   212 {
       
   213     m_captureDevice = deviceName;
       
   214 }
       
   215 
       
   216 // Needed observer for CMdaAudioRecorderUtility
       
   217 void S60AudioCaptureSession::MoscoStateChangeEvent(CBase* aObject,
       
   218         TInt aPreviousState, TInt aCurrentState, TInt /*aErrorCode*/)
       
   219 {
       
   220 	TRAPD(err, MoscoStateChangeEventL(aObject, aPreviousState, aCurrentState, NULL));
       
   221     qWarning() << err;
       
   222 }
       
   223 
       
   224 // Needed observer for CMdaAudioRecorderUtility
       
   225 void S60AudioCaptureSession::MoscoStateChangeEventL(CBase* aObject,
       
   226         TInt aPreviousState, TInt aCurrentState, TInt /*aErrorCode*/)
       
   227 {
       
   228 	if (aObject == m_recorderUtility)
       
   229     {
       
   230 		switch(aCurrentState)
       
   231 		{
       
   232             case CMdaAudioClipUtility::EOpen:
       
   233             {
       
   234                 if(aPreviousState == CMdaAudioClipUtility::ENotReady)
       
   235                 {
       
   236 					RArray<TUint> supportedSampleRates;
       
   237 					m_recorderUtility->GetSupportedSampleRatesL(supportedSampleRates);
       
   238 					
       
   239 					for (TInt i = 0; i < supportedSampleRates.Count(); i++ ) {
       
   240 						TUint supportedSampleRate = supportedSampleRates[i];
       
   241 						int frequency = m_format.frequency();
       
   242 						if (supportedSampleRate == frequency) 
       
   243 							m_recorderUtility->SetDestinationSampleRateL(m_format.frequency());
       
   244 					}
       
   245 					
       
   246 					/*
       
   247 					RArray<TUint> supportedBitRates;
       
   248 					TRAPD(ignore, m_recorderUtility->GetSupportedBitRatesL(supportedBitRates));
       
   249 					
       
   250 					for (TInt j = 0; j < supportedBitRates.Count(); j++ ) {
       
   251 						qWarning() << QString("Supported bit rate: ") + QString().number(supportedBitRates[j]);
       
   252 						
       
   253 					}
       
   254 					*/
       
   255 					
       
   256 					TFourCC fourCC;
       
   257 					
       
   258 					if (m_format.sampleSize() == 8) {
       
   259 						switch (m_format.sampleType()) {
       
   260 							case QAudioFormat::SignedInt: {
       
   261 								fourCC.Set(KMMFFourCCCodePCM8);
       
   262 								break;
       
   263 							}
       
   264 							case QAudioFormat::UnSignedInt: {
       
   265 								fourCC.Set(KMMFFourCCCodePCMU8);
       
   266 								break;
       
   267 							}
       
   268 							case QAudioFormat::Float: 
       
   269 							case QAudioFormat::Unknown:
       
   270 							default: {
       
   271 								fourCC.Set(KMMFFourCCCodePCM8);
       
   272 								break;
       
   273 							}
       
   274 						}
       
   275 					} else if (m_format.sampleSize() == 16) {
       
   276 						// 16 bit here
       
   277 						switch (m_format.sampleType()) {
       
   278 							case QAudioFormat::SignedInt: {
       
   279 								fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian?
       
   280 									KMMFFourCCCodePCM16B:KMMFFourCCCodePCM16);
       
   281 								break;
       
   282 							}
       
   283 							case QAudioFormat::UnSignedInt: {
       
   284 								fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian?
       
   285 									KMMFFourCCCodePCMU16B:KMMFFourCCCodePCMU16);
       
   286 								break;
       
   287 							}
       
   288 							default: {
       
   289 								fourCC.Set(KMMFFourCCCodePCM16);
       
   290 								break;
       
   291 							}
       
   292 						}
       
   293 					}
       
   294 					
       
   295 					RArray<TFourCC> supportedDataTypes;
       
   296 					m_recorderUtility->GetSupportedDestinationDataTypesL(supportedDataTypes);
       
   297 
       
   298 					for (TInt k = 0; k < supportedDataTypes.Count(); k++ ) {
       
   299 						if (supportedDataTypes[k].FourCC() == fourCC.FourCC()) {
       
   300 							m_recorderUtility->SetDestinationDataTypeL(supportedDataTypes[k]);
       
   301 						}
       
   302 					}
       
   303 					
       
   304 					//set channels 
       
   305 					m_recorderUtility->SetDestinationNumberOfChannelsL(m_format.channels());
       
   306 
       
   307 					m_recorderUtility->SetGain(m_recorderUtility->MaxGain());
       
   308                     m_recorderUtility->RecordL();
       
   309                 }
       
   310                 break;
       
   311             }
       
   312             default:
       
   313             {
       
   314                 break;
       
   315             }
       
   316 		}
       
   317 	}
       
   318 }
       
   319 
       
   320 
       
   321 void S60AudioCaptureSession::fetchAudioCodecsL()
       
   322 {
       
   323     CMMFControllerPluginSelectionParameters* pluginParameters = 
       
   324     	CMMFControllerPluginSelectionParameters::NewLC();
       
   325 	CMMFFormatSelectionParameters* formatParameters = 
       
   326 		CMMFFormatSelectionParameters::NewLC();
       
   327 	 
       
   328 	pluginParameters->SetRequiredRecordFormatSupportL(*formatParameters);
       
   329 	 
       
   330 	RArray<TUid> ids;
       
   331 	User::LeaveIfError(ids.Append(KUidMediaTypeAudio));  
       
   332 
       
   333 	pluginParameters->SetMediaIdsL(ids, 
       
   334 		CMMFPluginSelectionParameters::EAllowOnlySuppliedMediaIds);
       
   335 	 
       
   336 	RMMFControllerImplInfoArray controllers; 
       
   337 	CleanupResetAndDestroyPushL(controllers);
       
   338 	 
       
   339 	//Get all audio/video play and record controllers/formats that are supported
       
   340 	pluginParameters->ListImplementationsL(controllers);
       
   341 	 
       
   342 	for (TInt index=0; index<controllers.Count(); index++) {
       
   343 		const RMMFFormatImplInfoArray& recordFormats = 
       
   344 			controllers[index]->RecordFormats();
       
   345 		for (TInt j=0; j<recordFormats.Count(); j++) {
       
   346 			const CDesC8Array& mimeTypes = recordFormats[j]->SupportedMimeTypes();
       
   347 			TInt count = mimeTypes.Count();
       
   348 			if (count > 0) {
       
   349 				TPtrC8 mimeType = mimeTypes[0];
       
   350 				QString type = QString::fromUtf8((char *)mimeType.Ptr(), mimeType.Length()); 
       
   351                 // Currently only support for audio/wav due to quality issues.
       
   352                 if (type == "audio/wav") {
       
   353                     ItemData data;
       
   354                     data.controllerUid = controllers[index]->Uid().iUid;
       
   355                     data.destinationFormatUid = recordFormats[j]->Uid().iUid;
       
   356                     data.destinationFormatDescription = qt_TDesC2QString(recordFormats[j]->DisplayName());
       
   357                     m_controllerIdMap[type] = data;
       
   358                 }
       
   359 			}
       
   360 		}
       
   361 	}
       
   362 	
       
   363 	CleanupStack::PopAndDestroy(3);//controllers, formatParameters, pluginParameters
       
   364 }
       
   365