GF_Err EPOCAudio::Open(u32 sample_rate, Bool stereo) { TInt res = 0; u32 count; TMdaAudioDataSettings::TAudioCaps epoc_sr; switch (sample_rate) { case 8000: epoc_sr = TMdaAudioDataSettings::ESampleRate8000Hz; break; case 11025: epoc_sr = TMdaAudioDataSettings::ESampleRate11025Hz; break; case 12000: epoc_sr = TMdaAudioDataSettings::ESampleRate12000Hz; break; case 16000: epoc_sr = TMdaAudioDataSettings::ESampleRate16000Hz; break; case 22050: epoc_sr = TMdaAudioDataSettings::ESampleRate22050Hz; break; case 24000: epoc_sr = TMdaAudioDataSettings::ESampleRate24000Hz; break; case 32000: epoc_sr = TMdaAudioDataSettings::ESampleRate32000Hz; break; case 44100: epoc_sr = TMdaAudioDataSettings::ESampleRate44100Hz; break; case 48000: epoc_sr = TMdaAudioDataSettings::ESampleRate48000Hz; break; default: return GF_NOT_SUPPORTED; } state = EPOC_AUDIO_INIT; gf_sleep(10); TRAP(res, m_stream = CMdaAudioOutputStream::NewL(*this) ); if ((res!=KErrNone) || !m_stream) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOCAudio] Cannot create output audio stream\n")); return GF_IO_ERR; } m_stream->Open(&m_settings); /*wait for ack - if not getting it in 50*40 = 2sec, abort*/ count = 50; while (count) { if (state == EPOC_AUDIO_OPEN) break; else if (state == EPOC_AUDIO_ERROR) { return GF_IO_ERR; } gf_sleep(40); TInt error; CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); count--; } if (state != EPOC_AUDIO_OPEN) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOCAudio] Failed to open sound device - is it present?\n")); return GF_NOT_SUPPORTED; } TRAP(res, m_stream->SetAudioPropertiesL(epoc_sr, stereo ? TMdaAudioDataSettings::EChannelsStereo : TMdaAudioDataSettings::EChannelsMono) ); m_stream->SetPriority(EPriorityAbsoluteHigh, EMdaPriorityPreferenceTime ); m_stream->SetVolume(init_vol * m_stream->MaxVolume() / 100); current_buffer = nb_buffers_queued = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOCAudio] output audio stream ready - sample rate %d - %d channels\n", sample_rate, stereo ? 2 : 1)); return GF_OK; }
void EPOCAudio::Close(Bool and_wait) { u32 i; if (m_stream) { if (state==EPOC_AUDIO_PLAY) { #if 0 m_stream->Stop(); while (0 && and_wait) { if (state != EPOC_AUDIO_PLAY) break; gf_sleep(1); TInt error; CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); } #endif } delete m_stream; m_stream = NULL; } for (i=0; i<num_buffers; i++) { if (buffers[i]) gf_free(buffers[i]); buffers[i] = NULL; } num_buffers = 0; state = EPOC_AUDIO_INIT; GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOCAudio] output audio stream closed\n")); }
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::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::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); } }