⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbian_sound.cpp

📁 一个开源的sip源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
								   rec_cb, 
								   user_data);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
}

CPjAudioOutputEngine *
CPjAudioOutputEngine::NewL(pjmedia_snd_stream *parent_strm,
			   pjmedia_snd_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_->channel_count);
    iStreamSettings.iSampleRate = get_clock_rate_cap(parentStrm_->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_->clock_rate, 
    		         parentStrm_->channel_count));
    
    // Open stream.
    lastError_ = KRequestPending;
    iOutputStream_->Open(&iStreamSettings);

    // Wait until callback is called.
    while (lastError_ == KRequestPending)
	pj_thread_sleep(100);

    // Handle failure.
    if (lastError_ != KErrNone) {
	delete iOutputStream_;
	iOutputStream_ = NULL;
	return PJ_RETURN_OS_ERROR(lastError_);
    }

    // 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_thread_sleep(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_->channel_count);
	iSettings.iSampleRate = get_clock_rate_cap(parentStrm_->clock_rate);

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

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

	// Call callback to retrieve frame from upstream.
	pj_status_t status;
	status = playCb_(this->userData_, timestamp_, frameBuf_, 
			 frameBufSize_);
	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.
	TPtrC8 frame(frameBuf_, frameBufSize_);
	iOutputStream_->WriteL(frame);
    } 
}

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.
	pj_status_t status;
	status = playCb_(this->userData_, timestamp_, frameBuf_, 
			 frameBufSize_);
	if (status != PJ_SUCCESS) {
	    this->Stop();
	    return;
	}

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

	// Write to playback stream.
	TPtrC8 frame(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;
    }
}

void CPjAudioOutputEngine::MaoscPlayComplete(TInt aError)
{
    lastError_ = aError;
    state_ = STATE_INACTIVE;
}


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


/*
 * Initialize sound subsystem.
 */
PJ_DEF(pj_status_t) pjmedia_snd_init(pj_pool_factory *factory)
{
    snd_pool_factory = factory;
    return PJ_SUCCESS;
}

/*
 * Get device count.
 */
PJ_DEF(int) pjmedia_snd_get_dev_count(void)
{
    /* Always return 1 */
    return 1;
}

/*
 * Get device info.
 */
PJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index)
{
    /* Always return the default sound device */
    PJ_ASSERT_RETURN(index==0, NULL);
    return &symbian_snd_dev_info;
}



/*
 * Open sound recorder stream.
 */
PJ_DEF(pj_status_t) pjmedia_snd_open_rec( int index,
					  unsigned clock_rate,
					  unsigned channel_count,
					  unsigned samples_per_frame,
					  unsigned bits_per_sample,
					  pjmedia_snd_rec_cb rec_cb,
					  void *user_data,
					  pjmedia_snd_stream **p_snd_strm)
{
    pj_pool_t *pool;
    pjmedia_snd_stream *strm;

    PJ_ASSERT_RETURN(index == 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(clock_rate && channel_count && samples_per_frame &&
    		     bits_per_sample && rec_cb && p_snd_strm, PJ_EINVAL);

    pool = pj_pool_create(snd_pool_factory, POOL_NAME, POOL_SIZE, POOL_INC, 
    			  NULL);
    if (!pool)
	return PJ_ENOMEM;

    strm = (pjmedia_snd_stream*) pj_pool_zalloc(pool, 
    						sizeof(pjmedia_snd_stream));
    strm->pool = pool;
    strm->clock_rate = clock_rate;
    strm->channel_count = channel_count;
    strm->samples_per_frame = samples_per_frame;

    TMdaAudioDataSettings settings;
    TInt clockRateCap, channelCountCap;

    clockRateCap = get_clock_rate_cap(clock_rate);
    channelCountCap = get_channel_cap(channel_count);

    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);
    PJ_ASSERT_RETURN(clockRateCap != 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(channelCountCap != 0, PJ_EINVAL);

    // Create the input stream.
    TRAPD(err, strm->inEngine = CPjAudioInputEngine::NewL(strm, rec_cb, 
    							  user_data));
    if (err != KErrNone) {
    	pj_pool_release(pool);
	return PJ_RETURN_OS_ERROR(err);
    }


    // Done.
    *p_snd_strm = strm;
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
					unsigned clock_rate,
					unsigned channel_count,
					unsigned samples_per_frame,
					unsigned bits_per_sample,
					pjmedia_snd_play_cb play_cb,
					void *user_data,
					pjmedia_snd_stream **p_snd_strm )
{
    pj_pool_t *pool;
    pjmedia_snd_stream *strm;

    PJ_ASSERT_RETURN(index == 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(clock_rate && channel_count && samples_per_frame &&
    		     bits_per_sample && play_cb && p_snd_strm, PJ_EINVAL);

    pool = pj_pool_create(snd_pool_factory, POOL_NAME, POOL_SIZE, POOL_INC, 
    			  NULL);
    if (!pool)
	return PJ_ENOMEM;

    strm = (pjmedia_snd_stream*) pj_pool_zalloc(pool, 
    						sizeof(pjmedia_snd_stream));
    strm->pool = pool;
    strm->clock_rate = clock_rate;
    strm->channel_count = channel_count;
    strm->samples_per_frame = samples_per_frame;

    TMdaAudioDataSettings settings;
    TInt clockRateCap, channelCountCap;

    clockRateCap = get_clock_rate_cap(clock_rate);
    channelCountCap = get_channel_cap(channel_count);

    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);
    PJ_ASSERT_RETURN(clockRateCap != 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(channelCountCap != 0, PJ_EINVAL);

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

    // Done.
    *p_snd_strm = strm;
    return PJ_SUCCESS;
}

PJ_DEF(pj_status_t) pjmedia_snd_open( int rec_id,
				      int play_id,
				      unsigned clock_rate,
				      unsigned channel_count,
				      unsigned samples_per_frame,
				      unsigned bits_per_sample,
				      pjmedia_snd_rec_cb rec_cb,
				      pjmedia_snd_play_cb play_cb,
				      void *user_data,
				      pjmedia_snd_stream **p_snd_strm)
{
    pj_pool_t *pool;
    pjmedia_snd_stream *strm;

    PJ_ASSERT_RETURN(rec_id == 0 && play_id == 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(clock_rate && channel_count && samples_per_frame &&
    		     bits_per_sample && rec_cb && play_cb && p_snd_strm, 
    		     PJ_EINVAL);

    pool = pj_pool_create(snd_pool_factory, POOL_NAME, POOL_SIZE, POOL_INC, 
    			  NULL);
    if (!pool)
	return PJ_ENOMEM;

    strm = (pjmedia_snd_stream*) pj_pool_zalloc(pool, 
    						sizeof(pjmedia_snd_stream));
    strm->pool = pool;
    strm->clock_rate = clock_rate;
    strm->channel_count = channel_count;
    strm->samples_per_frame = samples_per_frame;

    TMdaAudioDataSettings settings;
    TInt clockRateCap, channelCountCap;

    clockRateCap = get_clock_rate_cap(clock_rate);
    channelCountCap = get_channel_cap(channel_count);

    PJ_ASSERT_RETURN(bits_per_sample == 16, PJ_EINVAL);
    PJ_ASSERT_RETURN(clockRateCap != 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(channelCountCap != 0, PJ_EINVAL);

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

    // Done.
    *p_snd_strm = strm;
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream)
{
    pj_status_t status;
    
    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
    
    if (stream->inEngine) {
    	status = stream->inEngine->StartRecord();
    	if (status != PJ_SUCCESS)
    	    return status;
    }
    	
    if (stream->outEngine) {
    	status = stream->outEngine->StartPlay();
    	if (status != PJ_SUCCESS)
    	    return status;
    }
    
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream)
{
    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
    
    if (stream->inEngine) {
    	stream->inEngine->Stop();
    }
    	
    if (stream->outEngine) {
    	stream->outEngine->Stop();
    }
    
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream)
{
    pj_pool_t *pool;
    
    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
    
    if (stream->inEngine) {
    	delete stream->inEngine;
    	stream->inEngine = NULL;
    }

    if (stream->outEngine) {
    	delete stream->outEngine;
    	stream->outEngine = NULL;
    }
    
    pool = stream->pool;
    if (pool) {	
    	stream->pool = NULL;
    	pj_pool_release(pool);
    }
    
    return PJ_SUCCESS;
}


PJ_DEF(pj_status_t) pjmedia_snd_deinit(void)
{
    /* Nothing to do */
    return PJ_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -