/* $Id$ */
/* 
 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjmedia-audiodev/audiodev_imp.h>
#include <pjmedia-audiodev/errno.h>
#include <pjmedia/alaw_ulaw.h>
#include <pj/assert.h>
#include <pj/log.h>
#include <pj/math.h>
#include <pj/os.h>
#include <pj/string.h>

#if PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA

/*
 * This file provides sound implementation for Symbian Audio Streaming
 * device. Application using this sound abstraction must link with:
 *  - mediaclientaudiostream.lib, and
 *  - mediaclientaudioinputstream.lib 
 */
#include <mda/common/audio.h>
#include <mdaaudiooutputstream.h>
#include <mdaaudioinputstream.h>


#define THIS_FILE			"symb_mda_dev.c"
#define BITS_PER_SAMPLE			16
#define BYTES_PER_SAMPLE		(BITS_PER_SAMPLE/8)


#if 1
#   define TRACE_(st) PJ_LOG(3, st)
#else
#   define TRACE_(st)
#endif


/* MDA factory */
struct mda_factory
{
    pjmedia_aud_dev_factory	 base;
    pj_pool_t			*pool;
    pj_pool_factory		*pf;
    pjmedia_aud_dev_info	 dev_info;
};

/* Forward declaration of internal engine. */
class CPjAudioInputEngine;
class CPjAudioOutputEngine;

/* MDA stream. */
struct mda_stream
{
    // Base
    pjmedia_aud_stream	 base;			/**< Base class.	*/
    
    // Pool
    pj_pool_t		*pool;			/**< Memory pool.       */

    // Common settings.
    pjmedia_aud_param param;		/**< Stream param.	*/

    // Audio engine
    CPjAudioInputEngine	*in_engine;		/**< Record engine.	*/
    CPjAudioOutputEngine *out_engine;		/**< Playback engine.	*/
};


/* Prototypes */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
static unsigned    factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
					unsigned index,
					pjmedia_aud_dev_info *info);
static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
					 unsigned index,
					 pjmedia_aud_param *param);
static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
					 const pjmedia_aud_param *param,
					 pjmedia_aud_rec_cb rec_cb,
					 pjmedia_aud_play_cb play_cb,
					 void *user_data,
					 pjmedia_aud_stream **p_aud_strm);

static pj_status_t stream_get_param(pjmedia_aud_stream *strm,
				    pjmedia_aud_param *param);
static pj_status_t stream_get_cap(pjmedia_aud_stream *strm,
				  pjmedia_aud_dev_cap cap,
				  void *value);
static pj_status_t stream_set_cap(pjmedia_aud_stream *strm,
				  pjmedia_aud_dev_cap cap,
				  const void *value);
static pj_status_t stream_start(pjmedia_aud_stream *strm);
static pj_status_t stream_stop(pjmedia_aud_stream *strm);
static pj_status_t stream_destroy(pjmedia_aud_stream *strm);


/* Operations */
static pjmedia_aud_dev_factory_op factory_op =
{
    &factory_init,
    &factory_destroy,
    &factory_get_dev_count,
    &factory_get_dev_info,
    &factory_default_param,
    &factory_create_stream
};

static pjmedia_aud_stream_op stream_op = 
{
    &stream_get_param,
    &stream_get_cap,
    &stream_set_cap,
    &stream_start,
    &stream_stop,
    &stream_destroy
};


/*
 * Convert clock rate to Symbian's TMdaAudioDataSettings capability.
 */
static TInt get_clock_rate_cap(unsigned clock_rate)
{
    switch (clock_rate) {
    case 8000:  return TMdaAudioDataSettings::ESampleRate8000Hz;
    case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz;
    case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz;
    case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz;
    case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz;
    case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz;
    case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz;
    case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz;
    case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz;
    case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz;
    case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz;
    default:
	return 0;
    }
}

/*
 * Convert number of channels into Symbian's TMdaAudioDataSettings capability.
 */
static TInt get_channel_cap(unsigned channel_count)
{
    switch (channel_count) {
    case 1: return TMdaAudioDataSettings::EChannelsMono;
    case 2: return TMdaAudioDataSettings::EChannelsStereo;
    default:
	return 0;
    }
}

/*
 * Utility: print sound device error
 */
static void snd_perror(const char *title, TInt rc) 
{
    PJ_LOG(1,(THIS_FILE, "%s: error code %d", title, rc));
}
 
//////////////////////////////////////////////////////////////////////////////
//

/*
 * Implementation: Symbian Input Stream.
 */
class CPjAudioInputEngine : public CBase, MMdaAudioInputStreamCallback
{
public:
    enum State
    {
	STATE_INACTIVE,
	STATE_ACTIVE,
    };

    ~CPjAudioInputEngine();

    static CPjAudioInputEngine *NewL(struct mda_stream *parent_strm,
				     pjmedia_aud_rec_cb rec_cb,
				     void *user_data);

    static CPjAudioInputEngine *NewLC(struct mda_stream *parent_strm,
				      pjmedia_aud_rec_cb rec_cb,
				      void *user_data);

    pj_status_t StartRecord();
    void Stop();

    pj_status_t SetGain(TInt gain) { 
	if (iInputStream_) { 
	    iInputStream_->SetGain(gain);
	    return PJ_SUCCESS;
	} else
	    return PJ_EINVALIDOP;
    }
    
    TInt GetGain() { 
	if (iInputStream_) { 
	    return iInputStream_->Gain();
	} else
	    return PJ_EINVALIDOP;
    }

    TInt GetMaxGain() { 
	if (iInputStream_) { 
	    return iInputStream_->MaxGain();
	} else
	    return PJ_EINVALIDOP;
    }
    
private:
    State		     state_;
    struct mda_stream	    *parentStrm_;
    pjmedia_aud_rec_cb	     recCb_;
    void		    *userData_;
    CMdaAudioInputStream    *iInputStream_;
    HBufC8		    *iStreamBuffer_;
    TPtr8		     iFramePtr_;
    TInt		     lastError_;
    pj_uint32_t		     timeStamp_;

    // cache variable
    // to avoid calculating frame length repeatedly
    TInt		     frameLen_;
    
    // sometimes recorded size != requested framesize, so let's
    // provide a buffer to make sure the rec callback returning
    // framesize as requested.
    TUint8		    *frameRecBuf_;
    TInt		     frameRecBufLen_;

    CPjAudioInputEngine(struct mda_stream *parent_strm,
	    pjmedia_aud_rec_cb rec_cb,
			void *user_data);
    void ConstructL();
    TPtr8 & GetFrame();
    
public:
    virtual void MaiscOpenComplete(TInt aError);
    virtual void MaiscBufferCopied(TInt aError, const TDesC8 &aBuffer);
    virtual void MaiscRecordComplete(TInt aError);

};


CPjAudioInputEngine::CPjAudioInputEngine(struct mda_stream *parent_strm,
					 pjmedia_aud_rec_cb rec_cb,
					 void *user_data)
    : state_(STATE_INACTIVE), parentStrm_(parent_strm), 
      recCb_(rec_cb), userData_(user_data), 
      iInputStream_(NULL), iStreamBuffer_(NULL), iFramePtr_(0, 0),
      lastError_(KErrNone), timeStamp_(0),
      frameLen_(parent_strm->param.samples_per_frame * 
	        parent_strm->param.channel_count * 
	        BYTES_PER_SAMPLE),
      frameRecBuf_(NULL), frameRecBufLen_(0)
{
}

CPjAudioInputEngine::~CPjAudioInputEngine()
{
    Stop();

    delete iStreamBuffer_;
    iStreamBuffer_ = NULL;
    
    delete [] frameRecBuf_;
    frameRecBuf_ = NULL;
    frameRecBufLen_ = 0;
}

void CPjAudioInputEngine::ConstructL()
{
    iStreamBuffer_ = HBufC8::NewL(frameLen_);
    CleanupStack::PushL(iStreamBuffer_);

    frameRecBuf_ = new TUint8[frameLen_*2];
    CleanupStack::PushL(frameRecBuf_);
}

CPjAudioInputEngine *CPjAudioInputEngine::NewLC(struct mda_stream *parent,
						pjmedia_aud_rec_cb rec_cb,
					        void *user_data)
{
    CPjAudioInputEngine* self = new (ELeave) CPjAudioInputEngine(parent,
								 rec_cb, 
								 user_data);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
}

CPjAudioInputEngine *CPjAudioInputEngine::NewL(struct mda_stream *parent,
					       pjmedia_aud_rec_cb rec_cb,
					       void *user_data)
{
    CPjAudioInputEngine *self = NewLC(parent, rec_cb, user_data);
    CleanupStack::Pop(self->frameRecBuf_);
    CleanupStack::Pop(self->iStreamBuffer_);
    CleanupStack::Pop(self);
    return self;
}


pj_status_t CPjAudioInputEngine::StartRecord()
{

    // Ignore command if recording is in progress.
    if (state_ == STATE_ACTIVE)
	return PJ_SUCCESS;

    // According to Nokia's AudioStream example, some 2nd Edition, FP2 devices
    // (such as Nokia 6630) require the stream to be reconstructed each time 
    // before calling Open() - otherwise the callback never gets called.
    // For uniform behavior, lets just delete/re-create the stream for all
    // devices.

    // Destroy existing stream.
    if (iInputStream_) delete iInputStream_;
    iInputStream_ = NULL;

    // Create the stream.
    TRAPD(err, iInputStream_ = CMdaAudioInputStream::NewL(*this));
    if (err != KErrNone)
	return PJ_RETURN_OS_ERROR(err);

    // Initialize settings.
    TMdaAudioDataSettings iStreamSettings;
    iStreamSettings.iChannels = 
			    get_channel_cap(parentStrm_->param.channel_count);
    iStreamSettings.iSampleRate = 
			    get_clock_rate_cap(parentStrm_->param.clock_rate);

    pj_assert(iStreamSettings.iChannels != 0 && 
	      iStreamSettings.iSampleRate != 0);

    PJ_LOG(4,(THIS_FILE, "Opening sound device for capture, "
    		         "clock rate=%d, channel count=%d..",
    		         parentStrm_->param.clock_rate, 
    		         parentStrm_->param.channel_count));
    
    // Open stream.
    lastError_ = KRequestPending;
    iInputStream_->Open(&iStreamSettings);
    
    // Success
    PJ_LOG(4,(THIS_FILE, "Sound capture started."));
    return PJ_SUCCESS;
}


void CPjAudioInputEngine::Stop()
{
    // If capture is in progress, stop it.
    if (iInputStream_ && state_ == STATE_ACTIVE) {
    	lastError_ = KRequestPending;
    	iInputStream_->Stop();

	// Wait until it's actually stopped
    	while (lastError_ == KRequestPending)
	    pj_symbianos_poll(-1, 100);
    }

    if (iInputStream_) {
	delete iInputStream_;
	iInputStream_ = NULL;
    }
    
    state_ = STATE_INACTIVE;
}


TPtr8 & CPjAudioInputEngine::GetFrame() 
{
    //iStreamBuffer_->Des().FillZ(frameLen_);
    iFramePtr_.Set((TUint8*)(iStreamBuffer_->Ptr()), frameLen_, frameLen_);
    return iFramePtr_;
}

void CPjAudioInputEngine::MaiscOpenComplete(TInt aError)
{
    lastError_ = aError;
    if (aError != KErrNone) {
        snd_perror("Error in MaiscOpenComplete()", aError);
    	return;
    }

    // set stream priority to normal and time sensitive
    iInputStream_->SetPriority(EPriorityNormal, 
    			       EMdaPriorityPreferenceTime);				

    // Read the first frame.
    TPtr8 & frm = GetFrame();
    TRAPD(err2, iInputStream_->ReadL(frm));
    if (err2) {
    	PJ_LOG(4,(THIS_FILE, "Exception in iInputStream_->ReadL()"));
    }
}

void CPjAudioInputEngine::MaiscBufferCopied(TInt aError, 
					    const TDesC8 &aBuffer)
{
    lastError_ = aError;
    if (aError != KErrNone) {
    	snd_perror("Error in MaiscBufferCopied()", aError);
	return;
    }

    if (frameRecBufLen_ || aBuffer.Size() < frameLen_) {
	pj_memcpy(frameRecBuf_ + frameRecBufLen_, (void*) aBuffer.Ptr(), aBuffer.Size());
	frameRecBufLen_ += aBuffer.Size();
    }

    if (frameRecBufLen_) {
    	while (frameRecBufLen_ >= frameLen_) {
    	    pjmedia_frame f;
    	    
    	    f.type = PJMEDIA_FRAME_TYPE_AUDIO;
    	    f.buf = frameRecBuf_;
    	    f.size = frameLen_;
    	    f.timestamp.u32.lo = timeStamp_;
    	    f.bit_info = 0;
    	    
    	    // Call the callback.
	    recCb_(userData_, &f);
	    // Increment timestamp.
	    timeStamp_ += parentStrm_->param.samples_per_frame;

	    frameRecBufLen_ -= frameLen_;
	    pj_memmove(frameRecBuf_, frameRecBuf_+frameLen_, frameRecBufLen_);
    	}
    } else {
	pjmedia_frame f;
	
	f.type = PJMEDIA_FRAME_TYPE_AUDIO;
	f.buf = (void*)aBuffer.Ptr();
	f.size = aBuffer.Size();
	f.timestamp.u32.lo = timeStamp_;
	f.bit_info = 0;
	
	// Call the callback.
	recCb_(userData_, &f);
	
	// Increment timestamp.
	timeStamp_ += parentStrm_->param.samples_per_frame;
    }

    // Record next frame
    TPtr8 & frm = GetFrame();
    TRAPD(err2, iInputStream_->ReadL(frm));
    if (err2) {
    	PJ_LOG(4,(THIS_FILE, "Exception in iInputStream_->ReadL()"));
    }
}


void CPjAudioInputEngine::MaiscRecordComplete(TInt aError)
{
    lastError_ = aError;
    state_ = STATE_INACTIVE;
    if (aError != KErrNone) {
    	snd_perror("Error in MaiscRecordComplete()", aError);
    }
}



//////////////////////////////////////////////////////////////////////////////
//

/*
 * Implementation: Symbian Output Stream.
 */

class CPjAudioOutputEngine : public CBase, MMdaAudioOutputStreamCallback
{
public:
    enum State
    {
	STATE_INACTIVE,
	STATE_ACTIVE,
    };

    ~CPjAudioOutputEngine();

    static CPjAudioOutputEngine *NewL(struct mda_stream *parent_strm,
				      pjmedia_aud_play_cb play_cb,
				      void *user_data);

    static CPjAudioOutputEngine *NewLC(struct mda_stream *parent_strm,
				       pjmedia_aud_play_cb rec_cb,
				       void *user_data);

    pj_status_t StartPlay();
    void Stop();

    pj_status_t SetVolume(TInt vol) { 
	if (iOutputStream_) { 
	    iOutputStream_->SetVolume(vol);
	    return PJ_SUCCESS;
	} else
	    return PJ_EINVALIDOP;
    }
    
    TInt GetVolume() { 
	if (iOutputStream_) { 
	    return iOutputStream_->Volume();
	} else
	    return PJ_EINVALIDOP;
    }

    TInt GetMaxVolume() { 
	if (iOutputStream_) { 
	    return iOutputStream_->MaxVolume();
	} else
	    return PJ_EINVALIDOP;
    }

private:
    State		     state_;
    struct mda_stream	    *parentStrm_;
    pjmedia_aud_play_cb	     playCb_;
    void		    *userData_;
    CMdaAudioOutputStream   *iOutputStream_;
    TUint8		    *frameBuf_;
    unsigned		     frameBufSize_;
    TPtrC8		     frame_;
    TInt		     lastError_;
    unsigned		     timestamp_;

    CPjAudioOutputEngine(struct mda_stream *parent_strm,
			 pjmedia_aud_play_cb play_cb,
			 void *user_data);
    void ConstructL();

    virtual void MaoscOpenComplete(TInt aError);
    virtual void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
    virtual void MaoscPlayComplete(TInt aError);
};


CPjAudioOutputEngine::CPjAudioOutputEngine(struct mda_stream *parent_strm,
					   pjmedia_aud_play_cb play_cb,
					   void *user_data) 
: state_(STATE_INACTIVE), parentStrm_(parent_strm), playCb_(play_cb), 
  userData_(user_data), iOutputStream_(NULL), frameBuf_(NULL),
  lastError_(KErrNone), timestamp_(0)
{
}


void CPjAudioOutputEngine::ConstructL()
{
    frameBufSize_ = parentStrm_->param.samples_per_frame *
		    parentStrm_->param.channel_count * 
		    BYTES_PER_SAMPLE;
    frameBuf_ = new TUint8[frameBufSize_];
}

CPjAudioOutputEngine::~CPjAudioOutputEngine()
{
    Stop();
    delete [] frameBuf_;	
}

CPjAudioOutputEngine *
CPjAudioOutputEngine::NewLC(struct mda_stream *parent_strm,
			    pjmedia_aud_play_cb play_cb,
			    void *user_data)
{
    CPjAudioOutputEngine* self = new (ELeave) CPjAudioOutputEngine(parent_strm,
								   play_cb, 
								   user_data);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
}

CPjAudioOutputEngine *
CPjAudioOutputEngine::NewL(struct mda_stream *parent_strm,
			   pjmedia_aud_play_cb play_cb,
			   void *user_data)
{
    CPjAudioOutputEngine *self = NewLC(parent_strm, play_cb, user_data);
    CleanupStack::Pop(self);
    return self;
}

pj_status_t CPjAudioOutputEngine::StartPlay()
{
    // Ignore command if playing is in progress.
    if (state_ == STATE_ACTIVE)
	return PJ_SUCCESS;
    
    // Destroy existing stream.
    if (iOutputStream_) delete iOutputStream_;
    iOutputStream_ = NULL;
    
    // Create the stream
    TRAPD(err, iOutputStream_ = CMdaAudioOutputStream::NewL(*this));
    if (err != KErrNone)
	return PJ_RETURN_OS_ERROR(err);
    
    // Initialize settings.
    TMdaAudioDataSettings iStreamSettings;
    iStreamSettings.iChannels = 
			    get_channel_cap(parentStrm_->param.channel_count);
    iStreamSettings.iSampleRate = 
			    get_clock_rate_cap(parentStrm_->param.clock_rate);

    pj_assert(iStreamSettings.iChannels != 0 && 
	      iStreamSettings.iSampleRate != 0);
    
    PJ_LOG(4,(THIS_FILE, "Opening sound device for playback, "
    		         "clock rate=%d, channel count=%d..",
    		         parentStrm_->param.clock_rate, 
    		         parentStrm_->param.channel_count));

    // Open stream.
    lastError_ = KRequestPending;
    iOutputStream_->Open(&iStreamSettings);

    // Success
    PJ_LOG(4,(THIS_FILE, "Sound playback started"));
    return PJ_SUCCESS;

}

void CPjAudioOutputEngine::Stop()
{
    // Stop stream if it's playing
    if (iOutputStream_ && state_ != STATE_INACTIVE) {
    	lastError_ = KRequestPending;
    	iOutputStream_->Stop();

	// Wait until it's actually stopped
    	while (lastError_ == KRequestPending)
	    pj_symbianos_poll(-1, 100);
    }
    
    if (iOutputStream_) {	
	delete iOutputStream_;
	iOutputStream_ = NULL;
    }
    
    state_ = STATE_INACTIVE;
}

void CPjAudioOutputEngine::MaoscOpenComplete(TInt aError)
{
    lastError_ = aError;
    
    if (aError==KErrNone) {
	// output stream opened succesfully, set status to Active
	state_ = STATE_ACTIVE;

	// set stream properties, 16bit 8KHz mono
	TMdaAudioDataSettings iSettings;
	iSettings.iChannels = 
			get_channel_cap(parentStrm_->param.channel_count);
	iSettings.iSampleRate = 
			get_clock_rate_cap(parentStrm_->param.clock_rate);

	iOutputStream_->SetAudioPropertiesL(iSettings.iSampleRate, 
					    iSettings.iChannels);

	// set volume to 1/2th of stream max volume
	iOutputStream_->SetVolume(iOutputStream_->MaxVolume()/2);
	
	// set stream priority to normal and time sensitive
	iOutputStream_->SetPriority(EPriorityNormal, 
				    EMdaPriorityPreferenceTime);				

	// Call callback to retrieve frame from upstream.
	pjmedia_frame f;
	pj_status_t status;
	
	f.type = PJMEDIA_FRAME_TYPE_AUDIO;
	f.buf = frameBuf_;
	f.size = frameBufSize_;
	f.timestamp.u32.lo = timestamp_;
	f.bit_info = 0;

	status = playCb_(this->userData_, &f);
	if (status != PJ_SUCCESS) {
	    this->Stop();
	    return;
	}

	// Increment timestamp.
	timestamp_ += (frameBufSize_ / BYTES_PER_SAMPLE);

	// issue WriteL() to write the first audio data block, 
	// subsequent calls to WriteL() will be issued in 
	// MMdaAudioOutputStreamCallback::MaoscBufferCopied() 
	// until whole data buffer is written.
	frame_.Set(frameBuf_, frameBufSize_);
	iOutputStream_->WriteL(frame_);
    } else {
    	snd_perror("Error in MaoscOpenComplete()", aError);
    }
}

void CPjAudioOutputEngine::MaoscBufferCopied(TInt aError, 
					     const TDesC8& aBuffer)
{
    PJ_UNUSED_ARG(aBuffer);

    if (aError==KErrNone) {
    	// Buffer successfully written, feed another one.

	// Call callback to retrieve frame from upstream.
	pjmedia_frame f;
	pj_status_t status;
	
	f.type = PJMEDIA_FRAME_TYPE_AUDIO;
	f.buf = frameBuf_;
	f.size = frameBufSize_;
	f.timestamp.u32.lo = timestamp_;
	f.bit_info = 0;

	status = playCb_(this->userData_, &f);
	if (status != PJ_SUCCESS) {
	    this->Stop();
	    return;
	}

	// Increment timestamp.
	timestamp_ += (frameBufSize_ / BYTES_PER_SAMPLE);

	// Write to playback stream.
	frame_.Set(frameBuf_, frameBufSize_);
	iOutputStream_->WriteL(frame_);

    } else if (aError==KErrAbort) {
	// playing was aborted, due to call to CMdaAudioOutputStream::Stop()
	state_ = STATE_INACTIVE;
    } else  {
	// error writing data to output
	lastError_ = aError;
	state_ = STATE_INACTIVE;
	snd_perror("Error in MaoscBufferCopied()", aError);
    }
}

void CPjAudioOutputEngine::MaoscPlayComplete(TInt aError)
{
    lastError_ = aError;
    state_ = STATE_INACTIVE;
    if (aError != KErrNone) {
    	snd_perror("Error in MaoscPlayComplete()", aError);
    }
}

/****************************************************************************
 * Factory operations
 */

/*
 * C compatible declaration of MDA factory.
 */
PJ_BEGIN_DECL
PJ_DECL(pjmedia_aud_dev_factory*) pjmedia_symb_mda_factory(pj_pool_factory *pf);
PJ_END_DECL

/*
 * Init Symbian audio driver.
 */
pjmedia_aud_dev_factory* pjmedia_symb_mda_factory(pj_pool_factory *pf)
{
    struct mda_factory *f;
    pj_pool_t *pool;

    pool = pj_pool_create(pf, "symb_aud", 1000, 1000, NULL);
    f = PJ_POOL_ZALLOC_T(pool, struct mda_factory);
    f->pf = pf;
    f->pool = pool;
    f->base.op = &factory_op;

    return &f->base;
}

/* API: init factory */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
{
    struct mda_factory *af = (struct mda_factory*)f;

    pj_ansi_strcpy(af->dev_info.name, "Symbian Audio");
    af->dev_info.default_samples_per_sec = 8000;
    af->dev_info.caps = PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING |
			PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
    af->dev_info.input_count = 1;
    af->dev_info.output_count = 1;

    PJ_LOG(4, (THIS_FILE, "Symb Mda initialized"));

    return PJ_SUCCESS;
}

/* API: destroy factory */
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
{
    struct mda_factory *af = (struct mda_factory*)f;
    pj_pool_t *pool = af->pool;

    af->pool = NULL;
    pj_pool_release(pool);

    PJ_LOG(4, (THIS_FILE, "Symbian Mda destroyed"));
    
    return PJ_SUCCESS;
}

/* API: get number of devices */
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
{
    PJ_UNUSED_ARG(f);
    return 1;
}

/* API: get device info */
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
					unsigned index,
					pjmedia_aud_dev_info *info)
{
    struct mda_factory *af = (struct mda_factory*)f;

    PJ_ASSERT_RETURN(index == 0, PJMEDIA_EAUD_INVDEV);

    pj_memcpy(info, &af->dev_info, sizeof(*info));

    return PJ_SUCCESS;
}

/* API: create default device parameter */
static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
					 unsigned index,
					 pjmedia_aud_param *param)
{
    struct mda_factory *af = (struct mda_factory*)f;

    PJ_ASSERT_RETURN(index == 0, PJMEDIA_EAUD_INVDEV);

    pj_bzero(param, sizeof(*param));
    param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
    param->rec_id = index;
    param->play_id = index;
    param->clock_rate = af->dev_info.default_samples_per_sec;
    param->channel_count = 1;
    param->samples_per_frame = af->dev_info.default_samples_per_sec * 20 / 1000;
    param->bits_per_sample = BITS_PER_SAMPLE;
    param->flags = af->dev_info.caps;

    return PJ_SUCCESS;
}


/* API: create stream */
static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
					 const pjmedia_aud_param *param,
					 pjmedia_aud_rec_cb rec_cb,
					 pjmedia_aud_play_cb play_cb,
					 void *user_data,
					 pjmedia_aud_stream **p_aud_strm)
{
    struct mda_factory *mf = (struct mda_factory*)f;
    pj_pool_t *pool;
    struct mda_stream *strm;

    /* Can only support 16bits per sample raw PCM format. */
    PJ_ASSERT_RETURN(param->bits_per_sample == BITS_PER_SAMPLE, PJ_EINVAL);
    PJ_ASSERT_RETURN((param->flags & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT)==0 ||
		     param->ext_fmt.id == PJMEDIA_FORMAT_L16,
		     PJ_ENOTSUP);

    /* Create and Initialize stream descriptor */
    pool = pj_pool_create(mf->pf, "symb_aud_dev", 1000, 1000, NULL);
    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);

    strm = PJ_POOL_ZALLOC_T(pool, struct mda_stream);
    strm->pool = pool;
    strm->param = *param;

    // Create the output stream.
    if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
	TRAPD(err, strm->out_engine = CPjAudioOutputEngine::NewL(strm, play_cb,
								 user_data));
	if (err != KErrNone) {
	    pj_pool_release(pool);	
	    return PJ_RETURN_OS_ERROR(err);
	}
    }

    // Create the input stream.
    if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
	TRAPD(err, strm->in_engine = CPjAudioInputEngine::NewL(strm, rec_cb, 
							       user_data));
	if (err != KErrNone) {
	    strm->in_engine = NULL;
	    delete strm->out_engine;
	    strm->out_engine = NULL;
	    pj_pool_release(pool);	
	    return PJ_RETURN_OS_ERROR(err);
	}
    }
	
    /* Done */
    strm->base.op = &stream_op;
    *p_aud_strm = &strm->base;

    return PJ_SUCCESS;
}

/* API: Get stream info. */
static pj_status_t stream_get_param(pjmedia_aud_stream *s,
				    pjmedia_aud_param *pi)
{
    struct mda_stream *strm = (struct mda_stream*)s;

    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);

    pj_memcpy(pi, &strm->param, sizeof(*pi));
    
    return PJ_SUCCESS;
}

/* API: get capability */
static pj_status_t stream_get_cap(pjmedia_aud_stream *s,
				  pjmedia_aud_dev_cap cap,
				  void *pval)
{
    struct mda_stream *strm = (struct mda_stream*)s;
    pj_status_t status = PJ_ENOTSUP;

    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);

    switch (cap) {
    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
	if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
	    PJ_ASSERT_RETURN(strm->in_engine, PJ_EINVAL);
	    
	    TInt max_gain = strm->in_engine->GetMaxGain();
	    TInt gain = strm->in_engine->GetGain();
	    
	    if (max_gain > 0 && gain >= 0) {
		*(unsigned*)pval = gain * 100 / max_gain; 
		status = PJ_SUCCESS;
	    } else {
		status = PJMEDIA_EAUD_NOTREADY;
	    }
	}
	break;
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
	if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
	    PJ_ASSERT_RETURN(strm->out_engine, PJ_EINVAL);
	    
	    TInt max_vol = strm->out_engine->GetMaxVolume();
	    TInt vol = strm->out_engine->GetVolume();
	    
	    if (max_vol > 0 && vol >= 0) {
		*(unsigned*)pval = vol * 100 / max_vol; 
		status = PJ_SUCCESS;
	    } else {
		status = PJMEDIA_EAUD_NOTREADY;
	    }
	}
	break;
    default:
	break;
    }
    
    return status;
}

/* API: set capability */
static pj_status_t stream_set_cap(pjmedia_aud_stream *s,
				  pjmedia_aud_dev_cap cap,
				  const void *pval)
{
    struct mda_stream *strm = (struct mda_stream*)s;
    pj_status_t status = PJ_ENOTSUP;

    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);

    switch (cap) {
    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
	if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
	    PJ_ASSERT_RETURN(strm->in_engine, PJ_EINVAL);
	    
	    TInt max_gain = strm->in_engine->GetMaxGain();
	    if (max_gain > 0) {
		TInt gain;
		
		gain = *(unsigned*)pval * max_gain / 100;
		status = strm->in_engine->SetGain(gain);
	    } else {
		status = PJMEDIA_EAUD_NOTREADY;
	    }
	}
	break;
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
	if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
	    PJ_ASSERT_RETURN(strm->out_engine, PJ_EINVAL);
	    
	    TInt max_vol = strm->out_engine->GetMaxVolume();
	    if (max_vol > 0) {
		TInt vol;
		
		vol = *(unsigned*)pval * max_vol / 100;
		status = strm->out_engine->SetVolume(vol);
	    } else {
		status = PJMEDIA_EAUD_NOTREADY;
	    }
	}
	break;
    default:
	break;
    }
    
    return status;
}

/* API: Start stream. */
static pj_status_t stream_start(pjmedia_aud_stream *strm)
{
    struct mda_stream *stream = (struct mda_stream*)strm;

    PJ_ASSERT_RETURN(stream, PJ_EINVAL);

    if (stream->out_engine) {
	pj_status_t status;
    	status = stream->out_engine->StartPlay();
    	if (status != PJ_SUCCESS)
    	    return status;
    }
    
    if (stream->in_engine) {
	pj_status_t status;
    	status = stream->in_engine->StartRecord();
    	if (status != PJ_SUCCESS)
    	    return status;
    }

    return PJ_SUCCESS;
}

/* API: Stop stream. */
static pj_status_t stream_stop(pjmedia_aud_stream *strm)
{
    struct mda_stream *stream = (struct mda_stream*)strm;

    PJ_ASSERT_RETURN(stream, PJ_EINVAL);

    if (stream->in_engine) {
    	stream->in_engine->Stop();
    }
    	
    if (stream->out_engine) {
    	stream->out_engine->Stop();
    }

    return PJ_SUCCESS;
}


/* API: Destroy stream. */
static pj_status_t stream_destroy(pjmedia_aud_stream *strm)
{
    struct mda_stream *stream = (struct mda_stream*)strm;

    PJ_ASSERT_RETURN(stream, PJ_EINVAL);

    stream_stop(strm);

    delete stream->in_engine;
    stream->in_engine = NULL;

    delete stream->out_engine;
    stream->out_engine = NULL;

    pj_pool_t *pool;
    pool = stream->pool;
    if (pool) {
    	stream->pool = NULL;
    	pj_pool_release(pool);
    }

    return PJ_SUCCESS;
}

#endif /* PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA */
