/* $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 * 
	        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.Length() < frameLen_) {
	pj_memcpy(frameRecBuf_ + frameRecBufLen_, (void*) aBuffer.Ptr(), aBuffer.Length());
	frameRecBufLen_ += aBuffer.Length();
    }

    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.Length();
	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 && aError != KErrCancel) {
    	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 *
		    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;
	}

	if (f.type != PJMEDIA_FRAME_TYPE_AUDIO)
	    pj_bzero(frameBuf_, frameBufSize_);
	
	// 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;
	}

	if (f.type != PJMEDIA_FRAME_TYPE_AUDIO)
	    pj_bzero(frameBuf_, frameBufSize_);
	
	// 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 && aError != KErrCancel) {
    	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);
    
    /* It seems that MDA recorder only supports for mono channel. */
    PJ_ASSERT_RETURN(param->channel_count == 1, PJ_EINVAL);

    /* 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 */
