/* $Id$ */
/* 
 * Copyright (C) 2008-2011 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 pj_status_t factory_refresh(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,
    &factory_refresh
};

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_;
    CActiveSchedulerWait     startAsw_;

    // 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);
    
#if defined(PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START) && \
    PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START != 0
    
    startAsw_.Start();
    
#endif
    
    // 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;
    }
    
    if (startAsw_.IsStarted()) {
	startAsw_.AsyncStop();
    }
    
    state_ = STATE_INACTIVE;
}


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

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

    /* Apply input volume setting if specified */
    if (parentStrm_->param.flags & 
        PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING) 
    {
        stream_set_cap(&parentStrm_->base,
                       PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING, 
                       &parentStrm_->param.input_vol);
    }

    // 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()"));
	lastError_ = err2;
	return;
    }

    // input stream opened succesfully, set status to Active
    state_ = STATE_ACTIVE;
}

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_;
    CActiveSchedulerWait     startAsw_;

    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);
    
#if defined(PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START) && \
    PJMEDIA_AUDIO_DEV_MDA_USE_SYNC_START != 0
    
    startAsw_.Start();
    
#endif

    // 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;
    }
    
    if (startAsw_.IsStarted()) {
	startAsw_.AsyncStop();
    }
    
    state_ = STATE_INACTIVE;
}

void CPjAudioOutputEngine::MaoscOpenComplete(TInt aError)
{
    if (startAsw_.IsStarted()) {
	startAsw_.AsyncStop();
    }

    lastError_ = aError;
    
    if (aError==KErrNone) {
	// 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);

        /* Apply output volume setting if specified */
        if (parentStrm_->param.flags & 
            PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) 
        {
            stream_set_cap(&parentStrm_->base,
                           PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 
                           &parentStrm_->param.output_vol);
        } else {
            // 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_);

	// output stream opened succesfully, set status to Active
	state_ = STATE_ACTIVE;
    } 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: refresh the device list */
static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)
{
    PJ_UNUSED_ARG(f);
    return PJ_ENOTSUP;
}

/* 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;
    // Don't set the flags without specifying the flags value.
    //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));
    
    /* Update the output volume setting */
    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
		       &pi->output_vol) == PJ_SUCCESS)
    {
	pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
    }
    
    /* Update the input volume setting */
    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING,
		       &pi->input_vol) == PJ_SUCCESS)
    {
	pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING;
    }
    
    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_PLAYBACK) {
	    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 */
