00001
00012 #include "audiodrv_er6.h"
00013 #include "alaw.h"
00014 #include "elog.h"
00015
00016
00017 #if defined(__CRYSTAL__) && defined(__WINS__)
00018 #undef HAVE_AUDIO_DRIVER
00019 #else
00020 #define HAVE_AUDIO_DRIVER
00021 #endif
00022
00023 const TInt KFileOpenWritable = EFileWrite | EFileShareAny | EFileStream;
00024
00025 struct wav_hdr
00026 {
00027 char main_chunk[4];
00028 TUint32 length;
00029 char chunk_type[4];
00030
00031 char sub_chunk[4];
00032 TUint32 clength;
00033 TUint16 format;
00034 TUint16 modus;
00035 TUint32 samplefreq;
00036 TUint32 bytespersec;
00037 TUint16 bytespersmpl;
00038 TUint16 bitspersmpl;
00039 char data_chunk[4];
00040 TUint32 data_length;
00041 };
00042
00043 const wav_hdr my_wav_hdr =
00044 {
00045 {'R','I','F','F'}, 0 , {'W','A','V','E'},
00046 {'f','m','t',' '}, 16, 1, 1, SAMPLE_FREQ, SAMPLE_FREQ*2, 2, 16,
00047 {'d','a','t','a'}, 0
00048 };
00049
00050
00051
00052
00053
00054
00055
00056 audioDriver::audioDriver()
00060 :audioHd(-1)
00061 ,frequency(0)
00062 ,encoding(0)
00063 ,precision(0)
00064 ,channels(0)
00065 ,iIsReady(EFalse)
00066 ,iBlocksInQueue(0)
00067 ,iPrefilled(EFalse)
00068 ,iIsWavDumping(0)
00069 {
00070 CTOR(audioDriver);
00071 }
00072
00073
00074 void audioDriver::ConstructL()
00078 {
00079 errorString = "None";
00080
00081 iSettings.iCaps = 0;
00082 iSettings.iMaxVolume = 0;
00083
00084 #ifdef HAVE_AUDIO_DRIVER
00085 iMdaAudio = CMdaAudioOutputStream::NewL(*this);
00086 iMdaAudio->Open(&iSettings);
00087 #endif
00088 }
00089
00090
00091 audioDriver::~audioDriver()
00095 {
00096 DTOR(audioDriver);
00097 if(iMdaAudio)
00098 {
00099 iMdaAudio->Stop();
00100 delete iMdaAudio;
00101 iMdaAudio = NULL;
00102 }
00103 }
00104
00105
00106 bool audioDriver::IsThere()
00112 {
00113 return true;
00114 }
00115
00116
00117 bool audioDriver::Open(udword inFreq, int inPrecision, int inChannels,
00118 int inFragments, int inFragBase)
00129 {
00130 audioHd = KErrNone;
00131
00132
00133
00134 frequency = inFreq;
00135 precision = inPrecision;
00136 channels = inChannels;
00137 fragments = inFragments;
00138 fragSizeBase = inFragBase;
00139
00140
00141 if (precision != SIDEMU_16BIT )
00142 {
00143 errorString = "AUDIO: Could not set sample size.(only 16 bit for ER6)";
00144 return false;
00145 }
00146
00147 encoding = SIDEMU_SIGNED_PCM;
00148
00149 if (channels != SIDEMU_MONO)
00150 {
00151 errorString = "AUDIO: only Mono supported for EPOC.";
00152 return false;
00153 }
00154
00155
00156 int dsp_stereo;
00157 if (channels == SIDEMU_STEREO)
00158 dsp_stereo = 1;
00159 else if (channels == SIDEMU_MONO)
00160 dsp_stereo = 0;
00161 else
00162 {
00163 errorString = "AUDIO: Could not set mono/stereo.";
00164 return false;
00165 }
00166
00167
00168 if (dsp_stereo == 1)
00169 channels = SIDEMU_STEREO;
00170 else if (dsp_stereo == 0)
00171 channels = SIDEMU_MONO;
00172
00173 blockSize = KDefaultBufSize;
00174 fragments = 2;
00175
00176 return true;
00177 }
00178
00179
00180 void audioDriver::Close()
00185 {
00186 if (audioHd != (-1))
00187 {
00188 audioHd = (-1);
00189 }
00190 }
00191
00192
00193 void audioDriver::Play(ubyte* pBuffer, int bufferSize)
00200 {
00201 if (audioHd != (-1))
00202 {
00203
00204
00205
00206
00207 iExtraBuf.Copy(pBuffer, bufferSize);
00208
00209
00210 #ifdef HAVE_AUDIO_DRIVER
00211 TRAPD(ret, iMdaAudio->WriteL(iExtraBuf));
00212 if(ret)
00213 {
00214 ELOG2(_L8("WARNING! WriteL left with %d \n"), ret);
00215 }
00216 #else
00217 User::After(200000);
00218 #endif
00219
00220 if(IsWavDumping())
00221 DoWavDump(iExtraBuf);
00222 }
00223 }
00224
00225
00226 void audioDriver::StopStream(void)
00230 {
00231 if(iMdaAudio)
00232 {
00233 if(iIsReady)
00234 iMdaAudio->Stop();
00235 ResetStream();
00236 }
00237 }
00238
00239
00240 void audioDriver::ResetStream(void)
00244 {
00245 iBlocksInQueue = 0;
00246 iPrefilled = EFalse;
00247 }
00248
00249
00250 TInt audioDriver::VolumeDelta(TInt aDelta)
00254 {
00255 iVolume += aDelta;
00256 if(iVolume < 0)
00257 iVolume = 0;
00258 else if(iVolume >= KVolumeSteps)
00259 iVolume = KVolumeSteps - 1;
00260
00261 if(iMdaAudio && iIsReady)
00262 iMdaAudio->SetVolume(iVolume * iMdaAudio->MaxVolume()/KVolumeSteps );
00263
00264 return iVolume;
00265 }
00266
00267
00268 void audioDriver::MaoscOpenComplete(TInt aError)
00274 {
00275 ELOG2(_L8("MaoscOpenComplete [aError=%d] \n"), aError);
00276
00277 #if (SAMPLE_FREQ == 44100)
00278 #define EPOC_SAMPLE_RATE TMdaAudioDataSettings::ESampleRate44100Hz
00279 #elif (SAMPLE_FREQ == 8000)
00280 #define EPOC_SAMPLE_RATE TMdaAudioDataSettings::ESampleRate8000Hz
00281 #else
00282 #error unsupported sample frequency
00283 #endif
00284
00285
00286 if(aError == KErrNone)
00287 {
00288
00289 iMdaAudio->SetAudioPropertiesL(EPOC_SAMPLE_RATE,
00290 TMdaAudioDataSettings::EChannelsMono);
00291 iMdaAudio->SetPriority(EPriorityNormal, EMdaPriorityPreferenceNone);
00292
00293
00294 iVolume = iMdaAudio->MaxVolume() / 2 / KVolumeSteps;
00295
00296 iIsReady = ETrue;
00297 }
00298 }
00299
00300
00301 void audioDriver::MaoscBufferCopied(TInt aError, const TDesC8& )
00309 {
00310 if(aError)
00311 {
00312 ELOG2(_L8("WARNING! MaoscBufferCopied [aError=%d] \n"), aError);
00313 }
00314
00315
00316 if(aError == KErrCancel)
00317 {
00318 ResetStream();
00319 }
00320
00321 iBlocksInQueue = 0;
00322 }
00323
00324
00325 void audioDriver::MaoscPlayComplete(TInt aError)
00329 {
00330 if(aError)
00331 {
00332 ELOG2(_L8("MaoscPlayComplete [aError=%d] \n"), aError);
00333 }
00334
00335
00336 if(aError == KErrCancel)
00337 {
00338 ResetStream();
00339 }
00340 }
00341
00342
00343 TInt audioDriver::StartWavDump(const TDesC& aSidTune)
00347 {
00348 ELOG(TBuf8<128> buf8;)
00349 ELOG(buf8.Copy(aSidTune);)
00350 ELOG2(_L8("Starting WAV dump of '%S.wav'\n"), &buf8);
00351
00352 if(iIsWavDumping)
00353 {
00354 ELOG1(_L8("already dumping wav\n"));
00355 return KErrAlreadyExists;
00356 }
00357
00358 TInt ret = iFs.Connect();
00359 if( (ret != KErrNone) && (ret != KErrAlreadyExists) )
00360 return ret;
00361
00362 iWavDump.Copy(aSidTune);
00363 iWavDump.Append(_L(".wav"));
00364
00365
00366 (void)iFs.Delete(iWavDump);
00367
00368 RFile file;
00369 ret = file.Open(iFs, iWavDump, KFileOpenWritable);
00370 if(ret == KErrNotFound)
00371 ret = file.Replace(iFs, iWavDump, KFileOpenWritable);
00372 if(ret == KErrNone)
00373 {
00374
00375 TPtrC8 ptr((TUint8*)&my_wav_hdr, sizeof(wav_hdr));
00376 ret = file.Write(ptr);
00377 if(ret)
00378 {
00379 file.Close();
00380 return ret;
00381 }
00382 }
00383 else
00384 return ret;
00385
00386 file.Close();
00387
00388
00389 iIsWavDumping = ETrue;
00390 return KErrNone;
00391 }
00392
00393
00394 TInt audioDriver::StopWavDump()
00398 {
00399 ELOG(TBuf8<128> buf8;)
00400 ELOG(buf8.Copy(iWavDump);)
00401 ELOG2(_L8("Stopping WAV dump of '%S'\n"), &buf8);
00402
00403 RFile file;
00404 TInt ret = file.Open(iFs, iWavDump, KFileOpenWritable);
00405 if(ret)
00406 {
00407 ELOG2(_L8("Serious problem, was supposed to open file [ret=%d]\n"), ret);
00408 iIsWavDumping = EFalse;
00409 return ret;
00410 }
00411
00412
00413 TInt size = 0;
00414 ret = file.Size(size);
00415 if(ret)
00416 {
00417 ELOG2(_L8("Wavdump: could not get size [ret=%d]\n"), ret);
00418 iIsWavDumping = EFalse;
00419 return ret;
00420 }
00421
00422
00423
00424
00425
00426 const TUint32 file_length = size - 8;
00427 const TUint32 data_length = size - sizeof(wav_hdr);
00428
00429 TBuf8<4> file_len;
00430 file_len.SetLength(4);
00431 file_len[0] = (TUint8)((file_length >> 0) & 0xff);
00432 file_len[1] = (TUint8)((file_length >> 8) & 0xff);
00433 file_len[2] = (TUint8)((file_length >> 16) & 0xff);
00434 file_len[3] = (TUint8)((file_length >> 24) & 0xff);
00435
00436 TBuf8<4> data_len;
00437 data_len.SetLength(4);
00438 data_len[0] = (TUint8)((data_length >> 0) & 0xff);
00439 data_len[1] = (TUint8)((data_length >> 8) & 0xff);
00440 data_len[2] = (TUint8)((data_length >> 16) & 0xff);
00441 data_len[3] = (TUint8)((data_length >> 24) & 0xff);
00442
00443 (void)file.Write(4, file_len);
00444 (void)file.Write(40, data_len);
00445
00446 iFs.Close();
00447 iIsWavDumping = EFalse;
00448 return size;
00449 }
00450
00451
00452 TBool audioDriver::IsWavDumping()
00456 {
00457 return iIsWavDumping;
00458 }
00459
00460
00461 void audioDriver::DoWavDump(const TDesC8& aBuffer)
00465 {
00466 RFile file;
00467 TInt ret = file.Open(iFs, iWavDump, KFileOpenWritable);
00468 if(ret)
00469 {
00470 ELOG2(_L8("Serious problem, was supposed to open wav file [ret=%d]\n"), ret);
00471 return;
00472 }
00473
00474
00475 TInt pos;
00476 ret = file.Seek(ESeekEnd, pos);
00477 if (ret==KErrNone)
00478 {
00479 (void)file.Write(aBuffer);
00480 }
00481 else
00482 {
00483 ELOG2(_L8("Wavdump: could not seek due to %d\n"), ret);
00484 }
00485
00486 file.Close();
00487 }
00488
00489
00490