:? The problem is that it can't record well, to my surprised,
after iAudioRecorderUtility -> OpenL(iDesLocation, &iFormat, &iCodec, &iAudioSettings) in CAudioRecorder::ConstructL been loaded, the callback of CAudioRecorder won't be loaded,
the record status always is "ENotReady".When recordL() be loaded, it will panic. But if I use new CAudioRecorder object in Engine class's constructor, and then use recordL in its RunOneMinute method, it will record only one minutes, when the next one minute event occur, its status won't change, so it won't work well, this problem puzzled me two weeks, I hope I can get some helpful advice here.
Some of my key code is below:
////////////////////////////////////////////////
my class to record is:
CAudioRecorder::CAudioRecorder()
:iAudioRecorderUtility(NULL),
iDesLocation(NULL),
iBlockCount(0),
iBlockSize(8000*2*5+58),
iPtrRecord(0,0,iBlockSize),
iFlag(0)
{
}
CAudioRecorder::~CAudioRecorder()
{
Stop();
if(iAudioRecorderUtility)
delete iAudioRecorderUtility;
iAudioRecorderUtility = NULL;
if (iDesLocation)
{
delete iDesLocation;
iDesLocation = NULL;
}
for (TInt i = 0; i < KMaxBlock; i++)
{
delete iRecordData[i];
iRecordData[i] = NULL;
}
}
CAudioRecorder* CAudioRecorder::NewL(String *pcmInputFile, String * aOutputFile, UInt32_t samplesPerSecond, UInt32_t sampleCount)
{
CAudioRecorder* self = new(ELeave) CAudioRecorder;
CleanupStack::PushL(self);
self->ConstructL(pcmInputFile, aOutputFile, samplesPerSecond, sampleCount);
CleanupStack::Pop();
return self;
}
void CAudioRecorder::ConstructL(String *pcmInputFile, String * aOutputFile, UInt32_t samplesPerSecond, UInt32_t sampleCount)
{
this->samplesPerSecond = samplesPerSecond;
this->sampleCount = sampleCount;
this->pcmInputFile = pcmInputFile;
if (aOutputFile)
{
iPcmOutputFile = new File(aOutputFile, File::CREATE, false);
}
iBlockSize = 6 * 8000 *2 +58 + 32; //extra 32 bytes
for (TInt i = 0; i < KMaxBlock; i++)
{
iRecordData[i] = new(ELeave) TUint8[iBlockSize];
}
FillWavHeaderBuf();
//iCodec.iBits = TMdaPcmWavCodec::E16BitPcm;
iAudioSettings.iSampleRate=TMdaAudioDataSettings::ESampleRate8000Hz;
iAudioSettings.iChannels=TMdaAudioDataSettings::EChannelsMono;
iPtrRecord.Set(iRecordData[iBlockCount],0,iBlockSize);
WriteWavFileHeader(iPtrRecord);
iDesLocation=NULL;
iDesLocation = new(ELeave) TMdaDesClipLocation(iPtrRecord);
if (iAudioRecorderUtility)
delete iAudioRecorderUtility;
iAudioRecorderUtility=NULL;
iAudioRecorderUtility = CMdaAudioRecorderUtility::NewL(*this);
iAudioRecorderUtility -> OpenL(iDesLocation, &iFormat, &iCodec, &iAudioSettings);
}
// Audio is now prepared to record a file
// from MMdaObjectStateChangeObserver
void CAudioRecorder::MoscoStateChangeEvent(CBase*/* aObject*/,
TInt /*aPreviousState*/, TInt /*aCurrentState*/, TInt aErrorCode)
{
if (aErrorCode)
{
if (aErrorCode == -9)
{
iAudioRecorderUtility -> Close();
WriteFile();
return;
}
}
}
void CAudioRecorder::RecordL()
{
// Set up file to record to, the recording format, codec, and settings
// Set the gain
TInt gain;//=iGain;
gain = iAudioRecorderUtility -> MaxGain() * 10;
iAudioRecorderUtility -> SetGain(gain);///
// And mode
iAudioRecorderUtility -> SetAudioDeviceMode(CMdaAudioRecorderUtility::ELocal);
iAudioRecorderUtility->SetPosition(TTimeIntervalMicroSeconds(0));
iAudioRecorderUtility->CropL();
// and start recording
iAudioRecorderUtility -> RecordL();
// This will call back MoscoStateChangeEvent() when preparation is complete
}
// Terminate current operation
void CAudioRecorder::Stop()
{
// Take appropriate action depending on what the state is
stop();
iAudioRecorderUtility -> Stop();
//RecordCleanup();
}
void CAudioRecorder::WriteWavFileHeader(TDes8 &aBuf)
{
aBuf.Copy(iWavHeaderBuf,58);
}
void CAudioRecorder::FillWavHeaderBuf()
{
TInt i=0;
iWavHeaderBuf[i++]=0x52 ;//RIFF2
iWavHeaderBuf[i++]='I';
iWavHeaderBuf[i++]='F';
iWavHeaderBuf[i++]='F';
iWavHeaderBuf[i++]='2';
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]='W';
iWavHeaderBuf[i++]='A';
iWavHeaderBuf[i++]='V';
iWavHeaderBuf[i++]='E';
iWavHeaderBuf[i++]='f';
iWavHeaderBuf[i++]='m';
iWavHeaderBuf[i++]='t';
iWavHeaderBuf[i++]=' ';
iWavHeaderBuf[i++]=0x12;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x01;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x01;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x40;
iWavHeaderBuf[i++]=0x1F;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x80;
iWavHeaderBuf[i++]=0x3E;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x02;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x10;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]='f';
iWavHeaderBuf[i++]='a';
iWavHeaderBuf[i++]='c';
iWavHeaderBuf[i++]='t';
iWavHeaderBuf[i++]=0x04;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]='d';
iWavHeaderBuf[i++]='a';
iWavHeaderBuf[i++]='t';
iWavHeaderBuf[i++]='a';
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
iWavHeaderBuf[i++]=0x00;
}
void CAudioRecorder::WriteFile()
{
TPtrC8 ptrRecordFile(iRecordData[iBlockCount],iBlockSize);
iPcmOutputFile->write(/*(UInt8_t *)*/ptrRecordFile/*.Ptr()*/, iBlockSize);
}
//////////////////////////////////////////////
In UI class:
void CExampleAppUi::ConstructL()
{
// BaseConstructL() completes the UI framework's
// construction of the App UI.
BaseConstructL();
// Create the single application view in which to
// draw the text "Hello World!", passing into it
// the rectangle available to it.
iAppView = CMlsMainController::NewL();
AddViewL(iAppView);
SetDefaultViewL(*iAppView);
iEngine = CMpmEngine::NewL(*this);
}
void CExampleAppUi::HandleCommandL(TInt aCommand)
{
switch (aCommand)
{
case EMpmStart:
iEngine->Run();
break;
case EMpmStop:
iEngine->Stop();
break;
case EEikCmdExit:
case EAknSoftkeyExit:
Exit();
break;
}
}
//////////////////////////////////////////////
In Engine class:
void CMpmEngine::Run()
{
recording = true;
while (recording)
{
running = runOneMinute(...);
}
}
bool CMpmEngine::runOneMinute(...)
{
iAudioRecorder = new (ELeave) CAudioRecorder;
iAudioRecorder->RecordL();
/* waitForTrigger function description:
when it is loaded, the main thread will
wait one minute or stop event occurred,
if stop event occurred, it will return false,
otherwise it will return true*/
running = !stopEvent->waitForTrigger(60000000);
stopAudioRecorder(); //stop audio recorder
return running;
}
/////////////////////////////////
Thanks in advice